the-swarm 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|