From febeeb8dd669c215dbaa1e063f1aea40dd2ff7c2 Mon Sep 17 00:00:00 2001 From: fdocr Date: Sat, 30 Sep 2023 01:06:52 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20fdocr/Cr?= =?UTF-8?q?ystalSnake@43319d894148e9dd1352d4841842c4da6f749ab9=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ApplicationJob.html | 10 ++++----- ApplicationRecord.html | 2 +- BattleSnake.html | 2 +- BattleSnake/Board.html | 32 +++++++++++++-------------- BattleSnake/Context.html | 32 +++++++++++++-------------- BattleSnake/Game.html | 24 ++++++++++---------- BattleSnake/Point.html | 32 +++++++++++++-------------- BattleSnake/Ruleset.html | 16 +++++++------- BattleSnake/Settings.html | 24 ++++++++++---------- BattleSnake/Snake.html | 40 +++++++++++++++++----------------- LTree.html | 16 +++++++------- PersistTurnJob.html | 28 ++++++++++++------------ Strategy.html | 4 ++-- Strategy/Base.html | 6 ++--- Strategy/BlastRandomValid.html | 4 ++-- Strategy/CautiousCarol.html | 4 ++-- Strategy/ChaseClosestFood.html | 4 ++-- Strategy/ChaseRandomFood.html | 4 ++-- Strategy/Random.html | 4 ++-- Strategy/RandomValid.html | 4 ++-- Strategy/Utils.html | 6 ++--- Turn.html | 6 ++--- index.json | 2 +- search-index.js | 2 +- toplevel.html | 4 ++-- 25 files changed, 156 insertions(+), 156 deletions(-) diff --git a/ApplicationJob.html b/ApplicationJob.html index e595976..88d7176 100644 --- a/ApplicationJob.html +++ b/ApplicationJob.html @@ -263,7 +263,7 @@

- + jobs/application_job.cr @@ -432,7 +432,7 @@


- [View source] + [View source]
@@ -469,7 +469,7 @@


- [View source] + [View source]
@@ -494,7 +494,7 @@


- [View source] + [View source]
@@ -531,7 +531,7 @@


- [View source] + [View source]
diff --git a/ApplicationRecord.html b/ApplicationRecord.html index 324dff3..7ef8536 100644 --- a/ApplicationRecord.html +++ b/ApplicationRecord.html @@ -248,7 +248,7 @@

- + models/application_record.cr diff --git a/BattleSnake.html b/BattleSnake.html index cde492a..0f2c693 100644 --- a/BattleSnake.html +++ b/BattleSnake.html @@ -232,7 +232,7 @@

- + battle_snake/board.cr diff --git a/BattleSnake/Board.html b/BattleSnake/Board.html index d960ac3..3fbf25e 100644 --- a/BattleSnake/Board.html +++ b/BattleSnake/Board.html @@ -262,7 +262,7 @@

- + battle_snake/board.cr @@ -437,7 +437,7 @@


- [View source] + [View source]
@@ -467,7 +467,7 @@


- [View source] + [View source]
@@ -490,7 +490,7 @@


- [View source] + [View source]
@@ -506,7 +506,7 @@


- [View source] + [View source]
@@ -522,7 +522,7 @@


- [View source] + [View source]
@@ -538,7 +538,7 @@


- [View source] + [View source]
@@ -554,7 +554,7 @@


- [View source] + [View source]
@@ -570,7 +570,7 @@


- [View source] + [View source]
@@ -586,7 +586,7 @@


- [View source] + [View source]
@@ -602,7 +602,7 @@


- [View source] + [View source]
@@ -618,7 +618,7 @@


- [View source] + [View source]
@@ -634,7 +634,7 @@


- [View source] + [View source]
@@ -650,7 +650,7 @@


- [View source] + [View source]
@@ -666,7 +666,7 @@


- [View source] + [View source]
@@ -682,7 +682,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Context.html b/BattleSnake/Context.html index 9a433d7..cfa2a3f 100644 --- a/BattleSnake/Context.html +++ b/BattleSnake/Context.html @@ -262,7 +262,7 @@

- + battle_snake/context.cr @@ -445,7 +445,7 @@


- [View source] + [View source]
@@ -491,7 +491,7 @@


- [View source] + [View source]
@@ -507,7 +507,7 @@


- [View source] + [View source]
@@ -523,7 +523,7 @@


- [View source] + [View source]
@@ -544,7 +544,7 @@


- [View source] + [View source]
@@ -571,7 +571,7 @@


- [View source] + [View source]
@@ -587,7 +587,7 @@


- [View source] + [View source]
@@ -603,7 +603,7 @@


- [View source] + [View source]
@@ -619,7 +619,7 @@


- [View source] + [View source]
@@ -642,7 +642,7 @@


- [View source] + [View source]
@@ -658,7 +658,7 @@


- [View source] + [View source]
@@ -674,7 +674,7 @@


- [View source] + [View source]
@@ -712,7 +712,7 @@


- [View source] + [View source]
@@ -728,7 +728,7 @@


- [View source] + [View source]
@@ -744,7 +744,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Game.html b/BattleSnake/Game.html index 1ee4983..59d73ee 100644 --- a/BattleSnake/Game.html +++ b/BattleSnake/Game.html @@ -248,7 +248,7 @@

- + battle_snake/game.cr @@ -401,7 +401,7 @@


- [View source] + [View source]
@@ -431,7 +431,7 @@


- [View source] + [View source]
@@ -447,7 +447,7 @@


- [View source] + [View source]
@@ -463,7 +463,7 @@


- [View source] + [View source]
@@ -479,7 +479,7 @@


- [View source] + [View source]
@@ -495,7 +495,7 @@


- [View source] + [View source]
@@ -511,7 +511,7 @@


- [View source] + [View source]
@@ -527,7 +527,7 @@


- [View source] + [View source]
@@ -543,7 +543,7 @@


- [View source] + [View source]
@@ -559,7 +559,7 @@


- [View source] + [View source]
@@ -575,7 +575,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Point.html b/BattleSnake/Point.html index dad44d3..ea2f235 100644 --- a/BattleSnake/Point.html +++ b/BattleSnake/Point.html @@ -262,7 +262,7 @@

- + battle_snake/point.cr @@ -470,7 +470,7 @@


- [View source] + [View source]
@@ -486,7 +486,7 @@


- [View source] + [View source]
@@ -507,7 +507,7 @@


- [View source] + [View source]
@@ -556,7 +556,7 @@


- [View source] + [View source]
@@ -577,7 +577,7 @@


- [View source] + [View source]
@@ -598,7 +598,7 @@


- [View source] + [View source]
@@ -620,7 +620,7 @@


- [View source] + [View source]
@@ -660,7 +660,7 @@


- [View source] + [View source]
@@ -681,7 +681,7 @@


- [View source] + [View source]
@@ -704,7 +704,7 @@


- [View source] + [View source]
@@ -725,7 +725,7 @@


- [View source] + [View source]
@@ -741,7 +741,7 @@


- [View source] + [View source]
@@ -757,7 +757,7 @@


- [View source] + [View source]
@@ -773,7 +773,7 @@


- [View source] + [View source]
@@ -789,7 +789,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Ruleset.html b/BattleSnake/Ruleset.html index e686d44..37ed6a5 100644 --- a/BattleSnake/Ruleset.html +++ b/BattleSnake/Ruleset.html @@ -248,7 +248,7 @@

- + battle_snake/ruleset.cr @@ -381,7 +381,7 @@


- [View source] + [View source]
@@ -411,7 +411,7 @@


- [View source] + [View source]
@@ -427,7 +427,7 @@


- [View source] + [View source]
@@ -443,7 +443,7 @@


- [View source] + [View source]
@@ -459,7 +459,7 @@


- [View source] + [View source]
@@ -475,7 +475,7 @@


- [View source] + [View source]
@@ -491,7 +491,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Settings.html b/BattleSnake/Settings.html index 740637d..9d66b9e 100644 --- a/BattleSnake/Settings.html +++ b/BattleSnake/Settings.html @@ -248,7 +248,7 @@

- + battle_snake/settings.cr @@ -401,7 +401,7 @@


- [View source] + [View source]
@@ -431,7 +431,7 @@


- [View source] + [View source]
@@ -447,7 +447,7 @@


- [View source] + [View source]
@@ -463,7 +463,7 @@


- [View source] + [View source]
@@ -479,7 +479,7 @@


- [View source] + [View source]
@@ -495,7 +495,7 @@


- [View source] + [View source]
@@ -511,7 +511,7 @@


- [View source] + [View source]
@@ -527,7 +527,7 @@


- [View source] + [View source]
@@ -543,7 +543,7 @@


- [View source] + [View source]
@@ -559,7 +559,7 @@


- [View source] + [View source]
@@ -575,7 +575,7 @@


- [View source] + [View source]
diff --git a/BattleSnake/Snake.html b/BattleSnake/Snake.html index a7e534d..ee16492 100644 --- a/BattleSnake/Snake.html +++ b/BattleSnake/Snake.html @@ -248,7 +248,7 @@

- + battle_snake/snake.cr @@ -441,7 +441,7 @@


- [View source] + [View source]
@@ -471,7 +471,7 @@


- [View source] + [View source]
@@ -487,7 +487,7 @@


- [View source] + [View source]
@@ -503,7 +503,7 @@


- [View source] + [View source]
@@ -519,7 +519,7 @@


- [View source] + [View source]
@@ -535,7 +535,7 @@


- [View source] + [View source]
@@ -551,7 +551,7 @@


- [View source] + [View source]
@@ -567,7 +567,7 @@


- [View source] + [View source]
@@ -583,7 +583,7 @@


- [View source] + [View source]
@@ -599,7 +599,7 @@


