Skip to content

Commit 8a79c6a

Browse files
committed
*
1 parent 10641ea commit 8a79c6a

File tree

7 files changed

+152
-78
lines changed

7 files changed

+152
-78
lines changed

src/grid/__main__.py

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
parser.add_argument('-i', '--interactive', action='store_true', help='Run an interactive session')
1010
parser.add_argument('-b', '--blueprint', dest='blueprint', type=str, default=None, help='Load a blueprint from a file')
11+
parser.add_argument('--ascii', action='store_true', help='Print the grid as ascii')
1112
parser.add_argument('-l', '--load', dest='load', type=str, default=None, help='Load a grid from a file')
1213
parser.add_argument('-t', '--terrain', action='store_true', default=True, help='Whether to generate terrain with the grid.')
1314
parser.add_argument('-ns', '--noise-scale', dest='noise_scale', type=int, default=100, help='Noise scale')
@@ -24,6 +25,7 @@
2425

2526
from .blueprint import *
2627
from .grid import *
28+
from .utility import *
2729

2830
terrain_grids = f'{os.getcwd()}{os.sep}src{os.sep}grid{os.sep}terrain_grids{os.sep}'
2931
grids = f'{os.getcwd()}{os.sep}src{os.sep}grid{os.sep}grids{os.sep}'
@@ -55,52 +57,32 @@ def print(*args):
5557
print('Success! Grid generated.')
5658

5759
if args.save:
58-
print('Saving grid ...')
60+
print('Pickling grid ...')
5961
save_grid(grid=grid)
6062
print('Success!')
61-
print('Saving blueprint ...')
63+
print('Pickling blueprint ...')
6264
Blueprint.save_blueprint(blueprint=blueprint)
6365
print('Success!')
6466

65-
print('Generating grid image ...')
66-
print('Importing pillow ...')
67-
from PIL import Image, ImageDraw
68-
print('Success.')
69-
70-
print('Creating raw image ...')
71-
image = Image.new('RGB', (grid.blueprint.grid_width, grid.blueprint.grid_height), (255, 255, 255))
72-
print('Creating draw object ...')
73-
draw = ImageDraw.Draw(image)
74-
print('Drawing cells ...')
75-
total = len(grid.cells.values())
76-
for count, (cell, info) in enumerate(grid.blueprint.dictGrid.items(), start=1):
77-
print(f'Drawing cell {info["designation"]} ... {round((count/total)*100)}%', end='\r')
78-
x = info['coordinates'][0]
79-
y = info['coordinates'][1]
80-
color = grid.blueprint.dictTerrain[cell]['color']
81-
draw.rectangle((x, y, x+(args.size), y+(args.size)), fill=color)
82-
83-
# def capture_grid_as_image(grid: Grid, output_path: str):
84-
# window_width = grid.blueprint.grid_width
85-
# window_height = grid.blueprint.grid_height
86-
87-
# # Create a larger window that can accommodate the entire grid
88-
# window = pyglet.window.Window(width=window_width, height=window_height)
89-
90-
# @window.event
91-
# def on_draw():
92-
# window.clear()
93-
# grid.grid_batch.draw()
94-
95-
# # Capture the grid as an image
96-
# image = pyglet.image.get_buffer_manager().get_color_buffer()
97-
# image.save(output_path)
98-
99-
# # Close the window after capturing the image
100-
# pyglet.app.exit()
101-
102-
# pyglet.app.run()
103-
104-
# Usage example
105-
image.save(f'{saves_dir}{grid.grid_id[-5:]}/grid.png')
67+
if args.ascii:
68+
print('Writing ascii to file ...')
69+
with open(f'{saves_dir}{grid.grid_id[-5:]}/grid.txt', 'w') as f:
70+
rows = []
71+
string = ''
72+
for row in grid.rows:
73+
for cell in row:
74+
string += cell.terrain_char
75+
rows.append(string)
76+
string = ''
77+
f.write('\n'.join(rows))
78+
print('Success!')
79+
80+
cdata = extract_cell_data(grid)
81+
grid_id = grid.grid_id[-5:]
82+
height = grid.blueprint.grid_height
83+
width = grid.blueprint.grid_width
84+
delete_grid(grid)
85+
86+
generate_images((width, height), cdata, args.size, grid_id)
87+
10688

