rdgc-dm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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