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)