- [View source] + [View source]
@@ -615,7 +615,7 @@


- [View source] + [View source]
@@ -631,7 +631,7 @@


- [View source] + [View source]
@@ -647,7 +647,7 @@


- [View source] + [View source]
@@ -663,7 +663,7 @@


- [View source] + [View source]
@@ -679,7 +679,7 @@


- [View source] + [View source]
@@ -695,7 +695,7 @@


- [View source] + [View source]
@@ -711,7 +711,7 @@


- [View source] + [View source]
@@ -727,7 +727,7 @@


- [View source] + [View source]
@@ -743,7 +743,7 @@


- [View source] + [View source]
diff --git a/LTree.html b/LTree.html index dc920b9..b164eac 100644 --- a/LTree.html +++ b/LTree.html @@ -249,7 +249,7 @@

- + l_tree.cr @@ -372,7 +372,7 @@


- [View source] + [View source]
@@ -402,7 +402,7 @@


- [View source] + [View source]
@@ -418,7 +418,7 @@


- [View source] + [View source]
@@ -434,7 +434,7 @@


- [View source] + [View source]
@@ -450,7 +450,7 @@


- [View source] + [View source]
@@ -466,7 +466,7 @@


- [View source] + [View source]
@@ -482,7 +482,7 @@


- [View source] + [View source]
diff --git a/PersistTurnJob.html b/PersistTurnJob.html index 671e4bd..3a1005b 100644 --- a/PersistTurnJob.html +++ b/PersistTurnJob.html @@ -234,7 +234,7 @@

- + jobs/persist_turn_job.cr @@ -476,7 +476,7 @@


- [View source] + [View source]
@@ -492,7 +492,7 @@


- [View source] + [View source]
@@ -520,7 +520,7 @@


- [View source] + [View source]
@@ -561,7 +561,7 @@


- [View source] + [View source]
@@ -577,7 +577,7 @@


- [View source] + [View source]
@@ -593,7 +593,7 @@


- [View source] + [View source]
@@ -609,7 +609,7 @@


- [View source] + [View source]
@@ -625,7 +625,7 @@


- [View source] + [View source]
@@ -641,7 +641,7 @@


- [View source] + [View source]
@@ -657,7 +657,7 @@


- [View source] + [View source]
@@ -673,7 +673,7 @@


- [View source] + [View source]
@@ -689,7 +689,7 @@


- [View source] + [View source]
@@ -717,7 +717,7 @@


- [View source] + [View source]
diff --git a/Strategy.html b/Strategy.html index 237860f..4f74809 100644 --- a/Strategy.html +++ b/Strategy.html @@ -244,7 +244,7 @@

- + strategy/base.cr @@ -326,7 +326,7 @@


- [View source] + [View source]
diff --git a/Strategy/Base.html b/Strategy/Base.html index 8c9217d..e325d93 100644 --- a/Strategy/Base.html +++ b/Strategy/Base.html @@ -258,7 +258,7 @@

- + strategy/base.cr @@ -358,7 +358,7 @@


- [View source] + [View source]
@@ -393,7 +393,7 @@


- [View source] + [View source]
diff --git a/Strategy/BlastRandomValid.html b/Strategy/BlastRandomValid.html index b0f6a87..b7b7ba6 100644 --- a/Strategy/BlastRandomValid.html +++ b/Strategy/BlastRandomValid.html @@ -247,7 +247,7 @@

- + strategy/blast_random_valid.cr @@ -371,7 +371,7 @@


- [View source] + [View source]
diff --git a/Strategy/CautiousCarol.html b/Strategy/CautiousCarol.html index eb8030f..0024d5a 100644 --- a/Strategy/CautiousCarol.html +++ b/Strategy/CautiousCarol.html @@ -248,7 +248,7 @@

- + strategy/cautious_carol.cr @@ -372,7 +372,7 @@


- [View source] + [View source]
diff --git a/Strategy/ChaseClosestFood.html b/Strategy/ChaseClosestFood.html index 532aa73..d8ecffd 100644 --- a/Strategy/ChaseClosestFood.html +++ b/Strategy/ChaseClosestFood.html @@ -245,7 +245,7 @@

- + strategy/chase_closest_food.cr @@ -369,7 +369,7 @@


- [View source] + [View source]
diff --git a/Strategy/ChaseRandomFood.html b/Strategy/ChaseRandomFood.html index 18e9cc3..f400466 100644 --- a/Strategy/ChaseRandomFood.html +++ b/Strategy/ChaseRandomFood.html @@ -245,7 +245,7 @@

- + strategy/chase_random_food.cr @@ -369,7 +369,7 @@


- [View source] + [View source]
diff --git a/Strategy/Random.html b/Strategy/Random.html index 12678c0..97e37bf 100644 --- a/Strategy/Random.html +++ b/Strategy/Random.html @@ -245,7 +245,7 @@

- + strategy/random.cr @@ -369,7 +369,7 @@


- [View source] + [View source]
diff --git a/Strategy/RandomValid.html b/Strategy/RandomValid.html index 7c6b12a..2fbf1c9 100644 --- a/Strategy/RandomValid.html +++ b/Strategy/RandomValid.html @@ -245,7 +245,7 @@

- + strategy/random_valid.cr @@ -369,7 +369,7 @@


- [View source] + [View source]
diff --git a/Strategy/Utils.html b/Strategy/Utils.html index 50b2b42..227f9d4 100644 --- a/Strategy/Utils.html +++ b/Strategy/Utils.html @@ -234,7 +234,7 @@

- + strategy/utils.cr @@ -343,7 +343,7 @@


- [View source] + [View source]
@@ -368,7 +368,7 @@


- [View source] + [View source]
diff --git a/Turn.html b/Turn.html index 756f600..c44b8dd 100644 --- a/Turn.html +++ b/Turn.html @@ -247,7 +247,7 @@

- + models/turn.cr @@ -1708,7 +1708,7 @@


- [View source] + [View source]
@@ -1724,7 +1724,7 @@


