aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2021-09-13 13:17:18 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2021-09-13 13:17:18 +0200
commit3482f66ce348d7dd0e5d2f72fa3ab370c5051b8c (patch)
tree893094690b81544c8ffc3364d301c7a4946b05ff /scripts
parent0e3172f314b69fd913e8db0bfc040cf722e4f2d5 (diff)
downloadmuhqs-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-xscripts/generate_map_img.py205
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()