diff --git a/ApplicationJob.html b/ApplicationJob.html index 50bb0f9..e595976 100644 --- a/ApplicationJob.html +++ b/ApplicationJob.html @@ -263,7 +263,7 @@
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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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
A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr
endpoints.
Similar to BattleSnake::Context#valid_moves
but considers all valid moves from enemies.
Checks collisions from snakes on the board and removes snakes that die
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"Returns a shallow copy of this object.
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"Simulate a move of a snake by id in some direction
.
Returns a hash with all the valid :moves
and :neighbors
available from a given BattleSnake::Point
.
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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"Abstract class of all strategies.
","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}} \ No newline at end of file +{"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it (Base class for jobs in the app.
","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"abstract, override in a Job descendant to do something productive
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"Represents the Board as it arrives from the BattleSnake API endpoint.
","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"Executed on #after_initialize
callback and all it does is populate snake_points variable (Array(Point)
) with all points that belong to a snake on the board
A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr
endpoints.
Similar to BattleSnake::Context#valid_moves
but considers all valid moves from enemies.
Checks collisions from snakes on the board and removes snakes that die
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"Returns a shallow copy of this object.
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"Simulate a move of a snake by id in some direction
.
Returns a hash with all the valid :moves
and :neighbors
available from a given BattleSnake::Point
.
Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.
","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"Initialize from two Int32 values
","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"Initialize from a string representation i.e.
","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"The comparison operator.
","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"Returns a new Point directly down from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"Returns a new Point directly left from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"Returns the point when it moves in a direction.
","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"Determines if a given target BattleSnake::Point is reachable.
","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"Returns a new Point directly right from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"Returns the String representation of the Point.
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"Returns a new Point directly up from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"Basic implementation of a Tree data structure.
","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"Abstract class of all strategies.
","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"A strategy that chooses a random valid move, or "up" if there isn't any.
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"Strategy that chases the closest available food from the board with caution against head-to-head collisions.
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"Strategy that chases the closest food from the board from You
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"Strategy that chases randomly selected food from the board
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"A strategy that chooses a random direction to move without any considerations
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"A strategy that chooses a random valid move, or "up" if there isn't any
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"Implementation of A* Search Algorithm (read more).
","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"Implementation of Flood Fill (read more).
","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"This is a DB record representation of a request from a game for either start/move/end request.
","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.
","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"Deletes object from db and calls all related callbacks.
","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}} \ No newline at end of file diff --git a/search-index.js b/search-index.js index c5818df..2842db9 100644 --- a/search-index.js +++ b/search-index.js @@ -1 +1 @@ -crystal_doc_search_index_callback({"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it (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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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
A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr
endpoints.
Similar to BattleSnake::Context#valid_moves
but considers all valid moves from enemies.
Checks collisions from snakes on the board and removes snakes that die
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"Returns a shallow copy of this object.
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"Simulate a move of a snake by id in some direction
.
Returns a hash with all the valid :moves
and :neighbors
available from a given BattleSnake::Point
.
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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"Abstract class of all strategies.
","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/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/b5b2b25b230bc68c2fa705d225105fcdc54356e2/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}}) \ No newline at end of file +crystal_doc_search_index_callback({"repository_name":"CrystalSnake","body":"# Crystal Snake\n\nThis is a [Battle Snake](https://play.battlesnake.com/) project written in [Crystal](https://crystal-lang.org/) using [Kemal](https://kemalcr.com/)\n\nI strongly recommend reading the docs in [https://fdocr.github.io/CrystalSnake/](https://fdocr.github.io/CrystalSnake/). You'll find detailed information on classes and methods there :)\n\nI wrote a few blog posts about this project. Check out [the first one here](https://dev.to/fdocr/learning-crystal-with-battlesnake-3chj).\n\n## Installation\n\nYou'll need Crystal, Postgres & Redis locally. The app uses [sam.cr](https://github.com/imdrasil/sam.cr) for ease of development.\n\n```bash\n# Install dependencies\nshards install\n\n# Create DB & run migrations\nmake sam db:setup\n\n# Start development server in port 8080 with live reload\nmake sam dev\n\n# Run tests\nmake sam test\n```\n\n## Development\n\nThe app can be configured copying the `.env.sample` file as `.env` in the directory root.\n\nFor local development I use the [BattleSnake CLI](https://github.com/BattlesnakeOfficial/rules/tree/main/cli) with the local server running. A basic example looks like this:\n\n```bash\n# Solo game with ChaseClosestFood strategy\nbattlesnake play -W 11 -H 11 --name dev --url http://localhost:8080/chase_closest_food -g solo -v\n\n# Play RandomValid vs CautiousCarol strategies\nbattlesnake play -W 11 -H 11 --name RandomValid --url http://localhost:8080/random_valid --name CautiousCarol --url http://localhost:8080/cautious_carol -v\n```\n\n#### Strategies & Architecture\n\nThe server is built on the `src/app.cr` file and you can choose to use [any of the available strategies](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy).\n\nTo start hacking a new one create a new strategy (in the `src/strategy` folder) that inherits from `Stategy::Base`. They're all initialized with a `BattleSnake::Context` and the server calls the `#move` method on it to respond with. You can re-use strategies within each other, i.e. `Strategy::ChaseClosestFood` uses the `Strategy::RandomValid` strategy when it can't reach any food on the board.\n\nIn order to start using a new strategy:\n1. Add new entry in case clause to `src/strategy/base.cr`\n - Must return the new strategy object\n2. The string in the case clause will determine its path\n - i.e. `http://localhost:8080/new_strategy`\n\nStrategies can use `Strategy::Utils` class methods like `Strategy::Utils.a_star` which implements the [A* Search Algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm). Check out the [available Utils helper methods](https://github.com/fdocr/CrystalSnake/tree/main/src/strategy/utils).\n\n## Deployment\n\nI'm currently using [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). The [Dockerfile](/Dockerfile) is detected and deployed on their cheapest tier. It \"should work\" in lots of other platforms with this setup, but [open an issue](https://github.com/fdocr/CrystalSnake/issues/new) if you need help troubleshooting or to discuss other solutions.\n\n**Customizations**\n\nENV variables are used to [customize your snake](https://docs.battlesnake.com/guides/customizations)\n\n- `SNAKE_COLOR` (i.e. \"#cccccc\")\n- `SNAKE_HEAD`\n- `SNAKE_TAIL`\n\n## Contributing\n\nMake sure to test your changes. First copy `.env.sample` as `.env.test` so you can run the test suite with `make sam test`.\n\n1. Fork it (Base class for jobs in the app.
","class_methods":[{"html_id":"job_name-class-method","name":"job_name","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"job_name","visibility":"Public","body":"\"ApplicationJob\".underscore.downcase"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"build_job_run","visibility":"Public","body":"Mosquito::JobRun.new(self.class.job_name)"}},{"html_id":"perform-instance-method","name":"perform","doc":"abstract, override in a Job descendant to do something productive","summary":"abstract, override in a Job descendant to do something productive
","abstract":false,"location":{"filename":"src/jobs/application_job.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L9"},"def":{"name":"perform","visibility":"Public","body":"if ENV[\"HONEYCOMB_API_KEY\"]?.presence\n OpenTelemetry.trace(self.class.to_s) do |span|\n span.kind = :internal\n trace_perform\n end\nelse\n trace_perform\nend"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/application_job.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/application_job.cr#L8"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/ApplicationRecord","path":"ApplicationRecord.html","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord","abstract":true,"superclass":{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/application_record.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/application_record.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}]},{"html_id":"CrystalSnake/BattleSnake","path":"BattleSnake.html","kind":"module","full_name":"BattleSnake","name":"BattleSnake","abstract":false,"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"types":[{"html_id":"CrystalSnake/BattleSnake/Board","path":"BattleSnake/Board.html","kind":"class","full_name":"BattleSnake::Board","name":"Board","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/board.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L8"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"doc":"Represents the Board as it arrives from the BattleSnake API endpoint.\n\n*@snake_points* is an `Array(BattleSnake::Point)` variable populated when a\nBoard is initialized and contains all the Points that are currently occupied\nby a snake (would represent a collision).","summary":"Represents the Board as it arrives from the BattleSnake API endpoint.
","constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/board.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L9"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"after_initialize-instance-method","name":"after_initialize","abstract":false,"location":{"filename":"src/battle_snake/board.cr","line_number":44,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/board.cr#L44"},"def":{"name":"after_initialize","visibility":"Public","body":"find_snake_points"}},{"html_id":"find_snake_points-instance-method","name":"find_snake_points","doc":"Executed on `after_initialize` callback and all it does is populate\nsnake_points variable (`Array(Point)`) with all points that belong to a\nsnake on the board","summary":"Executed on #after_initialize
callback and all it does is populate snake_points variable (Array(Point)
) with all points that belong to a snake on the board
A BattleSnake::Context is the representation of the game as it arrives from the Webhook API request to src/app.cr
endpoints.
Similar to BattleSnake::Context#valid_moves
but considers all valid moves from enemies.
Checks collisions from snakes on the board and removes snakes that die
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":188,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L188"},"def":{"name":"check_collisions","visibility":"Public","body":"collisions = [] of String\nboard.snakes.each_with_index do |snake, i|\n if ((snake.head.x < 0 || snake.head.y < 0) || snake.head.x > board.width) || snake.head.y > board.height\n collisions << snake.id\n next\n end\n if snake.body.count do |point|\n point == snake.head\n end > 1\n collisions << snake.id\n next\n end\n board.snakes.each_with_index do |opponent, k|\n if opponent.id == snake.id\n next\n end\n if snake.head == opponent.head\n case snake.body.size <=> opponent.body.size\n when .negative?\n collisions << snake.id\n when .positive?\n collisions << opponent.id\n else\n collisions << snake.id\n collisions << opponent.id\n end\n end\n if opponent.body.includes?(snake.head)\n collisions << snake.id\n end\n end\nend\ncollisions.uniq.each do |id|\n snake = board.snakes.find do |snake|\n snake.id == id\n end\n board.snakes.delete(snake)\nend\n"}},{"html_id":"dup-instance-method","name":"dup","doc":"Returns a shallow copy of this object.\n\nThis allocates a new object and copies the contents of\n`self` into it.","summary":"Returns a shallow copy of this object.
","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":23,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L23"},"def":{"name":"dup","visibility":"Public","body":"new_context = Context.from_json(to_json)\nnew_context.turn = turn + 1\nnew_context\n"}},{"html_id":"enemies-instance-method","name":"enemies","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":29,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L29"},"def":{"name":"enemies","visibility":"Public","body":"board.snakes.reject do |snake|\n snake.id == you.id\nend"}},{"html_id":"game:Game-instance-method","name":"game","abstract":false,"location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game","return_type":"Game","visibility":"Public","body":"@game"}},{"html_id":"game=(game:Game)-instance-method","name":"game=","abstract":false,"args":[{"name":"game","external_name":"game","restriction":"Game"}],"args_string":"(game : Game)","args_html":"(game : Game)","location":{"filename":"src/battle_snake/context.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/context.cr#L12"},"def":{"name":"game=","args":[{"name":"game","external_name":"game","restriction":"Game"}],"visibility":"Public","body":"@game = game"}},{"html_id":"move(snake_id,direction,pop_body=true)-instance-method","name":"move","doc":"Simulate a move of a snake by id in some `direction`. Optional param\n`pop_body` that defaults as `true`. If false it won't pop the body\nof the snake being moved (sometimes snakes may have been popped already)","summary":"Simulate a move of a snake by id in some direction
.
Returns a hash with all the valid :moves
and :neighbors
available from a given BattleSnake::Point
.
Represents a Point (x,y) coordinate on the board with some helper methods for processing of the board (i.e.
","constructors":[{"html_id":"new(x:Int32,y:Int32)-class-method","name":"new","doc":"Initialize from two Int32 values","summary":"Initialize from two Int32 values
","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(x : Int32, y : Int32)","args_html":"(x : Int32, y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L16"},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Int32"},{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/point.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L7"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}},{"html_id":"new(str:String)-class-method","name":"new","doc":"Initialize from a string representation i.e. \"x,y\"","summary":"Initialize from a string representation i.e.
","abstract":false,"args":[{"name":"str","external_name":"str","restriction":"String"}],"args_string":"(str : String)","args_html":"(str : String)","location":{"filename":"src/battle_snake/point.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L20"},"def":{"name":"new","args":[{"name":"str","external_name":"str","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(str)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"<=>(other:Point)-instance-method","name":"<=>","doc":"The comparison operator. Returns `0` if the two objects are equal,\na negative number if this object is considered less than *other*,\na positive number if this object is considered greater than *other*,\nor `nil` if the two objects are not comparable.\n\nSubclasses define this method to provide class-specific ordering.\n\nThe comparison operator is usually used to sort values:\n\n```\n# Sort in a descending way:\n[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]\n\n# Sort in an ascending way:\n[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]\n```","summary":"The comparison operator.
","abstract":false,"args":[{"name":"other","external_name":"other","restriction":"Point"}],"args_string":"(other : Point)","args_html":"(other : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":24,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L24"},"def":{"name":"<=>","args":[{"name":"other","external_name":"other","restriction":"Point"}],"visibility":"Public","body":"(x - other.x).abs + (y - other.y).abs"}},{"html_id":"down-instance-method","name":"down","doc":"Returns a new Point directly down from the instance","summary":"Returns a new Point directly down from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":106,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L106"},"def":{"name":"down","visibility":"Public","body":"Point.new(x, y - 1)"}},{"html_id":"left-instance-method","name":"left","doc":"Returns a new Point directly left from the instance","summary":"Returns a new Point directly left from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":101,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L101"},"def":{"name":"left","visibility":"Public","body":"Point.new(x - 1, y)"}},{"html_id":"move(direction)-instance-method","name":"move","doc":"Returns the point when it moves in a direction. Works the same way as #up,\nleft, etc. but with a string parameter so it's easier to manipulate","summary":"Returns the point when it moves in a direction.
","abstract":false,"args":[{"name":"direction","external_name":"direction","restriction":""}],"args_string":"(direction)","args_html":"(direction)","location":{"filename":"src/battle_snake/point.cr","line_number":80,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L80"},"def":{"name":"move","args":[{"name":"direction","external_name":"direction","restriction":""}],"visibility":"Public","body":"case direction\nwhen \"up\"\n up\nwhen \"left\"\n left\nwhen \"down\"\n down\nwhen \"right\"\n right\nelse\n self\nend"}},{"html_id":"move?(target:Point)-instance-method","name":"move?","doc":"Determines if a given *target* BattleSnake::Point is reachable. It returns\nthe direction the point itself needs to move to get to the `target`. It\nreturns an empty string if unreachable in one move.\n\nNOTE: The result of this method is a mathematic/geometric operation and\ndoes not take into account the current board/game, i.e. using negative\nnumbers will return valid results but aren't needed or practical.\n\nExample:\n\n```\nPoint.new(1,1).move?(Point.new(1,2))\n=> \"right\"\n\nPoint.new(2,1).move?(Point.new(1,1))\n=> \"up\"\n\n# Unreachable in one move\nPoint.new(1,1).move?(Point.new(3,3))\n=> \"\"\n\n# Valid result but not used in real scenarios\nPoint.new(-20,-10).move?(Point.new(-20,-11))\n=> \"down\"\n```","summary":"Determines if a given target BattleSnake::Point is reachable.
","abstract":false,"args":[{"name":"target","external_name":"target","restriction":"Point"}],"args_string":"(target : Point)","args_html":"(target : Point)","location":{"filename":"src/battle_snake/point.cr","line_number":63,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L63"},"def":{"name":"move?","args":[{"name":"target","external_name":"target","restriction":"Point"}],"visibility":"Public","body":"case target\nwhen up\n \"up\"\nwhen left\n \"left\"\nwhen down\n \"down\"\nwhen right\n \"right\"\nelse\n \"\"\nend"}},{"html_id":"right-instance-method","name":"right","doc":"Returns a new Point directly right from the instance","summary":"Returns a new Point directly right from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":111,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L111"},"def":{"name":"right","visibility":"Public","body":"Point.new(x + 1, y)"}},{"html_id":"to_s-instance-method","name":"to_s","doc":"Returns the String representation of the Point. Example:\n\n```\nPoint.new(2,2).to_s\n=> \"2,2\"\n```","summary":"Returns the String representation of the Point.
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":34,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L34"},"def":{"name":"to_s","visibility":"Public","body":"\"#{x},#{y}\""}},{"html_id":"up-instance-method","name":"up","doc":"Returns a new Point directly up from the instance","summary":"Returns a new Point directly up from the instance
","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":96,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L96"},"def":{"name":"up","visibility":"Public","body":"Point.new(x, y + 1)"}},{"html_id":"x:Int32-instance-method","name":"x","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x","return_type":"Int32","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Int32)-instance-method","name":"x=","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Int32"}],"args_string":"(x : Int32)","args_html":"(x : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L10"},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Int32"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Int32-instance-method","name":"y","abstract":false,"location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y","return_type":"Int32","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Int32)-instance-method","name":"y=","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Int32"}],"args_string":"(y : Int32)","args_html":"(y : Int32)","location":{"filename":"src/battle_snake/point.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/point.cr#L13"},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Int32"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"CrystalSnake/BattleSnake/Ruleset","path":"BattleSnake/Ruleset.html","kind":"class","full_name":"BattleSnake::Ruleset","name":"Ruleset","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/ruleset.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L7"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"settings:Settings-instance-method","name":"settings","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings","return_type":"Settings","visibility":"Public","body":"@settings"}},{"html_id":"settings=(settings:Settings)-instance-method","name":"settings=","abstract":false,"args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"args_string":"(settings : Settings)","args_html":"(settings : Settings)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L13"},"def":{"name":"settings=","args":[{"name":"settings","external_name":"settings","restriction":"Settings"}],"visibility":"Public","body":"@settings = settings"}},{"html_id":"version:String-instance-method","name":"version","abstract":false,"location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version","return_type":"String","visibility":"Public","body":"@version"}},{"html_id":"version=(version:String)-instance-method","name":"version=","abstract":false,"args":[{"name":"version","external_name":"version","restriction":"String"}],"args_string":"(version : String)","args_html":"(version : String)","location":{"filename":"src/battle_snake/ruleset.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/ruleset.cr#L10"},"def":{"name":"version=","args":[{"name":"version","external_name":"version","restriction":"String"}],"visibility":"Public","body":"@version = version"}}]},{"html_id":"CrystalSnake/BattleSnake/Settings","path":"BattleSnake/Settings.html","kind":"class","full_name":"BattleSnake::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/settings.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/settings.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"foodSpawnChance:Int32-instance-method","name":"foodSpawnChance","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance","return_type":"Int32","visibility":"Public","body":"@foodSpawnChance"}},{"html_id":"foodSpawnChance=(foodSpawnChance:Int32)-instance-method","name":"foodSpawnChance=","abstract":false,"args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"args_string":"(foodSpawnChance : Int32)","args_html":"(foodSpawnChance : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L7"},"def":{"name":"foodSpawnChance=","args":[{"name":"foodSpawnChance","external_name":"foodSpawnChance","restriction":"Int32"}],"visibility":"Public","body":"@foodSpawnChance = foodSpawnChance"}},{"html_id":"hazardDamagePerTurn:Int32-instance-method","name":"hazardDamagePerTurn","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn","return_type":"Int32","visibility":"Public","body":"@hazardDamagePerTurn"}},{"html_id":"hazardDamagePerTurn=(hazardDamagePerTurn:Int32)-instance-method","name":"hazardDamagePerTurn=","abstract":false,"args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"args_string":"(hazardDamagePerTurn : Int32)","args_html":"(hazardDamagePerTurn : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L13"},"def":{"name":"hazardDamagePerTurn=","args":[{"name":"hazardDamagePerTurn","external_name":"hazardDamagePerTurn","restriction":"Int32"}],"visibility":"Public","body":"@hazardDamagePerTurn = hazardDamagePerTurn"}},{"html_id":"hazardMap:String-instance-method","name":"hazardMap","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap","return_type":"String","visibility":"Public","body":"@hazardMap"}},{"html_id":"hazardMap=(hazardMap:String)-instance-method","name":"hazardMap=","abstract":false,"args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"args_string":"(hazardMap : String)","args_html":"(hazardMap : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L16"},"def":{"name":"hazardMap=","args":[{"name":"hazardMap","external_name":"hazardMap","restriction":"String"}],"visibility":"Public","body":"@hazardMap = hazardMap"}},{"html_id":"hazardMapAuthor:String-instance-method","name":"hazardMapAuthor","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor","return_type":"String","visibility":"Public","body":"@hazardMapAuthor"}},{"html_id":"hazardMapAuthor=(hazardMapAuthor:String)-instance-method","name":"hazardMapAuthor=","abstract":false,"args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"args_string":"(hazardMapAuthor : String)","args_html":"(hazardMapAuthor : String)","location":{"filename":"src/battle_snake/settings.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L19"},"def":{"name":"hazardMapAuthor=","args":[{"name":"hazardMapAuthor","external_name":"hazardMapAuthor","restriction":"String"}],"visibility":"Public","body":"@hazardMapAuthor = hazardMapAuthor"}},{"html_id":"minimumFood:Int32-instance-method","name":"minimumFood","abstract":false,"location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood","return_type":"Int32","visibility":"Public","body":"@minimumFood"}},{"html_id":"minimumFood=(minimumFood:Int32)-instance-method","name":"minimumFood=","abstract":false,"args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"args_string":"(minimumFood : Int32)","args_html":"(minimumFood : Int32)","location":{"filename":"src/battle_snake/settings.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/settings.cr#L10"},"def":{"name":"minimumFood=","args":[{"name":"minimumFood","external_name":"minimumFood","restriction":"Int32"}],"visibility":"Public","body":"@minimumFood = minimumFood"}}]},{"html_id":"CrystalSnake/BattleSnake/Snake","path":"BattleSnake/Snake.html","kind":"class","full_name":"BattleSnake::Snake","name":"Snake","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/battle_snake/snake.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"included_modules":[{"html_id":"CrystalSnake/JSON/Serializable","kind":"module","full_name":"JSON::Serializable","name":"Serializable"}],"namespace":{"html_id":"CrystalSnake/BattleSnake","kind":"module","full_name":"BattleSnake","name":"BattleSnake"},"constructors":[{"html_id":"new(pull:JSON::PullParser)-class-method","name":"new","abstract":false,"args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"args_string":"(pull : JSON::PullParser)","args_html":"(pull : JSON::PullParser)","location":{"filename":"src/battle_snake/snake.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L4"},"def":{"name":"new","args":[{"name":"pull","external_name":"pull","restriction":"::JSON::PullParser"}],"visibility":"Public","body":"new_from_json_pull_parser(pull)"}}],"instance_methods":[{"html_id":"body:Array(Point)-instance-method","name":"body","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body","return_type":"Array(Point)","visibility":"Public","body":"@body"}},{"html_id":"body=(body:Array(Point))-instance-method","name":"body=","abstract":false,"args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"args_string":"(body : Array(Point))","args_html":"(body : Array(Point))","location":{"filename":"src/battle_snake/snake.cr","line_number":19,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L19"},"def":{"name":"body=","args":[{"name":"body","external_name":"body","restriction":"Array(Point)"}],"visibility":"Public","body":"@body = body"}},{"html_id":"head:Point-instance-method","name":"head","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head","return_type":"Point","visibility":"Public","body":"@head"}},{"html_id":"head=(head:Point)-instance-method","name":"head=","abstract":false,"args":[{"name":"head","external_name":"head","restriction":"Point"}],"args_string":"(head : Point)","args_html":"(head : Point)","location":{"filename":"src/battle_snake/snake.cr","line_number":22,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L22"},"def":{"name":"head=","args":[{"name":"head","external_name":"head","restriction":"Point"}],"visibility":"Public","body":"@head = head"}},{"html_id":"health:Int32-instance-method","name":"health","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health","return_type":"Int32","visibility":"Public","body":"@health"}},{"html_id":"health=(health:Int32)-instance-method","name":"health=","abstract":false,"args":[{"name":"health","external_name":"health","restriction":"Int32"}],"args_string":"(health : Int32)","args_html":"(health : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L16"},"def":{"name":"health=","args":[{"name":"health","external_name":"health","restriction":"Int32"}],"visibility":"Public","body":"@health = health"}},{"html_id":"id:String-instance-method","name":"id","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id","return_type":"String","visibility":"Public","body":"@id"}},{"html_id":"id=(id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"id","external_name":"id","restriction":"String"}],"args_string":"(id : String)","args_html":"(id : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L7"},"def":{"name":"id=","args":[{"name":"id","external_name":"id","restriction":"String"}],"visibility":"Public","body":"@id = id"}},{"html_id":"latency:String-instance-method","name":"latency","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency","return_type":"String","visibility":"Public","body":"@latency"}},{"html_id":"latency=(latency:String)-instance-method","name":"latency=","abstract":false,"args":[{"name":"latency","external_name":"latency","restriction":"String"}],"args_string":"(latency : String)","args_html":"(latency : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":13,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L13"},"def":{"name":"latency=","args":[{"name":"latency","external_name":"latency","restriction":"String"}],"visibility":"Public","body":"@latency = latency"}},{"html_id":"length:Int32-instance-method","name":"length","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length","return_type":"Int32","visibility":"Public","body":"@length"}},{"html_id":"length=(length:Int32)-instance-method","name":"length=","abstract":false,"args":[{"name":"length","external_name":"length","restriction":"Int32"}],"args_string":"(length : Int32)","args_html":"(length : Int32)","location":{"filename":"src/battle_snake/snake.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L25"},"def":{"name":"length=","args":[{"name":"length","external_name":"length","restriction":"Int32"}],"visibility":"Public","body":"@length = length"}},{"html_id":"name:String-instance-method","name":"name","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name","return_type":"String","visibility":"Public","body":"@name"}},{"html_id":"name=(name:String)-instance-method","name":"name=","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"}],"args_string":"(name : String)","args_html":"(name : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L10"},"def":{"name":"name=","args":[{"name":"name","external_name":"name","restriction":"String"}],"visibility":"Public","body":"@name = name"}},{"html_id":"shout:String-instance-method","name":"shout","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout","return_type":"String","visibility":"Public","body":"@shout"}},{"html_id":"shout=(shout:String)-instance-method","name":"shout=","abstract":false,"args":[{"name":"shout","external_name":"shout","restriction":"String"}],"args_string":"(shout : String)","args_html":"(shout : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":28,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L28"},"def":{"name":"shout=","args":[{"name":"shout","external_name":"shout","restriction":"String"}],"visibility":"Public","body":"@shout = shout"}},{"html_id":"squad:String-instance-method","name":"squad","abstract":false,"location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad","return_type":"String","visibility":"Public","body":"@squad"}},{"html_id":"squad=(squad:String)-instance-method","name":"squad=","abstract":false,"args":[{"name":"squad","external_name":"squad","restriction":"String"}],"args_string":"(squad : String)","args_html":"(squad : String)","location":{"filename":"src/battle_snake/snake.cr","line_number":31,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/battle_snake/snake.cr#L31"},"def":{"name":"squad=","args":[{"name":"squad","external_name":"squad","restriction":"String"}],"visibility":"Public","body":"@squad = squad"}}]}]},{"html_id":"CrystalSnake/LTree","path":"LTree.html","kind":"class","full_name":"LTree","name":"LTree","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/l_tree.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L7"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"Basic implementation of a Tree data structure. Implemented using a List to\naccomodate N children per node.\n\nNOTE: Children in the Array are not sorted. This means the only way to \ntraverse/search the tree is brute force, but for the current use case this\nisn't necessary.","summary":"Basic implementation of a Tree data structure.
","constructors":[{"html_id":"new(value:String,parent:LTree|Nil=nil)-class-method","name":"new","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"args_string":"(value : String, parent : LTree | Nil = nil)","args_html":"(value : String, parent : LTree | Nil = nil)","location":{"filename":"src/l_tree.cr","line_number":12,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L12"},"def":{"name":"new","args":[{"name":"value","external_name":"value","restriction":"String"},{"name":"parent","default_value":"nil","external_name":"parent","restriction":"LTree | ::Nil"}],"visibility":"Public","body":"_ = allocate\n_.initialize(value, parent)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"add(text)-instance-method","name":"add","abstract":false,"args":[{"name":"text","external_name":"text","restriction":""}],"args_string":"(text)","args_html":"(text)","location":{"filename":"src/l_tree.cr","line_number":16,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L16"},"def":{"name":"add","args":[{"name":"text","external_name":"text","restriction":""}],"visibility":"Public","body":"@children << (LTree.new(text, self))"}},{"html_id":"children:Array(LTree)-instance-method","name":"children","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":8,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L8"},"def":{"name":"children","visibility":"Public","body":"@children"}},{"html_id":"leaves-instance-method","name":"leaves","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":20,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L20"},"def":{"name":"leaves","visibility":"Public","body":"if @children.any?\nelse\n return [self]\nend\n@children.map do |node|\n node.leaves\nend.flatten\n"}},{"html_id":"parent:LTree?-instance-method","name":"parent","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":10,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L10"},"def":{"name":"parent","visibility":"Public","body":"@parent"}},{"html_id":"root-instance-method","name":"root","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L26"},"def":{"name":"root","visibility":"Public","body":"parent.nil? ? self : parent.try(&.root)"}},{"html_id":"value:String-instance-method","name":"value","abstract":false,"location":{"filename":"src/l_tree.cr","line_number":9,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/l_tree.cr#L9"},"def":{"name":"value","visibility":"Public","body":"@value"}}]},{"html_id":"CrystalSnake/PersistTurnJob","path":"PersistTurnJob.html","kind":"class","full_name":"PersistTurnJob","name":"PersistTurnJob","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},"ancestors":[{"html_id":"CrystalSnake/ApplicationJob","kind":"class","full_name":"ApplicationJob","name":"ApplicationJob"},{"html_id":"CrystalSnake/Mosquito/QueuedJob","kind":"class","full_name":"Mosquito::QueuedJob","name":"QueuedJob"},{"html_id":"CrystalSnake/Mosquito/Job","kind":"class","full_name":"Mosquito::Job","name":"Job"},{"html_id":"CrystalSnake/Mosquito/Serializers/Primitives","kind":"module","full_name":"Mosquito::Serializers::Primitives","name":"Primitives"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"class_methods":[{"html_id":"job_name-class-method","name":"job_name","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"job_name","visibility":"Public","body":"\"PersistTurnJob\".underscore.downcase"}}],"constructors":[{"html_id":"new(path:String,context_json:String)-class-method","name":"new","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"args_string":"(path : String, context_json : String)","args_html":"(path : String, context_json : String)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","args":[{"name":"path","external_name":"path","restriction":"String"},{"name":"context_json","external_name":"context_json","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(path, context_json)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"build_job_run-instance-method","name":"build_job_run","doc":"Base class for jobs in the app. Overrides `perform` so that jobs can\nimplement `trace_perform` instead. This will allow for OpenTelemetry tracing\nif available, otherwise the job will be executed as it would if it overrides\n`perform` (mosquito standard). If someone does override `perform` on the job\nit will also have no behavior effect, other than tracing not taking place.","summary":"Base class for jobs in the app.
","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"build_job_run","visibility":"Public","body":"job_run = Mosquito::JobRun.new(self.class.job_name)\njob_run.config[\"path\"] = serialize_string(path)\njob_run.config[\"context_json\"] = serialize_string(context_json)\njob_run\n"}},{"html_id":"context_json:String-instance-method","name":"context_json","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json","return_type":"String","visibility":"Public","body":"if !(__temp_791 = context_json?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named context_json but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `context_json` instead?\"\n raise(msg)\nend"}},{"html_id":"context_json=(value:String):String-instance-method","name":"context_json=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@context_json = value"}},{"html_id":"context_json?:String|Nil-instance-method","name":"context_json?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"context_json?","return_type":"String | Nil","visibility":"Public","body":"@context_json"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path","return_type":"String","visibility":"Public","body":"if !(__temp_791 = path?).nil?\n __temp_791\nelse\n msg = \" Expected a parameter named path but found nil.\\n The parameter may not have been provided when the job was enqueued.\\n Should you be using `path` instead?\"\n raise(msg)\nend"}},{"html_id":"path=(value:String):String-instance-method","name":"path=","abstract":false,"args":[{"name":"value","external_name":"value","restriction":"String"}],"args_string":"(value : String) : String","args_html":"(value : String) : String","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path=","args":[{"name":"value","external_name":"value","restriction":"String"}],"return_type":"String","visibility":"Public","body":"@path = value"}},{"html_id":"path?:String|Nil-instance-method","name":"path?","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"path?","return_type":"String | Nil","visibility":"Public","body":"@path"}},{"html_id":"trace_perform-instance-method","name":"trace_perform","abstract":false,"location":{"filename":"src/jobs/persist_turn_job.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L6"},"def":{"name":"trace_perform","visibility":"Public","body":"context = BattleSnake::Context.from_json(context_json)\ndead = context.board.snakes.find do |s|\n s.id == context.you.id\nend.nil?\nturn = Turn.create(game_id: context.game.id, snake_id: context.you.id, context: context_json, path: path, dead: dead)\n"}},{"html_id":"vars_from(config:Hash(String,String))-instance-method","name":"vars_from","abstract":false,"args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"args_string":"(config : Hash(String, String))","args_html":"(config : Hash(String, String))","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L4"},"def":{"name":"vars_from","args":[{"name":"config","external_name":"config","restriction":"Hash(String, String)"}],"visibility":"Public","body":"@path = deserialize_string(config[\"path\"])\n@context_json = deserialize_string(config[\"context_json\"])\n"}}],"macros":[{"html_id":"params(*parameters)-macro","name":"params","abstract":false,"args":[{"name":"parameters","external_name":"parameters","restriction":""}],"args_string":"(*parameters)","args_html":"(*parameters)","location":{"filename":"src/jobs/persist_turn_job.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/jobs/persist_turn_job.cr#L3"},"def":{"name":"params","args":[{"name":"parameters","external_name":"parameters","restriction":""}],"splat_index":0,"visibility":"Public","body":" \n \n{% parsed_parameters = parameters.map do |parameter|\n type = nil\n simplified_type = nil\n if parameter.is_a?(Assign)\n name = parameter.target\n value = parameter.value\n else\n if parameter.is_a?(TypeDeclaration)\n name = parameter.var\n value = parameter.value\n type = parameter.type\n else\n raise(\"Mosquito Job: Unable to generate parameter for #{parameter}\")\n end\n end\n unless type\n raise(\"Mosquito Job: parameter types must be specified explicitly\")\n end\n if type.is_a?(Union)\n raise(\"Mosquito Job: Unable to generate a constructor for Union Types: #{type}\")\n else\n if type.is_a?(Path)\n simplified_type = type.resolve\n end\n end\n method_suffix = (simplified_type.stringify.underscore.gsub(/::/, \"__\")).id\n {name: name, value: value, type: type, simplified_type: simplified_type, method_suffix: method_suffix}\nend %}\n\n\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}?\n\n def {{ parameter[\"name\"] }} : {{ parameter[\"simplified_type\"] }}\n if ! (%object = {{ parameter[\"name\"] }}?).nil?\n %object\n else\n msg = <<-MSG\n Expected a parameter named {{ parameter[\"name\"] }} but found nil.\n The parameter may not have been provided when the job was enqueued.\n Should you be using `{{ parameter[\"name\"] }}` instead?\n MSG\n raise msg\n end\n end\n\n def {{ parameter[\"name\"] }}=(value : {{ parameter[\"simplified_type\"] }}) : {{ parameter[\"simplified_type\"] }}\n @{{ parameter[\"name\"] }} = value\n end\n\n def {{ parameter[\"name\"] }}? : {{ parameter[\"simplified_type\"] }} | Nil\n @{{ parameter[\"name\"] }}\n end\n {% end %}\n\n\n def initialize\n \nend\n\n def initialize(\n{{ (parsed_parameters.map do |parameter|\n assignment = \"@#{parameter[\"name\"]}\"\n if parameter[\"type\"]\n assignment = assignment + \" : #{parameter[\"type\"]}\"\n end\n unless parameter[\"value\"].is_a?(Nop)\n assignment = assignment + \" = #{parameter[\"value\"]}\"\n end\n assignment\nend.join(\", \")).id }}\n)\n \nend\n\n def vars_from(config : Hash(String, String))\n \n{% for parameter in parsed_parameters %}\n @{{ parameter[\"name\"] }} = deserialize_{{ parameter[\"method_suffix\"] }}(config[\"{{ parameter[\"name\"] }}\"])\n {% end %}\n\n \nend\n\n def build_job_run\n job_run = Mosquito::JobRun.new self.class.job_name\n\n \n{% for parameter in parsed_parameters %}\n job_run.config[\"{{ parameter[\"name\"] }}\"] = serialize_{{ parameter[\"method_suffix\"] }}({{ parameter[\"name\"] }})\n {% end %}\n\n\n job_run\n \nend\n \n \n"}}]},{"html_id":"CrystalSnake/Strategy","path":"Strategy.html","kind":"module","full_name":"Strategy","name":"Strategy","abstract":false,"locations":[{"filename":"src/strategy/base.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L3"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VALID_MOVES","name":"VALID_MOVES","value":"[\"up\", \"left\", \"down\", \"right\"]"}],"doc":"Abstract class of all strategies. They're all initialized with a *@context*\nand their entrypoint is the `#move` method","summary":"Abstract class of all strategies.
","class_methods":[{"html_id":"build(name,context)-class-method","name":"build","abstract":false,"args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"args_string":"(name, context)","args_html":"(name, context)","location":{"filename":"src/strategy/base.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L6"},"def":{"name":"build","args":[{"name":"name","external_name":"name","restriction":""},{"name":"context","external_name":"context","restriction":""}],"visibility":"Public","body":"case name\nwhen \"random\"\n Strategy::Random.new(context)\nwhen \"random_valid\"\n Strategy::RandomValid.new(context)\nwhen \"blast_random_valid\"\n Strategy::BlastRandomValid.new(context)\nwhen \"chase_closest_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"chase_random_food\"\n Strategy::ChaseClosestFood.new(context)\nwhen \"cautious_carol\"\n Strategy::CautiousCarol.new(context)\nelse\n nil\nend"}}],"types":[{"html_id":"CrystalSnake/Strategy/Base","path":"Strategy/Base.html","kind":"class","full_name":"Strategy::Base","name":"Base","abstract":true,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/base.cr","line_number":25,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L25"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"subclasses":[{"html_id":"CrystalSnake/Strategy/BlastRandomValid","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid"},{"html_id":"CrystalSnake/Strategy/CautiousCarol","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol"},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood"},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood"},{"html_id":"CrystalSnake/Strategy/Random","kind":"class","full_name":"Strategy::Random","name":"Random"},{"html_id":"CrystalSnake/Strategy/RandomValid","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid"}],"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"constructors":[{"html_id":"new(context:BattleSnake::Context)-class-method","name":"new","abstract":false,"args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(context : BattleSnake::Context)","args_html":"(context : BattleSnake::Context)","location":{"filename":"src/strategy/base.cr","line_number":26,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L26"},"def":{"name":"new","args":[{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"_ = allocate\n_.initialize(context)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/base.cr","line_number":30,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/base.cr#L30"},"def":{"name":"move","visibility":"Public","body":"\"up\""}}]},{"html_id":"CrystalSnake/Strategy/BlastRandomValid","path":"Strategy/BlastRandomValid.html","kind":"class","full_name":"Strategy::BlastRandomValid","name":"BlastRandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/blast_random_valid.cr","line_number":4,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L4"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any.\nInstead of the plain `BattleSnake::Conext::valid_moves` this strategy\nuses `BattleSnake::Conext::valid_moves` for a smarter choice if possible.","summary":"A strategy that chooses a random valid move, or "up" if there isn't any.
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/blast_random_valid.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/blast_random_valid.cr#L5"},"def":{"name":"move","visibility":"Public","body":"valid_moves = @context.blast_valid_moves!\nif valid_moves[:moves].empty?\nelse\n return valid_moves[:moves].sample\nend\nif valid_moves[:risky_moves].empty?\nelse\n return valid_moves[:risky_moves].sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/CautiousCarol","path":"Strategy/CautiousCarol.html","kind":"class","full_name":"Strategy::CautiousCarol","name":"CautiousCarol","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/cautious_carol.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest available food from the board with caution\nagainst head-to-head collisions. When a potentially dangerous move is in the\nway it analyzes the other valid moves available and picks the one with the \nmost open area of the board to avoid enclosed spaces.","summary":"Strategy that chases the closest available food from the board with caution against head-to-head collisions.
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/cautious_carol.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/cautious_carol.cr#L6"},"def":{"name":"move","visibility":"Public","body":"@context.board.snakes.each do |snake|\n snake.body.pop\nend\nvalid_moves = @context.valid_moves(@context.you.head)\nif valid_moves[:moves].empty?\n return (RandomValid.new(@context)).move\nend\ndangerous_moves = [] of BattleSnake::Point\n@context.enemies.each do |snake|\n if (snake.head <=> @context.you.head) > 2\n next\n end\n if snake.body.size < @context.you.body.size\n next\n end\n (@context.valid_moves(snake.head))[:neighbors].values.each do |point|\n meeting_point = valid_moves[:neighbors].values.find do |p|\n (point <=> p).zero?\n end\n if meeting_point.nil?\n next\n end\n dangerous_moves << point\n end\nend\nclosest_food = (ChaseClosestFood.new(@context)).move\ntarget_point = @context.you.head.move(closest_food)\nclosest_food_area = 0\nflood_fills = {} of Int32 => String\ncontexts = {} of String => BattleSnake::Context\nvalid_moves[:moves].each do |move|\n contexts[move] = @context.dup\n contexts[move].move(@context.you.id, move, false)\n area_size = (Utils.flood_fill(contexts[move].you.head, contexts[move])).size\n flood_fills[area_size] = move\n if move == closest_food\n closest_food_area = area_size\n end\nend\nsafe_move = dangerous_moves.find do |p|\n (p <=> target_point).zero?\nend.nil?\nsafe_area = closest_food_area >= @context.you.body.size\nif safe_move && safe_area\n return closest_food\nend\nif flood_fills.keys.size > 0\n return flood_fills[flood_fills.keys.sort.last]\nend\n(RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseClosestFood","path":"Strategy/ChaseClosestFood.html","kind":"class","full_name":"Strategy::ChaseClosestFood","name":"ChaseClosestFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_closest_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases the closest food from the board from You","summary":"Strategy that chases the closest food from the board from You
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/chase_closest_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_closest_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"food_routes = {} of Int32 => NamedTuple(route: Array(BattleSnake::Point), moves: Array(String))\n@context.board.food.each do |point|\n res = Utils.a_star(@context.you.head, point, @context)\n dist = res[:moves].size\n if dist > 0\n food_routes[dist] = res\n end\nend\nvalid_target_count = food_routes.keys.size.zero?\nif valid_target_count\n return (Strategy::RandomValid.new(@context)).move\nend\nclosest_dist = food_routes.keys.sort.first\nreturn food_routes[closest_dist][:moves].first\n"}}]},{"html_id":"CrystalSnake/Strategy/ChaseRandomFood","path":"Strategy/ChaseRandomFood.html","kind":"class","full_name":"Strategy::ChaseRandomFood","name":"ChaseRandomFood","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/chase_random_food.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"Strategy that chases randomly selected food from the board","summary":"Strategy that chases randomly selected food from the board
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/chase_random_food.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/chase_random_food.cr#L3"},"def":{"name":"move","visibility":"Public","body":"if @context.board.food.empty?\n return (Strategy::RandomValid.new(@context)).move\nend\nres = Utils.a_star(@context.you.head, @context.board.food.sample, @context)\nif res[:moves].empty?\nelse\n return res[:moves].first\nend\n(Strategy::RandomValid.new(@context)).move\n"}}]},{"html_id":"CrystalSnake/Strategy/Random","path":"Strategy/Random.html","kind":"class","full_name":"Strategy::Random","name":"Random","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random direction to move without any considerations","summary":"A strategy that chooses a random direction to move without any considerations
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/random.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random.cr#L3"},"def":{"name":"move","visibility":"Public","body":"VALID_MOVES.sample"}}]},{"html_id":"CrystalSnake/Strategy/RandomValid","path":"Strategy/RandomValid.html","kind":"class","full_name":"Strategy::RandomValid","name":"RandomValid","abstract":false,"superclass":{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},"ancestors":[{"html_id":"CrystalSnake/Strategy/Base","kind":"class","full_name":"Strategy::Base","name":"Base"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/random_valid.cr","line_number":2,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L2"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"doc":"A strategy that chooses a random valid move, or \"up\" if there isn't any","summary":"A strategy that chooses a random valid move, or "up" if there isn't any
","instance_methods":[{"html_id":"move-instance-method","name":"move","doc":"Returns the move (direction) to chose based on the *@context*","summary":"Returns the move (direction) to chose based on the @context
","abstract":false,"location":{"filename":"src/strategy/random_valid.cr","line_number":3,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/random_valid.cr#L3"},"def":{"name":"move","visibility":"Public","body":"valid_moves = (@context.valid_moves(@context.you.head))[:moves]\nif valid_moves.empty?\nelse\n return valid_moves.sample\nend\n\"up\"\n"}}]},{"html_id":"CrystalSnake/Strategy/Utils","path":"Strategy/Utils.html","kind":"class","full_name":"Strategy::Utils","name":"Utils","abstract":false,"superclass":{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/strategy/utils.cr","line_number":1,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils.cr#L1"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"CrystalSnake/Strategy","kind":"module","full_name":"Strategy","name":"Strategy"},"class_methods":[{"html_id":"a_star(a:BattleSnake::Point,b:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"a_star","doc":"Implementation of A* Search Algorithm\n([read more](https://en.wikipedia.org/wiki/A*_search_algorithm)).\n\nIt receives Point *a* (start) and *b* (objective), along with a\n`BattleSnake::Context` to access the game state. It returns a hash with\n`:route` (`Array(BattleSnake::Point)`) and `:moves` (`Array(String)`). They\nrepresent the points in the route and the moves (\"up\"/\"left\"/etc.) to take\nthat path from point *a* to *b*. Both arrays will be empty if the context\nmakes it impossible to find a valid route.\n\nNOTE: Implemented using the `spider-gazelle/priority-queue` project on GitHub\nNOTE: Naive Manhattan Distance used for estimation function of the algorithm\nNOTE: Performance can be optimized on data structure lookups and instance\ninitializations when using helper methods, i.e.\n`BattleSnake::Context#valid_moves`","summary":"Implementation of A* Search Algorithm (read more).
","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, b : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/a_star.cr","line_number":18,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/a_star.cr#L18"},"def":{"name":"a_star","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"b","external_name":"b","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"queue = Priority::Queue(BattleSnake::Point).new\ncame_from = {} of String => BattleSnake::Point\nnode_distance = {} of String => Int32\nnode_distance[a.to_s] = a <=> b\nqueue.push(node_distance[a.to_s], a)\nfinished = false\nwhile !finished\n current = queue.shift.value\n valid_moves = context.valid_moves(current)\n valid_moves[:moves].each do |move|\n new_point = valid_moves[:neighbors][move]\n if node_distance.has_key?(new_point.to_s)\n next\n end\n node_distance[new_point.to_s] = new_point <=> b\n queue.push(node_distance[new_point.to_s], new_point)\n came_from[new_point.to_s] = current\n if node_distance[new_point.to_s].zero?\n finished = true\n end\n end\n if (!finished) && queue.size.zero?\n break\n end\nend\nroute = [] of BattleSnake::Point\nmoves = [] of String\nif finished\nelse\n return {route: route, moves: moves}\nend\ncurrent = b\nwhile current != a\n route.unshift(current)\n moves.unshift(came_from[current.to_s].move?(current))\n current = came_from[current.to_s]\nend\n{route: route, moves: moves}\n"}},{"html_id":"flood_fill(a:BattleSnake::Point,context:BattleSnake::Context)-class-method","name":"flood_fill","doc":"Implementation of Flood Fill\n([read more](https://en.wikipedia.org/wiki/Flood_fill)).\n\nIt receives a BattleSnake::Point *a* and a BattleSnake::Context *context* to\nstart off a Flood Fill and returns a Set(BattleSnake::Point) with all the\npoints reachable to that area on the board","summary":"Implementation of Flood Fill (read more).
","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"args_string":"(a : BattleSnake::Point, context : BattleSnake::Context)","args_html":"(a : BattleSnake::Point, context : BattleSnake::Context)","location":{"filename":"src/strategy/utils/flood_fill.cr","line_number":7,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/strategy/utils/flood_fill.cr#L7"},"def":{"name":"flood_fill","args":[{"name":"a","external_name":"a","restriction":"BattleSnake::Point"},{"name":"context","external_name":"context","restriction":"BattleSnake::Context"}],"visibility":"Public","body":"area = Set(BattleSnake::Point).new\nqueue = [] of BattleSnake::Point\ncurrent = a\nloop do\n (context.valid_moves(current))[:neighbors].each_value.each do |point|\n if area.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n if queue.index do |p|\n (p <=> point).zero?\n end.nil?\n else\n next\n end\n queue.push(point)\n end\n if queue.empty?\n break\n end\n current = queue.pop\n area.add(current)\nend\narea\n"}}]}]},{"html_id":"CrystalSnake/Turn","path":"Turn.html","kind":"class","full_name":"Turn","name":"Turn","abstract":false,"superclass":{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},"ancestors":[{"html_id":"CrystalSnake/ApplicationRecord","kind":"class","full_name":"ApplicationRecord","name":"ApplicationRecord"},{"html_id":"CrystalSnake/Jennifer/Model/Base","kind":"class","full_name":"Jennifer::Model::Base","name":"Base"},{"html_id":"CrystalSnake/Jennifer/Model/Callback","kind":"module","full_name":"Jennifer::Model::Callback","name":"Callback"},{"html_id":"CrystalSnake/Jennifer/Model/Validation","kind":"module","full_name":"Jennifer::Model::Validation","name":"Validation"},{"html_id":"CrystalSnake/Jennifer/Validations/Macros","kind":"module","full_name":"Jennifer::Validations::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/STIMapping","kind":"module","full_name":"Jennifer::Model::STIMapping","name":"STIMapping"},{"html_id":"CrystalSnake/Jennifer/Model/OptimisticLocking","kind":"module","full_name":"Jennifer::Model::OptimisticLocking","name":"OptimisticLocking"},{"html_id":"CrystalSnake/Jennifer/Model/Timestamp","kind":"module","full_name":"Jennifer::Model::Timestamp","name":"Timestamp"},{"html_id":"CrystalSnake/Jennifer/Model/Mapping","kind":"module","full_name":"Jennifer::Model::Mapping","name":"Mapping"},{"html_id":"CrystalSnake/Jennifer/Model/CommonMapping","kind":"module","full_name":"Jennifer::Model::CommonMapping","name":"CommonMapping"},{"html_id":"CrystalSnake/Jennifer/Model/FieldDeclaration","kind":"module","full_name":"Jennifer::Model::FieldDeclaration","name":"FieldDeclaration"},{"html_id":"CrystalSnake/Jennifer/Presentable","kind":"module","full_name":"Jennifer::Presentable","name":"Presentable"},{"html_id":"CrystalSnake/Jennifer/Model/Resource","kind":"class","full_name":"Jennifer::Model::Resource","name":"Resource"},{"html_id":"CrystalSnake/Jennifer/Macros","kind":"module","full_name":"Jennifer::Macros","name":"Macros"},{"html_id":"CrystalSnake/Jennifer/Model/RelationDefinition","kind":"module","full_name":"Jennifer::Model::RelationDefinition","name":"RelationDefinition"},{"html_id":"CrystalSnake/Jennifer/Model/Scoping","kind":"module","full_name":"Jennifer::Model::Scoping","name":"Scoping"},{"html_id":"CrystalSnake/Jennifer/Model/Translation","kind":"module","full_name":"Jennifer::Model::Translation","name":"Translation"},{"html_id":"CrystalSnake/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"CrystalSnake/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/models/turn.cr","line_number":5,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L5"}],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":false,"const":false,"doc":"This is a DB record representation of a request from a game for either\nstart/move/end request.\n\nNOTE: https://imdrasil.github.io/jennifer.cr/docs/model_mapping","summary":"This is a DB record representation of a request from a game for either start/move/end request.
","class_methods":[{"html_id":"_context-class-method","name":"_context","abstract":false,"def":{"name":"_context","visibility":"Public","body":"c(\"context\")"}},{"html_id":"_created_at-class-method","name":"_created_at","abstract":false,"def":{"name":"_created_at","visibility":"Public","body":"c(\"created_at\")"}},{"html_id":"_dead-class-method","name":"_dead","abstract":false,"def":{"name":"_dead","visibility":"Public","body":"c(\"dead\")"}},{"html_id":"_game_id-class-method","name":"_game_id","abstract":false,"def":{"name":"_game_id","visibility":"Public","body":"c(\"game_id\")"}},{"html_id":"_id-class-method","name":"_id","abstract":false,"def":{"name":"_id","visibility":"Public","body":"c(\"id\")"}},{"html_id":"_path-class-method","name":"_path","abstract":false,"def":{"name":"_path","visibility":"Public","body":"c(\"path\")"}},{"html_id":"_snake_id-class-method","name":"_snake_id","abstract":false,"def":{"name":"_snake_id","visibility":"Public","body":"c(\"snake_id\")"}},{"html_id":"_updated_at-class-method","name":"_updated_at","abstract":false,"def":{"name":"_updated_at","visibility":"Public","body":"c(\"updated_at\")"}},{"html_id":"column_names:Array(String)-class-method","name":"column_names","abstract":false,"def":{"name":"column_names","return_type":"Array(String)","visibility":"Public","body":"[\"id\", \"game_id\", \"snake_id\", \"context\", \"path\", \"dead\", \"created_at\", \"updated_at\"]"}}],"constructors":[{"html_id":"new(values:Hash(Symbol,AttrType)|NamedTuple,new_record)-class-method","name":"new","doc":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.","summary":"Accepts symbol hash or named tuple, stringify it and calls constructor with string-based keys hash.
","abstract":false,"args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"args_string":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","args_html":"(values : Hash(Symbol, AttrType) | NamedTuple, new_record)","def":{"name":"new","args":[{"name":"values","external_name":"values","restriction":"Hash(Symbol, AttrType) | NamedTuple"},{"name":"new_record","external_name":"new_record","restriction":""}],"visibility":"Public","body":"_ = allocate\n_.initialize(values, new_record)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"context:String-instance-method","name":"context","abstract":false,"def":{"name":"context","visibility":"Public","body":"@context"}},{"html_id":"context!-instance-method","name":"context!","abstract":false,"def":{"name":"context!","visibility":"Public","body":"@context.not_nil!"}},{"html_id":"context=(_context:String)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"String"}],"args_string":"(_context : String)","args_html":"(_context : String)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"String"}],"visibility":"Public","body":"if _context != @context\n context_will_change!\nend\n@context = _context\n"}},{"html_id":"context=(_context:AttrType)-instance-method","name":"context=","abstract":false,"args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"args_string":"(_context : AttrType)","args_html":"(_context : AttrType)","def":{"name":"context=","args":[{"name":"_context","external_name":"_context","restriction":"AttrType"}],"visibility":"Public","body":"self.context = _context.as(String)"}},{"html_id":"context_changed?:Bool-instance-method","name":"context_changed?","abstract":false,"def":{"name":"context_changed?","visibility":"Public","body":"@context_changed"}},{"html_id":"context_will_change!-instance-method","name":"context_will_change!","abstract":false,"def":{"name":"context_will_change!","visibility":"Public","body":"@context_changed = true"}},{"html_id":"created_at:Time?-instance-method","name":"created_at","abstract":false,"def":{"name":"created_at","visibility":"Public","body":"@created_at"}},{"html_id":"created_at!-instance-method","name":"created_at!","abstract":false,"def":{"name":"created_at!","visibility":"Public","body":"@created_at.not_nil!"}},{"html_id":"created_at=(_created_at:Union(Time,Nil))-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_created_at : Union(Time, Nil))","args_html":"(_created_at : Union(Time, Nil))","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _created_at != @created_at\n created_at_will_change!\nend\n@created_at = _created_at\n"}},{"html_id":"created_at=(_created_at:String)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"args_string":"(_created_at : String)","args_html":"(_created_at : String)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"String"}],"visibility":"Public","body":"self.created_at = self.class.coerce_created_at(_created_at)"}},{"html_id":"created_at=(_created_at:AttrType)-instance-method","name":"created_at=","abstract":false,"args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"args_string":"(_created_at : AttrType)","args_html":"(_created_at : AttrType)","def":{"name":"created_at=","args":[{"name":"_created_at","external_name":"_created_at","restriction":"AttrType"}],"visibility":"Public","body":"self.created_at = _created_at.as(::Union(Time, ::Nil))"}},{"html_id":"created_at_changed?:Bool-instance-method","name":"created_at_changed?","abstract":false,"def":{"name":"created_at_changed?","visibility":"Public","body":"@created_at_changed"}},{"html_id":"created_at_will_change!-instance-method","name":"created_at_will_change!","abstract":false,"def":{"name":"created_at_will_change!","visibility":"Public","body":"@created_at_changed = true"}},{"html_id":"dead:Bool-instance-method","name":"dead","abstract":false,"def":{"name":"dead","visibility":"Public","body":"@dead"}},{"html_id":"dead!-instance-method","name":"dead!","abstract":false,"def":{"name":"dead!","visibility":"Public","body":"@dead.not_nil!"}},{"html_id":"dead=(_dead:Bool)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"args_string":"(_dead : Bool)","args_html":"(_dead : Bool)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"Bool"}],"visibility":"Public","body":"if _dead != @dead\n dead_will_change!\nend\n@dead = _dead\n"}},{"html_id":"dead=(_dead:String)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"args_string":"(_dead : String)","args_html":"(_dead : String)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"String"}],"visibility":"Public","body":"self.dead = self.class.coerce_dead(_dead)"}},{"html_id":"dead=(_dead:AttrType)-instance-method","name":"dead=","abstract":false,"args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"args_string":"(_dead : AttrType)","args_html":"(_dead : AttrType)","def":{"name":"dead=","args":[{"name":"_dead","external_name":"_dead","restriction":"AttrType"}],"visibility":"Public","body":"self.dead = _dead.as(Bool)"}},{"html_id":"dead?-instance-method","name":"dead?","abstract":false,"def":{"name":"dead?","visibility":"Public","body":"dead == true"}},{"html_id":"dead_changed?:Bool-instance-method","name":"dead_changed?","abstract":false,"def":{"name":"dead_changed?","visibility":"Public","body":"@dead_changed"}},{"html_id":"dead_will_change!-instance-method","name":"dead_will_change!","abstract":false,"def":{"name":"dead_will_change!","visibility":"Public","body":"@dead_changed = true"}},{"html_id":"destroy:Bool-instance-method","name":"destroy","doc":"Deletes object from db and calls all related callbacks.\n\nIt returns `true` if the object was successfully deleted.\n\n```\nContact.first!.destroy # => true\n```","summary":"Deletes object from db and calls all related callbacks.
","abstract":false,"def":{"name":"destroy","return_type":"Bool","visibility":"Public","body":"if new_record?\n return false\nend\nresult = if self.class.write_adapter.under_transaction?\n destroy_without_transaction\nelse\n self.class.transaction do\n destroy_without_transaction\n end\nend\nif result\nelse\n return false\nend\nif HAS_DESTROY_COMMIT_CALLBACK\n self.class.write_adapter.subscribe_on_commit(->__after_destroy_commit_callback)\nend\nif HAS_DESTROY_ROLLBACK_CALLBACK\n self.class.write_adapter.subscribe_on_rollback(->__after_destroy_rollback_callback)\nend\ntrue\n"}},{"html_id":"game_id:String-instance-method","name":"game_id","abstract":false,"def":{"name":"game_id","visibility":"Public","body":"@game_id"}},{"html_id":"game_id!-instance-method","name":"game_id!","abstract":false,"def":{"name":"game_id!","visibility":"Public","body":"@game_id.not_nil!"}},{"html_id":"game_id=(_game_id:String)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"args_string":"(_game_id : String)","args_html":"(_game_id : String)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"String"}],"visibility":"Public","body":"if _game_id != @game_id\n game_id_will_change!\nend\n@game_id = _game_id\n"}},{"html_id":"game_id=(_game_id:AttrType)-instance-method","name":"game_id=","abstract":false,"args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"args_string":"(_game_id : AttrType)","args_html":"(_game_id : AttrType)","def":{"name":"game_id=","args":[{"name":"_game_id","external_name":"_game_id","restriction":"AttrType"}],"visibility":"Public","body":"self.game_id = _game_id.as(String)"}},{"html_id":"game_id_changed?:Bool-instance-method","name":"game_id_changed?","abstract":false,"def":{"name":"game_id_changed?","visibility":"Public","body":"@game_id_changed"}},{"html_id":"game_id_will_change!-instance-method","name":"game_id_will_change!","abstract":false,"def":{"name":"game_id_will_change!","visibility":"Public","body":"@game_id_changed = true"}},{"html_id":"id:Int64?-instance-method","name":"id","abstract":false,"def":{"name":"id","visibility":"Public","body":"@id"}},{"html_id":"id!-instance-method","name":"id!","abstract":false,"def":{"name":"id!","visibility":"Public","body":"@id.not_nil!"}},{"html_id":"id=(_id:Union(Int64,Nil))-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"args_string":"(_id : Union(Int64, Nil))","args_html":"(_id : Union(Int64, Nil))","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"::Union(Int64, ::Nil)"}],"visibility":"Public","body":"if _id != @id\n id_will_change!\nend\n@id = _id\n"}},{"html_id":"id=(_id:String)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"String"}],"args_string":"(_id : String)","args_html":"(_id : String)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"String"}],"visibility":"Public","body":"self.id = self.class.coerce_id(_id)"}},{"html_id":"id=(_id:Int32)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"args_string":"(_id : Int32)","args_html":"(_id : Int32)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"Int32"}],"visibility":"Public","body":"self.id = _id.to_i64"}},{"html_id":"id=(_id:AttrType)-instance-method","name":"id=","abstract":false,"args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"args_string":"(_id : AttrType)","args_html":"(_id : AttrType)","def":{"name":"id=","args":[{"name":"_id","external_name":"_id","restriction":"AttrType"}],"visibility":"Public","body":"self.id = _id.as(::Union(Int64, ::Nil))"}},{"html_id":"id_changed?:Bool-instance-method","name":"id_changed?","abstract":false,"def":{"name":"id_changed?","visibility":"Public","body":"@id_changed"}},{"html_id":"id_will_change!-instance-method","name":"id_will_change!","abstract":false,"def":{"name":"id_will_change!","visibility":"Public","body":"@id_changed = true"}},{"html_id":"path:String-instance-method","name":"path","abstract":false,"def":{"name":"path","visibility":"Public","body":"@path"}},{"html_id":"path!-instance-method","name":"path!","abstract":false,"def":{"name":"path!","visibility":"Public","body":"@path.not_nil!"}},{"html_id":"path=(_path:String)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"String"}],"args_string":"(_path : String)","args_html":"(_path : String)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"String"}],"visibility":"Public","body":"if _path != @path\n path_will_change!\nend\n@path = _path\n"}},{"html_id":"path=(_path:AttrType)-instance-method","name":"path=","abstract":false,"args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"args_string":"(_path : AttrType)","args_html":"(_path : AttrType)","def":{"name":"path=","args":[{"name":"_path","external_name":"_path","restriction":"AttrType"}],"visibility":"Public","body":"self.path = _path.as(String)"}},{"html_id":"path_changed?:Bool-instance-method","name":"path_changed?","abstract":false,"def":{"name":"path_changed?","visibility":"Public","body":"@path_changed"}},{"html_id":"path_will_change!-instance-method","name":"path_will_change!","abstract":false,"def":{"name":"path_will_change!","visibility":"Public","body":"@path_changed = true"}},{"html_id":"snake_id:String-instance-method","name":"snake_id","abstract":false,"def":{"name":"snake_id","visibility":"Public","body":"@snake_id"}},{"html_id":"snake_id!-instance-method","name":"snake_id!","abstract":false,"def":{"name":"snake_id!","visibility":"Public","body":"@snake_id.not_nil!"}},{"html_id":"snake_id=(_snake_id:String)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"args_string":"(_snake_id : String)","args_html":"(_snake_id : String)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"String"}],"visibility":"Public","body":"if _snake_id != @snake_id\n snake_id_will_change!\nend\n@snake_id = _snake_id\n"}},{"html_id":"snake_id=(_snake_id:AttrType)-instance-method","name":"snake_id=","abstract":false,"args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"args_string":"(_snake_id : AttrType)","args_html":"(_snake_id : AttrType)","def":{"name":"snake_id=","args":[{"name":"_snake_id","external_name":"_snake_id","restriction":"AttrType"}],"visibility":"Public","body":"self.snake_id = _snake_id.as(String)"}},{"html_id":"snake_id_changed?:Bool-instance-method","name":"snake_id_changed?","abstract":false,"def":{"name":"snake_id_changed?","visibility":"Public","body":"@snake_id_changed"}},{"html_id":"snake_id_will_change!-instance-method","name":"snake_id_will_change!","abstract":false,"def":{"name":"snake_id_will_change!","visibility":"Public","body":"@snake_id_changed = true"}},{"html_id":"track_timestamps_on_create-instance-method","name":"track_timestamps_on_create","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_create","visibility":"Public","body":"current_time = Time.local(Jennifer::Config.local_time_zone)\nself.updated_at || (self.updated_at = current_time)\nself.created_at || (self.created_at = current_time)\n"}},{"html_id":"track_timestamps_on_update-instance-method","name":"track_timestamps_on_update","abstract":false,"location":{"filename":"src/models/turn.cr","line_number":6,"url":"https://github.com/fdocr/CrystalSnake/blob/8e7bf08cd41b1ceb68862a17319b577188de02b0/src/models/turn.cr#L6"},"def":{"name":"track_timestamps_on_update","visibility":"Public","body":"if updated_at_changed?\nelse\n self.updated_at = Time.local(Jennifer::Config.local_time_zone)\nend"}},{"html_id":"updated_at:Time?-instance-method","name":"updated_at","abstract":false,"def":{"name":"updated_at","visibility":"Public","body":"@updated_at"}},{"html_id":"updated_at!-instance-method","name":"updated_at!","abstract":false,"def":{"name":"updated_at!","visibility":"Public","body":"@updated_at.not_nil!"}},{"html_id":"updated_at=(_updated_at:Union(Time,Nil))-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"args_string":"(_updated_at : Union(Time, Nil))","args_html":"(_updated_at : Union(Time, Nil))","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"::Union(Time, ::Nil)"}],"visibility":"Public","body":"if _updated_at != @updated_at\n updated_at_will_change!\nend\n@updated_at = _updated_at\n"}},{"html_id":"updated_at=(_updated_at:String)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"args_string":"(_updated_at : String)","args_html":"(_updated_at : String)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"String"}],"visibility":"Public","body":"self.updated_at = self.class.coerce_updated_at(_updated_at)"}},{"html_id":"updated_at=(_updated_at:AttrType)-instance-method","name":"updated_at=","abstract":false,"args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"args_string":"(_updated_at : AttrType)","args_html":"(_updated_at : AttrType)","def":{"name":"updated_at=","args":[{"name":"_updated_at","external_name":"_updated_at","restriction":"AttrType"}],"visibility":"Public","body":"self.updated_at = _updated_at.as(::Union(Time, ::Nil))"}},{"html_id":"updated_at_changed?:Bool-instance-method","name":"updated_at_changed?","abstract":false,"def":{"name":"updated_at_changed?","visibility":"Public","body":"@updated_at_changed"}},{"html_id":"updated_at_will_change!-instance-method","name":"updated_at_will_change!","abstract":false,"def":{"name":"updated_at_will_change!","visibility":"Public","body":"@updated_at_changed = true"}}],"types":[{"html_id":"CrystalSnake/Turn/AttrType","path":"Turn/AttrType.html","kind":"alias","full_name":"Turn::AttrType","name":"AttrType","abstract":false,"locations":[],"repository_name":"CrystalSnake","program":false,"enum":false,"alias":true,"aliased":"(Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil)","aliased_html":"Array(Char) | Array(Float32) | Array(Float64) | Array(Int16) | Array(Int32) | Array(Int64) | Array(String) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | JSON::Any | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Numeric | Slice(UInt8) | String | Time | Time::Span | UInt32 | UUID | Nil","const":false,"namespace":{"html_id":"CrystalSnake/Turn","kind":"class","full_name":"Turn","name":"Turn"}}]}]}}) \ No newline at end of file diff --git a/toplevel.html b/toplevel.html index 2d82015..0ad02d3 100644 --- a/toplevel.html +++ b/toplevel.html @@ -343,7 +343,7 @@