Skip to content

Instantly share code, notes, and snippets.

@sbrl
Created June 25, 2015 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sbrl/284b45dc566516a9c11b to your computer and use it in GitHub Desktop.
Save sbrl/284b45dc566516a9c11b to your computer and use it in GitHub Desktop.
A maze game written in Python
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
"""
Notes
=====
Possible Directions
-------------------
- up
- down
- left
- right
"""
#imports
#core
from random import random, randint, shuffle, choice, randrange;
from math import floor;
#temporary
#import time;
registry = {
"player": "@", #the player
"unknown": "?", #an unknown tile
"wall": "#", #walls we can't go through
"space": " ", #spaces we can go through
"entrance": ":", #the entrance to the maze
"exit": "0", #the exit of the exit
"treasure-small": "*", #small amounts of treasure
"treasure-large": "=" #large amounts of treasure
};
difficulties = {
"easy": 0.75,
"normal": 1,
"hard": 1.25,
"insane": 2
};
def space(width = 16, height = 8, ch = registry["wall"]):
area = [];
for y in range(height):
area.append([]);
for x in range(width):
area[y].append(ch);
x
return area;
def chooseremove(items):
# pick an item index
if items:
index = randrange( len(items) )
return items.pop(index)
# nothing left!
return None
class coord:
def __init__(self, x = 1, y = 1):
self.x = x;
self.y = y;
#def to check a space for neighbours
def checkneighbors(area, cur):
neighbours = {"left": True, "right": True, "up": True, "down": True};
if(cur.x > 2):
#we are not near the left edge
if(area[cur.y][cur.x - 2] == registry["wall"]):
#we can move left
neighbours["left"] = False;
if(cur.x < len(area[0]) - 3):
if(area[cur.y][cur.x + 2] == registry["wall"]):
#we can move right
neighbours["right"] = False;
if(cur.y > 2):
if(area[cur.y - 2][cur.x] == registry["wall"]):
#we can move up
neighbours["up"] = False;
if(cur.y < len(area) - 3):
if(area[cur.y + 2][cur.x] == registry["wall"]):
#we can move down
neighbours["down"] = False;
return neighbours;
#def to determine which sides can be moved to based on neighbour data from the def above
def getpossibleneighbours(neighbours):
possiblesides = [];
if(not neighbours["left"]):
possiblesides.append("left");
if(not neighbours["right"]):
possiblesides.append("right");
if(not neighbours["up"]):
possiblesides.append("up");
if(not neighbours["down"]):
possiblesides.append("down");
return possiblesides;
def maze(width = 17, height = 9):
#this maze generator works on odd numbers
if(width % 2 == 0):
width += 1;
if(height % 2 == 0):
height += 1;
area = space(width, height); #create an area to build the maze
area[1][1] = " "; #fill in the initial space
nodes = [coord(1, 1)]; #node to continue from
while True:
#break out of the loop if there are no more nodes to choose from
if(len(nodes) == 0):
break;
shuffle(nodes); #shuffle the bag of nodes
cur = chooseremove(nodes); #grab a random node from the bag
neighbours = checkneighbors(area, cur); #check which neighbouring spots are free
possiblesides = getpossibleneighbours(neighbours); #determine the possible sides that we could move to
#there are no posible sides that we can go to here, let's move on
if(len(possiblesides) == 0):
continue;
newside = choice(possiblesides); #choose a random side from the list of possible sides
#todo implement loops here
#add a new section to the maze based on which sides
if(newside == "left"):
area[cur.y][cur.x - 1] = " ";
area[cur.y][cur.x - 2] = " ";
nodes.append(coord(cur.x - 2, cur.y));
elif(newside == "right"):
area[cur.y][cur.x + 1] = " ";
area[cur.y][cur.x + 2] = " ";
nodes.append(coord(cur.x + 2, cur.y));
elif(newside == "up"):
area[cur.y - 1][cur.x] = " ";
area[cur.y - 2][cur.x] = " ";
nodes.append(coord(cur.x, cur.y - 2));
elif(newside == "down"):
area[cur.y + 1][cur.x] = " ";
area[cur.y + 2][cur.x] = " ";
nodes.append(coord(cur.x, cur.y + 2));
neighbours[newside] = True;
possiblesides = getpossibleneighbours(neighbours); #update the list of possible sides
if(len(possiblesides) > 0):
nodes.append(cur);
shuffle(nodes); #shuffle the nodes
return area;
#def to print a space to stdout
def printspace(area):
for row in area:
print("".join(row));
def difftomult(diff = "normal"):
if(diff == "easy"):
return 0.75;
elif(diff == "normal"):
return 1;
elif(diff == "hard"):
return 1.25;
elif(diff == "insane"):
return 2;
def placestuff(maze, difficulty = "normal"):
print("Placing treasure....");
diffmult = difftomult(difficulty); #convert the difficulty to a multiplier
treasurecount = 0;
#loop over every space
y = 0;
for row in maze:
x = 0;
for ch in row:
if(ch == registry["space"]):
#we have a space
#place treasure
chance = int(floor((1 / diffmult) * random() * 10));
#print("stuffchance:", chance);
if(chance == 0):
treasurecount += 1;
#1 in 4 chance to place large treasure
if(randint(0, 4) == 0):
maze[y][x] = registry["treasure-large"];
else:
maze[y][x] = registry["treasure-small"];
x += 1;
y += 1;
print("Placed " + str(treasurecount) + " treasures");
#def to place the entrance and exit in a maze
def placedoors(maze, firstfloor = False, lastexit = [1, 1]):
placements = {};
if(firstfloor):
#we are on the first floor, the entrance should be a gap on the edge of the maze
#the space at (1, 1) is guaranteed to be a space because of the generation algorithm, so we can place the entrance there
maze[0][1] = registry["space"];
#record this in the object placements dictionary
placements["firstfloor"] = True;
placements["entrance"] = [1, 0];
else:
#we are not on the first floor, place the entrance in the same location as the exit on the previous floor
#todo check to see if there is a wall in the location that we have been told to place the entrance, and if so we should place it in the nearest free spot
#make sure that the entrance is on the screen
if(lastexit[0] > len(maze[0]) - 1):
lastexit[0] = len(maze[0]) - 1;
if(lastexit[1] > len(maze) - 1):
lastexit[1] = len(maze) - 1;
maze[lastexit[1]][lastexit[0]] = registry["entrance"];
#make sure that the player can actually move when they start playing
if(lastexit[0] == len(maze[1]) - 1 and lastexit[1] == len(maze) - 1):
#we are in the bottom corner, add a space so the player can get out
maze[lastexit[1]][lastexit[0] - 1] = registry["space"];
#record the entrance location in the placements dictionary
placements["firstfloor"] = False;
placements["entrance"] = lastexit;
while True:
exitloc = [randint(0, len(maze[0]) - 1), randint(0, len(maze) - 1)];
#make sure that there is a space at the generated position
#print("w", len(maze[0]), "h", len(maze));
#print(exitloc);
if(maze[exitloc[1]][exitloc[0]] != registry["space"]):
continue;
else:
maze[exitloc[1]][exitloc[0]] = registry["exit"]; #place the exit
placements["exit"] = exitloc; #record the exit's location
break;
return placements; #return the coordinates of the locations at which we placed the doors
#def to convert a difficulty into a viewsize - currently unused
def difftoviewsize(diff):
if(diff == "easy"):
return [9, 9];
elif(diff == "normal"):
return [7, 7];
elif(diff == "hard"):
return [5, 5];
elif(diff == "insane"):
return [3, 3];
else:
raise ValueError("Invalid difficulty " + diff);
#def to extract the view that a player will see from a maze, translating a difficulty into a view size
def playerview(maze, playerloc = (1, 0), diff = "normal"):
if(diff == "easy"):
return extractview(maze, playerloc, 9, 9);
elif(diff == "normal"):
return extractview(maze, playerloc, 7, 7);
elif(diff == "hard"):
return extractview(maze, playerloc, 5, 5);
elif(diff == "insane"):
return extractview(maze, playerloc, 3, 3);
else:
raise ValueError("Invalid difficulty " + diff);
#raw view extraction from mazes
def extractview(maze, playerloc = (1, 0), width = 3, height = 3):
view = space(width, height, registry["unknown"]);
xbounds = [playerloc[0] - ((width - 1) / 2), playerloc[0] + ((width - 1) / 2)];
ybounds = [playerloc[1] - ((height - 1) / 2), playerloc[1] + ((height - 1) / 2)];
#make sure that the bounds are within the maze
if(xbounds[0] < 0):
xbounds[0] = 0;
if(ybounds[0] < 0):
ybounds[0] = 0;
if(xbounds[1] > len(maze[0]) - 1):
xbounds[1] = len(maze[0]) - 1;
if(ybounds[1] > len(maze) - 1):
ybounds[1] = len(maze) - 1;
#print("xbounds", xbounds);
#print("ybounds", ybounds);
playerviewloc = (playerloc[0] - xbounds[0], playerloc[1] - ybounds[0]);
#print("Player in view at", playerviewloc);
#copy out a section of the maze to serve as the view
y = 0;
for row in maze:
x = 0;
for ch in row:
if(x >= xbounds[0] and x <= xbounds[1] and y >= ybounds[0] and y <= ybounds[1]):
#we are inside the view bounds
#print("adding char " + ch + " at abs (" + str(x) + ", " + str(y) + ")");
view[int(y - ybounds[0])][int(x - xbounds[0])] = ch;
x += 1;
y += 1;
#place the player in the view
view[int(playerviewloc[1])][int(playerviewloc[0])] = registry["player"];
return view;
#def to test the maze generator
def test():
printspace(maze(40, 30));
if __name__ == "__main__":
test();
#!/usr/bin/env python
import os, shlex, struct, platform, subprocess
def get_terminal_size():
""" getTerminalSize()
- get width and height of console
- works on linux,os x,windows,cygwin(windows)
originally retrieved from:
http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python
"""
current_os = platform.system()
tuple_xy = None
if current_os == 'Windows':
tuple_xy = _get_terminal_size_windows()
if tuple_xy is None:
tuple_xy = _get_terminal_size_tput()
# needed for window's python in cygwin's xterm!
if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'):
tuple_xy = _get_terminal_size_linux()
if tuple_xy is None:
print("default");
tuple_xy = (80, 25) # default value
return tuple_xy
def _get_terminal_size_windows():
try:
from ctypes import windll, create_string_buffer
# stdin handle is -10
# stdout handle is -11
# stderr handle is -12
h = windll.kernel32.GetStdHandle(-12)
csbi = create_string_buffer(22)
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
if res:
(bufx, bufy, curx, cury, wattr,
left, top, right, bottom,
maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
sizex = right - left + 1
sizey = bottom - top + 1
return sizex, sizey
except:
pass
def _get_terminal_size_tput():
# get terminal width
# src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
try:
cols = int(subprocess.check_call(shlex.split('tput cols')))
rows = int(subprocess.check_call(shlex.split('tput lines')))
return (cols, rows)
except:
pass
def _get_terminal_size_linux():
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
cr = struct.unpack('hh',
fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
return cr
except:
pass
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
try:
cr = (os.environ['LINES'], os.environ['COLUMNS'])
except:
return None
return int(cr[1]), int(cr[0])
if __name__ == "__main__":
sizex, sizey = get_terminal_size()
print('width =', sizex, 'height =', sizey)
##########################################################################################
#### _____ ___ _ ___ ####
#### |_ _|____ __ _____ _ _ / __|___ __| |___ | _ \__ _ _ _ ___ ___ _ _ ####
#### | |/ _ \ V V / -_) '_| | (__/ _ \/ _` / -_) | _/ _` | '_(_-</ -_) '_| ####
#### |_|\___/\_/\_/\___|_| \___\___/\__,_\___| |_| \__,_|_| /__/\___|_| ####
#### ####
##########################################################################################
"""
Examples
========
name:The tower of mazes,difficulty:normal,seed:2345953|1*4x4,3*11x15
"""
#imports
#temporary
from pprint import pprint;
#def to decode tower codes
def decode(str):
parts = str.split("|");
metadata = {};
for param in parts[0].split(","):
pparam = param.split(":");
metadata[pparam[0]] = pparam[1];
towerdata = {};
towerdata["metadata"] = metadata;
towerdata["floors"] = [];
for floorcode in parts[1].split(","):
multiply = int(floorcode[0:floorcode.index("*")]);
floordata = {};
floordata["partofsetof"] = multiply;
dimensions = floorcode[floorcode.index("*") + 1:].split("x");
floordata["width"] = int(dimensions[0]);
floordata["height"] = int(dimensions[1]);
for i in range(multiply):
towerdata["floors"].append(floordata);
return towerdata;
#def to encode tower codes
def encode(towerdata):
towercode = ""; #set up a string to hold the towercode
#encode the metadata
towercode += "name:" + towerdata["metadata"]["name"] + ",";
try:
towercode += "seed:" + towerdata["metadata"]["seed"] + ",";
except KeyError:
print("Warning: No seed was specified, so the mazes will be random!");
towercode = towercode[0:-1]; #remove the trailing comma
towercode += "|";
#encode the floors
skip = 0;
for floor in towerdata["floors"]:
if(skip > 0):
skip -= 1;
continue;
towercode += str(floor["partofsetof"]) + "*" + str(floor["width"]) + "x" + str(floor["height"]) + ",";
skip = floor["partofsetof"] - 1;
towercode = towercode[0:-1]; #remove the trailing comma
return towercode;
if __name__ == "__main__":
print("Encoding");
print("=-=-=-=-");
print(encode(decode("name:The tower of mazes,seed:2345953|1*4x4, 3*11x15")));
print();
print("Decoding");
print("=-=-=-=-");
pprint(decode("name:The tower of mazes,difficulty:normal,seed:2345953|1*4x4, 3*11x15"));
################################################################################################
################################################################################################
#### _____ _ __ __ ___ ####
#### |_ _|____ __ _____ _ _(_)_ _ __ _ | \/ |__ _ ______ / __|__ _ _ __ ___ ####
#### | |/ _ \ V V / -_) '_| | ' \/ _` | | |\/| / _` |_ / -_) | (_ / _` | ' \/ -_) ####
#### |_|\___/\_/\_/\___|_| |_|_||_\__, | |_| |_\__,_/__\___| \___\__,_|_|_|_\___| ####
#### |___/ ####
################################################################################################
################################################################################################
#imports
#core
import random;
from sys import exit, stdout;
from time import sleep;
from math import floor, ceil;
#other files
import maze, utils, towercode;
from getch import getch; #to use: getch(); #gets one char of input
#temporary
#from pprint import pprint;
#def to play a game of the towering maze game
def play(towerdata):
towerdata["metadata"]["totalfloors"] = len(towerdata["floors"]); #add the total number of floors to the tower's metadata
floor = 0;
#loop over all the floors in the towerdata we have been supplied
lastexit = [1, 0]; #the last exit's location
rawscore = 0; #the player's raw score, not includeing the movement bonus
score = 0; #the player's total score
moves = 0; #the number of moves that have beeen made
floornum = 0;
for floor in towerdata["floors"]:
#play the floor
flooresult = playfloor(floor, floornum, towerdata["metadata"], lastexit, towerdata["metadata"]["difficulty"], score, moves);
lastexit = flooresult["exitloc"]; #update the last exit location
score += flooresult["score"];
rawscore += flooresult["rawscore"];
moves += flooresult["moves"];
floornum += 1;
print("\n\n\n\n");
print("***** You reached the top of the tower! *****");
print("Moves: " + str(moves));
print("Difficulty Multiplier: " + str(maze.difftomult(towerdata["metadata"]["difficulty"])));
score *= maze.difftomult(towerdata["metadata"]["difficulty"]);
print("Score: " + str(score));
print("\n**** Press any key to continue ****");
getch();
return score;
#def to play a floor
def playfloor(floordata, floornum, towermetadata, lastexit = [1, 0], difficulty = "normal", totalscore = 0, totalmoves = 0):
#variable setup
score = 0; #the score the player has gained on this floor
moves = 0; #the number of moves the player has made on this floor
playerloc = lastexit; #the current location of the player
floormaze = maze.maze(floordata["width"], floordata["height"]);
maze.placestuff(floormaze, difficulty);
#determine whether we are on the first floor
if(floornum == 0):
firstfloor = True;
else:
firstfloor = False;
entexlocs = maze.placedoors(floormaze, firstfloor, lastexit); #place the entrance and exits and remember their locations
while True:
utils.clearterminal(); #clear the terminal
playerview = maze.playerview(floormaze, playerloc, difficulty); #extract the view that the player will see
if(difficulty != "insane" and difficulty != "hard"):
playerlocdisp = "(" + str(int(playerloc[0])) + ", " + str(int(playerloc[1])) + ")";
else:
playerlocdisp = "(?, ?)"; #mask the location on insane difficulty
#print the heading
print("+" + "="*44 + "+");
print("|" + towermetadata["name"].center(44) + "|");
print("+" + "="*23 + "+" + "="*20 + "+");
#prepare the sidebar
sidebar = [];
sidebar.append((" On floor " + str(floornum) + " / " + str(towermetadata["totalfloors"])).ljust(20) + "|");
sidebar.append((" at " + playerlocdisp).ljust(20) + "|");
sidebar.append("-"*20 + "+");
sidebar.append(" This Floor".ljust(20) + "|");
sidebar.append("-"*7 + "+" + "-"*12 + "+");
sidebar.append(" Score | " + str(int(score)).ljust(11) + "|");
sidebar.append(" Moves | " + str(int(moves)).ljust(11) + "|");
sidebar.append("-"*7 + "+" + "-"*12 + "+");
sidebar.append(" Overall".ljust(20) + "|");
sidebar.append("-"*7 + "+" + "-"*12 + "+");
sidebar.append(" Score | " + str(int(totalscore + score)).ljust(11) + "|");
sidebar.append(" Moves | " + str(int(totalmoves + moves)).ljust(11) + "|");
#prepare the player's view
pviewdisp = [];
if(len(playerview) < 12):
lendiff = 12 - len(playerview);
toprowsneeded = floor(lendiff / 2);
for i in range(toprowsneeded):
pviewdisp.append("|" + " "*23 + "|");
for row in playerview:
pviewdisp.append("|" + "".join(row).center(23) + "|");
if(len(playerview) < 12):
lendiff = 12 - len(playerview);
toprowsneeded = ceil(lendiff / 2);
for i in range(toprowsneeded):
pviewdisp.append("|" + " "*23 + "|");
#add plus signs at table intersections
pviewdisp[2] = pviewdisp[2][0:-1] + "+";
pviewdisp[4] = pviewdisp[4][0:-1] + "+";
pviewdisp[7] = pviewdisp[7][0:-1] + "+";
pviewdisp[9] = pviewdisp[9][0:-1] + "+";
#display the interface
for sides in zip(pviewdisp, sidebar):
print("".join(sides));
print("+" + "-"*23 + "+" + "-"*20 + "+");
#(new tui)
#+========================================+
#| The Tower of Mazes |
#+=======================+================+
#| | On floor 3 / 5 |
#| | at (3, 1) |
#| #####?? +----------------+
#| # 0@#?? | This Floor |
#| ### #?? +-------+--------+
#| # #?? | Score | 50 |
#| ### :?? | Moves | 29 |
#| ??????? +----------------+
#| ??????? | Overall |
#| +----------------+
#| | Score | 1050 |
#| | Moves | 329 |
#+-----------------------+----------------+
#print("+-" + ("-" * 30) + "-+");
#print("| " + floornumdisp.ljust(30) + " |");
#print("+-" + ("-" * 30) + "-+");
#print("| " + ("Score: ".ljust(15) + str(score).ljust(15)) + " |");
#print("+-" + ("-" * 30) + "-+");
#print("| " + ("Moves: ".ljust(15) + str(moves).ljust(15)) + " |");
#print("+-" + ("-" * 30) + "-+");
#print("| " + ("Location: ".ljust(15) + ("(" + str(playerloc[0]) + ", " + str(playerloc[1]) + ")").ljust(15)) + " |");
#print("+-" + ("-" * 30) + "-+\n");
#maze.printspace(playerview); #display the maze
ch1 = getch(); #get a character of input from the user
if(ch1 == b'\xe0' or ch1 == "\x1b"):
#if the first chracter is "\x1b", there will be an extra "[" character next - this needs picking up so it doesn't break the rest of the script
if(ch1 == "\x1b"):
ch1b = getch();
#we have an escaped character, get more input
ch2 = getch();
#todo make the arrow keys actually do something
#todo make sure that the player can't crash the game by moving out of the playing area on the first floor
#todo make sure that the player can't go through walls
if(ch2 == b'H' or ch2 == "A"):
#the up arrow key was pressed
if(playerloc[1] > 0):
if(floormaze[playerloc[1] - 1][playerloc[0]] != maze.registry["wall"]):
#the new space is not a wall :D Move the player.
playerloc[1] -= 1;
moves += 1; #increment the number of moves the player has made
elif(ch2 == b'P' or ch2 == "B"):
#the down arrow key was pressed
if(playerloc[1] < len(floormaze) - 1):
if(floormaze[playerloc[1] + 1][playerloc[0]] != maze.registry["wall"]):
#the new space is not a wall :D Move the player.
playerloc[1] += 1;
moves += 1; #increment the number of moves the player has made
elif(ch2 == b'K' or ch2 == "D"):
#the left arrow key was pressed
if(playerloc[0] > 0):
if(floormaze[playerloc[1]][playerloc[0] - 1] != maze.registry["wall"]):
#the new space is not a wall :D Move the player.
playerloc[0] -= 1;
moves += 1; #increment the number of moves the player has made
elif(ch2 == b'M' or ch2 == "C"):
#the right arrow key was pressed
if(playerloc[0] < len(floormaze[0]) - 1):
if(floormaze[playerloc[1]][playerloc[0] + 1] != maze.registry["wall"]):
#the new space is not a wall :D Move the player.
playerloc[0] += 1;
moves += 1; #increment the number of moves the player has made
elif(ch1 == b'\x03' or ch1 == "\x03"):
print("Press CTRL + C again to quit, or any other key to cancel.");
ch2 = getch();
if(ch2 == b'\x03'):
print("Exiting");
exit();
if(floormaze[playerloc[1]][playerloc[0]] == maze.registry["exit"]):
#calculate the bonus score gained through completing the floor in a low number of moves
#we add one here since we exit the loop early
#todo tweak this algorithm based on playtesting
movementscore = (1 / (moves + 1)) * floordata["width"] * floordata["height"] * 50;
print("-----------------------------");
print("---- Floor complete! ----");
print("-----------------------------");
print("**** Floor Results ****");
print("Moves: " + str(moves + 1) + "\n"); #we add one to the number of moves since we exit the loop early
print("Score: " + str(score));
print("Movement bonus: " + str(movementscore));
print("----");
print("Total floor score: " + str(score + movementscore));
print("\n\nPress any key to continue...");
ch = getch();
break;
elif(floormaze[playerloc[1]][playerloc[0]] == maze.registry["treasure-small"]):
#we have found a little bit of treasure! Add to the score and remove the treasure.
floormaze[playerloc[1]][playerloc[0]] = maze.registry["space"];
score += 50;
elif(floormaze[playerloc[1]][playerloc[0]] == maze.registry["treasure-large"]):
#we have found a little bit of treasure! Add to the score and remove the treasure.
floormaze[playerloc[1]][playerloc[0]] = maze.registry["space"];
score += 250;
return {
"exitloc": entexlocs["exit"],
"rawscore": score,
"score": score + movementscore,
"moves": moves
};
stdout.write(""" _____ _ __ __ ___
|_ _|____ __ _____ _ _(_)_ _ __ _ | \/ |__ _ ______ / __|__ _ _ __ ___
| |/ _ \ V V / -_) '_| | ' \/ _` | | |\/| / _` |_ / -_) | (_ / _` | ' \/ -_)
|_|\___/\_/\_/\___|_| |_|_||_\__, | |_| |_\__,_/__\___| \___\__,_|_|_|_\___|
|___/ v0.3dev b7, The name is temporary
******** Press any key ********\r""");
getch();
for i in range(10):
if(i % 2 == 1):
print("|---| |---| |---| |---| |---| |---| |---| |---|");
else:
print("| | | | | | | | | | | | | | | |");
sleep(random.random() * 0.1);
while True:
print("""
+=============================+
| Main Menu |
+=============================+
| 0: Help |
| 1: Load tower |
| |
| 2: Play the example tower |
| |
| 3: Changelog |
| 4: Exit |
+-----------------------------+
| (Press a number) |
+-----------------------------+
""");
ch = getch(); #get a charcter of input
if(ch == b'0' or ch == "0"):
#the player wants help
print("\n\n\n\n");
print(utils.file_get_contents("help.txt"));
print("Press any key to continue....");
ch2 = getch();
elif(ch == b'1' or ch == "1"):
#the player wants to play
print("\n\n\n\n");
towerdata = towercode.decode(utils.getinput("Enter tower code: ")); #get and decode a tower code
#set the seed if it is specified
if "seed" in towerdata["metadata"]:
random.seed(towerdata["metadata"]["seed"]);
play(towerdata); #play the game
elif(ch == b'2' or ch == "2"):
#the player wants to play the example tower
print("\n\n\n\n");
towerdata = towercode.decode("name:The tower of mazes,difficulty:normal,seed:2345953|1*4x4,3*11x15,1*5x5");
#set the seed if it is specified
if "seed" in towerdata["metadata"]:
random.seed(towerdata["metadata"]["seed"]);
play(towerdata);
elif(ch == b'3' or ch == "3"):
#the player wants the changelog
print(utils.file_get_contents("changelog.log"));
print("Press any key to continue....");
ch2 = getch();
if(ch == b'\x03' or ch == "\x03" or ch == "4" or ch == b'4'):
#CTRL + C
print("Exiting");
exit();
#imports
#other files
from terminalsize import get_terminal_size;
#function to get input from the user - guarantees that the user will enter at least 1 character.
def getinput(prompt = ">", minchars = 1):
while True:
inputstr = input(prompt);
if(len(inputstr) >= minchars):
return inputstr;
#function to get a yes / no input
def confirm(prompt = "Are you sure?"):
while True:
response = getinput(prompt).lower(); #get the input and convert it to lower case
if(response == "" or response == "y" or response == "ye" or response == "yes"):
#the user answered yes
return True;
elif(response == "n" or response == "no"):
#the user answered no
return False;
#temporary def to output a bunch of blank lines to clear the terminal while we figure out how to move the cursor upwards
def clearterminal():
tsize = get_terminal_size();
print("\n" * tsize[1]);
#def to get the contents of a file
def file_get_contents(filename):
with open(filename) as f:
return f.read()
@aniruddha-ingle
Copy link

How do you play this game?

@IronManRox228228
Copy link

How to play, please help.

@sbrl
Copy link
Author

sbrl commented May 27, 2021

Oh wow, this some old stuff I've written here.

@aniruddha-ingle: Sorry I didn't see your comment there!

@IronManRox228228: I would assume that you would download the contents of this gist, and then do python towermazegame.py.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment