ruby-perlin-2D-map-generator 0.0.3 → 0.0.5
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 +4 -4
- data/README.md +135 -44
- data/lib/CLI/command.rb +80 -12
- data/lib/ansi_colours.rb +3 -0
- data/lib/biome.rb +10 -0
- data/lib/map.rb +22 -1
- data/lib/map_config.rb +34 -8
- data/lib/pathfinding/a_star_finder.rb +57 -0
- data/lib/pathfinding/grid.rb +78 -0
- data/lib/road_generator.rb +63 -0
- data/lib/tile.rb +62 -4
- metadata +29 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a4341c2583eba83e95d6ea4a9c1ee05a857bc1f5c77c6d3aeeba41f6995a656
|
|
4
|
+
data.tar.gz: 599b47f78c83dc6acd99dcde0e9aadbeb8d445fc7d9b6ef7ba8b1acbb3c15d7b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bbabe795544e432d7cf4e5dac2fd6f2b14dd17239d3eb2a59013ce3655bcee1873ef4edb5e6048be372c474af04234e5f7ef33806b517de1b160ea5d59b3d62f
|
|
7
|
+
data.tar.gz: 246cc08e1413e89c6929eacf4201a7895e64595067367f02ed8e758a239e18b098186e16c1c8a85900e1519fa84eb5ace115d15e094894b62825664b1059e57d
|
data/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Ruby Perlin 2D Map Generator
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/ruby-perlin-2D-map-generator)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://rubygems.org/gems/ruby-perlin-2D-map-generator)
|
|
7
|
+
|
|
8
|
+
A gem that procedurally generates seeded and customizable 2D map with optional roads using perlin noise.
|
|
3
9
|
|
|
4
10
|
Include the gem in your project, or use the executable from the command line.
|
|
5
11
|
|
|
@@ -28,6 +34,7 @@ gem install ruby-perlin-2D-map-generator
|
|
|
28
34
|
See Command line Usage for full customization, below are some examples. Alter the temperature, moisture or elevation seeds to alter these maps:
|
|
29
35
|
|
|
30
36
|
- Plains with random terrain evens: `ruby-perlin-2D-map-generator render`
|
|
37
|
+
- Plains with random terrain events and two roads: `ruby-perlin-2D-map-generator render --roads=2`
|
|
31
38
|
- Desert (increase temperature, decrease moisture): `ruby-perlin-2D-map-generator render --temp=100 --moisture=-100`
|
|
32
39
|
- Mountainous with lakes (increase elevation, increase moisture) `ruby-perlin-2D-map-generator render --elevation=25 --moisture=25`
|
|
33
40
|
- Islands (decreaes elevation, increase moisture): `ruby-perlin-2D-map-generator render --elevation=-40 --moisture=25`
|
|
@@ -38,27 +45,61 @@ See Command line Usage for full customization, below are some examples. Alter th
|
|
|
38
45
|
--width=int The width of the generated map (default 128)
|
|
39
46
|
--height=int The height of the generated map (default 128)
|
|
40
47
|
|
|
48
|
+
--roads=int Add this many roads through the map,
|
|
49
|
+
starting and ending at edges
|
|
50
|
+
(default 0)
|
|
51
|
+
|
|
41
52
|
--hs=int The seed for a terrains height perlin generation
|
|
42
53
|
(default 10)
|
|
43
54
|
--ms=int The seed for a terrains moist perlin generation
|
|
44
55
|
(default 300)
|
|
45
56
|
--ts=int The seed for a terrains temperature perlin generation
|
|
46
57
|
(default 3000)
|
|
58
|
+
--rs=int The seed for generating roads
|
|
59
|
+
(default 100)
|
|
47
60
|
|
|
48
|
-
--elevation=float Adjust each generated elevation by this percent (
|
|
61
|
+
--elevation=float Adjust each generated elevation by this percent (-100 -
|
|
49
62
|
100) (default 0.0)
|
|
50
|
-
--moisture=float Adjust each generated moisture by this percent (
|
|
63
|
+
--moisture=float Adjust each generated moisture by this percent (-100 -
|
|
51
64
|
100) (default 0.0)
|
|
52
|
-
--temp=float Adjust each generated temperature by this percent (
|
|
65
|
+
--temp=float Adjust each generated temperature by this percent (-100
|
|
53
66
|
- 100) (default 0.0)
|
|
54
67
|
```
|
|
55
68
|
|
|
69
|
+
## Roads and the heuristic
|
|
70
|
+
Roads can be generated by providing a positive integer to the `roads=` argument. Roads are randomly seeded to begin
|
|
71
|
+
and start at an axis (but not the same axis).
|
|
72
|
+
|
|
73
|
+
A* pathfinding is used to generate the roads with a heuristic that uses manhattan distance, favours existing roads and similar elevations in adjacent tiles.
|
|
74
|
+
|
|
75
|
+
Roads can be configured to include/exclude generating paths thorugh water, mountains and flora.
|
|
76
|
+
|
|
77
|
+
Tiles containing roads are of type `road`, those without are of type `terrain`.
|
|
78
|
+
|
|
79
|
+
The `--roads_to_make` option allows you to specify multiple pairs of coordinates to attempt to build paths, subject to the heuristic and other option constraints. Expects a a single list, but must be sets of 4, example of two roads: `--roads_to_make=0,0,50,50,0,0,75,75`
|
|
80
|
+
|
|
56
81
|
# Generate without rendering
|
|
57
82
|
|
|
58
|
-
```
|
|
83
|
+
```irb
|
|
59
84
|
irb(main):001:0> map = Map.new
|
|
60
|
-
|
|
61
|
-
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Map can then be manipulated via traditional x,y lookup
|
|
88
|
+
```irb
|
|
89
|
+
map[x, y].to_h
|
|
90
|
+
=>
|
|
91
|
+
{:x=>0,
|
|
92
|
+
:y=>1,
|
|
93
|
+
:height=>0.29251394359649563,
|
|
94
|
+
:moist=>0.29100678755603004,
|
|
95
|
+
:temp=>0.6034041566100443,
|
|
96
|
+
:biome=>{:name=>"deep_valley", :flora_range=>1, :colour=>"\e[48;5;47m"},
|
|
97
|
+
:items=>[]}
|
|
98
|
+
```
|
|
99
|
+
or the less intuitative multidimensional lookup (reversed axis):
|
|
100
|
+
|
|
101
|
+
```irb
|
|
102
|
+
map.tiles[y][x].to_h
|
|
62
103
|
=>
|
|
63
104
|
{:x=>0,
|
|
64
105
|
:y=>1,
|
|
@@ -69,6 +110,20 @@ irb(main):002:0> map.describe[1][0]
|
|
|
69
110
|
:items=>[]}
|
|
70
111
|
```
|
|
71
112
|
|
|
113
|
+
or from the command line:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
$ ruby-perlin-2D-map-generator describe coordinates=0,1
|
|
117
|
+
|
|
118
|
+
{:x=>0,
|
|
119
|
+
:y=>1,
|
|
120
|
+
:height=>0.29251394359649563,
|
|
121
|
+
:moist=>0.29100678755603004,
|
|
122
|
+
:temp=>0.6034041566100443,
|
|
123
|
+
:biome=>{:name=>"deep_valley", :flora_range=>1, :colour=>"\e[48;5;47m"},
|
|
124
|
+
:items=>[]}
|
|
125
|
+
```
|
|
126
|
+
|
|
72
127
|
# Full Command line Usage
|
|
73
128
|
```bash
|
|
74
129
|
$ ruby-perlin-2D-map-generator --help
|
|
@@ -76,50 +131,80 @@ $ ruby-perlin-2D-map-generator --help
|
|
|
76
131
|
```bash
|
|
77
132
|
Usage: ruby-perlin-2D-map-generator [OPTIONS] (DESCRIBE | RENDER)
|
|
78
133
|
|
|
79
|
-
Generate a seeded customizable procedurally generated 2D map.
|
|
134
|
+
Generate a seeded customizable procedurally generated 2D map with optional roads.
|
|
80
135
|
Rendered in the console using ansi colours, or described as a 2D array of
|
|
81
136
|
hashes with each tiles information.
|
|
82
137
|
|
|
83
138
|
Arguments:
|
|
84
139
|
(DESCRIBE | RENDER) command to run: render prints the map to standard
|
|
85
|
-
output using ansi colors
|
|
86
|
-
|
|
140
|
+
output using ansi colors. describe prints each tiles
|
|
141
|
+
bionome information in the map, can be combined with the
|
|
142
|
+
coordinates keyword to print a specific tile.
|
|
143
|
+
(permitted: describe, render)
|
|
144
|
+
|
|
145
|
+
Keywords:
|
|
146
|
+
COORDINATES=INT_LIST Used with the describe command, only returns the given
|
|
147
|
+
coordinate tile details
|
|
87
148
|
|
|
88
149
|
Options:
|
|
89
|
-
--elevation=float
|
|
90
|
-
|
|
91
|
-
--fhx=float
|
|
92
|
-
|
|
93
|
-
--fhy=float
|
|
94
|
-
|
|
95
|
-
--fmx=float
|
|
96
|
-
|
|
97
|
-
--fmy=float
|
|
98
|
-
|
|
99
|
-
--ftx=float
|
|
100
|
-
|
|
101
|
-
--fty=float
|
|
102
|
-
|
|
103
|
-
--gf=bool
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
--
|
|
109
|
-
|
|
110
|
-
--
|
|
111
|
-
|
|
112
|
-
--
|
|
113
|
-
|
|
114
|
-
--
|
|
115
|
-
|
|
116
|
-
--
|
|
117
|
-
|
|
118
|
-
--
|
|
119
|
-
|
|
120
|
-
--
|
|
121
|
-
|
|
122
|
-
--
|
|
150
|
+
--elevation=float Adjust each generated elevation by
|
|
151
|
+
this percent (-100 - 100) (default 0.0)
|
|
152
|
+
--fhx=float The frequency for height generation
|
|
153
|
+
across the x-axis (default 2.5)
|
|
154
|
+
--fhy=float The frequency for height generation
|
|
155
|
+
across the y-axis (default 2.5)
|
|
156
|
+
--fmx=float The frequency for moist generation
|
|
157
|
+
across the x-axis (default 2.5)
|
|
158
|
+
--fmy=float The frequency for moist generation
|
|
159
|
+
across the y-axis (default 2.5)
|
|
160
|
+
--ftx=float The frequency for temp generation
|
|
161
|
+
across the x-axis (default 2.5)
|
|
162
|
+
--fty=float The frequency for temp generation
|
|
163
|
+
across the y-axis (default 2.5)
|
|
164
|
+
--gf=bool Generate flora, significantly affects
|
|
165
|
+
performance
|
|
166
|
+
--height=int The height of the generated map
|
|
167
|
+
(default 128)
|
|
168
|
+
-h, --help Print usage
|
|
169
|
+
--hs=int The seed for a terrains height perlin
|
|
170
|
+
generation (default 10)
|
|
171
|
+
--moisture=float Adjust each generated moisture by
|
|
172
|
+
this percent (-100 - 100) (default 0.0)
|
|
173
|
+
--ms=int The seed for a terrains moist perlin
|
|
174
|
+
generation (default 300)
|
|
175
|
+
--oh=int Octaves for height generation
|
|
176
|
+
(default 3)
|
|
177
|
+
--om=int Octaves for moist generation (default
|
|
178
|
+
3)
|
|
179
|
+
--ot=int Octaves for temp generation (default
|
|
180
|
+
3)
|
|
181
|
+
--ph=float Persistance for height generation
|
|
182
|
+
(default 1.0)
|
|
183
|
+
--pm=float Persistance for moist generation
|
|
184
|
+
(default 1.0)
|
|
185
|
+
--pt=float Persistance for temp generation
|
|
186
|
+
(default 1.0)
|
|
187
|
+
--road_exclude_flora_path=bool Controls if roads will run tiles
|
|
188
|
+
containing flora
|
|
189
|
+
--road_exclude_mountain_path=bool Controls if roads will run through
|
|
190
|
+
high mountains
|
|
191
|
+
--road_exclude_water_path=bool Controls if roads will run through
|
|
192
|
+
water
|
|
193
|
+
--roads=int Add this many roads through the map,
|
|
194
|
+
starting and ending at edges (default
|
|
195
|
+
0)
|
|
196
|
+
--roads_to_make ints Attempt to create a road from a start
|
|
197
|
+
and end point (4 integers), can be
|
|
198
|
+
supplied multiple paths
|
|
199
|
+
(default [])
|
|
200
|
+
--rs=int The seed for generating roads
|
|
201
|
+
(default 100)
|
|
202
|
+
--temp=float Adjust each generated temperature by
|
|
203
|
+
this percent (-100 - 100) (default 0.0)
|
|
204
|
+
--ts=int The seed for a terrains temperature
|
|
205
|
+
perlin generation (default 3000)
|
|
206
|
+
--width=int The width of the generated map
|
|
207
|
+
(default 128)
|
|
123
208
|
|
|
124
209
|
Examples:
|
|
125
210
|
Render with defaults
|
|
@@ -127,4 +212,10 @@ Examples:
|
|
|
127
212
|
|
|
128
213
|
Render with options
|
|
129
214
|
$ ruby-perlin-2D-map-generator render --elevation=-40 --moisture=25 --hs=1
|
|
215
|
+
|
|
216
|
+
Render with roads
|
|
217
|
+
$ ruby-perlin-2D-map-generator render --roads=2
|
|
218
|
+
|
|
219
|
+
Describe tile [1, 1]
|
|
220
|
+
$ ruby-perlin-2D-map-generator describe coordinates=1,1
|
|
130
221
|
```
|
data/lib/CLI/command.rb
CHANGED
|
@@ -12,7 +12,7 @@ module CLI
|
|
|
12
12
|
|
|
13
13
|
no_command
|
|
14
14
|
|
|
15
|
-
desc 'Generate a seeded customizable procedurally generated 2D map. Rendered in the console ' \
|
|
15
|
+
desc 'Generate a seeded customizable procedurally generated 2D map with optional roads. Rendered in the console ' \
|
|
16
16
|
' using ansi colours, or described as a 2D array of hashes with each tiles information.'
|
|
17
17
|
|
|
18
18
|
example 'Render with defaults',
|
|
@@ -20,14 +20,37 @@ module CLI
|
|
|
20
20
|
|
|
21
21
|
example 'Render with options',
|
|
22
22
|
' $ ruby-perlin-2D-map-generator render --elevation=-40 --moisture=25 --hs=1'
|
|
23
|
+
|
|
24
|
+
example 'Render with roads',
|
|
25
|
+
' $ ruby-perlin-2D-map-generator render --roads=2'
|
|
26
|
+
|
|
27
|
+
example 'Describe tile [1, 1]',
|
|
28
|
+
' $ ruby-perlin-2D-map-generator describe coordinates=1,1'
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
argument :command do
|
|
26
32
|
name '(describe | render)'
|
|
27
33
|
arity one
|
|
28
|
-
|
|
29
|
-
desc 'command to run: render prints the map to standard output using ansi colors
|
|
30
|
-
'
|
|
34
|
+
permit %w[describe render]
|
|
35
|
+
desc 'command to run: render prints the map to standard output using ansi colors. ' \
|
|
36
|
+
'describe prints each tiles bionome information in the map, can be combined with ' \
|
|
37
|
+
'the coordinates keyword to print a specific tile.'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
keyword :coordinates do
|
|
41
|
+
arity one
|
|
42
|
+
convert :int_list
|
|
43
|
+
validate ->(v) { v >= 0 }
|
|
44
|
+
desc 'Used with the describe command, only returns the given coordinate tile details'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
option :roads_to_make do
|
|
48
|
+
arity one
|
|
49
|
+
long '--roads_to_make ints'
|
|
50
|
+
convert :int_list
|
|
51
|
+
validate ->(v) { v >= 0 }
|
|
52
|
+
desc 'Attempt to create a road from a start and end point (4 integers), can be supplied multiple paths'
|
|
53
|
+
default MapConfig::DEFAULT_ROADS_TO_MAKE
|
|
31
54
|
end
|
|
32
55
|
|
|
33
56
|
option :height_seed do
|
|
@@ -199,7 +222,7 @@ module CLI
|
|
|
199
222
|
long '--temp float'
|
|
200
223
|
long '--temp=float'
|
|
201
224
|
|
|
202
|
-
desc 'Adjust each generated temperature by this percent (
|
|
225
|
+
desc 'Adjust each generated temperature by this percent (-100 - 100)'
|
|
203
226
|
convert ->(val) { val.to_f / 100.0 }
|
|
204
227
|
validate ->(val) { val >= -1.0 && val <= 1.0 }
|
|
205
228
|
default MapConfig::DEFAULT_TEMP_ADJUSTMENT
|
|
@@ -209,7 +232,7 @@ module CLI
|
|
|
209
232
|
long '--elevation float'
|
|
210
233
|
long '--elevation=float'
|
|
211
234
|
|
|
212
|
-
desc 'Adjust each generated elevation by this percent (
|
|
235
|
+
desc 'Adjust each generated elevation by this percent (-100 - 100)'
|
|
213
236
|
convert ->(val) { val.to_f / 100.0 }
|
|
214
237
|
validate ->(val) { val >= -1.0 && val <= 1.0 }
|
|
215
238
|
default MapConfig::DEFAULT_HEIGHT_ADJUSTMENT
|
|
@@ -219,12 +242,58 @@ module CLI
|
|
|
219
242
|
long '--moisture float'
|
|
220
243
|
long '--moisture=float'
|
|
221
244
|
|
|
222
|
-
desc 'Adjust each generated moisture by this percent (
|
|
245
|
+
desc 'Adjust each generated moisture by this percent (-100 - 100)'
|
|
223
246
|
convert ->(val) { val.to_f / 100.0 }
|
|
224
247
|
validate ->(val) { val >= -1.0 && val <= 1.0 }
|
|
225
248
|
default MapConfig::DEFAULT_MOIST_ADJUSTMENT
|
|
226
249
|
end
|
|
227
250
|
|
|
251
|
+
option :roads do
|
|
252
|
+
long '--roads int'
|
|
253
|
+
long '--roads=int'
|
|
254
|
+
|
|
255
|
+
desc 'Add this many roads through the map, starting and ending at edges'
|
|
256
|
+
convert Integer
|
|
257
|
+
validate ->(val) { val >= 0 }
|
|
258
|
+
default MapConfig::DEFAULT_NUM_OF_ROADS
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
option :road_seed do
|
|
262
|
+
long '--rs int'
|
|
263
|
+
long '--rs=int'
|
|
264
|
+
|
|
265
|
+
desc 'The seed for generating roads'
|
|
266
|
+
convert Integer
|
|
267
|
+
default MapConfig::DEFAULT_ROAD_SEED
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
option :road_exclude_water_path do
|
|
271
|
+
long '--road_exclude_water_path bool'
|
|
272
|
+
long '--road_exclude_water_path=bool'
|
|
273
|
+
|
|
274
|
+
desc 'Controls if roads will run through water'
|
|
275
|
+
convert :bool
|
|
276
|
+
default MapConfig::DEFAULT_ROAD_EXCLUDE_WATER_PATH
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
option :road_exclude_mountain_path do
|
|
280
|
+
long '--road_exclude_mountain_path bool'
|
|
281
|
+
long '--road_exclude_mountain_path=bool'
|
|
282
|
+
|
|
283
|
+
desc 'Controls if roads will run through high mountains'
|
|
284
|
+
convert :bool
|
|
285
|
+
default MapConfig::DEFAULT_ROAD_EXCLUDE_MOUNTAIN_PATH
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
option :road_exclude_flora_path do
|
|
289
|
+
long '--road_exclude_flora_path bool'
|
|
290
|
+
long '--road_exclude_flora_path=bool'
|
|
291
|
+
|
|
292
|
+
desc 'Controls if roads will run tiles containing flora'
|
|
293
|
+
convert :bool
|
|
294
|
+
default MapConfig::DEFAULT_ROAD_EXCLUDE_FLORA_PATH
|
|
295
|
+
end
|
|
296
|
+
|
|
228
297
|
flag :help do
|
|
229
298
|
short '-h'
|
|
230
299
|
long '--help'
|
|
@@ -248,14 +317,13 @@ module CLI
|
|
|
248
317
|
map = Map.new(map_config: MapConfig.new(
|
|
249
318
|
width: params[:width],
|
|
250
319
|
height: params[:height],
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
generate_flora: params[:generate_flora]
|
|
320
|
+
all_perlin_configs: MapConfig::AllPerlinConfigs.new(perlin_height_config, perlin_moist_config, perlin_temp_config),
|
|
321
|
+
generate_flora: params[:generate_flora],
|
|
322
|
+
road_config: MapConfig::RoadConfig.new(*params.to_h.slice(:road_seed, :roads, :road_exclude_water_path, :road_exclude_mountain_path, :road_exclude_flora_path, :roads_to_make).values)
|
|
255
323
|
))
|
|
256
324
|
case params[:command]
|
|
257
325
|
when 'render' then map.render
|
|
258
|
-
when 'describe' then puts map.describe
|
|
326
|
+
when 'describe' then puts(!params[:coordinates].nil? ? map[params[:coordinates][0], params[:coordinates][1]].to_h : map.describe)
|
|
259
327
|
end
|
|
260
328
|
end
|
|
261
329
|
|
data/lib/ansi_colours.rb
CHANGED
data/lib/biome.rb
CHANGED
|
@@ -32,6 +32,10 @@ class Biome
|
|
|
32
32
|
TAIGA_TERRAIN.include?(self)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
def high_mountain?
|
|
36
|
+
HIGH_MOUNTAIN.include?(self)
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
def flora_available
|
|
36
40
|
!flora_range.nil?
|
|
37
41
|
end
|
|
@@ -132,6 +136,12 @@ class Biome
|
|
|
132
136
|
TAIGA_COAST
|
|
133
137
|
].freeze
|
|
134
138
|
|
|
139
|
+
HIGH_MOUNTAIN = [
|
|
140
|
+
SNOW,
|
|
141
|
+
ROCKS,
|
|
142
|
+
MOUNTAIN
|
|
143
|
+
].freeze
|
|
144
|
+
|
|
135
145
|
LAND_TERRAIN = (ALL_TERRAIN - WATER_TERRAIN).freeze
|
|
136
146
|
|
|
137
147
|
class << self
|
data/lib/map.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'map_tile_generator'
|
|
4
4
|
require 'map_config'
|
|
5
|
+
require 'road_generator'
|
|
5
6
|
|
|
6
7
|
class Map
|
|
7
8
|
attr_reader :config
|
|
@@ -21,7 +22,27 @@ class Map
|
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
# rubocop:disable Naming/MethodParameterName:
|
|
26
|
+
def [](x, y)
|
|
27
|
+
raise ArgumentError, 'coordinates out of bounds' if y.nil? || y >= tiles.size || x.nil? || x >= tiles[y].size
|
|
28
|
+
|
|
29
|
+
tiles[y][x]
|
|
30
|
+
end
|
|
31
|
+
# rubocop:enable Naming/MethodParameterName:
|
|
32
|
+
|
|
24
33
|
def tiles
|
|
25
|
-
@tiles
|
|
34
|
+
return @tiles if @tiles
|
|
35
|
+
|
|
36
|
+
@tiles = generate_tiles
|
|
37
|
+
road_generator = RoadGenerator.new(@tiles)
|
|
38
|
+
road_generator.generate_num_of_random_roads(config.road_config)
|
|
39
|
+
road_generator.generate_roads_from_coordinate_list(config.road_config.roads_to_make)
|
|
40
|
+
@tiles
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def generate_tiles
|
|
46
|
+
MapTileGenerator.new(map: self).generate
|
|
26
47
|
end
|
|
27
48
|
end
|
data/lib/map_config.rb
CHANGED
|
@@ -25,25 +25,43 @@ class MapConfig
|
|
|
25
25
|
DEFAULT_TEMP_X_FREQUENCY = 2.5
|
|
26
26
|
DEFAULT_TEMP_ADJUSTMENT = 0.0
|
|
27
27
|
|
|
28
|
+
DEFAULT_ROAD_SEED = 100
|
|
29
|
+
DEFAULT_NUM_OF_ROADS = 0
|
|
30
|
+
DEFAULT_ROAD_EXCLUDE_WATER_PATH = true
|
|
31
|
+
DEFAULT_ROAD_EXCLUDE_MOUNTAIN_PATH = true
|
|
32
|
+
DEFAULT_ROAD_EXCLUDE_FLORA_PATH = true
|
|
33
|
+
DEFAULT_ROADS_TO_MAKE = [].freeze
|
|
34
|
+
|
|
28
35
|
PERLIN_CONFIG_OPTIONS = %i[width height noise_seed octaves x_frequency y_frequency persistance adjustment].freeze
|
|
29
|
-
|
|
36
|
+
ALL_PERLIN_CONFIGS = %i[perlin_height_config perlin_moist_config perlin_temp_config].freeze
|
|
37
|
+
ROAD_CONFIG_OPTIONS = %i[road_seed roads road_exclude_water_path road_exclude_mountain_path road_exclude_flora_path roads_to_make].freeze
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
PerlinConfig = Struct.new(*PERLIN_CONFIG_OPTIONS)
|
|
40
|
+
AllPerlinConfigs = Struct.new(*ALL_PERLIN_CONFIGS)
|
|
41
|
+
RoadConfig = Struct.new(*ROAD_CONFIG_OPTIONS)
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
height: DEFAULT_TILE_COUNT, generate_flora: DEFAULT_GENERATE_FLORA)
|
|
35
|
-
raise ArgumentError unless perlin_height_config.is_a?(PerlinConfig) && perlin_moist_config.is_a?(PerlinConfig)
|
|
43
|
+
attr_reader :generate_flora, :perlin_height_config, :perlin_moist_config, :perlin_temp_config, :width, :height, :road_config
|
|
36
44
|
|
|
45
|
+
def initialize(all_perlin_configs: default_perlin_configs, width: DEFAULT_TILE_COUNT,
|
|
46
|
+
height: DEFAULT_TILE_COUNT, generate_flora: DEFAULT_GENERATE_FLORA, road_config: default_road_config)
|
|
47
|
+
validate(all_perlin_configs)
|
|
37
48
|
@generate_flora = generate_flora
|
|
38
|
-
@perlin_height_config = perlin_height_config
|
|
39
|
-
@perlin_moist_config = perlin_moist_config
|
|
40
|
-
@perlin_temp_config = perlin_temp_config
|
|
49
|
+
@perlin_height_config = all_perlin_configs.perlin_height_config
|
|
50
|
+
@perlin_moist_config = all_perlin_configs.perlin_moist_config
|
|
51
|
+
@perlin_temp_config = all_perlin_configs.perlin_temp_config
|
|
41
52
|
@width = width
|
|
42
53
|
@height = height
|
|
54
|
+
@road_config = road_config
|
|
43
55
|
end
|
|
44
56
|
|
|
45
57
|
private
|
|
46
58
|
|
|
59
|
+
def validate(all_perlin_configs)
|
|
60
|
+
unless all_perlin_configs.perlin_height_config.is_a?(PerlinConfig) && all_perlin_configs.perlin_moist_config.is_a?(PerlinConfig) && all_perlin_configs.perlin_temp_config.is_a?(PerlinConfig)
|
|
61
|
+
raise ArgumentError
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
47
65
|
def default_perlin_height_config
|
|
48
66
|
PerlinConfig.new(DEFAULT_TILE_COUNT, DEFAULT_TILE_COUNT, DEFAULT_HEIGHT_SEED, DEFAULT_HEIGHT_OCTAVES,
|
|
49
67
|
DEFAULT_HEIGHT_X_FREQUENCY, DEFAULT_HEIGHT_Y_FREQUENCY, DEFAULT_HEIGHT_PERSISTANCE, DEFAULT_HEIGHT_ADJUSTMENT)
|
|
@@ -58,4 +76,12 @@ class MapConfig
|
|
|
58
76
|
PerlinConfig.new(DEFAULT_TILE_COUNT, DEFAULT_TILE_COUNT, DEFAULT_TEMP_SEED, DEFAULT_TEMP_OCTAVES,
|
|
59
77
|
DEFAULT_TEMP_X_FREQUENCY, DEFAULT_TEMP_Y_FREQUENCY, DEFAULT_TEMP_PERSISTANCE, DEFAULT_TEMP_ADJUSTMENT)
|
|
60
78
|
end
|
|
79
|
+
|
|
80
|
+
def default_road_config
|
|
81
|
+
RoadConfig.new(DEFAULT_ROAD_SEED, DEFAULT_NUM_OF_ROADS, DEFAULT_ROAD_EXCLUDE_WATER_PATH, DEFAULT_ROAD_EXCLUDE_MOUNTAIN_PATH, DEFAULT_ROAD_EXCLUDE_FLORA_PATH, DEFAULT_ROADS_TO_MAKE)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def default_perlin_configs
|
|
85
|
+
AllPerlinConfigs.new(default_perlin_height_config, default_perlin_moist_config, default_perlin_temp_config)
|
|
86
|
+
end
|
|
61
87
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pathfinding
|
|
4
|
+
#
|
|
5
|
+
# An A* Pathfinder to build roads/paths between two coordinates containing
|
|
6
|
+
# different path costs, the heuristic behaviour that can be altered via configuration
|
|
7
|
+
#
|
|
8
|
+
class AStarFinder
|
|
9
|
+
def find_path(start_node, end_node, grid)
|
|
10
|
+
open_set = [start_node]
|
|
11
|
+
came_from = {}
|
|
12
|
+
g_score = { start_node => 0 }
|
|
13
|
+
f_score = { start_node => heuristic_cost_estimate(start_node, end_node) }
|
|
14
|
+
|
|
15
|
+
until open_set.empty?
|
|
16
|
+
current_node = open_set.min_by { |node| f_score[node] }
|
|
17
|
+
|
|
18
|
+
return reconstruct_path(came_from, current_node) if current_node == end_node
|
|
19
|
+
|
|
20
|
+
open_set.delete(current_node)
|
|
21
|
+
|
|
22
|
+
grid.neighbors(current_node).each do |neighbor|
|
|
23
|
+
tentative_g_score = g_score[current_node] + 1
|
|
24
|
+
|
|
25
|
+
next unless !g_score[neighbor] || tentative_g_score < g_score[neighbor]
|
|
26
|
+
|
|
27
|
+
came_from[neighbor] = current_node
|
|
28
|
+
g_score[neighbor] = tentative_g_score
|
|
29
|
+
f_score[neighbor] = g_score[neighbor] + heuristic_cost_estimate(neighbor, end_node)
|
|
30
|
+
|
|
31
|
+
open_set << neighbor unless open_set.include?(neighbor)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# No path found
|
|
36
|
+
[]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def heuristic_cost_estimate(node, end_node)
|
|
42
|
+
(node.x - end_node.x).abs +
|
|
43
|
+
(node.y - end_node.y).abs +
|
|
44
|
+
(node.path_heuristic - end_node.path_heuristic) + # elevation for natural roads
|
|
45
|
+
(node.road? ? 0 : 5) # share existing roads
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reconstruct_path(came_from, current_node)
|
|
49
|
+
path = [current_node]
|
|
50
|
+
while came_from[current_node]
|
|
51
|
+
current_node = came_from[current_node]
|
|
52
|
+
path.unshift(current_node)
|
|
53
|
+
end
|
|
54
|
+
path
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pathfinding
|
|
4
|
+
#
|
|
5
|
+
# Responsible for manipulating and encapsulating behaviour of tiles related
|
|
6
|
+
# to pathfinding
|
|
7
|
+
#
|
|
8
|
+
class Grid
|
|
9
|
+
attr_reader :nodes
|
|
10
|
+
|
|
11
|
+
def initialize(nodes)
|
|
12
|
+
@nodes = nodes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# rubocop:disable Naming/MethodParameterName:
|
|
16
|
+
def node(x, y)
|
|
17
|
+
nodes[y][x]
|
|
18
|
+
end
|
|
19
|
+
# rubocop:enable Naming/MethodParameterName:
|
|
20
|
+
|
|
21
|
+
def neighbors(node)
|
|
22
|
+
neighbors = []
|
|
23
|
+
return neighbors unless node.can_contain_road?
|
|
24
|
+
|
|
25
|
+
x = node.x
|
|
26
|
+
y = node.y
|
|
27
|
+
|
|
28
|
+
node_lookup = node(x - 1, y) if x.positive?
|
|
29
|
+
neighbors << node_lookup if !node_lookup.nil? && node_lookup.can_contain_road?
|
|
30
|
+
node_lookup = node(x + 1, y) if x < @nodes[0].size - 1
|
|
31
|
+
neighbors << node_lookup if !node_lookup.nil? && node_lookup.can_contain_road?
|
|
32
|
+
node_lookup = node(x, y - 1) if y.positive?
|
|
33
|
+
neighbors << node_lookup if !node_lookup.nil? && node_lookup.can_contain_road?
|
|
34
|
+
node_lookup = node(x, y + 1) if y < @nodes.size - 1
|
|
35
|
+
neighbors << node_lookup if !node_lookup.nil? && node_lookup.can_contain_road?
|
|
36
|
+
|
|
37
|
+
neighbors
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def min_max_coordinates
|
|
41
|
+
@min_max_coordinates ||= begin
|
|
42
|
+
min_x = nil
|
|
43
|
+
min_y = nil
|
|
44
|
+
max_x = nil
|
|
45
|
+
max_y = nil
|
|
46
|
+
|
|
47
|
+
@nodes.each do |row|
|
|
48
|
+
row.each do |object|
|
|
49
|
+
x = object.x
|
|
50
|
+
y = object.y
|
|
51
|
+
|
|
52
|
+
# Update minimum x and y values
|
|
53
|
+
min_x = x if min_x.nil? || x < min_x
|
|
54
|
+
min_y = y if min_y.nil? || y < min_y
|
|
55
|
+
|
|
56
|
+
# Update maximum x and y values
|
|
57
|
+
max_x = x if max_x.nil? || x > max_x
|
|
58
|
+
max_y = y if max_y.nil? || y > max_y
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
{ min_x: min_x, min_y: min_y, max_x: max_x, max_y: max_y }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def edge_nodes
|
|
67
|
+
@edge_nodes ||=
|
|
68
|
+
@nodes.map do |row|
|
|
69
|
+
row.select do |obj|
|
|
70
|
+
obj.x == min_max_coordinates[:min_x] ||
|
|
71
|
+
obj.x == min_max_coordinates[:max_x] ||
|
|
72
|
+
obj.y == min_max_coordinates[:min_y] ||
|
|
73
|
+
obj.y == min_max_coordinates[:max_y]
|
|
74
|
+
end
|
|
75
|
+
end.flatten
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pathfinding/grid'
|
|
4
|
+
require 'pathfinding/a_star_finder'
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Generates roads across map tiles, randomly or given specific coordinates
|
|
8
|
+
#
|
|
9
|
+
class RoadGenerator
|
|
10
|
+
attr_reader :grid, :finder
|
|
11
|
+
|
|
12
|
+
def initialize(tiles)
|
|
13
|
+
@grid = Pathfinding::Grid.new(tiles)
|
|
14
|
+
@finder = Pathfinding::AStarFinder.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def generate_num_of_random_roads(config)
|
|
18
|
+
return if config.roads <= 0
|
|
19
|
+
|
|
20
|
+
seed = config.road_seed
|
|
21
|
+
(1..config.roads).each do |n|
|
|
22
|
+
random_objects_at_edges = random_nodes_not_on_same_edge(seed + n) # add n otherwise each road is the same
|
|
23
|
+
generate_path(
|
|
24
|
+
random_objects_at_edges[0].x,
|
|
25
|
+
random_objects_at_edges[0].y,
|
|
26
|
+
random_objects_at_edges[1].x,
|
|
27
|
+
random_objects_at_edges[1].y
|
|
28
|
+
).each(&:make_road)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def generate_roads_from_coordinate_list(road_paths)
|
|
33
|
+
road_paths.each_slice(4) do |road_coordinates|
|
|
34
|
+
generate_path(
|
|
35
|
+
road_coordinates[0],
|
|
36
|
+
road_coordinates[1],
|
|
37
|
+
road_coordinates[2],
|
|
38
|
+
road_coordinates[3]
|
|
39
|
+
).each(&:make_road)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def generate_path(start_x, start_y, end_x, end_y)
|
|
44
|
+
start_node = grid.node(start_x, start_y)
|
|
45
|
+
end_node = grid.node(end_x, end_y)
|
|
46
|
+
finder.find_path(start_node, end_node, grid)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def random_nodes_not_on_same_edge(seed)
|
|
52
|
+
random_generator = Random.new(seed)
|
|
53
|
+
length = @grid.edge_nodes.length
|
|
54
|
+
|
|
55
|
+
loop do
|
|
56
|
+
index1 = random_generator.rand(length)
|
|
57
|
+
index2 = random_generator.rand(length)
|
|
58
|
+
node_one, node_two = @grid.edge_nodes.values_at(index1, index2)
|
|
59
|
+
|
|
60
|
+
return [node_one, node_two] if node_one.x != node_two.x && node_one.y != node_two.y
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/tile.rb
CHANGED
|
@@ -2,17 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
require 'biome'
|
|
4
4
|
require 'flora'
|
|
5
|
+
require 'ansi_colours'
|
|
6
|
+
require 'pry-byebug'
|
|
5
7
|
|
|
6
8
|
class Tile
|
|
7
|
-
attr_reader :x, :y, :height, :moist, :temp, :map
|
|
9
|
+
attr_reader :x, :y, :height, :moist, :temp, :map, :type
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
TYPES = %i[
|
|
12
|
+
terrain
|
|
13
|
+
road
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
def initialize(map:, x:, y:, height: 0, moist: 0, temp: 0, type: :terrain)
|
|
10
17
|
@x = x
|
|
11
18
|
@y = y
|
|
12
19
|
@height = height
|
|
13
20
|
@moist = moist
|
|
14
21
|
@temp = temp
|
|
15
22
|
@map = map
|
|
23
|
+
raise ArgumentError, 'invalid tile type' unless TYPES.include?(type)
|
|
24
|
+
|
|
25
|
+
@type = type
|
|
16
26
|
end
|
|
17
27
|
|
|
18
28
|
def surrounding_tiles(distance = 1)
|
|
@@ -36,7 +46,7 @@ class Tile
|
|
|
36
46
|
end
|
|
37
47
|
|
|
38
48
|
def render_to_standard_output
|
|
39
|
-
print
|
|
49
|
+
print render_color_by_type + (!items.empty? ? item_with_highest_priority.render_symbol : ' ')
|
|
40
50
|
print AnsiColours::Background::ANSI_RESET
|
|
41
51
|
end
|
|
42
52
|
|
|
@@ -50,6 +60,10 @@ class Tile
|
|
|
50
60
|
items.max_by(&:render_priority)
|
|
51
61
|
end
|
|
52
62
|
|
|
63
|
+
def items_contain_flora?
|
|
64
|
+
items.any? { |i| i.is_a?(Flora) }
|
|
65
|
+
end
|
|
66
|
+
|
|
53
67
|
def to_h
|
|
54
68
|
{
|
|
55
69
|
x: x,
|
|
@@ -58,12 +72,56 @@ class Tile
|
|
|
58
72
|
moist: moist,
|
|
59
73
|
temp: temp,
|
|
60
74
|
biome: biome.to_h,
|
|
61
|
-
items: items.map(&:to_h)
|
|
75
|
+
items: items.map(&:to_h),
|
|
76
|
+
type: type
|
|
62
77
|
}
|
|
63
78
|
end
|
|
64
79
|
|
|
80
|
+
def make_road
|
|
81
|
+
@type = :road
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def road?
|
|
85
|
+
@type == :road
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def path_heuristic
|
|
89
|
+
height
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def can_contain_road?
|
|
93
|
+
return true unless biome_is_water_and_is_excluded? || biome_is_high_mountain_and_is_excluded? || tile_contains_flora_and_is_excluded?
|
|
94
|
+
end
|
|
95
|
+
|
|
65
96
|
private
|
|
66
97
|
|
|
98
|
+
def biome_is_water_and_is_excluded?
|
|
99
|
+
biome.water? && map.config.road_config.road_exclude_water_path
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def biome_is_high_mountain_and_is_excluded?
|
|
103
|
+
biome.high_mountain? && map.config.road_config.road_exclude_mountain_path
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def tile_contains_flora_and_is_excluded?
|
|
107
|
+
items_contain_flora? && map.config.road_config.road_exclude_flora_path
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def render_color_by_type
|
|
111
|
+
case type
|
|
112
|
+
when :terrain then biome.colour
|
|
113
|
+
when :road
|
|
114
|
+
case height
|
|
115
|
+
when 0.66..1
|
|
116
|
+
AnsiColours::Background::HIGH_ROAD_BLACK
|
|
117
|
+
when 0.33..0.66
|
|
118
|
+
AnsiColours::Background::ROAD_BLACK
|
|
119
|
+
when 0..0.33
|
|
120
|
+
AnsiColours::Background::LOW_ROAD_BLACK
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
67
125
|
def items_generated_with_flora_if_applicable
|
|
68
126
|
if map.config.generate_flora && biome.flora_available
|
|
69
127
|
range_max_value = map.tiles[(y - biome.flora_range)...(y + biome.flora_range)]&.map do |r|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-perlin-2D-map-generator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler Matthews (matthewstyler)
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-08-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: perlin
|
|
@@ -58,14 +58,28 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 2.0
|
|
61
|
+
version: 2.1.0
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 2.0
|
|
68
|
+
version: 2.1.0
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: pry-byebug
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 3.10.1
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 3.10.1
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: rake
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -86,14 +100,14 @@ dependencies:
|
|
|
86
100
|
requirements:
|
|
87
101
|
- - "~>"
|
|
88
102
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 1.
|
|
103
|
+
version: 1.55.1
|
|
90
104
|
type: :development
|
|
91
105
|
prerelease: false
|
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
107
|
requirements:
|
|
94
108
|
- - "~>"
|
|
95
109
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 1.
|
|
110
|
+
version: 1.55.1
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: simplecov
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,10 +122,10 @@ dependencies:
|
|
|
108
122
|
- - "~>"
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: 0.22.0
|
|
111
|
-
description: A gem that procedurally generates a seeded and customizable 2D map
|
|
112
|
-
perlin noise. Map can be rendered in console using ansi colors
|
|
113
|
-
array of hashes describing each tile and binome.
|
|
114
|
-
--help option for full usage details.
|
|
125
|
+
description: A gem that procedurally generates a seeded and customizable 2D map with
|
|
126
|
+
optional roads using perlin noise. Map can be rendered in console using ansi colors
|
|
127
|
+
or returned as 2D array of hashes describing each tile and binome. Completely customizable,
|
|
128
|
+
use the --help option for full usage details.
|
|
115
129
|
email: matthews.tyl@gmail.com
|
|
116
130
|
executables:
|
|
117
131
|
- ruby-perlin-2D-map-generator
|
|
@@ -128,6 +142,9 @@ files:
|
|
|
128
142
|
- lib/map.rb
|
|
129
143
|
- lib/map_config.rb
|
|
130
144
|
- lib/map_tile_generator.rb
|
|
145
|
+
- lib/pathfinding/a_star_finder.rb
|
|
146
|
+
- lib/pathfinding/grid.rb
|
|
147
|
+
- lib/road_generator.rb
|
|
131
148
|
- lib/tile.rb
|
|
132
149
|
- lib/tile_item.rb
|
|
133
150
|
- lib/tile_perlin_generator.rb
|
|
@@ -155,6 +172,6 @@ requirements: []
|
|
|
155
172
|
rubygems_version: 3.2.3
|
|
156
173
|
signing_key:
|
|
157
174
|
specification_version: 4
|
|
158
|
-
summary: Procedurally generate seeded and customizable 2D maps
|
|
159
|
-
colours or described in a 2D array of hashes
|
|
175
|
+
summary: Procedurally generate seeded and customizable 2D maps with optional roads,
|
|
176
|
+
rendered with ansi colours or described in a 2D array of hashes
|
|
160
177
|
test_files: []
|