Class: Battlesnake::Board

Inherits:
Base
  • Object
show all
Defined in:
lib/battlesnake/board.rb

Overview

Represents a single iteration (turn) of a Battlesnake board during gameplay.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#==

Constructor Details

#initialize(json_or_hash) ⇒ Board

Returns a new instance of Board.

Parameters:

  • json_or_hash (String, Hash)

    can be a hash of attributes, or a JSON string which represents such a structure.



32
33
34
35
36
37
38
39
40
41
# File 'lib/battlesnake/board.rb', line 32

def initialize(json_or_hash)
  data = json_or_hash.is_a?(String) ? JSON.parse(json_or_hash) : json_or_hash

  @as_json = data
  @height = data['height']
  @width = data['width']
  @snakes = data['snakes'].map{ |attrs| Snake.new(attrs) }
  @food = data['food'].map{ |attrs| Location.new(attrs) }
  @hazards = data['hazards'].map{ |attrs| Location.new(attrs) }
end

Instance Attribute Details

#as_jsonHash (readonly)

Returns board as a data structure usable by other objects.

Returns:

  • (Hash)

    board as a data structure usable by other objects.



8
9
10
# File 'lib/battlesnake/board.rb', line 8

def as_json
  @as_json
end

#foodArray<Location> (readonly)

Returns list of food location objects.

Returns:

  • (Array<Location>)

    list of food location objects



20
21
22
# File 'lib/battlesnake/board.rb', line 20

def food
  @food
end

#hazardsArray<Location> (readonly)

Returns list of hazard location objects.

Returns:

  • (Array<Location>)

    list of hazard location objects



23
24
25
# File 'lib/battlesnake/board.rb', line 23

def hazards
  @hazards
end

#heightInteger (readonly)

Returns height of the board.

Returns:

  • (Integer)

    height of the board



11
12
13
# File 'lib/battlesnake/board.rb', line 11

def height
  @height
end

#snakesArray<Snake> (readonly)

Returns list of snake objects.

Returns:

  • (Array<Snake>)

    list of snake objects



17
18
19
# File 'lib/battlesnake/board.rb', line 17

def snakes
  @snakes
end

#widthInteger (readonly)

Returns width of the board.

Returns:

  • (Integer)

    width of the board



14
15
16
# File 'lib/battlesnake/board.rb', line 14

def width
  @width
end

Instance Method Details

#available?(location) ⇒ Boolean

Whether the supplied location is available (unoccupied).

Parameters:

  • location (Location)

    being tested for availability.

Returns:

  • (Boolean)

    true if location is available (unoccupied by snakes, food, hazards, etc).



79
80
81
# File 'lib/battlesnake/board.rb', line 79

def available?(location)
  on_board?(location) && !occupied?(location)
end

#available_directions(location) ⇒ Array<String>

List of directions (up, down, left, right) available for moving from given Location.

Parameters:

  • location (Location)

    from which moving is desired.

Returns:

  • (Array<String>)

    list of direction strings (“up”, “down”, “left”, “right”)



99
100
101
102
103
# File 'lib/battlesnake/board.rb', line 99

def available_directions(location)
  Location::DIRECTIONS.select do |direction|
    available?(location.move(direction))
  end
end

#available_neighbors(location) ⇒ Array<Location>

List of neighboring locations available for moving from given Location.

Parameters:

  • location (Location)

    from which moving is desired.

Returns:

  • (Array<Location>)

    list of locations



111
112
113
# File 'lib/battlesnake/board.rb', line 111

def available_neighbors(location)
  Location::DIRECTIONS.map{ |direction| location.move(direction) }.select{ |l| available?(l) }
end

#find_path(from, to, max_distance: nil) ⇒ Array<Path>

List of valid, consecutive paths from one location to the next. Paths may not:

- wander outside board boundaries.
- use the same location more than once.
- contain occupied locations, EXCEPT the start/end locations.

The exception for start/end locations allows us to generate paths, for example, from a snake to a food location, without having to calulate the starting/ending permutations ourselves.

Parameters:

  • from (Location)

    starting location, may be occupied

  • to (Location)

    starting location, may be occupied

Returns:

  • (Array<Path>)

    a list of paths, which themselves are lists of consecutive, valid locations.



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/battlesnake/board.rb', line 146

def find_path(from, to, max_distance: nil)
  distance = from.distance(to)
  return nil if max_distance && max_distance < distance

  @paths = []
  @ideal_path_size = distance + 1
  @shortest_path_size = max_distance || @ideal_path_size
  @ideal_path_size_found = false

  recursive_paths(from, to, [from])

  @paths.select{ |path| path.size == @shortest_path_size }.first
end

#flood_fills(location) ⇒ Hash

List reachable locations in each orthogonal direction.

Returns:

  • (Hash)

    hash of reachable locations by direction



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/battlesnake/board.rb', line 119

def flood_fills(location)
  fills = Location::DIRECTIONS.map{ |direction| [direction, []]}.to_h

  available_directions(location).each do |direction|
    @flood_fill_checked = []
    @flood_fill_matches = []

    fills[direction] = flood_fill(location.move(direction)) #.uniq(&:coords)
  end

  fills
end

#food?(location) ⇒ Boolean

Whether the supplied location is food.

Parameters:

  • location (Location)

    being tested for availability.

Returns:

  • (Boolean)

    true if location is food.



89
90
91
# File 'lib/battlesnake/board.rb', line 89

def food?(location)
  food.include?(location)
end

#occupied?(location) ⇒ Boolean

Whether the supplied location is occupied.

Parameters:

  • location (Location)

    being checked for occupancy.

Returns:

  • (Boolean)

    true if location is occupied by snakes, food, hazards, etc.



59
60
61
# File 'lib/battlesnake/board.rb', line 59

def occupied?(location)
  occupied_locations.include?(location)
end

#occupied_locationsArray<Location>

List of all occupied locations on the board; snakes, hazards, etc. Does NOT include food, since we don’t want to avoid that.

Returns:

  • (Array<Location>)

    list of occupied locations



48
49
50
51
# File 'lib/battlesnake/board.rb', line 48

def occupied_locations
  return @occupied_locations if defined?(@occupied_locations)
  @occupied_locations = snakes.map(&:body).flatten + hazards
end

#on_board?(location) ⇒ Boolean

Where the supplied location falls within the boundaries of the board.

Parameters:

Returns:

  • (Boolean)

    true if location is within the boundaries of the board.



69
70
71
# File 'lib/battlesnake/board.rb', line 69

def on_board?(location)
  location.x >= 0 && location.y >= 0 && location.x < width && location.y < height
end