the-swarm 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.yardopts +8 -0
- data/Gemfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +26 -0
- data/bin/swarm +11 -0
- data/docs/Swarm.html +296 -0
- data/docs/Swarm/Catalog.html +819 -0
- data/docs/Swarm/Console.html +1050 -0
- data/docs/Swarm/Console/Color.html +160 -0
- data/docs/Swarm/Console/NormalKey.html +410 -0
- data/docs/Swarm/Console/PopUp.html +236 -0
- data/docs/Swarm/Console/VIKey.html +410 -0
- data/docs/Swarm/Five.html +421 -0
- data/docs/Swarm/Four.html +389 -0
- data/docs/Swarm/Game.html +1197 -0
- data/docs/Swarm/Intro.html +419 -0
- data/docs/Swarm/Level.html +700 -0
- data/docs/Swarm/Map.html +2336 -0
- data/docs/Swarm/One.html +353 -0
- data/docs/Swarm/Three.html +383 -0
- data/docs/Swarm/Tile.html +3823 -0
- data/docs/Swarm/Two.html +355 -0
- data/docs/_index.html +313 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +492 -0
- data/docs/file.LICENSE.html +70 -0
- data/docs/file.README.html +101 -0
- data/docs/file_list.html +61 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +101 -0
- data/docs/js/app.js +248 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +1195 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/swarm.rb +60 -0
- data/lib/swarm/catalog.rb +71 -0
- data/lib/swarm/console.rb +165 -0
- data/lib/swarm/game.rb +173 -0
- data/lib/swarm/level.rb +58 -0
- data/lib/swarm/levels/five.rb +71 -0
- data/lib/swarm/levels/four.rb +55 -0
- data/lib/swarm/levels/intro.rb +36 -0
- data/lib/swarm/levels/one.rb +35 -0
- data/lib/swarm/levels/three.rb +51 -0
- data/lib/swarm/levels/two.rb +38 -0
- data/lib/swarm/map.rb +254 -0
- data/lib/swarm/tile.rb +149 -0
- data/lib/swarm/version.rb +5 -0
- data/swarm.gemspec +24 -0
- metadata +112 -0
data/lib/swarm/level.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Swarm
|
2
|
+
|
3
|
+
class Level
|
4
|
+
|
5
|
+
def Level.each(&block)
|
6
|
+
[Intro, One, Two, Three, Four, Five].each { |level| block.call level.new }
|
7
|
+
end
|
8
|
+
|
9
|
+
def update
|
10
|
+
@map.update
|
11
|
+
end
|
12
|
+
|
13
|
+
def update!
|
14
|
+
@map.each(&:change!)
|
15
|
+
@map.update
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_player
|
19
|
+
@player = (@player && @player.player?) ? @player : @map.find(&:player?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def spawn_player
|
23
|
+
@map.center.player!
|
24
|
+
end
|
25
|
+
|
26
|
+
def move_player(direction)
|
27
|
+
move find_player, direction
|
28
|
+
end
|
29
|
+
|
30
|
+
def move(tile, direction)
|
31
|
+
case direction
|
32
|
+
when :north, :south, :west, :east
|
33
|
+
@map.move(tile, direction)
|
34
|
+
else
|
35
|
+
available = @map.available_moves(tile)
|
36
|
+
aggressive = @map.aggressive_moves(tile, direction)
|
37
|
+
aggressive &= available
|
38
|
+
|
39
|
+
if aggressive.any?
|
40
|
+
@map.move tile, aggressive.sample
|
41
|
+
elsif available.any?
|
42
|
+
@map.move tile, available.sample
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def over?
|
48
|
+
!Catalog.select(*%i[worker soldier queen egg]).any?
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
@map = Map.new(Console.width, Console.height, tile_width: 2)
|
53
|
+
|
54
|
+
@map.each &:empty!
|
55
|
+
@map.update
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Swarm
|
2
|
+
class Five < Level
|
3
|
+
|
4
|
+
def play
|
5
|
+
promoted =
|
6
|
+
laid_egg =
|
7
|
+
hatched = false
|
8
|
+
|
9
|
+
Catalog.select(*%i[worker soldier queen egg]).each do |tile|
|
10
|
+
tile.age!
|
11
|
+
|
12
|
+
if tile.worker?
|
13
|
+
if !promoted && (tile.age % 15).zero?
|
14
|
+
tile.soldier!
|
15
|
+
|
16
|
+
promoted = true
|
17
|
+
else
|
18
|
+
move tile, @player
|
19
|
+
end
|
20
|
+
elsif tile.queen?
|
21
|
+
if !laid_egg && (tile.age % 10).zero?
|
22
|
+
move tile, @player
|
23
|
+
tile.egg!
|
24
|
+
|
25
|
+
laid_egg = true
|
26
|
+
else
|
27
|
+
move tile, @player
|
28
|
+
end
|
29
|
+
elsif tile.egg?
|
30
|
+
if !hatched && (tile.age % 5).zero?
|
31
|
+
tile.queen!
|
32
|
+
|
33
|
+
hatched = true
|
34
|
+
end
|
35
|
+
elsif tile.soldier?
|
36
|
+
move tile, @player
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def show(players)
|
45
|
+
pause do
|
46
|
+
<<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
47
|
+
|
48
|
+
- LEVEL 5 -
|
49
|
+
|
50
|
+
|
51
|
+
Press %<pause>s to start.
|
52
|
+
|
53
|
+
(#{players} lives remaining)
|
54
|
+
POPUP
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup
|
59
|
+
@map.each &:empty!
|
60
|
+
|
61
|
+
@map.spawn :dirt!, 30
|
62
|
+
@map.spawn :rock!, 5
|
63
|
+
@map.spawn :worker!, 0.5
|
64
|
+
@map.spawn :soldier!, 0.15
|
65
|
+
@map.spawn :queen!, 0.3
|
66
|
+
@map.spawn :egg!, 0.15
|
67
|
+
|
68
|
+
@map.center.player!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Swarm
|
2
|
+
class Four < Level
|
3
|
+
|
4
|
+
def play
|
5
|
+
promoted = false
|
6
|
+
|
7
|
+
Catalog.select(*%i[worker soldier queen]).each do |tile|
|
8
|
+
tile.age!
|
9
|
+
|
10
|
+
if tile.worker?
|
11
|
+
if !promoted && (tile.age % 15).zero?
|
12
|
+
tile.soldier!
|
13
|
+
|
14
|
+
promoted = true
|
15
|
+
else
|
16
|
+
move tile, @player
|
17
|
+
end
|
18
|
+
elsif tile.queen?
|
19
|
+
move tile, @player
|
20
|
+
elsif tile.soldier?
|
21
|
+
move tile, @player
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def show(players)
|
30
|
+
pause do
|
31
|
+
<<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
32
|
+
|
33
|
+
- LEVEL 4 -
|
34
|
+
|
35
|
+
|
36
|
+
Press %<pause>s to start.
|
37
|
+
|
38
|
+
(#{players} lives remaining)
|
39
|
+
POPUP
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup
|
44
|
+
@map.each &:empty!
|
45
|
+
|
46
|
+
@map.spawn :dirt!, 30
|
47
|
+
@map.spawn :rock!, 5
|
48
|
+
@map.spawn :worker!, 0.5
|
49
|
+
@map.spawn :soldier!, 0.15
|
50
|
+
@map.spawn :queen!, 0.3
|
51
|
+
|
52
|
+
@map.center.player!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Swarm
|
2
|
+
class Intro < Level
|
3
|
+
def play
|
4
|
+
@over = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def show(*args)
|
8
|
+
@over = false
|
9
|
+
pause do <<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
10
|
+
Swarm Instructions
|
11
|
+
----------------------------------------------
|
12
|
+
Movement:
|
13
|
+
north: %<north>s
|
14
|
+
south: %<south>s
|
15
|
+
west: %<west>s
|
16
|
+
east: %<east>s
|
17
|
+
|
18
|
+
Pause: %<pause>s
|
19
|
+
Quit: %<quit>s
|
20
|
+
----------------------------------------------
|
21
|
+
|
22
|
+
Press %<pause>s to begin.
|
23
|
+
POPUP
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@map.center.player!
|
29
|
+
end
|
30
|
+
|
31
|
+
def over?
|
32
|
+
@over
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Swarm
|
2
|
+
class One < Level
|
3
|
+
|
4
|
+
def play
|
5
|
+
Catalog.select(:worker).each do |tile|
|
6
|
+
move tile, @player
|
7
|
+
end
|
8
|
+
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def show(players)
|
13
|
+
pause do
|
14
|
+
<<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
15
|
+
|
16
|
+
- LEVEL 1 -
|
17
|
+
|
18
|
+
Press %<pause>s to start.
|
19
|
+
|
20
|
+
(#{players} lives remaining)
|
21
|
+
POPUP
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@map.each &:empty!
|
27
|
+
|
28
|
+
@map.spawn :dirt!, 30
|
29
|
+
@map.spawn :rock!, 5
|
30
|
+
@map.spawn :worker!, 0.75
|
31
|
+
|
32
|
+
@map.center.player!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Swarm
|
2
|
+
class Three < Level
|
3
|
+
|
4
|
+
def play
|
5
|
+
promoted = false
|
6
|
+
|
7
|
+
Catalog.select(*%i[worker soldier]).each do |tile|
|
8
|
+
tile.age!
|
9
|
+
|
10
|
+
if tile.worker?
|
11
|
+
if !promoted && (tile.age % 15).zero?
|
12
|
+
tile.soldier!
|
13
|
+
|
14
|
+
promoted = true
|
15
|
+
else
|
16
|
+
move tile, @player
|
17
|
+
end
|
18
|
+
elsif tile.soldier?
|
19
|
+
move tile, @player
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def show(players)
|
27
|
+
pause do
|
28
|
+
<<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
29
|
+
|
30
|
+
- LEVEL 3 -
|
31
|
+
|
32
|
+
|
33
|
+
Press %<pause>s to start.
|
34
|
+
|
35
|
+
(#{players} lives remaining)
|
36
|
+
POPUP
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup
|
41
|
+
@map.each &:empty!
|
42
|
+
|
43
|
+
@map.spawn :dirt!, 30
|
44
|
+
@map.spawn :rock!, 5
|
45
|
+
@map.spawn :worker!, 0.5
|
46
|
+
@map.spawn :soldier!, 0.2
|
47
|
+
|
48
|
+
@map.center.player!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Swarm
|
2
|
+
class Two < Level
|
3
|
+
|
4
|
+
def play
|
5
|
+
Catalog.select(*%i[worker soldier]).each do |tile|
|
6
|
+
move tile, @player
|
7
|
+
end
|
8
|
+
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def show(players)
|
14
|
+
pause do
|
15
|
+
<<-POPUP.gsub(/[ ]{10}/, '') % Console.key_info
|
16
|
+
|
17
|
+
- LEVEL 2 -
|
18
|
+
|
19
|
+
|
20
|
+
Press %<pause>s to start.
|
21
|
+
|
22
|
+
(#{players} lives remaining)
|
23
|
+
POPUP
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@map.each &:empty!
|
29
|
+
|
30
|
+
@map.spawn :dirt!, 30
|
31
|
+
@map.spawn :rock!, 5
|
32
|
+
@map.spawn :worker!, 0.5
|
33
|
+
@map.spawn :soldier!, 0.15
|
34
|
+
|
35
|
+
@map.center.player!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/swarm/map.rb
ADDED
@@ -0,0 +1,254 @@
|
|
1
|
+
module Swarm
|
2
|
+
|
3
|
+
# @example The +Map+ Layout
|
4
|
+
# +-------------------------------------------+
|
5
|
+
# | |
|
6
|
+
# | [0,0] [1,0] [2,0] [3,0] [4,0] [5,0] [6,0] |
|
7
|
+
# | |
|
8
|
+
# | [0,1] [1,1] [2,1] [3,1] [4,1] [5,1] [6,1] |
|
9
|
+
# | |
|
10
|
+
# | [0,2] [1,2] [2,2] [3,2] [4,2] [5,2] [6,2] |
|
11
|
+
# | |
|
12
|
+
# | [0,3] [1,3] [2,3] [3,3] [4,3] [5,3] [6,3] |
|
13
|
+
# | |
|
14
|
+
# | [0,4] [1,4] [2,4] [3,4] [4,4] [5,4] [6,4] |
|
15
|
+
# | |
|
16
|
+
# | [0,5] [1,5] [2,5] [3,5] [4,5] [5,5] [6,5] |
|
17
|
+
# | |
|
18
|
+
# | [0,6] [1,6] [2,6] [3,6] [4,6] [5,6] [6,6] |
|
19
|
+
# | |
|
20
|
+
# +-------------------------------------------+
|
21
|
+
class Map
|
22
|
+
|
23
|
+
# @macro swarm.map.dimensions
|
24
|
+
# @return [Integer] the +$1+ of the +Map+.
|
25
|
+
|
26
|
+
# @macro swarm.map.dimensions
|
27
|
+
attr_reader :width
|
28
|
+
|
29
|
+
# @macro swarm.map.dimensions
|
30
|
+
attr_reader :height
|
31
|
+
|
32
|
+
# A 2 dimensional array of tiles.
|
33
|
+
def initialize(width, height, tile_width: 1, tile_height: 1)
|
34
|
+
@tiles = (0...height).step(tile_height).map.with_index do |console_y, map_y|
|
35
|
+
(0...width).step(tile_width).map.with_index do |console_x, map_x|
|
36
|
+
Tile.new map_x,
|
37
|
+
map_y,
|
38
|
+
[console_y, console_x] # reversed for Console::setpos
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@height = height / tile_height
|
43
|
+
@width = width / tile_width
|
44
|
+
end
|
45
|
+
|
46
|
+
include Enumerable
|
47
|
+
|
48
|
+
def each(&block)
|
49
|
+
@tiles.each { |row| row.each &block }
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Tile] a center tile
|
53
|
+
def center
|
54
|
+
@tiles[height / 2][width / 2]
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Tile] a random tile
|
58
|
+
def sample
|
59
|
+
@tiles.sample.sample
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param x [Integer]
|
63
|
+
# @param y [Integer]
|
64
|
+
# @return [Tile]
|
65
|
+
def [](x, y)
|
66
|
+
@tiles.fetch(y, Array.new)[x]
|
67
|
+
end
|
68
|
+
|
69
|
+
# @param x [Integer]
|
70
|
+
# @param y [Integer]
|
71
|
+
# @param tile [Tile]
|
72
|
+
# @return [Tile]
|
73
|
+
def []=(x, y, tile)
|
74
|
+
@tiles[y] ||= Array.new
|
75
|
+
@tiles[y][x] = tile
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [Tile] the last tile (highest +x+ and +y+ value)
|
79
|
+
def last
|
80
|
+
self[-1, -1]
|
81
|
+
end
|
82
|
+
|
83
|
+
def score(key)
|
84
|
+
Catalog.fetch :destroyed, key, 0
|
85
|
+
end
|
86
|
+
|
87
|
+
def spawn(flag, percent = 0.0)
|
88
|
+
total = ((percent.to_f / 100) * count)
|
89
|
+
|
90
|
+
select(&:empty?).sample(total.to_i).each &flag
|
91
|
+
end
|
92
|
+
|
93
|
+
# Move a +Tile+ on the +Map+. This movement action causes a chain
|
94
|
+
# reaction potentially moving (or killing) tiles down the map in that
|
95
|
+
# same direction.
|
96
|
+
#
|
97
|
+
# It does this by comparing each neighboring pair
|
98
|
+
# tile_1 -> tile_2
|
99
|
+
# tile_2 -> tile_3
|
100
|
+
# tile_3 -> tile_4
|
101
|
+
#
|
102
|
+
# And follows these rules
|
103
|
+
# * empty tiles don't transfer movement
|
104
|
+
# * enemies block enemies
|
105
|
+
# * players are killed when touching enemies
|
106
|
+
# * enemies get squished by players
|
107
|
+
# * players get squished by queens
|
108
|
+
# * rocks block everything
|
109
|
+
#
|
110
|
+
# @param tile [Tile]
|
111
|
+
# @param direction [Symbol] +:north+, +:south+, +:east+ or +:west+
|
112
|
+
# @return [Boolean] +true+ if the +tile+ is moved successfully, +false+ if it is not
|
113
|
+
def move(tile, direction)
|
114
|
+
tiles = send(direction, tile)
|
115
|
+
move = []
|
116
|
+
|
117
|
+
tiles.each_cons(2) do |this, that|
|
118
|
+
break if this.empty?
|
119
|
+
# break move.clear if (tile == this) && this.enemy? && that.empty?
|
120
|
+
break move.clear if this.enemy? && that.enemy?
|
121
|
+
|
122
|
+
break move.clear if this.egg? && that.enemy?
|
123
|
+
break move.clear if this.enemy? && that.egg?
|
124
|
+
|
125
|
+
break this.destroy! if this.player? && (that.enemy? || that.egg?)
|
126
|
+
break that.destroy! if (this.enemy? || this.egg?) && that.player?
|
127
|
+
|
128
|
+
if (this.worker? || this.queen? || this.egg?) && tile.player? && (that.dirt? || that.rock?)
|
129
|
+
this.destroy!
|
130
|
+
break
|
131
|
+
end
|
132
|
+
|
133
|
+
if this.soldier? && tile.player? && that.rock?
|
134
|
+
(neighbors(this) - neighbors(tile)).each &:worker!
|
135
|
+
|
136
|
+
this.destroy!
|
137
|
+
break
|
138
|
+
end
|
139
|
+
|
140
|
+
if this.player? && tile.queen? && !that.empty?
|
141
|
+
this.destroy!
|
142
|
+
break
|
143
|
+
end
|
144
|
+
|
145
|
+
break move.clear if that.rock?
|
146
|
+
|
147
|
+
move << [that, this.type, this.age]
|
148
|
+
end
|
149
|
+
|
150
|
+
return if move.empty?
|
151
|
+
|
152
|
+
tile.empty!
|
153
|
+
move.each { |t, type, age| t.send(type, age) }
|
154
|
+
end
|
155
|
+
|
156
|
+
# Find the closest route from +this+ to +that+ based only on position
|
157
|
+
# (ignoring all obstacles between +this+ and +that+).
|
158
|
+
#
|
159
|
+
# @param this [Tile] origin tile
|
160
|
+
# @param that [Tile] destination tile
|
161
|
+
# @return [Array<Symbol, ...>] +:north+, +:east+, +:west+ and/or +:south+
|
162
|
+
def aggressive_moves(this, that)
|
163
|
+
directions = []
|
164
|
+
directions << :north if (this.y > that.y) && ((this.y - that.y) < 10)
|
165
|
+
directions << :south if (that.y > this.y) && ((that.y - this.y) < 10)
|
166
|
+
directions << :west if (this.x > that.x) && ((this.x - that.x) < 10)
|
167
|
+
directions << :east if (that.x > this.x) && ((that.x - this.x) < 10)
|
168
|
+
directions
|
169
|
+
end
|
170
|
+
|
171
|
+
# Find "open" (non-blocking) moves for a +worker+ or +soldier+.
|
172
|
+
#
|
173
|
+
# @see {Map#north}
|
174
|
+
# @see {Map#south}
|
175
|
+
# @see {Map#east}
|
176
|
+
# @see {Map#west}
|
177
|
+
#
|
178
|
+
# @param tile [Tile] a +worker+ or +soldier+
|
179
|
+
# @return [Array<Symbol, ...>] +:north+, +:east+, +:west+ and/or +:south+
|
180
|
+
def available_moves(tile)
|
181
|
+
%i(north south east west).select do |direction|
|
182
|
+
_, neighbor, _ = send(direction, tile)
|
183
|
+
|
184
|
+
next if neighbor.nil?
|
185
|
+
|
186
|
+
neighbor.player? || neighbor.empty? || (tile.queen? && neighbor.dirt?)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def neighbors(tile)
|
191
|
+
[
|
192
|
+
[ 0, 1],
|
193
|
+
[ 1, 0],
|
194
|
+
[ 0,-1],
|
195
|
+
[-1, 0],
|
196
|
+
# [ 0, 0], <- self
|
197
|
+
[ 1, 1],
|
198
|
+
[-1,-1],
|
199
|
+
[ 1,-1],
|
200
|
+
[-1, 1]
|
201
|
+
].map do |x, y|
|
202
|
+
self[tile.x + x, tile.y + y]
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def update
|
207
|
+
Console.update Catalog.flush(:changed)
|
208
|
+
end
|
209
|
+
|
210
|
+
# @macro swarm.map.direction
|
211
|
+
# @see Map#column
|
212
|
+
# @see Map#row
|
213
|
+
# @param tile [Tile]
|
214
|
+
# @return [Array<Tile, ...>] +column+ or +row+ of tiles starting with +tile+ headed $0 until the end of the map
|
215
|
+
|
216
|
+
# @macro swarm.map.direction
|
217
|
+
def north(tile)
|
218
|
+
tiles = column(tile).reverse
|
219
|
+
tiles.rotate(tiles.index tile)
|
220
|
+
end
|
221
|
+
|
222
|
+
# @macro swarm.map.direction
|
223
|
+
def south(tile)
|
224
|
+
tiles = column(tile)
|
225
|
+
tiles.rotate(tiles.index tile)
|
226
|
+
end
|
227
|
+
|
228
|
+
# @macro swarm.map.direction
|
229
|
+
def east(tile)
|
230
|
+
tiles = row(tile)
|
231
|
+
tiles.rotate(tiles.index tile)
|
232
|
+
end
|
233
|
+
|
234
|
+
# @macro swarm.map.direction
|
235
|
+
def west(tile)
|
236
|
+
tiles = row(tile).reverse
|
237
|
+
tiles.rotate(tiles.index tile)
|
238
|
+
end
|
239
|
+
|
240
|
+
# @macro swarm.map.axis
|
241
|
+
# @param tile [Tile]
|
242
|
+
# @return [Array<Tile, ...>] the $0 of tiles that the +tile+ resides on
|
243
|
+
|
244
|
+
# @macro swarm.map.axis
|
245
|
+
def row(tile)
|
246
|
+
@tiles[tile.y]
|
247
|
+
end
|
248
|
+
|
249
|
+
# @macro swarm.map.axis
|
250
|
+
def column(tile)
|
251
|
+
@tiles.map { |row| row[tile.x] }
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|