src/grid/blueprint/grid_blueprint.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ def load_blueprint(num: int):
4141
'terrain': [
4242
'raw', 'int',
4343
'str', 'color',
44-
'cost_in', 'cost_out'
44+
'cost_in', 'cost_out',
45+
'char'
4546
]
4647
}
4748

@@ -312,6 +313,7 @@ def _set_base_terrain(self):
312313
self.dictTerrain[cell]['color'] = OCEAN_BLUE
313314
self.dictTerrain[cell]['cost_in'] = float('inf')
314315
self.dictTerrain[cell]['cost_out'] = float('inf')
316+
self.dictTerrain[cell]['char'] = '~'
315317
self.dictGrid[cell]['passable'] = False
316318

317319

src/grid/blueprint/terrain_processing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ def generate_terrain_dict(terrain_data_ds: type[np.ndarray], terrain_data_pn: ty
170170
terrain_dict[cell]['color'] = info['color']
171171
terrain_dict[cell]['cost_in'] = info['cost_in']
172172
terrain_dict[cell]['cost_out'] = info['cost_out']
173+
terrain_dict[cell]['char'] = info['char']
173174
break
174175
return terrain_dict
175176

src/grid/blueprint/terrains.json

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,84 +5,96 @@
55
"int": 0,
66
"color": "SNOW_WHITE",
77
"cost_in": Infinity,
8-
"cost_out": 10
8+
"cost_out": 10,
9+
"char": "X"
910
},
1011
"MOUNTAIN_CRAG": {
1112
"raw_max": 0.15,
1213
"int": 0,
1314
"color": "CRAG_GREY",
1415
"cost_in": Infinity,
15-
"cost_out": 5
16+
"cost_out": 5,
17+
"char": "|"
1618
},
1719
"MOUNTAIN_SIDE": {
1820
"raw_max": 0.18,
1921
"int": 1,
2022
"color": "SIDE_GREY",
2123
"cost_in": Infinity,
22-
"cost_out": 5
24+
"cost_out": 5,
25+
"char": "/"
2326
},
2427
"MOUNTAIN_BASE": {
2528
"raw_max": 0.23,
2629
"int": 2,
2730
"color": "BASE_GREY",
2831
"cost_in": Infinity,
29-
"cost_out": 0
32+
"cost_out": 0,
33+
"char": "-"
3034
},
3135
"MOUND": {
3236
"raw_max": 0.28,
3337
"int": 3,
3438
"color": "MOUND_GREY",
3539
"cost_in": 2,
36-
"cost_out": 0
40+
"cost_out": 0,
41+
"char": "_"
3742
},
3843
"FOOTHILL": {
3944
"raw_max": 0.43,
4045
"int": 3,
4146
"color": "FOOTHILL_GREEN",
4247
"cost_in": 1,
43-
"cost_out": 0
48+
"cost_out": 0,
49+
"char": " "
4450
},
4551
"GRASS0": {
4652
"raw_max": 0.448,
4753
"int": 4,
4854
"color": "GRASS_GREEN",
4955
"cost_in": 1,
50-
"cost_out": 0
56+
"cost_out": 0,
57+
"char": " "
5158
},
5259
"GRASS1": {
5360
"raw_max": 0.482,
5461
"int": 4,
5562
"color": "PLAIN_GREEN",
5663
"cost_in": 0,
57-
"cost_out": 1
64+
"cost_out": 1,
65+
"char": " "
5866
},
5967
"GRASS2": {
6068
"raw_max": 0.488,
6169
"int": 4,
6270
"color": "GRASS_GREEN",
6371
"cost_in": 1,
64-
"cost_out": 0
72+
"cost_out": 0,
73+
"char": " "
6574
},
6675
"GRASS3": {
6776
"raw_max": 0.495,
6877
"int": 4,
6978
"color": "PLAIN_GREEN",
7079
"cost_in": 0,
71-
"cost_out": 1
80+
"cost_out": 1,
81+
"char": " "
7282
},
7383
"SAND": {
7484
"raw_max": 0.517,
7585
"int": 5,
7686
"color": "SANDY_GREY",
7787
"cost_in": 1.25,
78-
"cost_out": 1
88+
"cost_out": 1,
89+
"char": "."
7990
},
8091
"SEASHELL": {
8192
"raw_max": 0.519,
8293
"int": 6,
8394
"color": "SEASHELL_WHITE",
8495
"cost_in": 1.5,
85-
"cost_out": 1
96+
"cost_out": 1,
97+
"char": ","
8698
}
8799
}
88100
}

