world_in_your_terminal 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/Action.rb +10 -0
- data/lib/Display.rb +31 -0
- data/lib/Engine.rb +142 -0
- data/lib/GenerateMatrix.rb +54 -0
- data/lib/GenerateName.rb +37 -0
- data/lib/World.rb +432 -0
- data/lib/constants/themes/black_white.rb +29 -0
- data/lib/constants/themes/default.rb +37 -0
- data/lib/constants/tile_types.rb +13 -0
- data/lib/run.rb +3 -0
- data/lib/world_in_your_terminal.rb +13 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6869d27eda194e7a3ff7943230e0b9a63a4f1231d669aa3168934bc5281b8b7b
|
4
|
+
data.tar.gz: b4d40183401e2251d34d59ec57267929084e09cf3fec3bd7c96d97902b8c473a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8173168e07aa1f1813c7e9530865d90447d696423dfe35885dcfec40996039d7663a6894745782424d13d7adc6ee3fe61f779f5a5731ddea96a73175766db3db
|
7
|
+
data.tar.gz: 30308740445c368da0e35d7db0573aa3f89caedb3b56c2bdf8027a7070cef5a2a4e641564dbee97e4da77cbcb07a2268e388cff13d972803cabd1fcbc8253e56
|
data/lib/Action.rb
ADDED
data/lib/Display.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative './constants/themes/default.rb'
|
2
|
+
require_relative './constants/themes/black_white.rb'
|
3
|
+
require_relative './World.rb'
|
4
|
+
|
5
|
+
class Display
|
6
|
+
def initialize(screen_size)
|
7
|
+
@screen_size = screen_size
|
8
|
+
@world = initialize_world
|
9
|
+
end
|
10
|
+
|
11
|
+
def draw
|
12
|
+
world.draw(tile_size)
|
13
|
+
end
|
14
|
+
|
15
|
+
def screen_size
|
16
|
+
@screen_size
|
17
|
+
end
|
18
|
+
|
19
|
+
def tile_size
|
20
|
+
return 1
|
21
|
+
# screen_size / world.current_matrix_width
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize_world
|
25
|
+
World.new(Constants::THEME::BLACKWHITE)
|
26
|
+
end
|
27
|
+
|
28
|
+
def world
|
29
|
+
@world
|
30
|
+
end
|
31
|
+
end
|
data/lib/Engine.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'tty-file'
|
2
|
+
require 'date'
|
3
|
+
require_relative './Action.rb'
|
4
|
+
|
5
|
+
class Engine
|
6
|
+
def initialize(prompt, display)
|
7
|
+
@running = false
|
8
|
+
@prompt = prompt
|
9
|
+
@display = display
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
initialize_key_prompt
|
14
|
+
while is_running
|
15
|
+
display.draw
|
16
|
+
show_key_prompts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_v1
|
21
|
+
while is_running
|
22
|
+
display.draw
|
23
|
+
answer = get_answer
|
24
|
+
proccess_answer(answer)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_answer
|
29
|
+
prompt.select('', action_map.keys, cycle: true)
|
30
|
+
end
|
31
|
+
|
32
|
+
def proccess_answer(answer)
|
33
|
+
action = action_map[answer]
|
34
|
+
action.call
|
35
|
+
end
|
36
|
+
|
37
|
+
def action_map
|
38
|
+
{
|
39
|
+
'REGENERATE' => Action.new(world.method(:regenerate)),
|
40
|
+
'ZOOM_IN' => Action.new(world.method(:zoom_in)),
|
41
|
+
'ZOOM_OUT' => Action.new(world.method(:zoom_out)),
|
42
|
+
'SCROLL_UP' => Action.new(method(:default_action)),
|
43
|
+
'SCROLL_RIGHT' => Action.new(method(:default_action)),
|
44
|
+
'SCROLL_DOWN' => Action.new(method(:default_action)),
|
45
|
+
'SCROLL_LEFT' => Action.new(method(:default_action)),
|
46
|
+
'QUIT' => Action.new(method(:stop)),
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def key_map
|
51
|
+
{
|
52
|
+
'q' => Action.new(method(:stop)),
|
53
|
+
'r' => Action.new(world.method(:regenerate)),
|
54
|
+
'z' => Action.new(world.method(:zoom_in)),
|
55
|
+
'x' => Action.new(world.method(:zoom_out)),
|
56
|
+
'n' => Action.new(method(:name_world)),
|
57
|
+
'e' => Action.new(method(:export_to_txt)),
|
58
|
+
:up => Action.new(world.method(:scroll_up)), # scroll up
|
59
|
+
:down => Action.new(world.method(:scroll_down)), # scroll down
|
60
|
+
:right => Action.new(world.method(:scroll_right)), # scroll right
|
61
|
+
:left => Action.new(world.method(:scroll_left)), # scroll left
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize_key_prompt
|
66
|
+
prompt.on(:keypress) { |event|
|
67
|
+
event_key = event.value
|
68
|
+
event_name = event.key.name
|
69
|
+
key_map[event_key].call if key_map.keys.include?(event_key)
|
70
|
+
key_map[event_name].call if key_map.keys.include?(event_name)
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def show_key_prompts
|
75
|
+
prompt.keypress(
|
76
|
+
[
|
77
|
+
"",
|
78
|
+
"-----------------------",
|
79
|
+
"r to generate new world",
|
80
|
+
"arrow keys to explore",
|
81
|
+
"z to zoom in",
|
82
|
+
"x to zoom out",
|
83
|
+
"n to rename this world",
|
84
|
+
"e to save this world in text",
|
85
|
+
"q to quit",
|
86
|
+
""
|
87
|
+
].join("\n")
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
def name_world
|
92
|
+
new_name = prompt.ask('what do people call this world?')
|
93
|
+
world.set_name(new_name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def export_to_txt
|
97
|
+
content = world.render_map_as_text(display.tile_size)
|
98
|
+
|
99
|
+
directory = "exported_worlds"
|
100
|
+
extension = 'txt'
|
101
|
+
file_name = "#{DateTime.now.strftime('%Y_%m_%d__%H%M%S')}__#{world.name}.txt".gsub!(" ","_")
|
102
|
+
|
103
|
+
TTY::File.create_file("#{directory}/#{file_name}", content)
|
104
|
+
end
|
105
|
+
|
106
|
+
def default_action
|
107
|
+
return true
|
108
|
+
end
|
109
|
+
|
110
|
+
def prompt
|
111
|
+
@prompt
|
112
|
+
end
|
113
|
+
|
114
|
+
def display
|
115
|
+
@display
|
116
|
+
end
|
117
|
+
|
118
|
+
def world
|
119
|
+
@display.world
|
120
|
+
end
|
121
|
+
|
122
|
+
def start
|
123
|
+
if is_running
|
124
|
+
throw "engine already running"
|
125
|
+
end
|
126
|
+
|
127
|
+
@running = true
|
128
|
+
run
|
129
|
+
end
|
130
|
+
|
131
|
+
def stop
|
132
|
+
@running = false
|
133
|
+
end
|
134
|
+
|
135
|
+
def is_running
|
136
|
+
@running
|
137
|
+
end
|
138
|
+
|
139
|
+
def is_stopped
|
140
|
+
!is_running
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'perlin_noise'
|
2
|
+
require_relative './constants/tile_types.rb'
|
3
|
+
|
4
|
+
class GenerateMatrix
|
5
|
+
def two_lands_matrix
|
6
|
+
[
|
7
|
+
[Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:PLAIN]],
|
8
|
+
[Constants::TILE_TYPES[:PLAIN], Constants::TILE_TYPES[:PLAIN], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
9
|
+
[Constants::TILE_TYPES[:FOREST], Constants::TILE_TYPES[:PLAIN], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
10
|
+
[Constants::TILE_TYPES[:MOUNTAIN], Constants::TILE_TYPES[:FOREST], Constants::TILE_TYPES[:PLAIN], Constants::TILE_TYPES[:WATER]],
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
def water_world_matrix
|
15
|
+
[
|
16
|
+
[Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
17
|
+
[Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
18
|
+
[Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
19
|
+
[Constants::TILE_TYPES[:MOUNTAIN], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER], Constants::TILE_TYPES[:WATER]],
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def perlin_matrix(size)
|
24
|
+
noises = Perlin::Noise.new(2)
|
25
|
+
contrast = Perlin::Curve.contrast(Perlin::Curve::CUBIC, 2)
|
26
|
+
|
27
|
+
bars = [
|
28
|
+
Constants::TILE_TYPES[:WATER],
|
29
|
+
Constants::TILE_TYPES[:WATER],
|
30
|
+
Constants::TILE_TYPES[:PLAIN],
|
31
|
+
Constants::TILE_TYPES[:FOREST],
|
32
|
+
Constants::TILE_TYPES[:MOUNTAIN],
|
33
|
+
]
|
34
|
+
bar = lambda { |n|
|
35
|
+
bars[ (bars.length * n).floor ]
|
36
|
+
}
|
37
|
+
|
38
|
+
perlin_matrix = []
|
39
|
+
|
40
|
+
size.times do |x|
|
41
|
+
row = []
|
42
|
+
size.times do |y|
|
43
|
+
n = noises[x * 0.2, y * 0.2]
|
44
|
+
n = contrast.call n
|
45
|
+
|
46
|
+
row << bar.call(n)
|
47
|
+
end
|
48
|
+
|
49
|
+
perlin_matrix << row
|
50
|
+
end
|
51
|
+
|
52
|
+
perlin_matrix
|
53
|
+
end
|
54
|
+
end
|
data/lib/GenerateName.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class GenerateName
|
2
|
+
def world
|
3
|
+
name = [
|
4
|
+
'Earth',
|
5
|
+
'Solace',
|
6
|
+
'Terra',
|
7
|
+
'Nova',
|
8
|
+
'Solida',
|
9
|
+
'Humus',
|
10
|
+
'Viridis',
|
11
|
+
'Orb',
|
12
|
+
'Solo',
|
13
|
+
'Lutum',
|
14
|
+
'Vita',
|
15
|
+
].sample
|
16
|
+
|
17
|
+
adjective = [
|
18
|
+
'',
|
19
|
+
'Red',
|
20
|
+
'Green',
|
21
|
+
'Blue',
|
22
|
+
'Speckled',
|
23
|
+
'Spotted',
|
24
|
+
].sample
|
25
|
+
|
26
|
+
suffix = [
|
27
|
+
'',
|
28
|
+
'',
|
29
|
+
'',
|
30
|
+
'One',
|
31
|
+
'Two',
|
32
|
+
'Seven',
|
33
|
+
].sample
|
34
|
+
|
35
|
+
"#{adjective} #{name} #{suffix}"
|
36
|
+
end
|
37
|
+
end
|
data/lib/World.rb
ADDED
@@ -0,0 +1,432 @@
|
|
1
|
+
require 'tty-table'
|
2
|
+
require 'tty-box'
|
3
|
+
require_relative './constants/tile_types.rb'
|
4
|
+
require_relative './constants/themes/black_white.rb'
|
5
|
+
require_relative './GenerateName.rb'
|
6
|
+
require_relative './GenerateMatrix.rb'
|
7
|
+
|
8
|
+
|
9
|
+
class Point
|
10
|
+
attr_reader :x, :y, :z
|
11
|
+
|
12
|
+
def initialize(x, y, z)
|
13
|
+
@x = x
|
14
|
+
@y = y
|
15
|
+
@z = z
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{@x},#{@y},#{@z}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class World
|
25
|
+
attr_reader :name
|
26
|
+
|
27
|
+
def initialize(theme)
|
28
|
+
@theme = theme
|
29
|
+
@pastel = Pastel.new
|
30
|
+
@max_x = 4
|
31
|
+
@max_y = 4
|
32
|
+
@max_z = 4
|
33
|
+
regenerate
|
34
|
+
end
|
35
|
+
|
36
|
+
def regenerate
|
37
|
+
@name = initialize_name
|
38
|
+
@matrix = initialize_matrix
|
39
|
+
@current_position = Point.new(0, 0, 0)
|
40
|
+
|
41
|
+
@matrix_map = {
|
42
|
+
@current_position.to_s => @matrix
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def matrix
|
47
|
+
@matrix_map[@current_position.to_s]
|
48
|
+
end
|
49
|
+
|
50
|
+
def themed_matrix(theme)
|
51
|
+
matrix.map{ |row|
|
52
|
+
row.map{ |tile|
|
53
|
+
theme.colored_tile(@pastel, tile)
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def colored_matrix
|
59
|
+
themed_matrix(@theme)
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize_matrix
|
63
|
+
GenerateMatrix.new.perlin_matrix(4)
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize_name
|
67
|
+
GenerateName.new.world
|
68
|
+
end
|
69
|
+
|
70
|
+
def set_name(name)
|
71
|
+
@name = name
|
72
|
+
end
|
73
|
+
|
74
|
+
def draw(tile_size)
|
75
|
+
# puts render_framed_map(tile_size)
|
76
|
+
# puts render_framed_table_map(tile_size)
|
77
|
+
# puts render_map(tile_size)
|
78
|
+
puts render_map_with_info(tile_size)
|
79
|
+
# puts render_table_map(tile_size)
|
80
|
+
end
|
81
|
+
|
82
|
+
def render_map_with_info(tile_size)
|
83
|
+
[
|
84
|
+
render_map(tile_size),
|
85
|
+
world_name_display,
|
86
|
+
zoom_level_display,
|
87
|
+
coordinates_display,
|
88
|
+
].join("\n")
|
89
|
+
end
|
90
|
+
|
91
|
+
def render_matrix(matrix_to_render, theme, tile_size)
|
92
|
+
matrix_to_render.map.with_index { |row, y|
|
93
|
+
row.map.with_index { |tile, x|
|
94
|
+
tile
|
95
|
+
}.join(
|
96
|
+
theme.colored_tile(
|
97
|
+
@pastel,
|
98
|
+
Constants::TILE_TYPES[:NONE]
|
99
|
+
) * tile_size
|
100
|
+
)
|
101
|
+
}.join("\n" * tile_size)
|
102
|
+
end
|
103
|
+
|
104
|
+
def render_map_as_text(tile_size)
|
105
|
+
theme = Constants::THEME::BLACKWHITE
|
106
|
+
new_matrix = themed_matrix(theme)
|
107
|
+
|
108
|
+
render_matrix(new_matrix, theme, tile_size)
|
109
|
+
end
|
110
|
+
|
111
|
+
def render_map(tile_size)
|
112
|
+
render_matrix(colored_matrix, @theme, tile_size)
|
113
|
+
end
|
114
|
+
|
115
|
+
def render_table_map(tile_size)
|
116
|
+
table = TTY::Table.new({rows: colored_matrix})
|
117
|
+
|
118
|
+
table.render(
|
119
|
+
:basic,
|
120
|
+
alignments: [:center],
|
121
|
+
padding: tile_size - 1
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def render_framed_map(tile_size)
|
126
|
+
map = render_map(tile_size)
|
127
|
+
|
128
|
+
render_frame_around_map(map)
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def render_framed_table_map(tile_size)
|
133
|
+
map = render_table_map(tile_size)
|
134
|
+
|
135
|
+
render_frame_around_map(map)
|
136
|
+
end
|
137
|
+
|
138
|
+
def render_frame_around_map(map)
|
139
|
+
framed_map = TTY::Box.frame(
|
140
|
+
align: :center,
|
141
|
+
title: {
|
142
|
+
bottom_left: coordinates_display,
|
143
|
+
bottom_right: zoom_level_display
|
144
|
+
},
|
145
|
+
border: :thick
|
146
|
+
) { map }
|
147
|
+
|
148
|
+
framed_map
|
149
|
+
end
|
150
|
+
|
151
|
+
def world_name_display
|
152
|
+
"You are exploring #{@pastel.italic(@name)}"
|
153
|
+
end
|
154
|
+
|
155
|
+
def zoom_level_display
|
156
|
+
"Zoom: #{@current_position.z}"
|
157
|
+
end
|
158
|
+
|
159
|
+
def coordinates_display
|
160
|
+
"x: #{@current_position.x}, y: #{@current_position.y}"
|
161
|
+
end
|
162
|
+
|
163
|
+
def current_matrix_width
|
164
|
+
matrix.length
|
165
|
+
end
|
166
|
+
|
167
|
+
def next_matrix_width
|
168
|
+
(current_matrix_width * 2) - 1
|
169
|
+
end
|
170
|
+
|
171
|
+
def matrix_exists_in_position(position)
|
172
|
+
@matrix_map.keys.include?(position.to_s)
|
173
|
+
end
|
174
|
+
|
175
|
+
def zoom_in
|
176
|
+
new_position = increment_z_level(@current_position)
|
177
|
+
if !matrix_exists_in_position(new_position)
|
178
|
+
generate_new_zoomed_in_map(new_position)
|
179
|
+
end
|
180
|
+
|
181
|
+
@current_position = new_position
|
182
|
+
end
|
183
|
+
|
184
|
+
def zoom_out
|
185
|
+
new_position = decrement_z_level(@current_position)
|
186
|
+
if !matrix_exists_in_position(new_position)
|
187
|
+
generate_new_zoomed_out_map(new_position)
|
188
|
+
end
|
189
|
+
|
190
|
+
@current_position = new_position
|
191
|
+
end
|
192
|
+
|
193
|
+
def scroll_right
|
194
|
+
new_position = increment_x_level(@current_position)
|
195
|
+
if !matrix_exists_in_position(new_position)
|
196
|
+
generate_new_scrolled_right_map(new_position)
|
197
|
+
end
|
198
|
+
|
199
|
+
@current_position = new_position
|
200
|
+
end
|
201
|
+
|
202
|
+
def scroll_left
|
203
|
+
new_position = decrement_x_level(@current_position)
|
204
|
+
if !matrix_exists_in_position(new_position)
|
205
|
+
generate_new_scrolled_left_map(new_position)
|
206
|
+
end
|
207
|
+
|
208
|
+
@current_position = new_position
|
209
|
+
end
|
210
|
+
|
211
|
+
def scroll_up
|
212
|
+
new_position = increment_y_level(@current_position)
|
213
|
+
if !matrix_exists_in_position(new_position)
|
214
|
+
generate_new_scrolled_up_map(new_position)
|
215
|
+
end
|
216
|
+
|
217
|
+
@current_position = new_position
|
218
|
+
end
|
219
|
+
|
220
|
+
def scroll_down
|
221
|
+
new_position = decrement_y_level(@current_position)
|
222
|
+
if !matrix_exists_in_position(new_position)
|
223
|
+
generate_new_scrolled_down_map(new_position)
|
224
|
+
end
|
225
|
+
|
226
|
+
@current_position = new_position
|
227
|
+
end
|
228
|
+
|
229
|
+
def increment_x_level(position)
|
230
|
+
add_to_x_level(1, position)
|
231
|
+
end
|
232
|
+
|
233
|
+
def decrement_x_level(position)
|
234
|
+
add_to_x_level(-1, position)
|
235
|
+
end
|
236
|
+
|
237
|
+
def increment_y_level(position)
|
238
|
+
add_to_y_level(1, position)
|
239
|
+
end
|
240
|
+
|
241
|
+
def decrement_y_level(position)
|
242
|
+
add_to_y_level(-1, position)
|
243
|
+
end
|
244
|
+
|
245
|
+
def increment_z_level(position)
|
246
|
+
add_to_z_level(1, position)
|
247
|
+
end
|
248
|
+
|
249
|
+
def decrement_z_level(position)
|
250
|
+
add_to_z_level(-1, position)
|
251
|
+
end
|
252
|
+
|
253
|
+
def add_to_x_level(amount, position)
|
254
|
+
new_x = (position.x + amount).clamp(-@max_x, @max_x)
|
255
|
+
|
256
|
+
Point.new(
|
257
|
+
new_x,
|
258
|
+
position.y,
|
259
|
+
position.z,
|
260
|
+
)
|
261
|
+
end
|
262
|
+
|
263
|
+
def add_to_y_level(amount, position)
|
264
|
+
new_y = (position.y + amount).clamp(-@max_y, @max_y)
|
265
|
+
|
266
|
+
Point.new(
|
267
|
+
position.x,
|
268
|
+
new_y,
|
269
|
+
position.z,
|
270
|
+
)
|
271
|
+
end
|
272
|
+
|
273
|
+
def add_to_z_level(amount, position)
|
274
|
+
new_z = (position.z + amount).clamp(0, @max_z)
|
275
|
+
|
276
|
+
Point.new(
|
277
|
+
position.x,
|
278
|
+
position.y,
|
279
|
+
new_z,
|
280
|
+
)
|
281
|
+
end
|
282
|
+
|
283
|
+
def generate_new_zoomed_in_map(position)
|
284
|
+
zoom_length = next_matrix_width
|
285
|
+
unfilled_new_matrix = []
|
286
|
+
matrix.each_with_index{ |row, i|
|
287
|
+
unfilled_new_matrix << expanded_row(zoom_length, matrix[i])
|
288
|
+
if unfilled_new_matrix.length < zoom_length
|
289
|
+
unfilled_new_matrix << new_row(zoom_length)
|
290
|
+
end
|
291
|
+
}
|
292
|
+
|
293
|
+
filled_new_matrix = fill_none_tiles(unfilled_new_matrix)
|
294
|
+
|
295
|
+
@matrix_map[position.to_s] = filled_new_matrix
|
296
|
+
end
|
297
|
+
|
298
|
+
def generate_new_zoomed_out_map(position)
|
299
|
+
new_matrix = []
|
300
|
+
matrix.each_with_index{ |row, i|
|
301
|
+
if i.even?
|
302
|
+
new_row = []
|
303
|
+
matrix[i].each_with_index{ |tile, j|
|
304
|
+
new_row << tile if j.even?
|
305
|
+
}
|
306
|
+
new_matrix << new_row
|
307
|
+
end
|
308
|
+
}
|
309
|
+
|
310
|
+
@matrix_map[position.to_s] = new_matrix
|
311
|
+
end
|
312
|
+
|
313
|
+
def generate_new_scrolled_right_map(position)
|
314
|
+
unfilled_new_matrix = matrix.dup.map.with_index{ |row, y|
|
315
|
+
new_row = row.dup
|
316
|
+
new_row.shift
|
317
|
+
new_row << Constants::TILE_TYPES[:NONE]
|
318
|
+
|
319
|
+
new_row
|
320
|
+
}
|
321
|
+
|
322
|
+
filled_new_matrix = fill_none_tiles(unfilled_new_matrix)
|
323
|
+
|
324
|
+
@matrix_map[position.to_s] = filled_new_matrix
|
325
|
+
end
|
326
|
+
|
327
|
+
def generate_new_scrolled_left_map(position)
|
328
|
+
unfilled_new_matrix = matrix.dup.map.with_index{ |row, y|
|
329
|
+
new_row = row.dup
|
330
|
+
new_row.pop
|
331
|
+
new_row.unshift(Constants::TILE_TYPES[:NONE])
|
332
|
+
|
333
|
+
new_row
|
334
|
+
}
|
335
|
+
|
336
|
+
filled_new_matrix = fill_none_tiles(unfilled_new_matrix)
|
337
|
+
|
338
|
+
@matrix_map[position.to_s] = filled_new_matrix
|
339
|
+
end
|
340
|
+
|
341
|
+
def generate_new_scrolled_up_map(position)
|
342
|
+
unfilled_new_matrix = []
|
343
|
+
matrix.dup.map.with_index{ |row, i|
|
344
|
+
unfilled_new_matrix << row.dup if i < (current_matrix_width - 1)
|
345
|
+
}
|
346
|
+
|
347
|
+
unfilled_new_matrix.unshift(new_row(current_matrix_width))
|
348
|
+
|
349
|
+
filled_new_matrix = fill_none_tiles(unfilled_new_matrix)
|
350
|
+
|
351
|
+
@matrix_map[position.to_s] = filled_new_matrix
|
352
|
+
end
|
353
|
+
|
354
|
+
def generate_new_scrolled_down_map(position)
|
355
|
+
unfilled_new_matrix = []
|
356
|
+
matrix.dup.map.with_index{ |row, i|
|
357
|
+
unfilled_new_matrix << row.dup if i > 0
|
358
|
+
}
|
359
|
+
|
360
|
+
unfilled_new_matrix << new_row(current_matrix_width)
|
361
|
+
|
362
|
+
filled_new_matrix = fill_none_tiles(unfilled_new_matrix)
|
363
|
+
|
364
|
+
@matrix_map[position.to_s] = filled_new_matrix
|
365
|
+
end
|
366
|
+
|
367
|
+
def expanded_row(zoom_length, current_row)
|
368
|
+
new_row = []
|
369
|
+
current_row.each_with_index{ |row, i|
|
370
|
+
new_row << current_row[i]
|
371
|
+
if new_row.length < zoom_length
|
372
|
+
new_row << Constants::TILE_TYPES[:NONE]
|
373
|
+
end
|
374
|
+
}
|
375
|
+
|
376
|
+
new_row
|
377
|
+
end
|
378
|
+
|
379
|
+
def new_row(zoom_length)
|
380
|
+
return Array.new(zoom_length, Constants::TILE_TYPES[:NONE])
|
381
|
+
end
|
382
|
+
|
383
|
+
def fill_none_tiles(unfilled_matrix)
|
384
|
+
new_matrix = []
|
385
|
+
unfilled_matrix.each_with_index { |row, y|
|
386
|
+
new_row = []
|
387
|
+
row.each_with_index { |tile, x|
|
388
|
+
new_tile = tile
|
389
|
+
if tile == Constants::TILE_TYPES[:NONE]
|
390
|
+
neighboring_tiles = get_tiles_in_neighboring_positions(x, y, unfilled_matrix);
|
391
|
+
random_neighbor_tile = neighboring_tiles.select{|tile| ![Constants::TILE_TYPES[:NONE]].include?(tile) }.sample
|
392
|
+
new_tile = random_neighbor_tile != Constants::TILE_TYPES[:NONE] ? random_neighbor_tile : Constants::TILE_TYPES.sample
|
393
|
+
end
|
394
|
+
|
395
|
+
new_row << new_tile
|
396
|
+
}
|
397
|
+
|
398
|
+
new_matrix << new_row
|
399
|
+
}
|
400
|
+
|
401
|
+
new_matrix
|
402
|
+
end
|
403
|
+
|
404
|
+
def get_tiles_in_neighboring_positions(x, y, current_matrix)
|
405
|
+
relative_neighboring_positions = [
|
406
|
+
{x: -1, y: 0},
|
407
|
+
{x: 1, y: 0},
|
408
|
+
{x: 0, y: -1},
|
409
|
+
{x: 0, y: 1},
|
410
|
+
{x: -1, y: -1},
|
411
|
+
{x: 1, y: 1},
|
412
|
+
{x: 1, y: -1},
|
413
|
+
{x: -1, y: 1},
|
414
|
+
]
|
415
|
+
|
416
|
+
neighboring_tiles = []
|
417
|
+
relative_neighboring_positions.map { |pos|
|
418
|
+
tile = get_tile_at_position(x + pos[:x], y + pos[:y], current_matrix)
|
419
|
+
neighboring_tiles << tile if tile
|
420
|
+
}
|
421
|
+
|
422
|
+
neighboring_tiles
|
423
|
+
end
|
424
|
+
|
425
|
+
def get_tile_at_position(x, y, current_matrix)
|
426
|
+
begin
|
427
|
+
return current_matrix[y][x]
|
428
|
+
rescue => exception
|
429
|
+
return false
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Constants
|
2
|
+
module THEME
|
3
|
+
module BLACKWHITE
|
4
|
+
def BLACKWHITE.colored_tile(pastel_instance, tile_type)
|
5
|
+
BLACKWHITE.tile_map(pastel_instance)[tile_type][:character]
|
6
|
+
end
|
7
|
+
|
8
|
+
def BLACKWHITE.tile_map(pastel_instance)
|
9
|
+
{
|
10
|
+
Constants::TILE_TYPES[:NONE] => {
|
11
|
+
character: ' ',
|
12
|
+
},
|
13
|
+
Constants::TILE_TYPES[:WATER] => {
|
14
|
+
character: ' ',
|
15
|
+
},
|
16
|
+
Constants::TILE_TYPES[:FOREST] => {
|
17
|
+
character: 't',
|
18
|
+
},
|
19
|
+
Constants::TILE_TYPES[:MOUNTAIN] => {
|
20
|
+
character: 'M',
|
21
|
+
},
|
22
|
+
Constants::TILE_TYPES[:PLAIN] => {
|
23
|
+
character: '_',
|
24
|
+
},
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Constants
|
2
|
+
module THEME
|
3
|
+
module DEFAULT
|
4
|
+
def DEFAULT.colored_tile(pastel_instance, tile_type)
|
5
|
+
character = DEFAULT.tile_map(pastel_instance)[tile_type][:character]
|
6
|
+
color_method = DEFAULT.tile_map(pastel_instance)[tile_type][:color_method]
|
7
|
+
|
8
|
+
color_method.call(character)
|
9
|
+
end
|
10
|
+
|
11
|
+
def DEFAULT.tile_map(pastel_instance)
|
12
|
+
{
|
13
|
+
Constants::TILE_TYPES[:NONE] => {
|
14
|
+
character: ' ',
|
15
|
+
color_method: pastel_instance.black.method(:on_black),
|
16
|
+
},
|
17
|
+
Constants::TILE_TYPES[:WATER] => {
|
18
|
+
character: '■',
|
19
|
+
color_method: pastel_instance.blue.method(:on_black),
|
20
|
+
},
|
21
|
+
Constants::TILE_TYPES[:FOREST] => {
|
22
|
+
character: '■',
|
23
|
+
color_method: pastel_instance.green.method(:on_black),
|
24
|
+
},
|
25
|
+
Constants::TILE_TYPES[:MOUNTAIN] => {
|
26
|
+
character: '■',
|
27
|
+
color_method: pastel_instance.bright_white.method(:on_black),
|
28
|
+
},
|
29
|
+
Constants::TILE_TYPES[:PLAIN] => {
|
30
|
+
character: '■',
|
31
|
+
color_method: pastel_instance.bright_yellow.method(:on_black),
|
32
|
+
},
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/run.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'tty-prompt'
|
2
|
+
require_relative './Display.rb'
|
3
|
+
require_relative './Engine.rb'
|
4
|
+
|
5
|
+
class WorldInYourTerminal
|
6
|
+
def explore
|
7
|
+
display = Display.new(40)
|
8
|
+
prompt = TTY::Prompt.new
|
9
|
+
|
10
|
+
engine = Engine.new(prompt, display)
|
11
|
+
engine.start
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: world_in_your_terminal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Vanderhaar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pastel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: perlin_noise
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-box
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.7.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.7.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tty-color
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.6.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.6.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: tty-file
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.10.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.10.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: tty-prompt
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.23.1
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.23.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tty-screen
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.8.1
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.8.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tty-table
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.12.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.12.0
|
125
|
+
description:
|
126
|
+
email: d.vanderhaarhunter@gmail.com
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- lib/Action.rb
|
132
|
+
- lib/Display.rb
|
133
|
+
- lib/Engine.rb
|
134
|
+
- lib/GenerateMatrix.rb
|
135
|
+
- lib/GenerateName.rb
|
136
|
+
- lib/World.rb
|
137
|
+
- lib/constants/themes/black_white.rb
|
138
|
+
- lib/constants/themes/default.rb
|
139
|
+
- lib/constants/tile_types.rb
|
140
|
+
- lib/run.rb
|
141
|
+
- lib/world_in_your_terminal.rb
|
142
|
+
homepage: https://rubygems.org/gems/world_in_your_terminal
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
metadata: {}
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 2.7.0
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
requirements: []
|
161
|
+
rubygems_version: 3.1.6
|
162
|
+
signing_key:
|
163
|
+
specification_version: 4
|
164
|
+
summary: Explore tiny worlds in yor terminal
|
165
|
+
test_files: []
|