Class: SpaceDozer::Map

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/spacedozer/map.rb

Instance Method Summary collapse

Constructor Details

#initializeMap

Returns a new instance of Map.


4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/spacedozer/map.rb', line 4

def initialize
  0.upto(count * 0.20) { sample.dirt }
  0.upto(count * 0.01) { sample.rock }
  0.upto(count * 0.01) { sample.alien }

  center.dozer

  tiles[0].each &:wall
  tiles[-1].each &:wall
  tiles.map { |row| row[0] }.each &:wall
  tiles.map { |row| row[-1] }.each &:wall
end

Instance Method Details

#centerTile

Returns a center tile.

Returns:

  • (Tile)

    a center tile


24
25
26
# File 'lib/spacedozer/map.rb', line 24

def center
  tiles[(width / 2) - 1][(height / 2) - 1]
end

#column(tile) ⇒ Array<Tile, ...> (private)

Returns the column of tiles that the tile resides on.

Parameters:

Returns:

  • (Array<Tile, ...>)

    the column of tiles that the tile resides on


175
176
177
# File 'lib/spacedozer/map.rb', line 175

def column(tile)
  @tiles.map { |row| row[tile.x] }
end

#dozer_directions(this, that) ⇒ Array<Symbol, ...>

Find the closest route from this to that based only on position (ignoring all obstacles between this and that).

Parameters:

  • this (Tile)

    origin tile

  • that (Tile)

    destination tile

Returns:

  • (Array<Symbol, ...>)

    :north, :east, :west and/or :south


81
82
83
84
85
86
87
88
# File 'lib/spacedozer/map.rb', line 81

def dozer_directions(this, that)
  directions = []
  directions << :west  if (this.y > that.y)
  directions << :east  if (this.y < that.y)
  directions << :north if (this.x > that.x)
  directions << :south if (this.x < that.x)
  directions
end

#each(&block) ⇒ Object


19
20
21
# File 'lib/spacedozer/map.rb', line 19

def each(&block)
  tiles.each { |row| row.each &block }
end

#east(tile) ⇒ Array<Tile, ...> (private)

Returns collection of tiles starting with tile headed east until the end of the map.

Parameters:

Returns:

  • (Array<Tile, ...>)

    collection of tiles starting with tile headed east until the end of the map.


142
143
144
145
# File 'lib/spacedozer/map.rb', line 142

def east(tile)
  tiles = column(tile)
  tiles[tiles.index(tile)..-1]
end

#empty_directions(tile) ⇒ Array<Symbol, ...>

Find “open” (non-blocking) moves for a Tile#alien

Parameters:

  • tile (Tile)

    a Tile#alien

Returns:

  • (Array<Symbol, ...>)

    :north, :east, :west and/or :south


94
95
96
97
98
99
100
# File 'lib/spacedozer/map.rb', line 94

def empty_directions(tile)
  %i(north south east west).select do |direction|
    _, neighbor, _ = send(direction, tile)

    neighbor && (neighbor.empty? || neighbor.dozer?)
  end
end

#heightInteger (private)

Returns the height of the SpaceDozer::Map. Each SpaceDozer::Tile is 1 character tall and 2 characters wide (square).

Returns:

  • (Integer)

    the height of the SpaceDozer::Map. Each SpaceDozer::Tile is 1 character tall and 2 characters wide (square).


133
134
135
# File 'lib/spacedozer/map.rb', line 133

def height
  Console.height
end

#move(tile, direction) ⇒ Boolean

Move a tile on the +SpaceDozer::Map. This movement causes a chain-reaction potentially moving (or killing) tiles down the map in that same direction.

It does this by comparing each neighboring pair

tile_1 -> tile_2
tile_2 -> tile_3
tile_3 -> tile_4

And follows these rules

  • empty tiles don't transfer movement

  • rocks and walls block everything

  • aliens block aliens

  • dozers die when touching aliens

  • aliens kill dozers when touching them

  • aliens get squished by dozers

