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.
@@ -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