Files
MiniMapGen/main.py
2022-01-17 22:10:35 +00:00

198 lines
5.4 KiB
Python

import sys
import functools
import random
from noise import pnoise2
from termcolor import colored
def addition(a, b):
return a + b
seed = 0
seed_codes = sys.argv[1].encode("utf-8")
if seed_codes:
seed = functools.reduce(addition, seed_codes)
scale = 25.0
world_w, world_h = 16, 16
water_deepest = -0.3
water_deep = -0.2
water = -0.1
grass = 0.3
grass_high = 0.6
mountains = 1
block = ""
block = block + block
def generate_world(seed):
try:
print("Seed: " + str(seed))
random.seed(seed)
world = []
for y in range(1, world_h + 1):
row = []
for x in range(1, world_w + 1):
row_noise = pnoise2(
x / scale,
y / scale,
octaves=10,
persistence=0.5,
lacunarity=2.0,
base=seed
)
row.append(row_noise)
world.append(row)
return world
except Exception as e:
print(e)
def terrain_matches(cell1, cell2):
return cell1["is_land"] == cell2["is_land"] or cell1["is_water"] == cell2["is_water"]
def get_from_coords(world, x, y):
if y >= 0 and x>= 0 and y < len(world) and x < len(world[y]):
return world[y][x]
return None
def get_adjacent(world, x, y):
north = None
east = None
south = None
west = None
if y - 1 >= 0:
north = get_from_coords(world, x, y - 1)
if x + 1 < world_w:
east = get_from_coords(world, x + 1, y)
if y + 1 < world_h:
south = get_from_coords(world, x, y + 1)
if x - 1 >= 0:
west = get_from_coords(world, x - 1, y)
return north, east, south, west
def group_terrain(world):
groups = [[], []]
for y in range(world_h):
row = []
for x in range(world_w):
cell = world[y][x]
terrain = {
"v": cell,
"x": x,
"y": y
}
if cell > water:
groups[0].append(terrain)
else:
groups[1].append(terrain)
for group in groups:
sub_group_id = 1
for i, cell in enumerate(group):
if i == 0:
cell["group_id"] = sub_group_id
elif
print(groups)
return groups
def add_home(world):
print("Choosing home location")
home = (0, 0)
# build only on "grass"
valid_locations = []
for y in range(world_h):
if y > 0 and y < world_h - 1:
for x in range(world_w):
if x > 0 and x < world_w - 1:
cell = world[y][x]
if cell > water and cell <= grass:
valid_locations.append((x, y))
location = random.randrange(len(valid_locations))
home = valid_locations[location]
print(home)
return home
def add_dock(world, home):
print("Adding a dock")
# find the closest bit of water to the house?
# find the biggest body of water
def distribution(world):
total = world_w * world_h
above_water = 0
for y in range(world_h):
for x in range(world_w):
cell = world[y][x]
if cell > water:
above_water = above_water + 1
return above_water / total
def print_map(world, home):
print(" ", end="", flush=True)
for x in range(world_w):
to_print = str(x) + " " if x < 10 else x
print(to_print, end="", flush=True)
print("")
for y in range(world_h):
to_print = str(y) + " " if y < 10 else y
print(to_print, end="", flush=True)
for x in range(world_w):
cell = world[y][x]
if home[0] == x and home[1] == y:
print(colored(block, "magenta"), end="", flush=True)
elif cell <= water_deepest:
print(colored(block, "grey"), end="", flush=True)
elif cell <= water_deep:
print(colored(block, "blue", attrs=["dark"]), end="", flush=True)
elif cell <= water:
print(colored(block, "blue"), end="", flush=True)
elif cell <= grass:
print(colored(block, "green"), end="", flush=True)
elif cell <= grass_high:
print(colored(block, "green", attrs=["dark"]), end="", flush=True)
else:
print(colored(block, "white"), end="", flush=True)
print("")
def print_terrain(world):
colours = ["grey", "red", "green", "yellow", "blue", "magenta", "cyan", "white"]
colours = colours + colours + colours + colours
print(" ", end="", flush=True)
for x in range(world_w):
to_print = str(x) + " " if x < 10 else x
print(to_print, end="", flush=True)
print("")
for y in range(world_h):
to_print = str(y) + " " if y < 10 else y
print(to_print, end="", flush=True)
for x in range(world_w):
cell = world[y][x]
print(colored(block, colours[cell["group_id"]]), end="", flush=True)
print("")
world = generate_world(seed)
i = 1
land_percentage = distribution(world)
while (land_percentage < 0.25 or 1 - land_percentage < 0.25):
world = generate_world(seed + i)
land_percentage = distribution(world)
i = i + 1
world_terrain = group_terrain(world)
print(str(i - 1) + " seed iterations")
home = add_home(world)
dock = add_dock(world, home)
print_map(world, home)
print_terrain(world_terrain)