Class: Swarm::Map
Overview
Instance Attribute Summary collapse
-
#height ⇒ Integer
readonly
The
heightof theMap. -
#width ⇒ Integer
readonly
The
widthof theMap.
Instance Method Summary collapse
- #[](x, y) ⇒ Tile
- #[]=(x, y, tile) ⇒ Tile
-
#aggressive_moves(this, that) ⇒ Array<Symbol, ...>
Find the closest route from
thistothatbased only on position (ignoring all obstacles betweenthisandthat). -
#available_moves(tile) ⇒ Array<Symbol, ...>
Find “open” (non-blocking) moves for a
workerorsoldier. -
#center ⇒ Tile
A center tile.
-
#column(tile) ⇒ Array<Tile, ...>
The column of tiles that the
tileresides on. - #each(&block) ⇒ Object
-
#east(tile) ⇒ Array<Tile, ...>
columnorrowof tiles starting withtileheaded east until the end of the map. -
#initialize(width, height, tile_width: 1, tile_height: 1) ⇒ Map
constructor
A 2 dimensional array of tiles.
-
#last ⇒ Tile
The last tile (highest
xandyvalue). -
#move(tile, direction) ⇒ Boolean
Move a
Tileon theMap. - #neighbors(tile) ⇒ Object
-
#north(tile) ⇒ Array<Tile, ...>
columnorrowof tiles starting withtileheaded north until the end of the map. -
#row(tile) ⇒ Array<Tile, ...>
The row of tiles that the
tileresides on. -
#sample ⇒ Tile
A random tile.
- #score(key) ⇒ Object
-
#south(tile) ⇒ Array<Tile, ...>
columnorrowof tiles starting withtileheaded south until the end of the map. - #spawn(flag, percent = 0.0) ⇒ Object
- #update ⇒ Object
-
#west(tile) ⇒ Array<Tile, ...>
columnorrowof tiles starting withtileheaded west until the end of the map.
Constructor Details
#initialize(width, height, tile_width: 1, tile_height: 1) ⇒ Map
A 2 dimensional array of tiles.
33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/swarm/map.rb', line 33 def initialize(width, height, tile_width: 1, tile_height: 1) @tiles = (0...height).step(tile_height).map.with_index do |console_y, map_y| (0...width).step(tile_width).map.with_index do |console_x, map_x| Tile.new map_x, map_y, [console_y, console_x] # reversed for Console::setpos end end @height = height / tile_height @width = width / tile_width end |
Instance Attribute Details
#height ⇒ Integer (readonly)
Returns the height of the Map.
30 31 32 |
# File 'lib/swarm/map.rb', line 30 def height @height end |
#width ⇒ Integer (readonly)
Returns the width of the Map.
27 28 29 |
# File 'lib/swarm/map.rb', line 27 def width @width end |
Instance Method Details
#[](x, y) ⇒ Tile
65 66 67 |
# File 'lib/swarm/map.rb', line 65 def [](x, y) @tiles.fetch(y, Array.new)[x] end |
#[]=(x, y, tile) ⇒ Tile
73 74 75 76 |
# File 'lib/swarm/map.rb', line 73 def []=(x, y, tile) @tiles[y] ||= Array.new @tiles[y][x] = tile end |
#aggressive_moves(this, that) ⇒ Array<Symbol, ...>
Find the closest route from this to that based
only on position (ignoring all obstacles between this and
that).
162 163 164 165 166 167 168 169 |
# File 'lib/swarm/map.rb', line 162 def aggressive_moves(this, that) directions = [] directions << :north if (this.y > that.y) && ((this.y - that.y) < 10) directions << :south if (that.y > this.y) && ((that.y - this.y) < 10) directions << :west if (this.x > that.x) && ((this.x - that.x) < 10) directions << :east if (that.x > this.x) && ((that.x - this.x) < 10) directions end |
#available_moves(tile) ⇒ Array<Symbol, ...>
Find “open” (non-blocking) moves for a worker or
soldier.
180 181 182 183 184 185 186 187 188 |
# File 'lib/swarm/map.rb', line 180 def available_moves(tile) %i(north south east west).select do |direction| _, neighbor, _ = send(direction, tile) next if neighbor.nil? neighbor.player? || neighbor.empty? || (tile.queen? && neighbor.dirt?) end end |
#center ⇒ Tile
Returns a center tile
53 54 55 |
# File 'lib/swarm/map.rb', line 53 def center @tiles[height / 2][width / 2] end |
#column(tile) ⇒ Array<Tile, ...>
Returns the column of tiles that the tile resides on
250 251 252 |
# File 'lib/swarm/map.rb', line 250 def column(tile) @tiles.map { |row| row[tile.x] } end |
#each(&block) ⇒ Object
48 49 50 |
# File 'lib/swarm/map.rb', line 48 def each(&block) @tiles.each { |row| row.each &block } end |
#east(tile) ⇒ Array<Tile, ...>
Returns column or row of tiles starting with
tile headed east until the end of the map
229 230 231 232 |
# File 'lib/swarm/map.rb', line 229 def east(tile) tiles = row(tile) tiles.rotate(tiles.index tile) end |
#last ⇒ Tile
Returns the last tile (highest x and y value)
79 80 81 |
# File 'lib/swarm/map.rb', line 79 def last self[-1, -1] end |
#move(tile, direction) ⇒ Boolean
Move a Tile on the Map. This movement action
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
-
enemies block enemies
-
playeras are turned into eggs when touching enemies
-
enemies get squished by players
-
players get squished by soldiers
-
rocks block everything
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/swarm/map.rb', line 113 def move(tile, direction) tiles = send(direction, tile) move = [] tiles.each_cons(2) do |this, that| break if this.empty? # break move.clear if (tile == this) && this.enemy? && that.empty? break move.clear if this.enemy? && that.enemy? break move.clear if this.egg? && that.enemy? break move.clear if this.enemy? && that.egg? break this.destroy! if this.player? && (that.enemy? || that.egg?) break that.destroy! if (this.enemy? || this.egg?) && that.player? if (this.worker? || this.queen? || this.egg?) && tile.player? && (that.dirt? || that.rock?) this.destroy! break end if this.soldier? && tile.player? && that.rock? (neighbors(this) - neighbors(tile)).each &:worker! this.destroy! break end if this.player? && tile.queen? && !that.empty? this.destroy! break end break move.clear if that.rock? move << [that, this.type, this.age] end return if move.empty? tile.empty! move.each { |t, type, age| t.send(type, age) } end |
#neighbors(tile) ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/swarm/map.rb', line 190 def neighbors(tile) [ [ 0, 1], [ 1, 0], [ 0,-1], [-1, 0], # [ 0, 0], <- self [ 1, 1], [-1,-1], [ 1,-1], [-1, 1] ].map do |x, y| self[tile.x + x, tile.y + y] end end |
#north(tile) ⇒ Array<Tile, ...>
Returns column or row of tiles starting with
tile headed north until the end of the map
217 218 219 220 |
# File 'lib/swarm/map.rb', line 217 def north(tile) tiles = column(tile).reverse tiles.rotate(tiles.index tile) end |
#row(tile) ⇒ Array<Tile, ...>
Returns the row of tiles that the tile resides on
245 246 247 |
# File 'lib/swarm/map.rb', line 245 def row(tile) @tiles[tile.y] end |
#sample ⇒ Tile
Returns a random tile
58 59 60 |
# File 'lib/swarm/map.rb', line 58 def sample @tiles.sample.sample end |
#score(key) ⇒ Object
83 84 85 |
# File 'lib/swarm/map.rb', line 83 def score(key) Catalog.fetch :destroyed, key, 0 end |
#south(tile) ⇒ Array<Tile, ...>
Returns column or row of tiles starting with
tile headed south until the end of the map
223 224 225 226 |
# File 'lib/swarm/map.rb', line 223 def south(tile) tiles = column(tile) tiles.rotate(tiles.index tile) end |
#spawn(flag, percent = 0.0) ⇒ Object
87 88 89 90 91 |
# File 'lib/swarm/map.rb', line 87 def spawn(flag, percent = 0.0) total = ((percent.to_f / 100) * count) select(&:empty?).sample(total.to_i).each &flag end |
#update ⇒ Object
206 207 208 |
# File 'lib/swarm/map.rb', line 206 def update Console.update Catalog.flush(:changed) end |
#west(tile) ⇒ Array<Tile, ...>
Returns column or row of tiles starting with
tile headed west until the end of the map
235 236 237 238 |
# File 'lib/swarm/map.rb', line 235 def west(tile) tiles = row(tile).reverse tiles.rotate(tiles.index tile) end |