diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2021-09-13 13:17:18 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2021-09-13 13:17:18 +0200 |
| commit | 3482f66ce348d7dd0e5d2f72fa3ab370c5051b8c (patch) | |
| tree | 893094690b81544c8ffc3364d301c7a4946b05ff /scripts | |
| parent | 0e3172f314b69fd913e8db0bfc040cf722e4f2d5 (diff) | |
| download | muhqs-game-3482f66ce348d7dd0e5d2f72fa3ab370c5051b8c.tar.gz muhqs-game-3482f66ce348d7dd0e5d2f72fa3ab370c5051b8c.zip | |
[maps] add new tyrant map, tiles and improve map generation script
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/generate_map_img.py | 205 |
1 files changed, 154 insertions, 51 deletions
diff --git a/scripts/generate_map_img.py b/scripts/generate_map_img.py index ee30cd90..f3b3671d 100755 --- a/scripts/generate_map_img.py +++ b/scripts/generate_map_img.py @@ -1,22 +1,165 @@ #!/usr/bin/env python3 +"""Generate map images from map files""" import argparse -import cv2 import pathlib -import numpy import os -from typing import MutableMapping +from typing import Sequence, Tuple import yaml +import cv2 +import numpy + MAP_ROOT = pathlib.Path(os.getcwd()) TILES_DIR = MAP_ROOT / '../assets/tiles' SHOW_MAP = False +Row = Sequence[str] +Tiles = Sequence[Row] + def get_tile_path(tile: str) -> pathlib.Path: """Return the corresponding image file name for a tile""" return TILES_DIR / f'{tile.lower().replace(" ", "_")}.png' +def is_connected_to(tiles: Tiles, + x: int, + y: int, + kind=None) -> Tuple[bool, bool, bool, bool]: + is_kind = lambda tile: tile == kind if kind else tile != 'neutral' + row = tiles[y] + left = x > 0 and is_kind(row[x - 1]) + right = x < len(row) - 1 and is_kind(row[x + 1]) + above = y > 0 and is_kind(tiles[y - 1][x]) + below = y < len(tiles) - 1 and is_kind(tiles[y + 1][x]) + + return left, right, above, below + +def count_connections(left:bool , right:bool, above:bool, below:bool) -> int: + return len([b for b in [left, right, above, below] if b is True]) + + +def find_street_tile(tiles: Tiles, x: int, y: int): + # find street continuations + left, right, above, below = is_connected_to(tiles, x, y, kind='street') + + connections = count_connections(left, right, above, below) + + if connections == 0: + # This street is not connected to another street -> + # check any other non neutral tiles + left, right, above, below = is_connected_to(tiles, x, y, kind=None) + + connections = count_connections(left, right, above, below) + + # This street is not connected to anything. Seams odd! + # Use a 4 way street + if connections == 0: + tile_img = cv2.imread(str(get_tile_path('street_4'))) + + # straight lines + elif connections == 1 or (connections == 2 and ((left and right) or + (above and below))): + tile_img = cv2.imread(str(get_tile_path('street'))) + if above or below: + tile_img = numpy.rot90(tile_img) + # elbow + elif connections == 2: + # normal orientation above and right + tile_img = cv2.imread(str(get_tile_path('street_2'))) + if right and below: + tile_img = numpy.rot90(tile_img, 3) + elif left and below: + tile_img = numpy.rot90(tile_img, 2) + elif above and left: + tile_img = numpy.rot90(tile_img) + elif connections == 3: + # normal orientation left above right + tile_img = cv2.imread(str(get_tile_path('street_3'))) + if above and right and below: + tile_img = numpy.rot90(tile_img, 3) + elif left and below and right: + tile_img = numpy.rot90(tile_img, 2) + elif below and left and above: + tile_img = numpy.rot90(tile_img) + elif connections == 4: + tile_img = cv2.imread(str(get_tile_path('street_4'))) + + return tile_img + + +def find_wall_tile(tiles: Sequence[Sequence[str]], x: int, y: int): + # find wall continuations + left, right, above, below = is_connected_to(tiles, x, y, kind='wall') + + connections = count_connections(left, right, above, below) + + if connections == 0: + # This wall is not connected to another wall -> + # check any other non neutral tiles + left, right, above, below = is_connected_to(tiles, x, y, kind=None) + + connections = count_connections(left, right, above, below) + + # This wall is not connected to anything. Seams odd! + # Use default horizontal wall + if connections == 0: + tile_img = cv2.imread(str(get_tile_path('wall'))) + + # straight walls + elif connections == 1 or (connections == 2 and ((left and right) or + (above and below))): + if above or below: + tile_img = cv2.imread(str(get_tile_path('wall_h'))) + else: + tile_img = cv2.imread(str(get_tile_path('wall'))) + + # elbow + elif connections == 2: + if above: + tile_img = cv2.imread(str(get_tile_path('wall_elbow_up'))) + else: + tile_img = cv2.imread(str(get_tile_path('wall_elbow_down'))) + + if left: + tile_img = cv2.flip(tile_img, 1) + + elif connections == 3 or connections == 4: + # We don't have wall tiles for those structures yet use default vertical wall + tile_img = cv2.imread(str(get_tile_path('wall'))) + + return tile_img + + +def find_gate_tile(tiles: Sequence[Sequence[str]], x: int, y: int): + # find wall continuations + left, right, above, below = is_connected_to(tiles, x, y, kind='wall') + + connections = count_connections(left, right, above, below) + + if connections == 0: + # This gate is not connected to a wall -> check towers next + left, right, above, below = is_connected_to(tiles, x, y, kind='tower') + + connections = count_connections(left, right, above, below) + + if connections == 0: + # If the gate is not connected to any fortification structure use default tile + return cv2.imread(str(get_tile_path('gate'))) + + # straight gates are the only special gates we have + if connections == 2 and ((left and right) or (above and below)): + if above or below: + tile_img = cv2.imread(str(get_tile_path('gate'))) + else: + tile_img = cv2.imread(str(get_tile_path('gate_wall_h'))) + + else: + tile_img = cv2.imread(str(get_tile_path('gate'))) + + return tile_img + + def generate_img(map_path: pathlib.Path): """Generate a image from a map file""" with open(map_path, 'r') as map_file: @@ -42,47 +185,16 @@ def generate_img(map_path: pathlib.Path): tiles.append(row) rows_imgs = [] - for i, row in enumerate(tiles): + for y, row in enumerate(tiles): tile_imgs = [] - for j, tile in enumerate(row): + for x, tile in enumerate(row): # find the right street and rotation if tile == 'street': - # check continuations - left = j > 1 and row[j - 1] == 'street' - right = j < len(row) - 1 and row[j + 1] == 'street' - above = i > 1 and tiles[i - 1][j] == 'street' - below = i < len(tiles) - 1 and tiles[i + 1][j] == 'street' - - connections = len( - [b for b in [left, right, above, below] if b == True]) - # straight lines - if connections == 1 or (connections == 2 and - ((left and right) or - (above and below))): - tile_img = cv2.imread(str(get_tile_path('street'))) - if above or below: - tile_img = numpy.rot90(tile_img) - # elbow - elif connections == 2: - # normal orientation above and right - tile_img = cv2.imread(str(get_tile_path('street_2'))) - if right and below: - tile_img = numpy.rot90(tile_img, 3) - elif left and below: - tile_img = numpy.rot90(tile_img, 2) - elif above and left: - tile_img = numpy.rot90(tile_img) - elif connections == 3: - # normal orientation left above right - tile_img = cv2.imread(str(get_tile_path('street_3'))) - if above and right and below: - tile_img = numpy.rot90(tile_img, 3) - elif left and below and right: - tile_img = numpy.rot90(tile_img, 2) - elif below and left and above: - tile_img = numpy.rot90(tile_img) - elif connections == 4: - tile_img = cv2.imread(str(get_tile_path('street_4'))) + tile_img = find_street_tile(tiles, x, y) + elif tile == 'wall': + tile_img = find_wall_tile(tiles, x, y) + elif tile == 'gate': + tile_img = find_gate_tile(tiles, x, y) else: tile_img = cv2.imread(str(get_tile_path(tile))) @@ -98,9 +210,7 @@ def generate_img(map_path: pathlib.Path): cv2.imwrite(f'{map_path.stem}.png', map_img) -def main(): - """Generate map images from map files""" - +if __name__ == '__main__': parser = argparse.ArgumentParser( description='generate latex standalone cards') parser.add_argument('map_input', @@ -113,13 +223,10 @@ def main(): args = parser.parse_args() if args.map_root: - global MAP_ROOT MAP_ROOT = pathlib.Path(args.latex_root) - global TILES_DIR TILES_DIR = MAP_ROOT / '../assets/tiles' if args.show_map: - global SHOW_MAP SHOW_MAP = True map_path = pathlib.Path(args.map_input) @@ -129,7 +236,3 @@ def main(): for m in map_files: generate_img(m) - - -if __name__ == '__main__': - main() |
