Files
basic-computer-games/02_Amazing/python/amazing.py
Martin Thoma a721c91557 Python: Add Continuous Integration for Python
There are a lot of exceptions, but it's a start.
This will ensure that no more issues get added / that issues
get fixed before the code is added
2022-03-09 21:29:06 +01:00

149 lines
4.3 KiB
Python

import random
from typing import List, NamedTuple, Tuple
# Python translation by Frank Palazzolo - 2/2021
class Maze(NamedTuple):
used: List[List[int]]
walls: List[List[int]]
enter_col: int
width: int
length: int
def main() -> None:
welcome_header()
width, length = get_maze_dimensions()
maze = build_maze(width, length)
print_maze(maze)
def welcome_header() -> None:
print(" " * 28 + "AMAZING PROGRAM")
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
def build_maze(width: int, length: int) -> Maze:
# Build two 2D arrays
#
# used:
# Initially set to zero, unprocessed cells
# Filled in with consecutive non-zero numbers as cells are processed
#
# walls:
# Initially set to zero, (all paths blocked)
# Remains 0 if there is no exit down or right
# Set to 1 if there is an exit down
# Set to 2 if there is an exit right
# Set to 3 if there are exits down and right
assert width >= 2 and length >= 2
used = []
walls = []
for _ in range(length):
used.append([0] * width)
walls.append([0] * width)
# Use direction variables with nice names
GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN = [0, 1, 2, 3]
# Give Exit directions nice names
EXIT_DOWN = 1
EXIT_RIGHT = 2
# Pick a random entrance, mark as used
enter_col = random.randint(0, width - 1)
row, col = 0, enter_col
count = 1
used[row][col] = count
count = count + 1
while count != width * length + 1:
# remove possible directions that are blocked or
# hit cells that we have already processed
possible_dirs = [GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN]
if col == 0 or used[row][col - 1] != 0:
possible_dirs.remove(GO_LEFT)
if row == 0 or used[row - 1][col] != 0:
possible_dirs.remove(GO_UP)
if col == width - 1 or used[row][col + 1] != 0:
possible_dirs.remove(GO_RIGHT)
if row == length - 1 or used[row + 1][col] != 0:
possible_dirs.remove(GO_DOWN)
# If we can move in a direction, move and make opening
if len(possible_dirs) != 0:
direction = random.choice(possible_dirs)
if direction == GO_LEFT:
col = col - 1
walls[row][col] = EXIT_RIGHT
elif direction == GO_UP:
row = row - 1
walls[row][col] = EXIT_DOWN
elif direction == GO_RIGHT:
walls[row][col] = walls[row][col] + EXIT_RIGHT
col = col + 1
elif direction == GO_DOWN:
walls[row][col] = walls[row][col] + EXIT_DOWN
row = row + 1
used[row][col] = count
count = count + 1
# otherwise, move to the next used cell, and try again
else:
while True:
if col != width - 1:
col = col + 1
elif row != length - 1:
row, col = row + 1, 0
else:
row, col = 0, 0
if used[row][col] != 0:
break
# Add a random exit
col = random.randint(0, width - 1)
row = length - 1
walls[row][col] = walls[row][col] + 1
return Maze(used, walls, enter_col, width, length)
def get_maze_dimensions() -> Tuple[int, int]:
while True:
width_str, length_str = input("What are your width and length?").split(",")
width = int(width_str)
length = int(length_str)
if width > 1 and length > 1:
break
print("Meaningless dimensions. Try again.")
return width, length
def print_maze(maze: Maze) -> None:
for col in range(maze.width):
if col == maze.enter_col:
print(". ", end="")
else:
print(".--", end="")
print(".")
for row in range(maze.length):
print("I", end="")
for col in range(maze.width):
if maze.walls[row][col] < 2:
print(" I", end="")
else:
print(" ", end="")
print()
for col in range(maze.width):
if maze.walls[row][col] == 0 or maze.walls[row][col] == 2:
print(":--", end="")
else:
print(": ", end="")
print(".")
if __name__ == "__main__":
main()