)\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":23,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/app.cr#L23"},"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":16,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/app.cr#L16"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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":186,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/battle_snake/context.cr#L186"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some direction","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":""}],"args_string":"(snake_id, direction)","args_html":"(snake_id, direction)","location":{"filename":"src/battle_snake/context.cr","line_number":167,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/battle_snake/context.cr#L167"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\ndeleted_point = board.snakes[index].body.pop\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_793 = context_json?).nil?\n __temp_793\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_793 = path?).nil?\n __temp_793\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"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":3,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L3"}],"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"},"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.
","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":4,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L4"},"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":8,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L8"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\nenemies = @context.board.snakes.reject do |s|\n s.id == @context.you.id\nend\nenemies.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)\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nif safe_move\n return closest_food\nend\nsafe_moves = valid_moves[:moves].reject do |move|\n move == closest_food\nend\nif safe_moves.size.zero?\n return (RandomValid.new(@context)).move\nend\nflood_fills = {} of Int32 => String\ncontexts = [] of BattleSnake::Context\nsafe_moves.size.times do\n contexts << @context.dup\nend\nsafe_moves.each_with_index do |move, i|\n contexts[i].move(@context.you.id, move)\n area_size = (Utils.flood_fill(@context.you.head, contexts[i])).size\n flood_fills[area_size] = move\nend\nflood_fills[flood_fills.keys.sort.last]\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"[\"up\", \"left\", \"down\", \"right\"].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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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 aa6d956..4ac14ab 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 14 & 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# Use a custom strategy\nSTRATEGY=\"ChaseClosestFood\" make sam dev\n```\n\n## Development\n\nThe app can be configured using an `.env` file (example below)\n\n```bash\nDATABASE_URL=\"postgresql://localhost:5432/battlesnake\"\nREDIS_URL=\"redis://localhost:6379\"\nHONEYCOMB_API_KEY=\"\"\nSTRATEGY=\"CautiousCarol\"\nLOG_LEVEL=\"DEBUG\"\n```\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\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080 -g solo -v\n\n# 1v1 against itself (you should be able to use any public snake if you know their URL)\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080 --name dev2 --url http://localhost:8080 -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 ([list available here](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy)).\n\nTo start hacking a new one create a new strategy (in that folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and you call `#move` method to chose a move to respond with (the method your logic will live). You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when reachable food doesn't exist on the board.\n\nYou can also use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) (list of [Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils) available).\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- `STRATEGY` (i.e. \"CautiousCarol\")\n\n## Contributing\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":19,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/app.cr#L19"},"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":12,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/app.cr#L12"},"def":{"name":"persist_turn!","visibility":"Public","body":" PersistTurnJob.new(\n path: \nenv.request.path,\n context_json: \nenv.params.json.to_json\n ).enqueue\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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":"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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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":110,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/battle_snake/context.cr#L110"},"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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"@enemies || (@enemies = board.snakes.reject do |s|\n s.id == @context.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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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)-instance-method","name":"move","doc":"Simulate a move of a snake in some direction","summary":"Simulate a move of a snake in some direction
","abstract":false,"args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(snake_id, direction)","args_html":"(snake_id, direction)","location":{"filename":"src/battle_snake/context.cr","line_number":91,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/battle_snake/context.cr#L91"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\ndeleted_point = board.snakes[index].body.pop\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_793 = context_json?).nil?\n __temp_793\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_793 = path?).nil?\n __temp_793\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"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":3,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"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"},"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.
","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":4,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/base.cr#L4"},"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":8,"url":"https://github.com/fdocr/CrystalSnake/blob/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/base.cr#L8"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\nenemies = @context.board.snakes.reject do |s|\n s.id == @context.you.id\nend\nenemies.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)\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nif safe_move\n return closest_food\nend\nsafe_moves = valid_moves[:moves].reject do |move|\n move == closest_food\nend\nif safe_moves.size.zero?\n return (RandomValid.new(@context)).move\nend\nflood_fills = {} of Int32 => String\ncontexts = [] of BattleSnake::Context\nsafe_moves.size.times do\n contexts << @context.dup\nend\nsafe_moves.each_with_index do |move, i|\n contexts[i].move(@context.you.id, move)\n area_size = (Utils.flood_fill(@context.you.head, contexts[i])).size\n flood_fills[area_size] = move\nend\nflood_fills[flood_fills.keys.sort.last]\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"[\"up\", \"left\", \"down\", \"right\"].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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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 current = queue.pop\n if current.nil?\n else\n area.add(current)\n end\n if queue.empty?\n break\n end\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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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/6700e98e3ea1db24d451c94015e46f3ef23c21cd/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 14 & 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# Use a custom strategy\nSTRATEGY=\"ChaseClosestFood\" make sam dev\n```\n\n## Development\n\nThe app can be configured using an `.env` file (example below)\n\n```bash\nDATABASE_URL=\"postgresql://localhost:5432/battlesnake\"\nREDIS_URL=\"redis://localhost:6379\"\nHONEYCOMB_API_KEY=\"\"\nSTRATEGY=\"CautiousCarol\"\nLOG_LEVEL=\"DEBUG\"\n```\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\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080 -g solo -v\n\n# 1v1 against itself (you should be able to use any public snake if you know their URL)\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080 --name dev2 --url http://localhost:8080 -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 ([list available here](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy)).\n\nTo start hacking a new one create a new strategy (in that folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and you call `#move` method to chose a move to respond with (the method your logic will live). You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when reachable food doesn't exist on the board.\n\nYou can also use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) (list of [Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils) available).\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- `STRATEGY` (i.e. \"CautiousCarol\")\n\n## Contributing\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":23,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/app.cr#L23"},"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":16,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/app.cr#L16"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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":186,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/battle_snake/context.cr#L186"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some direction","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":""}],"args_string":"(snake_id, direction)","args_html":"(snake_id, direction)","location":{"filename":"src/battle_snake/context.cr","line_number":167,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/battle_snake/context.cr#L167"},"def":{"name":"move","args":[{"name":"snake_id","external_name":"snake_id","restriction":""},{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"index = board.snakes.index! do |snake|\n snake.id == snake_id\nend\ndeleted_point = board.snakes[index].body.pop\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_793 = context_json?).nil?\n __temp_793\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_793 = path?).nil?\n __temp_793\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"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":3,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L3"}],"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"},"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.
","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":4,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L4"},"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":8,"url":"https://github.com/fdocr/CrystalSnake/blob/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/base.cr#L8"},"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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\nenemies = @context.board.snakes.reject do |s|\n s.id == @context.you.id\nend\nenemies.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)\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nif safe_move\n return closest_food\nend\nsafe_moves = valid_moves[:moves].reject do |move|\n move == closest_food\nend\nif safe_moves.size.zero?\n return (RandomValid.new(@context)).move\nend\nflood_fills = {} of Int32 => String\ncontexts = [] of BattleSnake::Context\nsafe_moves.size.times do\n contexts << @context.dup\nend\nsafe_moves.each_with_index do |move, i|\n contexts[i].move(@context.you.id, move)\n area_size = (Utils.flood_fill(@context.you.head, contexts[i])).size\n flood_fills[area_size] = move\nend\nflood_fills[flood_fills.keys.sort.last]\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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"[\"up\", \"left\", \"down\", \"right\"].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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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/a994c66774e1c0dd375f55d9b548233e1e653eb3/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 fcde4b4..a67713f 100644
--- a/toplevel.html
+++ b/toplevel.html
@@ -137,6 +137,11 @@