ruby-perlin-2D-map-generator 0.0.4 → 0.0.6
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 +104 -40
- data/lib/CLI/command.rb +101 -8
- data/lib/ansi_colours.rb +3 -0
- data/lib/biome.rb +20 -10
- data/lib/building.rb +20 -0
- data/lib/flora_generator.rb +28 -0
- data/lib/map.rb +33 -1
- data/lib/map_config.rb +53 -8
- data/lib/map_tile_generator.rb +1 -0
- data/lib/pathfinding/a_star_finder.rb +70 -0
- data/lib/pathfinding/grid.rb +78 -0
- data/lib/pathfinding/priority_queue.rb +73 -0
- data/lib/poisson_disk_sampling/sample_area.rb +43 -0
- data/lib/poisson_disk_sampling/sampler.rb +108 -0
- data/lib/road_generator.rb +70 -0
- data/lib/tile.rb +80 -16
- data/lib/town_generator.rb +154 -0
- metadata +37 -13
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'poisson_disk_sampling/sampler'
|
4
|
+
require 'poisson_disk_sampling/sample_area'
|
5
|
+
require 'road_generator'
|
6
|
+
require 'map_config'
|
7
|
+
|
8
|
+
#
|
9
|
+
# Generates building tile items using Poisson Disk Sampling for the given tiles
|
10
|
+
# Roads are generated between the buildings and between towns using A* pathfinding
|
11
|
+
#
|
12
|
+
class TownGenerator
|
13
|
+
attr_reader :sample_area, :road_generator
|
14
|
+
|
15
|
+
def initialize(tiles, seed: MapConfig::DEFAULT_TOWN_SEED)
|
16
|
+
@sample_area = PoissonDiskSampling::SampleArea.new(grid: tiles)
|
17
|
+
@road_generator = RoadGenerator.new(tiles)
|
18
|
+
@seed = seed
|
19
|
+
@all_town_points = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_random_towns(config)
|
23
|
+
return if config.towns <= 0
|
24
|
+
|
25
|
+
puts "generating #{config.towns} random towns..." if config.verbose
|
26
|
+
|
27
|
+
@all_town_points.concat(iterate_through_towns(config.towns) do |n|
|
28
|
+
generate_random_town(n, config.verbose)
|
29
|
+
end)
|
30
|
+
|
31
|
+
generate_roads_between_towns(config.verbose)
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_towns_from_coordinate_list(config)
|
35
|
+
return unless (config.towns_to_make.length % 4).zero?
|
36
|
+
|
37
|
+
puts "generating #{config.towns_to_make.length / 4} coordinate towns..." if config.verbose
|
38
|
+
|
39
|
+
@all_town_points.concat(iterate_through_towns((config.towns_to_make.length / 4)) do |n|
|
40
|
+
town_values = config.towns_to_make[(n - 1) * 4..].take(4)
|
41
|
+
generate_town(n, town_values[2], town_values[3], [sample_area[town_values[0], town_values[1]]], config.verbose)
|
42
|
+
end)
|
43
|
+
|
44
|
+
generate_roads_between_towns(config.verbose)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def iterate_through_towns(num_of_towns)
|
50
|
+
(1..num_of_towns).map do |n|
|
51
|
+
town_points = yield n
|
52
|
+
@seed += 1000
|
53
|
+
town_points
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_random_town(town_num, verbose)
|
58
|
+
random_town_gen = Random.new(@seed)
|
59
|
+
generate_town(town_num, random_town_gen.rand(10..40), random_town_gen.rand(2..4), nil, verbose)
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_town(town_num, num_of_points, radius, initial_coords, verbose)
|
63
|
+
puts "generating town #{town_num}..." if verbose
|
64
|
+
|
65
|
+
points = generate_points_for_town(num_of_points, radius, initial_coords)
|
66
|
+
generate_town_roads(points, town_num, verbose)
|
67
|
+
points
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_points_for_town(num_of_points, radius, intial_coordinates)
|
71
|
+
points =
|
72
|
+
PoissonDiskSampling::Sampler.new(
|
73
|
+
sample_area: sample_area,
|
74
|
+
seed: @seed
|
75
|
+
).generate_points(num_of_points, radius, intial_coordinates)
|
76
|
+
points.each do |point|
|
77
|
+
@seed += 1
|
78
|
+
point.add_town_item(@seed)
|
79
|
+
end
|
80
|
+
points
|
81
|
+
end
|
82
|
+
|
83
|
+
def generate_town_roads(points, town_num, verbose)
|
84
|
+
# TODO: slow, bad (complete graph) will update to use minimum tree spanning algorithm instead
|
85
|
+
puts "generating town #{town_num} roads..." if verbose
|
86
|
+
|
87
|
+
connected_pairs = Set.new
|
88
|
+
points.each_with_index do |point_one, idx_one|
|
89
|
+
points[idx_one + 1..].each do |point_two|
|
90
|
+
next if connected_pairs.include?([point_one, point_two]) || connected_pairs.include?([point_two, point_one])
|
91
|
+
|
92
|
+
road_to_building_one = place_in_front_or_behind(point_one)
|
93
|
+
road_to_building_two = place_in_front_or_behind(point_two)
|
94
|
+
|
95
|
+
connected_pairs.add([point_one, point_two])
|
96
|
+
connected_pairs.add([point_two, point_one])
|
97
|
+
|
98
|
+
next if road_to_building_one.nil? || road_to_building_two.nil?
|
99
|
+
|
100
|
+
road_generator.generate_roads_from_coordinate_list(road_to_building_one.concat(road_to_building_two), false)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def place_in_front_or_behind(point)
|
106
|
+
return [point.x, point.y - 1] if sample_area.point_within_bounds_and_can_have_road?(point.x, point.y - 1)
|
107
|
+
return [point.x, point.y + 1] if sample_area.point_within_bounds_and_can_have_road?(point.x, point.y + 1)
|
108
|
+
return [point.x - 1, point.y] if sample_area.point_within_bounds_and_can_have_road?(point.x - 1, point.y)
|
109
|
+
return [point.x + 1, point.y] if sample_area.point_within_bounds_and_can_have_road?(point.x + 1, point.y)
|
110
|
+
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
114
|
+
def generate_roads_between_towns(verbose)
|
115
|
+
return if @all_town_points.length < 2
|
116
|
+
|
117
|
+
puts 'generating roads between towns...' if verbose
|
118
|
+
|
119
|
+
connected_pairs = Set.new
|
120
|
+
town_centroids = {}
|
121
|
+
|
122
|
+
@all_town_points.each_with_index do |town_one, idx_one|
|
123
|
+
find_town_centroid(town_one)
|
124
|
+
|
125
|
+
@all_town_points[idx_one + 1..].each do |town_two|
|
126
|
+
next if connected_pairs.include?([town_one, town_two]) || connected_pairs.include?([town_two, town_one])
|
127
|
+
|
128
|
+
town_one_center_x, town_one_center_y = (town_centroids[town_one] ||= find_town_centroid(town_one))
|
129
|
+
town_two_center_x, town_two_center_y = (town_centroids[town_two] ||= find_town_centroid(town_two))
|
130
|
+
|
131
|
+
road_generator.generate_roads_from_coordinate_list([town_one_center_x, town_one_center_y, town_two_center_x, town_two_center_y], false)
|
132
|
+
|
133
|
+
connected_pairs.add([town_one, town_two])
|
134
|
+
connected_pairs.add([town_two, town_one])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def find_town_centroid(points)
|
140
|
+
total_x = 0
|
141
|
+
total_y = 0
|
142
|
+
num_coordinates = points.length
|
143
|
+
|
144
|
+
points.each do |point|
|
145
|
+
total_x += point.x
|
146
|
+
total_y += point.y
|
147
|
+
end
|
148
|
+
|
149
|
+
average_x = total_x / num_coordinates.to_f
|
150
|
+
average_y = total_y / num_coordinates.to_f
|
151
|
+
|
152
|
+
[average_x, average_y]
|
153
|
+
end
|
154
|
+
end
|
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.6
|
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-15 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.56.0
|
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.56.0
|
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
|
@@ -124,20 +138,30 @@ files:
|
|
124
138
|
- lib/CLI/command.rb
|
125
139
|
- lib/ansi_colours.rb
|
126
140
|
- lib/biome.rb
|
141
|
+
- lib/building.rb
|
127
142
|
- lib/flora.rb
|
143
|
+
- lib/flora_generator.rb
|
128
144
|
- lib/map.rb
|
129
145
|
- lib/map_config.rb
|
130
146
|
- lib/map_tile_generator.rb
|
147
|
+
- lib/pathfinding/a_star_finder.rb
|
148
|
+
- lib/pathfinding/grid.rb
|
149
|
+
- lib/pathfinding/priority_queue.rb
|
150
|
+
- lib/poisson_disk_sampling/sample_area.rb
|
151
|
+
- lib/poisson_disk_sampling/sampler.rb
|
152
|
+
- lib/road_generator.rb
|
131
153
|
- lib/tile.rb
|
132
154
|
- lib/tile_item.rb
|
133
155
|
- lib/tile_perlin_generator.rb
|
156
|
+
- lib/town_generator.rb
|
134
157
|
homepage: https://github.com/matthewstyler/ruby-perlin-2D-map-generator
|
135
158
|
licenses:
|
136
159
|
- MIT
|
137
160
|
metadata:
|
138
161
|
source_code_uri: https://github.com/matthewstyler/ruby-perlin-2D-map-generator
|
139
162
|
bug_tracker_uri: https://github.com/matthewstyler/ruby-perlin-2D-map-generator/issues
|
140
|
-
post_install_message:
|
163
|
+
post_install_message: Thanks for installing! Star on github if you found this useful,
|
164
|
+
or raise issues and requests.
|
141
165
|
rdoc_options: []
|
142
166
|
require_paths:
|
143
167
|
- lib
|
@@ -155,6 +179,6 @@ requirements: []
|
|
155
179
|
rubygems_version: 3.2.3
|
156
180
|
signing_key:
|
157
181
|
specification_version: 4
|
158
|
-
summary: Procedurally generate seeded and customizable 2D maps
|
159
|
-
colours or described in a 2D array of hashes
|
182
|
+
summary: Procedurally generate seeded and customizable 2D maps with optional roads
|
183
|
+
and towns, rendered with ansi colours or described in a 2D array of hashes
|
160
184
|
test_files: []
|