Parameters:

  • tile (Tile)
  • direction (Symbol)

    :north, :south, :east or :west

Returns:

  • (Boolean)

    true if the tile is moved successfully, false if it is not


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/spacedozer/map.rb', line 53

def move(tile, direction)
  tiles = send(direction, tile)
  move = []

  tiles.each_cons(2) do |this, that|
    break if (this.empty? || that == tile)
    (move.clear; break) if (that.rock? || that.wall?)
    (move.clear; break) if (this.alien? && that.alien?)
    (this.kill;  break) if (this.dozer? && that.alien?)
    (that.kill;  break) if (this.alien? && that.dozer?)
    (this.kill;  break) if (this.alien? && tile.dozer? && !that.empty?)

    move << [that, this.type]
  end

  return false if move.empty?

  tile.empty
  move.each { |tile, type| tile.send(type) }
  true
end

#north(tile) ⇒ Array<Tile, ...> (private)

Returns collection of tiles starting with tile headed north until the end of the map.

Parameters:

Returns:

  • (Array<Tile, ...>)

    collection of tiles starting with tile headed north until the end of the map.


160
161
162
163
# File 'lib/spacedozer/map.rb', line 160

def north(tile)
  tiles = row(tile).reverse
  tiles[tiles.index(tile)..-1]
end

#row(tile) ⇒ Array<Tile, ...> (private)

Returns the row of tiles that the tile resides on.

Parameters:

Returns:

  • (Array<Tile, ...>)

    the row of tiles that the tile resides on


170
171
172
# File 'lib/spacedozer/map.rb', line 170

def row(tile)
  @tiles[tile.y]
end

#sampleTile

Returns a random tile.

Returns:

  • (Tile)

    a random tile


29
30
31
# File 'lib/spacedozer/map.rb', line 29

def sample
  tiles.sample.sample
end

#score(key) ⇒ Integer

The sum of all scores on all SpaceDozer::Tile scoreboards for key

Parameters:

  • key (Symbol)

    :alien, :dozer, etc

Returns:

  • (Integer)

    total alien deaths


105
106
107
# File 'lib/spacedozer/map.rb', line 105

def score(key)
  inject(0) { |total, tile| total + tile.score[key] }
end

#south(tile) ⇒ Array<Tile, ...> (private)

Returns collection of tiles starting with tile headed south until the end of the map.

Parameters:

Returns:

  • (Array<Tile, ...>)

    collection of tiles starting with tile headed south until the end of the map.


154
155
156
157
# File 'lib/spacedozer/map.rb', line 154

def south(tile)
  tiles = row(tile)
  tiles[tiles.index(tile)..-1]
end

#tilesObject (private)


117
118
119
120
121
# File 'lib/spacedozer/map.rb', line 117

def tiles
  @tiles ||= (0...Console.width).step(2).map do |y|
    (0...Console.height).map { |x| Tile.new x, y }
  end
end

#update {|Tile| ... } ⇒ Object

Update all tiles or all tiles that return true for block

Yields:


111
112
113
# File 'lib/spacedozer/map.rb', line 111

def update(&block)
  Console.update select(&block)
end

#west(tile) ⇒ Array<Tile, ...> (private)

Returns collection of tiles starting with tile headed west until the end of the map.

Parameters:

Returns:

  • (Array<Tile, ...>)

    collection of tiles starting with tile headed west until the end of the map.


148
149
150
151
# File 'lib/spacedozer/map.rb', line 148

def west(tile)
  tiles = column(tile).reverse
  tiles[tiles.index(tile)..-1]
end

#widthInteger (private)

Returns the width of the SpaceDozer::Map. Each SpaceDozer::Tile is 1 character tall and 2 characters wide (square).

Returns:

  • (Integer)

    the width of the SpaceDozer::Map. Each SpaceDozer::Tile is 1 character tall and 2 characters wide (square).


128
129
130
# File 'lib/spacedozer/map.rb', line 128

def width
  Console.width / 2
end