rdgc-dm 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +22 -0
- data/README.rdoc +148 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/rdgc/maker/divide_dungeon_maker.rb +371 -0
- data/lib/rdgc/maker/divide_temp_block.rb +269 -0
- data/lib/rdgc/maker/dungeon_maker.rb +57 -0
- data/lib/rdgc/maker/temp_block.rb +23 -0
- data/lib/rdgc/map/area.rb +103 -0
- data/lib/rdgc/map/block.rb +155 -0
- data/lib/rdgc/map/board.rb +81 -0
- data/lib/rdgc/map/road.rb +18 -0
- data/lib/rdgc/map/room.rb +69 -0
- data/lib/rdgc/map/tile.rb +35 -0
- data/lib/rdgc/map/tile_type.rb +11 -0
- data/lib/rdgc/util/config.rb +74 -0
- data/lib/rdgc/util/random_util.rb +104 -0
- data/lib/rdgc-dm.rb +17 -0
- data/rdgc-dm.gemspec +93 -0
- data/spec/rdgc/maker/01_temp_block_spec.rb +45 -0
- data/spec/rdgc/maker/02_divide_temp_block_spec.rb +241 -0
- data/spec/rdgc/maker/03_divide_dungeon_maker_divide_spec.rb +224 -0
- data/spec/rdgc/maker/04_divide_dungeon_maker_create_spec.rb +244 -0
- data/spec/rdgc/map/01_tile_spec.rb +56 -0
- data/spec/rdgc/map/02_area_spec.rb +118 -0
- data/spec/rdgc/map/03_road_spec.rb +23 -0
- data/spec/rdgc/map/04_room_spec.rb +190 -0
- data/spec/rdgc/map/05_block_spec.rb +273 -0
- data/spec/rdgc/map/06_board_spec.rb +132 -0
- data/spec/rdgc/util/01_config_spec.rb +44 -0
- data/spec/rdgc/util/02_random_util_spec.rb +153 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -0
- metadata +124 -0
@@ -0,0 +1,269 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Maker
|
4
|
+
class DivideTempBlock < TempBlock
|
5
|
+
|
6
|
+
attr_accessor :divide_direction
|
7
|
+
attr_writer :depth, :min_size
|
8
|
+
|
9
|
+
def depth
|
10
|
+
@depth ||= 0
|
11
|
+
@depth
|
12
|
+
end
|
13
|
+
|
14
|
+
def min_size
|
15
|
+
@min_size = Util::Config.min_block_size if @min_size.to_i < Util::Config.min_block_size
|
16
|
+
@min_size
|
17
|
+
end
|
18
|
+
|
19
|
+
def min_divide_size
|
20
|
+
min_size * 2
|
21
|
+
end
|
22
|
+
|
23
|
+
def opposite_direction
|
24
|
+
case self.divide_direction
|
25
|
+
when :horizontal
|
26
|
+
:vertical
|
27
|
+
when :vertical
|
28
|
+
:horizontal
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def dividable_size?
|
35
|
+
case self.divide_direction
|
36
|
+
when :horizontal
|
37
|
+
height >= min_divide_size ? true : false
|
38
|
+
when :vertical
|
39
|
+
width >= min_divide_size ? true : false
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dividable(f = true)
|
46
|
+
@dividable = f
|
47
|
+
end
|
48
|
+
|
49
|
+
def dividable?
|
50
|
+
@dividable
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_dividable
|
54
|
+
return unless dividable_size?
|
55
|
+
dividable
|
56
|
+
end
|
57
|
+
|
58
|
+
def divide_point(val)
|
59
|
+
range_rand(min_size, val - min_divide_size)
|
60
|
+
end
|
61
|
+
|
62
|
+
def divide
|
63
|
+
self.divide_direction ||= select_rand({:horizontal => 1, :vertical => 1})
|
64
|
+
return unless dividable_size?
|
65
|
+
|
66
|
+
case self.divide_direction
|
67
|
+
when :horizontal
|
68
|
+
divide_horizontal
|
69
|
+
when :vertical
|
70
|
+
divide_vertical
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def divide_horizontal
|
75
|
+
return unless dividable_size?
|
76
|
+
|
77
|
+
# 分割幅決定
|
78
|
+
point = divide_point(height)
|
79
|
+
|
80
|
+
upper = DivideTempBlock.create(top, top + point - 1, left, right)
|
81
|
+
lower = DivideTempBlock.create(top + point, bottom, left, right)
|
82
|
+
|
83
|
+
set_next_value(upper, lower)
|
84
|
+
[upper, lower].shuffle
|
85
|
+
end
|
86
|
+
|
87
|
+
def divide_vertical
|
88
|
+
return unless dividable_size?
|
89
|
+
|
90
|
+
# 分割点決定
|
91
|
+
point = divide_point(width)
|
92
|
+
|
93
|
+
lefter = DivideTempBlock.create(top, bottom, left, left + point - 1)
|
94
|
+
righter = DivideTempBlock.create(top, bottom, left + point, right)
|
95
|
+
|
96
|
+
set_next_value(lefter, righter)
|
97
|
+
[lefter, righter].shuffle
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_next_value(b1, b2)
|
101
|
+
[b1, b2].each do |b|
|
102
|
+
b.depth = self.depth + 1
|
103
|
+
b.divide_direction = opposite_direction
|
104
|
+
b.min_size = min_size
|
105
|
+
end
|
106
|
+
|
107
|
+
if bool_rand
|
108
|
+
b1.set_dividable
|
109
|
+
b2.set_dividable if bool_rand
|
110
|
+
else
|
111
|
+
b2.set_dividable
|
112
|
+
b1.set_dividable if bool_rand
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# for road ----------------------------------------------------
|
117
|
+
|
118
|
+
def road_created(f = true)
|
119
|
+
@road_created = f
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
def road_created?
|
124
|
+
@road_created
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_road_point(direction, point)
|
128
|
+
@road_point ||= {}
|
129
|
+
@road_point[direction] = point
|
130
|
+
end
|
131
|
+
|
132
|
+
def road_point
|
133
|
+
@road_point ||= {}
|
134
|
+
@road_point
|
135
|
+
end
|
136
|
+
|
137
|
+
def remain_cling_blocks
|
138
|
+
@remain_cling_blocks ||= []
|
139
|
+
@remain_cling_blocks
|
140
|
+
end
|
141
|
+
|
142
|
+
def add_remain_cling_blocks(b)
|
143
|
+
return if b.has_room?
|
144
|
+
remain_cling_blocks << b
|
145
|
+
end
|
146
|
+
|
147
|
+
def has_remain_cling_blocks?
|
148
|
+
remain_cling_blocks.empty? ? false : true
|
149
|
+
end
|
150
|
+
|
151
|
+
def dead_end?
|
152
|
+
return false if has_room?
|
153
|
+
return false unless has_cross_point?
|
154
|
+
road_point.keys.size == 1 ? true : false
|
155
|
+
end
|
156
|
+
|
157
|
+
def remain_direction
|
158
|
+
[:top, :bottom, :left, :right] - road_point.keys
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_road_to(b)
|
162
|
+
return unless (has_room? || has_cross_point?)
|
163
|
+
return unless (b.has_room? || b.has_cross_point?)
|
164
|
+
|
165
|
+
# 相手とどこで接しているか調べる
|
166
|
+
# 接線に向かって道を伸ばす
|
167
|
+
# 左か上に位置する部屋に接続線を引く
|
168
|
+
case cling_direction_to(b)
|
169
|
+
when :top
|
170
|
+
my_x = create_road_for_direction(:top)
|
171
|
+
b_x = b.create_road_for_direction(:bottom)
|
172
|
+
b.create_road_for_adjoin_x(my_x, b_x)
|
173
|
+
when :bottom
|
174
|
+
my_x = create_road_for_direction(:bottom)
|
175
|
+
b_x = b.create_road_for_direction(:top)
|
176
|
+
create_road_for_adjoin_x(my_x, b_x)
|
177
|
+
when :left
|
178
|
+
my_y = create_road_for_direction(:left)
|
179
|
+
b_y = b.create_road_for_direction(:right)
|
180
|
+
b.create_road_for_adjoin_y(my_y, b_y)
|
181
|
+
when :right
|
182
|
+
my_y = create_road_for_direction(:right)
|
183
|
+
b_y = b.create_road_for_direction(:left)
|
184
|
+
create_road_for_adjoin_y(my_y, b_y)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def create_road_for_direction(d)
|
189
|
+
# 道を描くポイントを持っている(すでに道がある)ならそれを返す
|
190
|
+
val = road_point[d]
|
191
|
+
return val if val
|
192
|
+
|
193
|
+
# 新しい道を描く
|
194
|
+
case
|
195
|
+
when has_room?
|
196
|
+
val = create_road_from_room(d)
|
197
|
+
when has_cross_point?
|
198
|
+
val = create_road_from_point(d)
|
199
|
+
end
|
200
|
+
|
201
|
+
val
|
202
|
+
end
|
203
|
+
|
204
|
+
def create_road_from_room(d)
|
205
|
+
return unless has_room?
|
206
|
+
return if road_point[d]
|
207
|
+
|
208
|
+
case d
|
209
|
+
when :top
|
210
|
+
x = range_rand(room.left, room.right)
|
211
|
+
set_road_point(:top, x)
|
212
|
+
add_road(Map::Road.create(top, room.top-1, x, x))
|
213
|
+
x
|
214
|
+
when :bottom
|
215
|
+
x = range_rand(room.left, room.right)
|
216
|
+
set_road_point(:bottom, x)
|
217
|
+
add_road(Map::Road.create(room.bottom+1, bottom, x, x))
|
218
|
+
x
|
219
|
+
when :left
|
220
|
+
y = range_rand(room.top, room.bottom)
|
221
|
+
set_road_point(:left, y)
|
222
|
+
add_road(Map::Road.create(y, y, left, room.left-1))
|
223
|
+
y
|
224
|
+
when :right
|
225
|
+
y = range_rand(room.top, room.bottom)
|
226
|
+
set_road_point(:right, y)
|
227
|
+
add_road(Map::Road.create(y, y, room.right+1, right))
|
228
|
+
y
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def create_road_from_point(d)
|
233
|
+
return unless has_cross_point?
|
234
|
+
return if road_point[d]
|
235
|
+
|
236
|
+
x, y = cross_point
|
237
|
+
case d
|
238
|
+
when :top
|
239
|
+
set_road_point(:top, x)
|
240
|
+
add_road(Map::Road.create(top, y, x, x))
|
241
|
+
x
|
242
|
+
when :bottom
|
243
|
+
set_road_point(:bottom, x)
|
244
|
+
add_road(Map::Road.create(y, bottom, x, x))
|
245
|
+
x
|
246
|
+
when :left
|
247
|
+
set_road_point(:left, y)
|
248
|
+
add_road(Map::Road.create(y, y, left, x))
|
249
|
+
y
|
250
|
+
when :right
|
251
|
+
set_road_point(:right, y)
|
252
|
+
add_road(Map::Road.create(y, y, x, right))
|
253
|
+
y
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def create_road_for_adjoin_x(x1, x2)
|
258
|
+
p_s, p_e = [x1, x2].sort
|
259
|
+
add_road(Map::Road.create(bottom, bottom, p_s, p_e))
|
260
|
+
end
|
261
|
+
|
262
|
+
def create_road_for_adjoin_y(y1, y2)
|
263
|
+
p_s, p_e = [y1, y2].sort
|
264
|
+
add_road(Map::Road.create(p_s, p_e, right, right))
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Maker
|
4
|
+
module DungeonMaker
|
5
|
+
|
6
|
+
def make(width, height, params = nil)
|
7
|
+
@params = params
|
8
|
+
tb = create_whole_block(width, height)
|
9
|
+
@blocks = make_blocks(tb)
|
10
|
+
@blocks.freeze
|
11
|
+
create_room
|
12
|
+
create_road
|
13
|
+
clear_block
|
14
|
+
create_pure_blocks
|
15
|
+
end
|
16
|
+
|
17
|
+
def params
|
18
|
+
@params ||= {}
|
19
|
+
@params
|
20
|
+
end
|
21
|
+
|
22
|
+
def blocks
|
23
|
+
@blocks ||= []
|
24
|
+
@blocks
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_whole_block(width, height)
|
28
|
+
end
|
29
|
+
|
30
|
+
def make_blocks(tb)
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_room
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_road
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear_block
|
40
|
+
return if blocks.size <= 1
|
41
|
+
blocks.each do |b|
|
42
|
+
next if b.has_road?
|
43
|
+
b.remove_all
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_pure_blocks
|
48
|
+
blocks.inject([]) do |l, b|
|
49
|
+
pb = b.create_pure_block
|
50
|
+
l << pb if pb
|
51
|
+
l
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Maker
|
4
|
+
class TempBlock < Map::Block
|
5
|
+
|
6
|
+
def self.create_whole_block(width, height)
|
7
|
+
left = 0
|
8
|
+
right = width - 1
|
9
|
+
top = 0
|
10
|
+
bottom = height - 1
|
11
|
+
self.create(top, bottom, left, right)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_pure_block
|
15
|
+
b = Map::Block.create(self.top, self.bottom, self.left, self.right)
|
16
|
+
b.room = self.room if self.has_room?
|
17
|
+
self.roads.each{|r| b.add_road(r) if r}
|
18
|
+
b.empty? ? nil : b
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Map
|
4
|
+
class Area
|
5
|
+
include TileType
|
6
|
+
|
7
|
+
attr_accessor :top, :bottom, :left, :right
|
8
|
+
|
9
|
+
def self.create(top, bottom, left, right)
|
10
|
+
b = self.new
|
11
|
+
b.top = top
|
12
|
+
b.bottom = bottom
|
13
|
+
b.left = left
|
14
|
+
b.right = right
|
15
|
+
b
|
16
|
+
end
|
17
|
+
|
18
|
+
def coordinates
|
19
|
+
"t:#{top} b:#{bottom} l:#{left} r:#{right} / w:#{width} h:#{height}"
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :to_co :coordinates
|
23
|
+
|
24
|
+
def height
|
25
|
+
bottom - top + 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def width
|
29
|
+
right - left + 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_xy?(x, y)
|
33
|
+
return false if x < left
|
34
|
+
return false if x > right
|
35
|
+
return false if y < top
|
36
|
+
return false if y > bottom
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def random_point
|
41
|
+
[range_rand(left, right), range_rand(top, bottom)]
|
42
|
+
end
|
43
|
+
|
44
|
+
def each
|
45
|
+
return to_enum(:each) unless block_given?
|
46
|
+
each_x do |x|
|
47
|
+
each_y do |y|
|
48
|
+
yield(x, y)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def each_x
|
54
|
+
return to_enum(:each_x) unless block_given?
|
55
|
+
(left..right).each do |x|
|
56
|
+
yield(x)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def each_y
|
61
|
+
return to_enum(:each_y) unless block_given?
|
62
|
+
(top..bottom).each do |y|
|
63
|
+
yield(y)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def each_tile
|
68
|
+
return to_enum(:each_tile) unless block_given?
|
69
|
+
each do |x, y|
|
70
|
+
yield(x, y, tile(x, y))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def fill
|
75
|
+
# need override
|
76
|
+
end
|
77
|
+
|
78
|
+
def fill_tile(tile)
|
79
|
+
each do |x, y|
|
80
|
+
set_tile(x, y, tile)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_tile(x, y, tile)
|
85
|
+
return unless has_xy?(x, y)
|
86
|
+
tile_data[x][y] = tile
|
87
|
+
end
|
88
|
+
|
89
|
+
def tile(x, y)
|
90
|
+
return unless has_xy?(x, y)
|
91
|
+
tile_data[x][y]
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def tile_data
|
97
|
+
@tile_data ||= Hash.new{|hash, key| hash[key] = {}}
|
98
|
+
@tile_data
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Map
|
4
|
+
class Block < Area
|
5
|
+
|
6
|
+
def self.create(top, bottom, left, right)
|
7
|
+
# fillはしない
|
8
|
+
super(top, bottom, left, right)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fill
|
12
|
+
# 初期化
|
13
|
+
fill_tile TileType::WALL
|
14
|
+
|
15
|
+
fill_room
|
16
|
+
fill_roads
|
17
|
+
end
|
18
|
+
|
19
|
+
def fill_room
|
20
|
+
return unless has_room?
|
21
|
+
room.each_tile do |x, y, t|
|
22
|
+
set_tile(x, y, t)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def fill_roads
|
27
|
+
return unless has_road?
|
28
|
+
roads.each do |r|
|
29
|
+
r.each_tile do |x, y, t|
|
30
|
+
set_tile(x, y, t)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def room
|
36
|
+
@room
|
37
|
+
end
|
38
|
+
|
39
|
+
def room=(r)
|
40
|
+
@room = r
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_room
|
44
|
+
@room = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def has_room?
|
48
|
+
@room ? true : false
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_room(opt = nil)
|
52
|
+
@room = Room.create_from_block(self, opt)
|
53
|
+
@room
|
54
|
+
end
|
55
|
+
|
56
|
+
def roads
|
57
|
+
@roads ||= []
|
58
|
+
@roads
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_road(road)
|
62
|
+
@roads ||= []
|
63
|
+
@roads << road
|
64
|
+
end
|
65
|
+
|
66
|
+
def remove_roads
|
67
|
+
@roads = []
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_road?
|
71
|
+
roads.empty? ? false : true
|
72
|
+
end
|
73
|
+
|
74
|
+
def cross_point
|
75
|
+
@cross_point
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_cross_point
|
79
|
+
@cross_point = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def has_cross_point?
|
83
|
+
@cross_point ? true : false
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_cross_point
|
87
|
+
# 右と下は接線を引くので余計に空ける
|
88
|
+
x_min = self.left + 1
|
89
|
+
x_max = self.right - 2
|
90
|
+
y_min = self.top + 1
|
91
|
+
y_max = self.bottom - 2
|
92
|
+
|
93
|
+
x = range_rand(x_min, x_max)
|
94
|
+
y = range_rand(y_min, y_max)
|
95
|
+
|
96
|
+
@cross_point = [x, y]
|
97
|
+
@cross_point
|
98
|
+
end
|
99
|
+
|
100
|
+
def remove_all
|
101
|
+
remove_room
|
102
|
+
remove_roads
|
103
|
+
remove_cross_point
|
104
|
+
end
|
105
|
+
|
106
|
+
def empty?
|
107
|
+
return false if has_room?
|
108
|
+
return false if has_road?
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
def cling_to_top?(b)
|
113
|
+
return false unless top == b.bottom+1
|
114
|
+
return false if left > b.right
|
115
|
+
return false if right < b.left
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
def cling_to_bottom?(b)
|
120
|
+
return false unless bottom == b.top-1
|
121
|
+
return false if left > b.right
|
122
|
+
return false if right < b.left
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
def cling_to_left?(b)
|
127
|
+
return false unless left == b.right+1
|
128
|
+
return false if top > b.bottom
|
129
|
+
return false if bottom < b.top
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
def cling_to_right?(b)
|
134
|
+
return false unless right == b.left-1
|
135
|
+
return false if top > b.bottom
|
136
|
+
return false if bottom < b.top
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
def cling_direction_to(b)
|
141
|
+
case
|
142
|
+
when cling_to_top?(b)
|
143
|
+
:top
|
144
|
+
when cling_to_bottom?(b)
|
145
|
+
:bottom
|
146
|
+
when cling_to_left?(b)
|
147
|
+
:left
|
148
|
+
when cling_to_right?(b)
|
149
|
+
:right
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Map
|
4
|
+
class Board < Area
|
5
|
+
|
6
|
+
def self.create_from_blocks(blocks)
|
7
|
+
d = self.new
|
8
|
+
d.init(blocks)
|
9
|
+
d
|
10
|
+
end
|
11
|
+
|
12
|
+
def init(list)
|
13
|
+
return unless list
|
14
|
+
return if list.empty?
|
15
|
+
|
16
|
+
@blocks = list
|
17
|
+
@rooms = blocks.map(&:room).compact
|
18
|
+
@roads = blocks.map(&:roads).flatten.compact
|
19
|
+
|
20
|
+
set_coordinates
|
21
|
+
fill
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_coordinates
|
25
|
+
return unless blocks
|
26
|
+
self.top = blocks.map(&:top).min
|
27
|
+
self.bottom = blocks.map(&:bottom).max
|
28
|
+
self.left = blocks.map(&:left).min
|
29
|
+
self.right = blocks.map(&:right).max
|
30
|
+
end
|
31
|
+
|
32
|
+
def fill
|
33
|
+
# 初期化
|
34
|
+
fill_tile TileType::WALL
|
35
|
+
|
36
|
+
rooms.each do |r|
|
37
|
+
r.each_tile do |x, y, t|
|
38
|
+
set_tile(x, y, t)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
roads.each do |r|
|
43
|
+
r.each_tile do |x, y, t|
|
44
|
+
set_tile(x, y, t)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def blocks
|
50
|
+
@blocks ||= []
|
51
|
+
@blocks
|
52
|
+
end
|
53
|
+
|
54
|
+
def rooms
|
55
|
+
@rooms ||= []
|
56
|
+
@rooms
|
57
|
+
end
|
58
|
+
|
59
|
+
def roads
|
60
|
+
@roads ||= []
|
61
|
+
@roads
|
62
|
+
end
|
63
|
+
|
64
|
+
def movable?(x, y)
|
65
|
+
return false unless has_xy?(x, y)
|
66
|
+
tile(x, y).movable?
|
67
|
+
end
|
68
|
+
|
69
|
+
def room?(x, y)
|
70
|
+
return false unless has_xy?(x, y)
|
71
|
+
tile(x, y).room?
|
72
|
+
end
|
73
|
+
|
74
|
+
def road?(x, y)
|
75
|
+
return false unless has_xy?(x, y)
|
76
|
+
tile(x, y).road?
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
module RDGC
|
3
|
+
module Map
|
4
|
+
class Road < Area
|
5
|
+
|
6
|
+
def self.create(top, bottom, left, right)
|
7
|
+
road = super(top, bottom, left, right)
|
8
|
+
road.fill
|
9
|
+
road
|
10
|
+
end
|
11
|
+
|
12
|
+
def fill
|
13
|
+
fill_tile TileType::ROAD
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|