src/grid/cell.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ def __init__(
354354
self.terrain_raw = self.parentgrid.dictTerrain[self.designation]['raw']
355355
self.terrain_int = self.parentgrid.dictTerrain[self.designation]['int']
356356
self.terrain_color = self.parentgrid.dictTerrain[self.designation]['color']
357+
self.terrain_char = self.parentgrid.dictTerrain[self.designation]['char']
357358

358359
self.overlay_color = None
359360
self.stored_overlay_color = None

src/grid/grid.py

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from typing import Optional as _Optional, Union as _Union
3030

3131
RIVER_BLUE = (18, 70, 132, 255)
32+
RIVERBANK_BROWN = (92, 45, 15, 255)
3233

3334
saves_dir = '/devel/fresh/envs/grid-engine/src/grid/saves/'
3435

@@ -62,6 +63,18 @@ def get_vector_direction(pointa, pointb):
6263
)
6364

6465

66+
def extract_cell_data(grid):
67+
"""Accepts a grid object and returns only the necessary data to draw the cells"""
68+
cell_data = []
69+
for c, cell in grid.cells.items.items():
70+
cdata = [cell.x, cell.y, cell.terrain_color]
71+
cell_data.append(cdata)
72+
return cell_data
73+
74+
def delete_grid(grid: Grid):
75+
"""Deletes the grid object from memory in order to avoid OOM events"""
76+
del grid
77+
6578
def save_grid(grid: Grid):
6679
import os
6780
os.chdir(f'{saves_dir}')
@@ -697,7 +710,7 @@ def generate_realistic_river(self, start_cell: Cell, end_cell: Cell):
697710
expanded_path = self.expand_river_path(path)
698711
# shaped_path = self.shape_river_path(expanded_path)
699712
for cell in expanded_path:
700-
cell.terrain_str = 'river'
713+
cell.terrain_str = 'RIVER'
701714
cell.terrain_raw = 0.0
702715
cell.terrain_int = 9
703716
cell.terrain_color = RIVER_BLUE
@@ -712,37 +725,52 @@ def generate_realistic_river(self, start_cell: Cell, end_cell: Cell):
712725
else:
713726
print("No path found between the start and end cells.")
714727

728+
def get_river_banks(self):
729+
for cell in self.cells.values():
730+
if cell.terrain_str == 'river':
731+
adjacent_cells = cell.adjacent
732+
for adjacent_cell in adjacent_cells:
733+
adjacent_cell = self.cells[adjacent_cell]
734+
if adjacent_cell.terrain_str not in ['RIVER', 'OCEAN', 'SAND']:
735+
adjacent_cell.terrain_str = 'RIVERBANK'
736+
adjacent_cell.terrain_raw = 0.0
737+
adjacent_cell.terrain_int = 8
738+
adjacent_cell.terrain_color = RIVERBANK_BROWN
739+
self.dictTerrain[adjacent_cell.designation] = {
740+
'str': adjacent_cell.terrain_str,
741+
'raw': adjacent_cell.terrain_raw,
742+
'int': adjacent_cell.terrain_int,
743+
'color': adjacent_cell.terrain_color,
744+
'cost_in': 1,
745+
'cost_out': 2
746+
}
715747