- [View source] + [View source]
diff --git a/index.json b/index.json index ac0e631..e338597 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -{"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Fernando Valverde](https://github.com/fdocr) - creator and maintainer\n","program":{"html_id":"CrystalSnake/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"ancestors":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"locations":[],"repository_name":"CrystalSnake","program":true,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"extended_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"class_methods":[{"html_id":"truncate_uuid(str)-class-method","name":"truncate_uuid","abstract":false,"args":[{"name":"str","external_name":"str","restriction":""}],"args_string":"(str)","args_html":"(str)","location":{"filename":"src/app.cr","line_number":35,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/app.cr#L35"},"def":{"name":"truncate_uuid","args":[{"name":"str","external_name":"str","restriction":""}],"visibility":"Public","body":"\"#{str[0..7]}...#{str[24..32]}\""}}],"macros":[{"html_id":"persist_turn!-macro","name":"persist_turn!","abstract":false,"location":{"filename":"src/app.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/app.cr#L28"},"def":{"name":"persist_turn!","visibility":"Public","body":" PersistTurnJob.new(\n path: \nenv.request.path,\n context_json: \nenv.params.json.to_json\n ).enqueue if persist_to_db\n\n"}}],"types":[{"html_id":"CrystalSnake/ApplicationJob","path":"ApplicationJob.html","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob","abstract":true,"superclass":{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},"ancestors":[{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/PersistTurnJob","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob"}],"doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"

abstract, override in a Job descendant to do something productive

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"

Represents the Board as it arrives from the BattleSnake API endpoint.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"

Executed on #after_initialize callback and all it does is populate snake_points variable (Array(Point)) with all points that belong to a snake on the board

","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":32,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L32"},"def":{"name":"find_snake_points","visibility":"Public","body":"snakes.each do |snake|\n snake.body.each do |point|\n if @snake_points.includes?(point)\n else\n @snake_points << point\n end\n end\nend"}},{"html_id":"food:Array(Point)-instance-method","name":"food","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L21"},"def":{"name":"food","return_type":"Array(Point)","visibility":"Public","body":"@food"}},{"html_id":"food=(food:Array(Point))-instance-method","name":"food=","abstract":false,"args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"args_string":"(food : Array(Point))","args_html":"(food : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L21"},"def":{"name":"food=","args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"visibility":"Public","body":"@food = food"}},{"html_id":"hazards:Array(Point)-instance-method","name":"hazards","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L24"},"def":{"name":"hazards","return_type":"Array(Point)","visibility":"Public","body":"@hazards"}},{"html_id":"hazards=(hazards:Array(Point))-instance-method","name":"hazards=","abstract":false,"args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"args_string":"(hazards : Array(Point))","args_html":"(hazards : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L24"},"def":{"name":"hazards=","args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"visibility":"Public","body":"@hazards = hazards"}},{"html_id":"height:Int32-instance-method","name":"height","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L12"},"def":{"name":"height","return_type":"Int32","visibility":"Public","body":"@height"}},{"html_id":"height=(height:Int32)-instance-method","name":"height=","abstract":false,"args":[{"name":"height","external_name":"height","restriction":"Int32"}],"args_string":"(height : Int32)","args_html":"(height : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L12"},"def":{"name":"height=","args":[{"name":"height","external_name":"height","restriction":"Int32"}],"visibility":"Public","body":"@height = height"}},{"html_id":"living?(id)-instance-method","name":"living?","abstract":false,"args":[{"name":"id","external_name":"id","restriction":""}],"args_string":"(id)","args_html":"(id)","location":{"filename":"src/battle_snake/board.cr","line_number":40,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L40"},"def":{"name":"living?","args":[{"name":"id","external_name":"id","restriction":""}],"visibility":"Public","body":"snakes.index do |snake|\n snake.id == id\nend"}},{"html_id":"snake_points:Array(Point)-instance-method","name":"snake_points","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":27,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L27"},"def":{"name":"snake_points","return_type":"Array(Point)","visibility":"Public","body":"@snake_points"}},{"html_id":"snakes:Array(Snake)-instance-method","name":"snakes","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L18"},"def":{"name":"snakes","return_type":"Array(Snake)","visibility":"Public","body":"@snakes"}},{"html_id":"snakes=(snakes:Array(Snake))-instance-method","name":"snakes=","abstract":false,"args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"args_string":"(snakes : Array(Snake))","args_html":"(snakes : Array(Snake))","location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L18"},"def":{"name":"snakes=","args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"visibility":"Public","body":"@snakes = snakes"}},{"html_id":"width:Int32-instance-method","name":"width","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L15"},"def":{"name":"width","return_type":"Int32","visibility":"Public","body":"@width"}},{"html_id":"width=(width:Int32)-instance-method","name":"width=","abstract":false,"args":[{"name":"width","external_name":"width","restriction":"Int32"}],"args_string":"(width : Int32)","args_html":"(width : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L15"},"def":{"name":"width=","args":[{"name":"width","external_name":"width","restriction":"Int32"}],"visibility":"Public","body":"@width = width"}}]},{"html_id":"CrystalSnake/BattleSnake/Context","path":"BattleSnake/Context.html","kind":"class","full_name":"BattleSnake::Context","name":"Context","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/context.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"A BattleSnake::Context is the representation of the game as it arrives from\nthe [Webhook API](https://docs.battlesnake.com/api) request to `src/app.cr`\nendpoints.\n\nThe context's key method is `#valid_moves`","summary":"

A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr endpoints.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/context.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"blast_valid_moves!-instance-method","name":"blast_valid_moves!","doc":"Similar to `BattleSnake::Context#valid_moves` but considers all valid\nmoves from enemies. Returns a hash with all the valid `:moves`,\n`:neighbors` and `:risky_moves` (we might collide with enemy) available\nfor `you`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:risky_moves` is an `Array(BattleSnake::Point)` that containts the\ndirections from the given `#point` that are valid to move but there's a\nchance we could die (`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.","summary":"

Similar to BattleSnake::Context#valid_moves but considers all valid moves from enemies.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":105,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L105"},"def":{"name":"blast_valid_moves!","visibility":"Public","body":"moves = [] of String\nrisky_moves = [] of String\nyou.body.pop\nindex = board.snakes.index! do |snake|\n snake.id == you.id\nend\nboard.snakes[index].body.pop\npossible_moves = valid_moves(you.head)\nenemy_valid_moves = {} of String => Array(String)\nenemies.each_with_index do |snake, index|\n snake_moves = (valid_moves(snake.head))[:moves]\n if snake_moves.empty?\n else\n enemy_valid_moves[snake.id] = snake_moves\n end\nend\nif enemy_valid_moves.empty?\n return {moves: possible_moves[:moves], neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\nend\ncontexts = [] of BattleSnake::Context\npermutations = enemy_valid_moves.values.map(&.size).reduce do |acc, i|\n acc * i\nend\npermutations.times do\n contexts << self.dup\nend\ncontexts.each_with_index do |context, index|\n offset = 1\n enemy_valid_moves.each do |snake_id, moves|\n direction = moves[(index / offset).floor.to_i % moves.size]\n context.move(snake_id, direction)\n offset = offset * moves.size\n end\nend\npossible_moves[:moves].each do |direction|\n target = possible_moves[:neighbors][direction]\n collision = contexts.find do |context|\n context.board.snake_points.includes?(target)\n end\n if collision.nil?\n moves << direction\n else\n risky_moves << direction\n end\nend\n{moves: moves, neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\n"}},{"html_id":"board:Board-instance-method","name":"board","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L18"},"def":{"name":"board","return_type":"Board","visibility":"Public","body":"@board"}},{"html_id":"board=(board:Board)-instance-method","name":"board=","abstract":false,"args":[{"name":"board","external_name":"board","restriction":"Board"}],"args_string":"(board : Board)","args_html":"(board : Board)","location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L18"},"def":{"name":"board=","args":[{"name":"board","external_name":"board","restriction":"Board"}],"visibility":"Public","body":"@board = board"}},{"html_id":"check_collisions-instance-method","name":"check_collisions","doc":"Checks collisions from snakes on the board and removes snakes that die","summary":"

Checks collisions from snakes on the board and removes snakes that die

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"

Returns a shallow copy of this object.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"

Simulate a move of a snake by id in some direction.

","abstract":false,"args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"args_string":"(snake_id, direction, pop_body = true)","args_html":"(snake_id, direction, pop_body = true)","location":{"filename":"src/battle_snake/context.cr","line_number":169,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L169"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\nif pop_body\n deleted_point = board.snakes[index].body.pop\nend\nboard.snakes[index].head = board.snakes[index].head.move(direction)\nboard.snakes[index].body.unshift(board.snakes[index].head)\nif @you.id == snake_id\n @you = board.snakes[index]\nend\nboard.snake_points.clear\nboard.find_snake_points\n"}},{"html_id":"turn:Int32-instance-method","name":"turn","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L15"},"def":{"name":"turn","return_type":"Int32","visibility":"Public","body":"@turn"}},{"html_id":"turn=(turn:Int32)-instance-method","name":"turn=","abstract":false,"args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"args_string":"(turn : Int32)","args_html":"(turn : Int32)","location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L15"},"def":{"name":"turn=","args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"visibility":"Public","body":"@turn = turn"}},{"html_id":"valid_moves(point:Point)-instance-method","name":"valid_moves","doc":"Returns a hash with all the valid `:moves` and `:neighbors` available from\na given `BattleSnake::Point`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.\n\nExample:\n\n```\ncontext.valid_moves(Point.new(1,1))\n=> {\n moves: [ \"up\", \"right\" ],\n neighbors: { Point.new(2,1), Point.new(1,2) }\n}\n```\n\nNOTE: A common method to help manipulate the results is\n`BattleSnake::Point#move?`. An example of this in practice is the\n`Strategy::Utils.a_star` method implementation.\n\nTODO: Take into account the last point of snakes that will move on next\nturn, which would be in fact valid moves (not counted at the moment).","summary":"

Returns a hash with all the valid :moves and :neighbors available from a given BattleSnake::Point.

","abstract":false,"args":[{"name":"point","external_name":"point","restriction":"Point"}],"args_string":"(point : Point)","args_html":"(point : Point)","location":{"filename":"src/battle_snake/context.cr","line_number":59,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L59"},"def":{"name":"valid_moves","args":[{"name":"point","external_name":"point","restriction":"Point"}],"visibility":"Public","body":"moves = [] of String\nneighbors = {} of String => Point\nup = point.up\nif up.y < board.height && (!(board.snake_points.includes?(up)))\n moves << \"up\"\n neighbors[\"up\"] = up\nend\nleft = point.left\nif left.x >= 0 && (!(board.snake_points.includes?(left)))\n moves << \"left\"\n neighbors[\"left\"] = left\nend\ndown = point.down\nif down.y >= 0 && (!(board.snake_points.includes?(down)))\n moves << \"down\"\n neighbors[\"down\"] = down\nend\nright = point.right\nif right.x < board.width && (!(board.snake_points.includes?(right)))\n moves << \"right\"\n neighbors[\"right\"] = right\nend\n{moves: moves, neighbors: neighbors}\n"}},{"html_id":"you:Snake-instance-method","name":"you","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L21"},"def":{"name":"you","return_type":"Snake","visibility":"Public","body":"@you"}},{"html_id":"you=(you:Snake)-instance-method","name":"you=","abstract":false,"args":[{"name":"you","external_name":"you","restriction":"Snake"}],"args_string":"(you : Snake)","args_html":"(you : Snake)","location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L21"},"def":{"name":"you=","args":[{"name":"you","external_name":"you","restriction":"Snake"}],"visibility":"Public","body":"@you = you"}}]},{"html_id":"CrystalSnake/BattleSnake/Game","path":"BattleSnake/Game.html","kind":"class","full_name":"BattleSnake::Game","name":"Game","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/game.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/game.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"map:String-instance-method","name":"map","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L13"},"def":{"name":"map","return_type":"String","visibility":"Public","body":"@map"}},{"html_id":"map=(map:String)-instance-method","name":"map=","abstract":false,"args":[{"name":"map","external_name":"map","restriction":"String"}],"args_string":"(map : String)","args_html":"(map : String)","location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L13"},"def":{"name":"map=","args":[{"name":"map","external_name":"map","restriction":"String"}],"visibility":"Public","body":"@map = map"}},{"html_id":"ruleset:Ruleset-instance-method","name":"ruleset","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset","return_type":"Ruleset","visibility":"Public","body":"@ruleset"}},{"html_id":"ruleset=(ruleset:Ruleset)-instance-method","name":"ruleset=","abstract":false,"args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"args_string":"(ruleset : Ruleset)","args_html":"(ruleset : Ruleset)","location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset=","args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"visibility":"Public","body":"@ruleset = ruleset"}},{"html_id":"source:String-instance-method","name":"source","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L19"},"def":{"name":"source","return_type":"String","visibility":"Public","body":"@source"}},{"html_id":"source=(source:String)-instance-method","name":"source=","abstract":false,"args":[{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(source : String)","args_html":"(source : String)","location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L19"},"def":{"name":"source=","args":[{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"@source = source"}},{"html_id":"timeout:Int32-instance-method","name":"timeout","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L16"},"def":{"name":"timeout","return_type":"Int32","visibility":"Public","body":"@timeout"}},{"html_id":"timeout=(timeout:Int32)-instance-method","name":"timeout=","abstract":false,"args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"args_string":"(timeout : Int32)","args_html":"(timeout : Int32)","location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L16"},"def":{"name":"timeout=","args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"visibility":"Public","body":"@timeout = timeout"}}]},{"html_id":"CrystalSnake/BattleSnake/Point","path":"BattleSnake/Point.html","kind":"class","full_name":"BattleSnake::Point","name":"Point","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/point.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents a Point (x,y) coordinate on the board with some helper methods for\nprocessing of the board (i.e. `#move?`)","summary":"

Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.

","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"

Initialize from two Int32 values

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"

Initialize from a string representation i.e.

","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"

The comparison operator.

","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"

Returns a new Point directly down from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"

Returns a new Point directly left from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"

Returns the point when it moves in a direction.

","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"

Determines if a given target BattleSnake::Point is reachable.

","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"

Returns a new Point directly right from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"

Returns the String representation of the Point.

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"

Returns a new Point directly up from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"

Basic implementation of a Tree data structure.

","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"

Abstract class of all strategies.

","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"

Strategy that chases the closest available food from the board with caution against head-to-head collisions.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"

Strategy that chases the closest food from the board from You

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"

Strategy that chases randomly selected food from the board

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"

A strategy that chooses a random direction to move without any considerations

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"

Implementation of A* Search Algorithm (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"

Implementation of Flood Fill (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"

This is a DB record representation of a request from a game for either start/move/end request.

","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"

Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.

","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"

Deletes object from db and calls all related callbacks.

","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}} \ No newline at end of file +{"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Fernando Valverde](https://github.com/fdocr) - creator and maintainer\n","program":{"html_id":"CrystalSnake/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"ancestors":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"locations":[],"repository_name":"CrystalSnake","program":true,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"extended_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"class_methods":[{"html_id":"truncate_uuid(str)-class-method","name":"truncate_uuid","abstract":false,"args":[{"name":"str","external_name":"str","restriction":""}],"args_string":"(str)","args_html":"(str)","location":{"filename":"src/app.cr","line_number":35,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/app.cr#L35"},"def":{"name":"truncate_uuid","args":[{"name":"str","external_name":"str","restriction":""}],"visibility":"Public","body":"\"#{str[0..7]}...#{str[24..32]}\""}}],"macros":[{"html_id":"persist_turn!-macro","name":"persist_turn!","abstract":false,"location":{"filename":"src/app.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/app.cr#L28"},"def":{"name":"persist_turn!","visibility":"Public","body":" PersistTurnJob.new(\n path: \nenv.request.path,\n context_json: \nenv.params.json.to_json\n ).enqueue if persist_to_db\n\n"}}],"types":[{"html_id":"CrystalSnake/ApplicationJob","path":"ApplicationJob.html","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob","abstract":true,"superclass":{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},"ancestors":[{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/PersistTurnJob","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob"}],"doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"

abstract, override in a Job descendant to do something productive

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"

Represents the Board as it arrives from the BattleSnake API endpoint.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"

Executed on #after_initialize callback and all it does is populate snake_points variable (Array(Point)) with all points that belong to a snake on the board

","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":32,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L32"},"def":{"name":"find_snake_points","visibility":"Public","body":"snakes.each do |snake|\n snake.body.each do |point|\n if @snake_points.includes?(point)\n else\n @snake_points << point\n end\n end\nend"}},{"html_id":"food:Array(Point)-instance-method","name":"food","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L21"},"def":{"name":"food","return_type":"Array(Point)","visibility":"Public","body":"@food"}},{"html_id":"food=(food:Array(Point))-instance-method","name":"food=","abstract":false,"args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"args_string":"(food : Array(Point))","args_html":"(food : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L21"},"def":{"name":"food=","args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"visibility":"Public","body":"@food = food"}},{"html_id":"hazards:Array(Point)-instance-method","name":"hazards","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L24"},"def":{"name":"hazards","return_type":"Array(Point)","visibility":"Public","body":"@hazards"}},{"html_id":"hazards=(hazards:Array(Point))-instance-method","name":"hazards=","abstract":false,"args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"args_string":"(hazards : Array(Point))","args_html":"(hazards : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L24"},"def":{"name":"hazards=","args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"visibility":"Public","body":"@hazards = hazards"}},{"html_id":"height:Int32-instance-method","name":"height","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L12"},"def":{"name":"height","return_type":"Int32","visibility":"Public","body":"@height"}},{"html_id":"height=(height:Int32)-instance-method","name":"height=","abstract":false,"args":[{"name":"height","external_name":"height","restriction":"Int32"}],"args_string":"(height : Int32)","args_html":"(height : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L12"},"def":{"name":"height=","args":[{"name":"height","external_name":"height","restriction":"Int32"}],"visibility":"Public","body":"@height = height"}},{"html_id":"living?(id)-instance-method","name":"living?","abstract":false,"args":[{"name":"id","external_name":"id","restriction":""}],"args_string":"(id)","args_html":"(id)","location":{"filename":"src/battle_snake/board.cr","line_number":40,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L40"},"def":{"name":"living?","args":[{"name":"id","external_name":"id","restriction":""}],"visibility":"Public","body":"snakes.index do |snake|\n snake.id == id\nend"}},{"html_id":"snake_points:Array(Point)-instance-method","name":"snake_points","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":27,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L27"},"def":{"name":"snake_points","return_type":"Array(Point)","visibility":"Public","body":"@snake_points"}},{"html_id":"snakes:Array(Snake)-instance-method","name":"snakes","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L18"},"def":{"name":"snakes","return_type":"Array(Snake)","visibility":"Public","body":"@snakes"}},{"html_id":"snakes=(snakes:Array(Snake))-instance-method","name":"snakes=","abstract":false,"args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"args_string":"(snakes : Array(Snake))","args_html":"(snakes : Array(Snake))","location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L18"},"def":{"name":"snakes=","args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"visibility":"Public","body":"@snakes = snakes"}},{"html_id":"width:Int32-instance-method","name":"width","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L15"},"def":{"name":"width","return_type":"Int32","visibility":"Public","body":"@width"}},{"html_id":"width=(width:Int32)-instance-method","name":"width=","abstract":false,"args":[{"name":"width","external_name":"width","restriction":"Int32"}],"args_string":"(width : Int32)","args_html":"(width : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L15"},"def":{"name":"width=","args":[{"name":"width","external_name":"width","restriction":"Int32"}],"visibility":"Public","body":"@width = width"}}]},{"html_id":"CrystalSnake/BattleSnake/Context","path":"BattleSnake/Context.html","kind":"class","full_name":"BattleSnake::Context","name":"Context","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/context.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"A BattleSnake::Context is the representation of the game as it arrives from\nthe [Webhook API](https://docs.battlesnake.com/api) request to `src/app.cr`\nendpoints.\n\nThe context's key method is `#valid_moves`","summary":"

A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr endpoints.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/context.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"blast_valid_moves!-instance-method","name":"blast_valid_moves!","doc":"Similar to `BattleSnake::Context#valid_moves` but considers all valid\nmoves from enemies. Returns a hash with all the valid `:moves`,\n`:neighbors` and `:risky_moves` (we might collide with enemy) available\nfor `you`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:risky_moves` is an `Array(BattleSnake::Point)` that containts the\ndirections from the given `#point` that are valid to move but there's a\nchance we could die (`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.","summary":"

Similar to BattleSnake::Context#valid_moves but considers all valid moves from enemies.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":105,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L105"},"def":{"name":"blast_valid_moves!","visibility":"Public","body":"moves = [] of String\nrisky_moves = [] of String\nyou.body.pop\nindex = board.snakes.index! do |snake|\n snake.id == you.id\nend\nboard.snakes[index].body.pop\npossible_moves = valid_moves(you.head)\nenemy_valid_moves = {} of String => Array(String)\nenemies.each_with_index do |snake, index|\n snake_moves = (valid_moves(snake.head))[:moves]\n if snake_moves.empty?\n else\n enemy_valid_moves[snake.id] = snake_moves\n end\nend\nif enemy_valid_moves.empty?\n return {moves: possible_moves[:moves], neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\nend\ncontexts = [] of BattleSnake::Context\npermutations = enemy_valid_moves.values.map(&.size).reduce do |acc, i|\n acc * i\nend\npermutations.times do\n contexts << self.dup\nend\ncontexts.each_with_index do |context, index|\n offset = 1\n enemy_valid_moves.each do |snake_id, moves|\n direction = moves[(index / offset).floor.to_i % moves.size]\n context.move(snake_id, direction)\n offset = offset * moves.size\n end\nend\npossible_moves[:moves].each do |direction|\n target = possible_moves[:neighbors][direction]\n collision = contexts.find do |context|\n context.board.snake_points.includes?(target)\n end\n if collision.nil?\n moves << direction\n else\n risky_moves << direction\n end\nend\n{moves: moves, neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\n"}},{"html_id":"board:Board-instance-method","name":"board","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L18"},"def":{"name":"board","return_type":"Board","visibility":"Public","body":"@board"}},{"html_id":"board=(board:Board)-instance-method","name":"board=","abstract":false,"args":[{"name":"board","external_name":"board","restriction":"Board"}],"args_string":"(board : Board)","args_html":"(board : Board)","location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L18"},"def":{"name":"board=","args":[{"name":"board","external_name":"board","restriction":"Board"}],"visibility":"Public","body":"@board = board"}},{"html_id":"check_collisions-instance-method","name":"check_collisions","doc":"Checks collisions from snakes on the board and removes snakes that die","summary":"

Checks collisions from snakes on the board and removes snakes that die

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"

Returns a shallow copy of this object.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"

Simulate a move of a snake by id in some direction.

","abstract":false,"args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"args_string":"(snake_id, direction, pop_body = true)","args_html":"(snake_id, direction, pop_body = true)","location":{"filename":"src/battle_snake/context.cr","line_number":169,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L169"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\nif pop_body\n deleted_point = board.snakes[index].body.pop\nend\nboard.snakes[index].head = board.snakes[index].head.move(direction)\nboard.snakes[index].body.unshift(board.snakes[index].head)\nif @you.id == snake_id\n @you = board.snakes[index]\nend\nboard.snake_points.clear\nboard.find_snake_points\n"}},{"html_id":"turn:Int32-instance-method","name":"turn","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L15"},"def":{"name":"turn","return_type":"Int32","visibility":"Public","body":"@turn"}},{"html_id":"turn=(turn:Int32)-instance-method","name":"turn=","abstract":false,"args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"args_string":"(turn : Int32)","args_html":"(turn : Int32)","location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L15"},"def":{"name":"turn=","args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"visibility":"Public","body":"@turn = turn"}},{"html_id":"valid_moves(point:Point)-instance-method","name":"valid_moves","doc":"Returns a hash with all the valid `:moves` and `:neighbors` available from\na given `BattleSnake::Point`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.\n\nExample:\n\n```\ncontext.valid_moves(Point.new(1,1))\n=> {\n moves: [ \"up\", \"right\" ],\n neighbors: { Point.new(2,1), Point.new(1,2) }\n}\n```\n\nNOTE: A common method to help manipulate the results is\n`BattleSnake::Point#move?`. An example of this in practice is the\n`Strategy::Utils.a_star` method implementation.\n\nTODO: Take into account the last point of snakes that will move on next\nturn, which would be in fact valid moves (not counted at the moment).","summary":"

Returns a hash with all the valid :moves and :neighbors available from a given BattleSnake::Point.

","abstract":false,"args":[{"name":"point","external_name":"point","restriction":"Point"}],"args_string":"(point : Point)","args_html":"(point : Point)","location":{"filename":"src/battle_snake/context.cr","line_number":59,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L59"},"def":{"name":"valid_moves","args":[{"name":"point","external_name":"point","restriction":"Point"}],"visibility":"Public","body":"moves = [] of String\nneighbors = {} of String => Point\nup = point.up\nif up.y < board.height && (!(board.snake_points.includes?(up)))\n moves << \"up\"\n neighbors[\"up\"] = up\nend\nleft = point.left\nif left.x >= 0 && (!(board.snake_points.includes?(left)))\n moves << \"left\"\n neighbors[\"left\"] = left\nend\ndown = point.down\nif down.y >= 0 && (!(board.snake_points.includes?(down)))\n moves << \"down\"\n neighbors[\"down\"] = down\nend\nright = point.right\nif right.x < board.width && (!(board.snake_points.includes?(right)))\n moves << \"right\"\n neighbors[\"right\"] = right\nend\n{moves: moves, neighbors: neighbors}\n"}},{"html_id":"you:Snake-instance-method","name":"you","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L21"},"def":{"name":"you","return_type":"Snake","visibility":"Public","body":"@you"}},{"html_id":"you=(you:Snake)-instance-method","name":"you=","abstract":false,"args":[{"name":"you","external_name":"you","restriction":"Snake"}],"args_string":"(you : Snake)","args_html":"(you : Snake)","location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L21"},"def":{"name":"you=","args":[{"name":"you","external_name":"you","restriction":"Snake"}],"visibility":"Public","body":"@you = you"}}]},{"html_id":"CrystalSnake/BattleSnake/Game","path":"BattleSnake/Game.html","kind":"class","full_name":"BattleSnake::Game","name":"Game","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/game.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/game.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"map:String-instance-method","name":"map","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L13"},"def":{"name":"map","return_type":"String","visibility":"Public","body":"@map"}},{"html_id":"map=(map:String)-instance-method","name":"map=","abstract":false,"args":[{"name":"map","external_name":"map","restriction":"String"}],"args_string":"(map : String)","args_html":"(map : String)","location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L13"},"def":{"name":"map=","args":[{"name":"map","external_name":"map","restriction":"String"}],"visibility":"Public","body":"@map = map"}},{"html_id":"ruleset:Ruleset-instance-method","name":"ruleset","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset","return_type":"Ruleset","visibility":"Public","body":"@ruleset"}},{"html_id":"ruleset=(ruleset:Ruleset)-instance-method","name":"ruleset=","abstract":false,"args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"args_string":"(ruleset : Ruleset)","args_html":"(ruleset : Ruleset)","location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset=","args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"visibility":"Public","body":"@ruleset = ruleset"}},{"html_id":"source:String-instance-method","name":"source","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L19"},"def":{"name":"source","return_type":"String","visibility":"Public","body":"@source"}},{"html_id":"source=(source:String)-instance-method","name":"source=","abstract":false,"args":[{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(source : String)","args_html":"(source : String)","location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L19"},"def":{"name":"source=","args":[{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"@source = source"}},{"html_id":"timeout:Int32-instance-method","name":"timeout","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L16"},"def":{"name":"timeout","return_type":"Int32","visibility":"Public","body":"@timeout"}},{"html_id":"timeout=(timeout:Int32)-instance-method","name":"timeout=","abstract":false,"args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"args_string":"(timeout : Int32)","args_html":"(timeout : Int32)","location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L16"},"def":{"name":"timeout=","args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"visibility":"Public","body":"@timeout = timeout"}}]},{"html_id":"CrystalSnake/BattleSnake/Point","path":"BattleSnake/Point.html","kind":"class","full_name":"BattleSnake::Point","name":"Point","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/point.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents a Point (x,y) coordinate on the board with some helper methods for\nprocessing of the board (i.e. `#move?`)","summary":"

Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.

","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"

Initialize from two Int32 values

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"

Initialize from a string representation i.e.

","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"

The comparison operator.

","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"

Returns a new Point directly down from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"

Returns a new Point directly left from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"

Returns the point when it moves in a direction.

","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"

Determines if a given target BattleSnake::Point is reachable.

","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"

Returns a new Point directly right from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"

Returns the String representation of the Point.

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"

Returns a new Point directly up from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"

Basic implementation of a Tree data structure.

","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"

Abstract class of all strategies.

","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"

Strategy that chases the closest available food from the board with caution against head-to-head collisions.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"

Strategy that chases the closest food from the board from You

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"

Strategy that chases randomly selected food from the board

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"

A strategy that chooses a random direction to move without any considerations

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"

Implementation of A* Search Algorithm (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"

Implementation of Flood Fill (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"

This is a DB record representation of a request from a game for either start/move/end request.

","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"

Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.

","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"

Deletes object from db and calls all related callbacks.

","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}} \ No newline at end of file diff --git a/search-index.js b/search-index.js index 2842db9..8c96403 100644 --- a/search-index.js +++ b/search-index.js @@ -1 +1 @@ -crystal_doc_search_index_callback({"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Fernando Valverde](https://github.com/fdocr) - creator and maintainer\n","program":{"html_id":"CrystalSnake/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"ancestors":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"locations":[],"repository_name":"CrystalSnake","program":true,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"extended_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"class_methods":[{"html_id":"truncate_uuid(str)-class-method","name":"truncate_uuid","abstract":false,"args":[{"name":"str","external_name":"str","restriction":""}],"args_string":"(str)","args_html":"(str)","location":{"filename":"src/app.cr","line_number":35,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/app.cr#L35"},"def":{"name":"truncate_uuid","args":[{"name":"str","external_name":"str","restriction":""}],"visibility":"Public","body":"\"#{str[0..7]}...#{str[24..32]}\""}}],"macros":[{"html_id":"persist_turn!-macro","name":"persist_turn!","abstract":false,"location":{"filename":"src/app.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/app.cr#L28"},"def":{"name":"persist_turn!","visibility":"Public","body":" PersistTurnJob.new(\n path: \nenv.request.path,\n context_json: \nenv.params.json.to_json\n ).enqueue if persist_to_db\n\n"}}],"types":[{"html_id":"CrystalSnake/ApplicationJob","path":"ApplicationJob.html","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob","abstract":true,"superclass":{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},"ancestors":[{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/PersistTurnJob","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob"}],"doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"

abstract, override in a Job descendant to do something productive

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"

Represents the Board as it arrives from the BattleSnake API endpoint.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"

Executed on #after_initialize callback and all it does is populate snake_points variable (Array(Point)) with all points that belong to a snake on the board

","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":32,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L32"},"def":{"name":"find_snake_points","visibility":"Public","body":"snakes.each do |snake|\n snake.body.each do |point|\n if @snake_points.includes?(point)\n else\n @snake_points << point\n end\n end\nend"}},{"html_id":"food:Array(Point)-instance-method","name":"food","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L21"},"def":{"name":"food","return_type":"Array(Point)","visibility":"Public","body":"@food"}},{"html_id":"food=(food:Array(Point))-instance-method","name":"food=","abstract":false,"args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"args_string":"(food : Array(Point))","args_html":"(food : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L21"},"def":{"name":"food=","args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"visibility":"Public","body":"@food = food"}},{"html_id":"hazards:Array(Point)-instance-method","name":"hazards","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L24"},"def":{"name":"hazards","return_type":"Array(Point)","visibility":"Public","body":"@hazards"}},{"html_id":"hazards=(hazards:Array(Point))-instance-method","name":"hazards=","abstract":false,"args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"args_string":"(hazards : Array(Point))","args_html":"(hazards : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L24"},"def":{"name":"hazards=","args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"visibility":"Public","body":"@hazards = hazards"}},{"html_id":"height:Int32-instance-method","name":"height","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L12"},"def":{"name":"height","return_type":"Int32","visibility":"Public","body":"@height"}},{"html_id":"height=(height:Int32)-instance-method","name":"height=","abstract":false,"args":[{"name":"height","external_name":"height","restriction":"Int32"}],"args_string":"(height : Int32)","args_html":"(height : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L12"},"def":{"name":"height=","args":[{"name":"height","external_name":"height","restriction":"Int32"}],"visibility":"Public","body":"@height = height"}},{"html_id":"living?(id)-instance-method","name":"living?","abstract":false,"args":[{"name":"id","external_name":"id","restriction":""}],"args_string":"(id)","args_html":"(id)","location":{"filename":"src/battle_snake/board.cr","line_number":40,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L40"},"def":{"name":"living?","args":[{"name":"id","external_name":"id","restriction":""}],"visibility":"Public","body":"snakes.index do |snake|\n snake.id == id\nend"}},{"html_id":"snake_points:Array(Point)-instance-method","name":"snake_points","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":27,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L27"},"def":{"name":"snake_points","return_type":"Array(Point)","visibility":"Public","body":"@snake_points"}},{"html_id":"snakes:Array(Snake)-instance-method","name":"snakes","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L18"},"def":{"name":"snakes","return_type":"Array(Snake)","visibility":"Public","body":"@snakes"}},{"html_id":"snakes=(snakes:Array(Snake))-instance-method","name":"snakes=","abstract":false,"args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"args_string":"(snakes : Array(Snake))","args_html":"(snakes : Array(Snake))","location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L18"},"def":{"name":"snakes=","args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"visibility":"Public","body":"@snakes = snakes"}},{"html_id":"width:Int32-instance-method","name":"width","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L15"},"def":{"name":"width","return_type":"Int32","visibility":"Public","body":"@width"}},{"html_id":"width=(width:Int32)-instance-method","name":"width=","abstract":false,"args":[{"name":"width","external_name":"width","restriction":"Int32"}],"args_string":"(width : Int32)","args_html":"(width : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L15"},"def":{"name":"width=","args":[{"name":"width","external_name":"width","restriction":"Int32"}],"visibility":"Public","body":"@width = width"}}]},{"html_id":"CrystalSnake/BattleSnake/Context","path":"BattleSnake/Context.html","kind":"class","full_name":"BattleSnake::Context","name":"Context","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/context.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"A BattleSnake::Context is the representation of the game as it arrives from\nthe [Webhook API](https://docs.battlesnake.com/api) request to `src/app.cr`\nendpoints.\n\nThe context's key method is `#valid_moves`","summary":"

A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr endpoints.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/context.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"blast_valid_moves!-instance-method","name":"blast_valid_moves!","doc":"Similar to `BattleSnake::Context#valid_moves` but considers all valid\nmoves from enemies. Returns a hash with all the valid `:moves`,\n`:neighbors` and `:risky_moves` (we might collide with enemy) available\nfor `you`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:risky_moves` is an `Array(BattleSnake::Point)` that containts the\ndirections from the given `#point` that are valid to move but there's a\nchance we could die (`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.","summary":"

Similar to BattleSnake::Context#valid_moves but considers all valid moves from enemies.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":105,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L105"},"def":{"name":"blast_valid_moves!","visibility":"Public","body":"moves = [] of String\nrisky_moves = [] of String\nyou.body.pop\nindex = board.snakes.index! do |snake|\n snake.id == you.id\nend\nboard.snakes[index].body.pop\npossible_moves = valid_moves(you.head)\nenemy_valid_moves = {} of String => Array(String)\nenemies.each_with_index do |snake, index|\n snake_moves = (valid_moves(snake.head))[:moves]\n if snake_moves.empty?\n else\n enemy_valid_moves[snake.id] = snake_moves\n end\nend\nif enemy_valid_moves.empty?\n return {moves: possible_moves[:moves], neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\nend\ncontexts = [] of BattleSnake::Context\npermutations = enemy_valid_moves.values.map(&.size).reduce do |acc, i|\n acc * i\nend\npermutations.times do\n contexts << self.dup\nend\ncontexts.each_with_index do |context, index|\n offset = 1\n enemy_valid_moves.each do |snake_id, moves|\n direction = moves[(index / offset).floor.to_i % moves.size]\n context.move(snake_id, direction)\n offset = offset * moves.size\n end\nend\npossible_moves[:moves].each do |direction|\n target = possible_moves[:neighbors][direction]\n collision = contexts.find do |context|\n context.board.snake_points.includes?(target)\n end\n if collision.nil?\n moves << direction\n else\n risky_moves << direction\n end\nend\n{moves: moves, neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\n"}},{"html_id":"board:Board-instance-method","name":"board","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L18"},"def":{"name":"board","return_type":"Board","visibility":"Public","body":"@board"}},{"html_id":"board=(board:Board)-instance-method","name":"board=","abstract":false,"args":[{"name":"board","external_name":"board","restriction":"Board"}],"args_string":"(board : Board)","args_html":"(board : Board)","location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L18"},"def":{"name":"board=","args":[{"name":"board","external_name":"board","restriction":"Board"}],"visibility":"Public","body":"@board = board"}},{"html_id":"check_collisions-instance-method","name":"check_collisions","doc":"Checks collisions from snakes on the board and removes snakes that die","summary":"

Checks collisions from snakes on the board and removes snakes that die

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"

Returns a shallow copy of this object.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"

Simulate a move of a snake by id in some direction.

","abstract":false,"args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"args_string":"(snake_id, direction, pop_body = true)","args_html":"(snake_id, direction, pop_body = true)","location":{"filename":"src/battle_snake/context.cr","line_number":169,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L169"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\nif pop_body\n deleted_point = board.snakes[index].body.pop\nend\nboard.snakes[index].head = board.snakes[index].head.move(direction)\nboard.snakes[index].body.unshift(board.snakes[index].head)\nif @you.id == snake_id\n @you = board.snakes[index]\nend\nboard.snake_points.clear\nboard.find_snake_points\n"}},{"html_id":"turn:Int32-instance-method","name":"turn","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L15"},"def":{"name":"turn","return_type":"Int32","visibility":"Public","body":"@turn"}},{"html_id":"turn=(turn:Int32)-instance-method","name":"turn=","abstract":false,"args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"args_string":"(turn : Int32)","args_html":"(turn : Int32)","location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L15"},"def":{"name":"turn=","args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"visibility":"Public","body":"@turn = turn"}},{"html_id":"valid_moves(point:Point)-instance-method","name":"valid_moves","doc":"Returns a hash with all the valid `:moves` and `:neighbors` available from\na given `BattleSnake::Point`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.\n\nExample:\n\n```\ncontext.valid_moves(Point.new(1,1))\n=> {\n moves: [ \"up\", \"right\" ],\n neighbors: { Point.new(2,1), Point.new(1,2) }\n}\n```\n\nNOTE: A common method to help manipulate the results is\n`BattleSnake::Point#move?`. An example of this in practice is the\n`Strategy::Utils.a_star` method implementation.\n\nTODO: Take into account the last point of snakes that will move on next\nturn, which would be in fact valid moves (not counted at the moment).","summary":"

Returns a hash with all the valid :moves and :neighbors available from a given BattleSnake::Point.

","abstract":false,"args":[{"name":"point","external_name":"point","restriction":"Point"}],"args_string":"(point : Point)","args_html":"(point : Point)","location":{"filename":"src/battle_snake/context.cr","line_number":59,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L59"},"def":{"name":"valid_moves","args":[{"name":"point","external_name":"point","restriction":"Point"}],"visibility":"Public","body":"moves = [] of String\nneighbors = {} of String => Point\nup = point.up\nif up.y < board.height && (!(board.snake_points.includes?(up)))\n moves << \"up\"\n neighbors[\"up\"] = up\nend\nleft = point.left\nif left.x >= 0 && (!(board.snake_points.includes?(left)))\n moves << \"left\"\n neighbors[\"left\"] = left\nend\ndown = point.down\nif down.y >= 0 && (!(board.snake_points.includes?(down)))\n moves << \"down\"\n neighbors[\"down\"] = down\nend\nright = point.right\nif right.x < board.width && (!(board.snake_points.includes?(right)))\n moves << \"right\"\n neighbors[\"right\"] = right\nend\n{moves: moves, neighbors: neighbors}\n"}},{"html_id":"you:Snake-instance-method","name":"you","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L21"},"def":{"name":"you","return_type":"Snake","visibility":"Public","body":"@you"}},{"html_id":"you=(you:Snake)-instance-method","name":"you=","abstract":false,"args":[{"name":"you","external_name":"you","restriction":"Snake"}],"args_string":"(you : Snake)","args_html":"(you : Snake)","location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L21"},"def":{"name":"you=","args":[{"name":"you","external_name":"you","restriction":"Snake"}],"visibility":"Public","body":"@you = you"}}]},{"html_id":"CrystalSnake/BattleSnake/Game","path":"BattleSnake/Game.html","kind":"class","full_name":"BattleSnake::Game","name":"Game","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/game.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/game.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"map:String-instance-method","name":"map","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L13"},"def":{"name":"map","return_type":"String","visibility":"Public","body":"@map"}},{"html_id":"map=(map:String)-instance-method","name":"map=","abstract":false,"args":[{"name":"map","external_name":"map","restriction":"String"}],"args_string":"(map : String)","args_html":"(map : String)","location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L13"},"def":{"name":"map=","args":[{"name":"map","external_name":"map","restriction":"String"}],"visibility":"Public","body":"@map = map"}},{"html_id":"ruleset:Ruleset-instance-method","name":"ruleset","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset","return_type":"Ruleset","visibility":"Public","body":"@ruleset"}},{"html_id":"ruleset=(ruleset:Ruleset)-instance-method","name":"ruleset=","abstract":false,"args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"args_string":"(ruleset : Ruleset)","args_html":"(ruleset : Ruleset)","location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset=","args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"visibility":"Public","body":"@ruleset = ruleset"}},{"html_id":"source:String-instance-method","name":"source","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L19"},"def":{"name":"source","return_type":"String","visibility":"Public","body":"@source"}},{"html_id":"source=(source:String)-instance-method","name":"source=","abstract":false,"args":[{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(source : String)","args_html":"(source : String)","location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L19"},"def":{"name":"source=","args":[{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"@source = source"}},{"html_id":"timeout:Int32-instance-method","name":"timeout","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L16"},"def":{"name":"timeout","return_type":"Int32","visibility":"Public","body":"@timeout"}},{"html_id":"timeout=(timeout:Int32)-instance-method","name":"timeout=","abstract":false,"args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"args_string":"(timeout : Int32)","args_html":"(timeout : Int32)","location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/game.cr#L16"},"def":{"name":"timeout=","args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"visibility":"Public","body":"@timeout = timeout"}}]},{"html_id":"CrystalSnake/BattleSnake/Point","path":"BattleSnake/Point.html","kind":"class","full_name":"BattleSnake::Point","name":"Point","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/point.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents a Point (x,y) coordinate on the board with some helper methods for\nprocessing of the board (i.e. `#move?`)","summary":"

Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.

","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"

Initialize from two Int32 values

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"

Initialize from a string representation i.e.

","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"

The comparison operator.

","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"

Returns a new Point directly down from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"

Returns a new Point directly left from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"

Returns the point when it moves in a direction.

","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"

Determines if a given target BattleSnake::Point is reachable.

","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"

Returns a new Point directly right from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"

Returns the String representation of the Point.

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"

Returns a new Point directly up from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"

Basic implementation of a Tree data structure.

","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"

Abstract class of all strategies.

","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"

Strategy that chases the closest available food from the board with caution against head-to-head collisions.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"

Strategy that chases the closest food from the board from You

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"

Strategy that chases randomly selected food from the board

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"

A strategy that chooses a random direction to move without any considerations

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"

Implementation of A* Search Algorithm (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"

Implementation of Flood Fill (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"

This is a DB record representation of a request from a game for either start/move/end request.

","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"

Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.

","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"

Deletes object from db and calls all related callbacks.

","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}}) \ No newline at end of file +crystal_doc_search_index_callback({"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Fernando Valverde](https://github.com/fdocr) - creator and maintainer\n","program":{"html_id":"CrystalSnake/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"ancestors":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"locations":[],"repository_name":"CrystalSnake","program":true,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"extended_modules":[{"html_id":"CrystalSnake/Sam/DSL","kind":"module","full_name":"Sam::DSL","name":"DSL"}],"class_methods":[{"html_id":"truncate_uuid(str)-class-method","name":"truncate_uuid","abstract":false,"args":[{"name":"str","external_name":"str","restriction":""}],"args_string":"(str)","args_html":"(str)","location":{"filename":"src/app.cr","line_number":35,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/app.cr#L35"},"def":{"name":"truncate_uuid","args":[{"name":"str","external_name":"str","restriction":""}],"visibility":"Public","body":"\"#{str[0..7]}...#{str[24..32]}\""}}],"macros":[{"html_id":"persist_turn!-macro","name":"persist_turn!","abstract":false,"location":{"filename":"src/app.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/app.cr#L28"},"def":{"name":"persist_turn!","visibility":"Public","body":" PersistTurnJob.new(\n path: \nenv.request.path,\n context_json: \nenv.params.json.to_json\n ).enqueue if persist_to_db\n\n"}}],"types":[{"html_id":"CrystalSnake/ApplicationJob","path":"ApplicationJob.html","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob","abstract":true,"superclass":{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},"ancestors":[{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/PersistTurnJob","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob"}],"doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"

abstract, override in a Job descendant to do something productive

","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"

Represents the Board as it arrives from the BattleSnake API endpoint.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"

Executed on #after_initialize callback and all it does is populate snake_points variable (Array(Point)) with all points that belong to a snake on the board

","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":32,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L32"},"def":{"name":"find_snake_points","visibility":"Public","body":"snakes.each do |snake|\n snake.body.each do |point|\n if @snake_points.includes?(point)\n else\n @snake_points << point\n end\n end\nend"}},{"html_id":"food:Array(Point)-instance-method","name":"food","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L21"},"def":{"name":"food","return_type":"Array(Point)","visibility":"Public","body":"@food"}},{"html_id":"food=(food:Array(Point))-instance-method","name":"food=","abstract":false,"args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"args_string":"(food : Array(Point))","args_html":"(food : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L21"},"def":{"name":"food=","args":[{"name":"food","external_name":"food","restriction":"Array(Point)"}],"visibility":"Public","body":"@food = food"}},{"html_id":"hazards:Array(Point)-instance-method","name":"hazards","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L24"},"def":{"name":"hazards","return_type":"Array(Point)","visibility":"Public","body":"@hazards"}},{"html_id":"hazards=(hazards:Array(Point))-instance-method","name":"hazards=","abstract":false,"args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"args_string":"(hazards : Array(Point))","args_html":"(hazards : Array(Point))","location":{"filename":"src/battle_snake/board.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L24"},"def":{"name":"hazards=","args":[{"name":"hazards","external_name":"hazards","restriction":"Array(Point)"}],"visibility":"Public","body":"@hazards = hazards"}},{"html_id":"height:Int32-instance-method","name":"height","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L12"},"def":{"name":"height","return_type":"Int32","visibility":"Public","body":"@height"}},{"html_id":"height=(height:Int32)-instance-method","name":"height=","abstract":false,"args":[{"name":"height","external_name":"height","restriction":"Int32"}],"args_string":"(height : Int32)","args_html":"(height : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L12"},"def":{"name":"height=","args":[{"name":"height","external_name":"height","restriction":"Int32"}],"visibility":"Public","body":"@height = height"}},{"html_id":"living?(id)-instance-method","name":"living?","abstract":false,"args":[{"name":"id","external_name":"id","restriction":""}],"args_string":"(id)","args_html":"(id)","location":{"filename":"src/battle_snake/board.cr","line_number":40,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L40"},"def":{"name":"living?","args":[{"name":"id","external_name":"id","restriction":""}],"visibility":"Public","body":"snakes.index do |snake|\n snake.id == id\nend"}},{"html_id":"snake_points:Array(Point)-instance-method","name":"snake_points","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":27,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L27"},"def":{"name":"snake_points","return_type":"Array(Point)","visibility":"Public","body":"@snake_points"}},{"html_id":"snakes:Array(Snake)-instance-method","name":"snakes","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L18"},"def":{"name":"snakes","return_type":"Array(Snake)","visibility":"Public","body":"@snakes"}},{"html_id":"snakes=(snakes:Array(Snake))-instance-method","name":"snakes=","abstract":false,"args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"args_string":"(snakes : Array(Snake))","args_html":"(snakes : Array(Snake))","location":{"filename":"src/battle_snake/board.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L18"},"def":{"name":"snakes=","args":[{"name":"snakes","external_name":"snakes","restriction":"Array(Snake)"}],"visibility":"Public","body":"@snakes = snakes"}},{"html_id":"width:Int32-instance-method","name":"width","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L15"},"def":{"name":"width","return_type":"Int32","visibility":"Public","body":"@width"}},{"html_id":"width=(width:Int32)-instance-method","name":"width=","abstract":false,"args":[{"name":"width","external_name":"width","restriction":"Int32"}],"args_string":"(width : Int32)","args_html":"(width : Int32)","location":{"filename":"src/battle_snake/board.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/board.cr#L15"},"def":{"name":"width=","args":[{"name":"width","external_name":"width","restriction":"Int32"}],"visibility":"Public","body":"@width = width"}}]},{"html_id":"CrystalSnake/BattleSnake/Context","path":"BattleSnake/Context.html","kind":"class","full_name":"BattleSnake::Context","name":"Context","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/context.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"A BattleSnake::Context is the representation of the game as it arrives from\nthe [Webhook API](https://docs.battlesnake.com/api) request to `src/app.cr`\nendpoints.\n\nThe context's key method is `#valid_moves`","summary":"

A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr endpoints.

","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/context.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"blast_valid_moves!-instance-method","name":"blast_valid_moves!","doc":"Similar to `BattleSnake::Context#valid_moves` but considers all valid\nmoves from enemies. Returns a hash with all the valid `:moves`,\n`:neighbors` and `:risky_moves` (we might collide with enemy) available\nfor `you`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:risky_moves` is an `Array(BattleSnake::Point)` that containts the\ndirections from the given `#point` that are valid to move but there's a\nchance we could die (`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.","summary":"

Similar to BattleSnake::Context#valid_moves but considers all valid moves from enemies.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":105,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L105"},"def":{"name":"blast_valid_moves!","visibility":"Public","body":"moves = [] of String\nrisky_moves = [] of String\nyou.body.pop\nindex = board.snakes.index! do |snake|\n snake.id == you.id\nend\nboard.snakes[index].body.pop\npossible_moves = valid_moves(you.head)\nenemy_valid_moves = {} of String => Array(String)\nenemies.each_with_index do |snake, index|\n snake_moves = (valid_moves(snake.head))[:moves]\n if snake_moves.empty?\n else\n enemy_valid_moves[snake.id] = snake_moves\n end\nend\nif enemy_valid_moves.empty?\n return {moves: possible_moves[:moves], neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\nend\ncontexts = [] of BattleSnake::Context\npermutations = enemy_valid_moves.values.map(&.size).reduce do |acc, i|\n acc * i\nend\npermutations.times do\n contexts << self.dup\nend\ncontexts.each_with_index do |context, index|\n offset = 1\n enemy_valid_moves.each do |snake_id, moves|\n direction = moves[(index / offset).floor.to_i % moves.size]\n context.move(snake_id, direction)\n offset = offset * moves.size\n end\nend\npossible_moves[:moves].each do |direction|\n target = possible_moves[:neighbors][direction]\n collision = contexts.find do |context|\n context.board.snake_points.includes?(target)\n end\n if collision.nil?\n moves << direction\n else\n risky_moves << direction\n end\nend\n{moves: moves, neighbors: possible_moves[:neighbors], risky_moves: risky_moves}\n"}},{"html_id":"board:Board-instance-method","name":"board","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L18"},"def":{"name":"board","return_type":"Board","visibility":"Public","body":"@board"}},{"html_id":"board=(board:Board)-instance-method","name":"board=","abstract":false,"args":[{"name":"board","external_name":"board","restriction":"Board"}],"args_string":"(board : Board)","args_html":"(board : Board)","location":{"filename":"src/battle_snake/context.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L18"},"def":{"name":"board=","args":[{"name":"board","external_name":"board","restriction":"Board"}],"visibility":"Public","body":"@board = board"}},{"html_id":"check_collisions-instance-method","name":"check_collisions","doc":"Checks collisions from snakes on the board and removes snakes that die","summary":"

Checks collisions from snakes on the board and removes snakes that die

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"

Returns a shallow copy of this object.

","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"

Simulate a move of a snake by id in some direction.

","abstract":false,"args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"args_string":"(snake_id, direction, pop_body = true)","args_html":"(snake_id, direction, pop_body = true)","location":{"filename":"src/battle_snake/context.cr","line_number":169,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L169"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""},{"name":"pop_body","default_value":"true","external_name":"pop_body","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\nif pop_body\n deleted_point = board.snakes[index].body.pop\nend\nboard.snakes[index].head = board.snakes[index].head.move(direction)\nboard.snakes[index].body.unshift(board.snakes[index].head)\nif @you.id == snake_id\n @you = board.snakes[index]\nend\nboard.snake_points.clear\nboard.find_snake_points\n"}},{"html_id":"turn:Int32-instance-method","name":"turn","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L15"},"def":{"name":"turn","return_type":"Int32","visibility":"Public","body":"@turn"}},{"html_id":"turn=(turn:Int32)-instance-method","name":"turn=","abstract":false,"args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"args_string":"(turn : Int32)","args_html":"(turn : Int32)","location":{"filename":"src/battle_snake/context.cr","line_number":15,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L15"},"def":{"name":"turn=","args":[{"name":"turn","external_name":"turn","restriction":"Int32"}],"visibility":"Public","body":"@turn = turn"}},{"html_id":"valid_moves(point:Point)-instance-method","name":"valid_moves","doc":"Returns a hash with all the valid `:moves` and `:neighbors` available from\na given `BattleSnake::Point`.\n\n`:moves` is an `Array(BattleSnake::Point)` that containts the directions\nfrom the given `#point` that are valid to move without dying\n(`\"up\"/\"left\"/\"down\"/\"right\"`).\n\n`:neighbors` is a `{} of String => BattleSnake::Point` that contains those\ndirections' coordinates.\n\nExample:\n\n```\ncontext.valid_moves(Point.new(1,1))\n=> {\n moves: [ \"up\", \"right\" ],\n neighbors: { Point.new(2,1), Point.new(1,2) }\n}\n```\n\nNOTE: A common method to help manipulate the results is\n`BattleSnake::Point#move?`. An example of this in practice is the\n`Strategy::Utils.a_star` method implementation.\n\nTODO: Take into account the last point of snakes that will move on next\nturn, which would be in fact valid moves (not counted at the moment).","summary":"

Returns a hash with all the valid :moves and :neighbors available from a given BattleSnake::Point.

","abstract":false,"args":[{"name":"point","external_name":"point","restriction":"Point"}],"args_string":"(point : Point)","args_html":"(point : Point)","location":{"filename":"src/battle_snake/context.cr","line_number":59,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L59"},"def":{"name":"valid_moves","args":[{"name":"point","external_name":"point","restriction":"Point"}],"visibility":"Public","body":"moves = [] of String\nneighbors = {} of String => Point\nup = point.up\nif up.y < board.height && (!(board.snake_points.includes?(up)))\n moves << \"up\"\n neighbors[\"up\"] = up\nend\nleft = point.left\nif left.x >= 0 && (!(board.snake_points.includes?(left)))\n moves << \"left\"\n neighbors[\"left\"] = left\nend\ndown = point.down\nif down.y >= 0 && (!(board.snake_points.includes?(down)))\n moves << \"down\"\n neighbors[\"down\"] = down\nend\nright = point.right\nif right.x < board.width && (!(board.snake_points.includes?(right)))\n moves << \"right\"\n neighbors[\"right\"] = right\nend\n{moves: moves, neighbors: neighbors}\n"}},{"html_id":"you:Snake-instance-method","name":"you","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L21"},"def":{"name":"you","return_type":"Snake","visibility":"Public","body":"@you"}},{"html_id":"you=(you:Snake)-instance-method","name":"you=","abstract":false,"args":[{"name":"you","external_name":"you","restriction":"Snake"}],"args_string":"(you : Snake)","args_html":"(you : Snake)","location":{"filename":"src/battle_snake/context.cr","line_number":21,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/context.cr#L21"},"def":{"name":"you=","args":[{"name":"you","external_name":"you","restriction":"Snake"}],"visibility":"Public","body":"@you = you"}}]},{"html_id":"CrystalSnake/BattleSnake/Game","path":"BattleSnake/Game.html","kind":"class","full_name":"BattleSnake::Game","name":"Game","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/game.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/game.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/game.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"map:String-instance-method","name":"map","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L13"},"def":{"name":"map","return_type":"String","visibility":"Public","body":"@map"}},{"html_id":"map=(map:String)-instance-method","name":"map=","abstract":false,"args":[{"name":"map","external_name":"map","restriction":"String"}],"args_string":"(map : String)","args_html":"(map : String)","location":{"filename":"src/battle_snake/game.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L13"},"def":{"name":"map=","args":[{"name":"map","external_name":"map","restriction":"String"}],"visibility":"Public","body":"@map = map"}},{"html_id":"ruleset:Ruleset-instance-method","name":"ruleset","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset","return_type":"Ruleset","visibility":"Public","body":"@ruleset"}},{"html_id":"ruleset=(ruleset:Ruleset)-instance-method","name":"ruleset=","abstract":false,"args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"args_string":"(ruleset : Ruleset)","args_html":"(ruleset : Ruleset)","location":{"filename":"src/battle_snake/game.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L10"},"def":{"name":"ruleset=","args":[{"name":"ruleset","external_name":"ruleset","restriction":"Ruleset"}],"visibility":"Public","body":"@ruleset = ruleset"}},{"html_id":"source:String-instance-method","name":"source","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L19"},"def":{"name":"source","return_type":"String","visibility":"Public","body":"@source"}},{"html_id":"source=(source:String)-instance-method","name":"source=","abstract":false,"args":[{"name":"source","external_name":"source","restriction":"String"}],"args_string":"(source : String)","args_html":"(source : String)","location":{"filename":"src/battle_snake/game.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L19"},"def":{"name":"source=","args":[{"name":"source","external_name":"source","restriction":"String"}],"visibility":"Public","body":"@source = source"}},{"html_id":"timeout:Int32-instance-method","name":"timeout","abstract":false,"location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L16"},"def":{"name":"timeout","return_type":"Int32","visibility":"Public","body":"@timeout"}},{"html_id":"timeout=(timeout:Int32)-instance-method","name":"timeout=","abstract":false,"args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"args_string":"(timeout : Int32)","args_html":"(timeout : Int32)","location":{"filename":"src/battle_snake/game.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/game.cr#L16"},"def":{"name":"timeout=","args":[{"name":"timeout","external_name":"timeout","restriction":"Int32"}],"visibility":"Public","body":"@timeout = timeout"}}]},{"html_id":"CrystalSnake/BattleSnake/Point","path":"BattleSnake/Point.html","kind":"class","full_name":"BattleSnake::Point","name":"Point","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/point.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents a Point (x,y) coordinate on the board with some helper methods for\nprocessing of the board (i.e. `#move?`)","summary":"

Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.

","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"

Initialize from two Int32 values

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"

Initialize from a string representation i.e.

","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"

The comparison operator.

","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"

Returns a new Point directly down from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"

Returns a new Point directly left from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"

Returns the point when it moves in a direction.

","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"

Determines if a given target BattleSnake::Point is reachable.

","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"

Returns a new Point directly right from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"

Returns the String representation of the Point.

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"

Returns a new Point directly up from the instance

","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"

Basic implementation of a Tree data structure.

","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"

Base class for jobs in the app.

","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"

Abstract class of all strategies.

","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"

Strategy that chases the closest available food from the board with caution against head-to-head collisions.

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"

Strategy that chases the closest food from the board from You

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"

Strategy that chases randomly selected food from the board

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"

A strategy that chooses a random direction to move without any considerations

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"

A strategy that chooses a random valid move, or "up" if there isn't any

","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"

Returns the move (direction) to chose based on the @context

","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"

Implementation of A* Search Algorithm (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"

Implementation of Flood Fill (read more).

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"

This is a DB record representation of a request from a game for either start/move/end request.

","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"

Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.

","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"

Deletes object from db and calls all related callbacks.

","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/43319d894148e9dd1352d4841842c4da6f749ab9/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}}) \ No newline at end of file diff --git a/toplevel.html b/toplevel.html index 0ad02d3..f23b7fa 100644 --- a/toplevel.html +++ b/toplevel.html @@ -343,7 +343,7 @@


@@ -373,7 +373,7 @@