716748
def get_river_by_walk(self, start_cell: Cell):
717749
river_cells = [start_cell]
718750
branch_cells = []
719-
start_cell = self.cells[start_cell]
720751
direction = random.randint(0, 7)
721-
for step in range(640):
722-
direction = direction if step % 16 != 0 else abs((random.randint(0, 7)) - direction)
723-
current_cell = start_cell if step == 0 else self.cells[river_cells[-1]]
724-
adjacent_cells = current_cell.adjacent
752+
for step in range(random.randint(960, 1496)):
753+
direction = direction if step % 24 != 0 else abs((random.randint(0, 7)) - direction)
754+
current_cell = self.cells[river_cells[-1]]
725755
if adjacent_cells := [
726756
adjacent_cell
727-
for adjacent_cell in adjacent_cells
757+
for adjacent_cell in current_cell.adjacent
728758
if self.cells[adjacent_cell].passable
729759
]:
730-
next_cell = adjacent_cells[direction % len(adjacent_cells)]
760+
next_cell = adjacent_cells[(direction + (0 if step % 6 else random.randint(-2, 2))) % len(adjacent_cells)]
731761
river_cells.append(next_cell)
732-
if step >= 240:
762+
if step >= 768:
733763
# create branch and continue branch with each step
734-
direction2 = direction + 1 if direction < 7 else direction - 1
764+
direction2 = direction + 4 if direction < 3 else direction - 4
735765
if not branch_cells:
736-
branch_cells.append(current_cell.adjacent[direction2 % len(current_cell.adjacent)])
737-
else:
738-
adjacent_cells = self.cells[branch_cells[-1]].adjacent
739-
if adjacent_cells := [
740-
adjacent_cell
741-
for adjacent_cell in adjacent_cells
742-
if self.cells[adjacent_cell].passable
743-
]:
744-
next_branch_cell = adjacent_cells[direction2 % len(adjacent_cells)]
745-
river_cells.append(next_branch_cell)
766+
branch_cells.append(current_cell.adjacent[(direction2 + (0 if step % 4 else random.randint(-2, 2))) % len(adjacent_cells)])
767+
elif adjacent_cells := [
768+
adjacent_cell
769+
for adjacent_cell in self.cells[branch_cells[-1]].adjacent
770+
if self.cells[adjacent_cell].passable
771+
]:
772+
next_branch_cell = adjacent_cells[(direction2 + (0 if step % 6 else random.randint(-1, 1))) % len(adjacent_cells)]
773+
branch_cells.append(next_branch_cell)
746774

747775
return [river_cells, branch_cells]
748776

@@ -912,13 +940,21 @@ def get_bend_directions(heading, path_count):
912940

913941

914942
def set_rivers(self, river_count):
943+
largest_land = 0
944+
largest_size = 0
945+
for i, landmass in self.landmasses.items():
946+
landmass_size = len(landmass['landmass_cells'])
947+
if landmass_size > largest_size:
948+
largest_land = i
949+
largest_size = landmass_size
915950
for _ in range(river_count):
916-
landmass = self.landmasses[random.choice(list(self.landmasses.keys()))]
951+
landmass = self.landmasses[largest_land]
917952
coastal_cells = landmass['coastal_cells']
918953
print('Building river ...')
919954
start, end = self.get_river_ends(coastal_cells)
920955
self.generate_realistic_river(start, end)
921-
print('done')
956+
self.get_river_banks()
957+
print('done')
922958
# Define the _heuristic function
923959

924960
def _heuristic(self, cella, cellb):

0 commit comments

Comments
 (0)