Adds comments

This commit is contained in:
Peter Sharp
2022-02-22 07:08:26 -07:00
parent 67e6481f0c
commit c7386b795a

View File

@@ -1,37 +1,25 @@
"""
BUG
Ported by Peter Sharp
"""
from random import randint
from collections import namedtuple
PAGE_WIDTH = 64
def main():
states = {
'start': (print_start, control_start, update_state),
'instructions': (print_instructions, goto_game, update_state),
'game': (print_game, control_game, update_game),
'pictures': (print_pictures, goto_game, update_state),
'won': (print_winner, exit_game, update_state)
}
def main(states, data):
"""
Starts the game loop using given states and data
partTypes = (
Bodypart(name="BODY", count=1 , depends=None),
Bodypart(name="NECK", count=1 , depends=0),
Bodypart(name="HEAD", count=1 , depends=1),
Bodypart(name="FEELERS", count=2 , depends=2),
Bodypart(name="TAIL", count=1 , depends=0),
Bodypart(name="LEGS", count=6 , depends=0)
)
Uses a modified version of the MVC (Model View Controller) pattern that uses functions instead of objects
data = {
'state': 'start',
'partNo': None,
'players': {
'YOU': [0] * len(partTypes),
'I': [0] * len(partTypes)
},
'partTypes': partTypes,
'finished': [],
'logs': []
}
each state in the game has one of each of the following:
View, displays data
Control, converts raw command from user into something the model understands
Model, updates game data based on action received from controller
"""
while True:
if 'exit' == data['state']: break
@@ -43,6 +31,9 @@ def main():
Bodypart = namedtuple('Bodypart', ['name', 'count', 'depends'])
def print_start(_):
"""
Prints start message
"""
print_centered("BUG")
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
@@ -54,6 +45,9 @@ def print_start(_):
return input("DO YOU WANT INSTRUCTIONS? ")
def control_start(cmd):
"""
Controls the start state
"""
if cmd.lower() in ('y', 'yes'):
action = 'instructions'
else:
@@ -61,6 +55,9 @@ def control_start(cmd):
return action
def print_instructions(data):
"""
Prints game instructions
"""
print("THE OBJECT OF BUG IS TO FINISH YOUR BUG BEFORE I FINISH")
print("MINE. EACH NUMBER STANDS FOR A PART OF THE BUG BODY.")
print("I WILL ROLL THE DIE FOR YOU, TELL YOU WHAT I ROLLED FOR YOU")
@@ -80,12 +77,22 @@ def print_instructions(data):
return ''
def goto_game(_):
"""
Returns game
"""
return 'game'
def update_state(data, action):
"""
sets game state to given player value
"""
return {**data, 'state': action}
def update_game(data, action):
"""
Updates game data for player turns until one player successfully gets a body part
"""
# stores logs of what happened during a particular round
logs = []
if 'pictures' == action:
@@ -94,16 +101,24 @@ def update_game(data, action):
partAdded = False
while partAdded == False:
for player, parts in data['players'].items():
# rolls the dice for a part
newPartIdx = randint(1,6) - 1
# gets information about the picked part
partType = data['partTypes'][newPartIdx]
# gets the number of existing parts of that type the player has
partCount = parts[newPartIdx]
logs.append(('rolled', newPartIdx, player))
# a new part can only be added if the player has the parts
# the new part depends on and doesn't have enough of the part already
overMaxParts = partType.count < partCount + 1
missingPartDep = partType.depends != None and parts[partType.depends] == 0
if not overMaxParts and not missingPartDep:
# adds a new part
partCount += 1
logs.append(('added', newPartIdx, player))
partAdded = True
@@ -115,13 +130,18 @@ def update_game(data, action):
data['players'][player][newPartIdx] = partCount
data['logs'] = logs
# checks if any players have finished their bug
finished = get_finished(data)
if len(finished) > 0:
# and sets the state to 'won' if that's the case
data['finished'] = finished
data['state'] = 'won'
return data
def get_finished(data):
"""
Gets players who have finished their bugs
"""
totalParts = sum([partType.count for partType in data['partTypes']])
finished = []
for player, parts in data['players'].items():
@@ -129,6 +149,9 @@ def get_finished(data):
return finished
def print_game(data):
"""
Displays the results of the game turn
"""
for log in data['logs']:
code, partIdx, player, *logdata = log
partType = data['partTypes'][partIdx]
@@ -170,6 +193,9 @@ def print_game(data):
return input("DO YOU WANT THE PICTURES? ") if len(data['logs']) else 'n'
def print_pictures(data):
"""
Displays what the bugs look like for each player
"""
typeIxs = { partType.name: idx for idx, partType in enumerate(data['partTypes']) }
PIC_WIDTH = 22
for player, parts in data['players'].items():
@@ -205,6 +231,9 @@ def print_pictures(data):
print()
def control_game(cmd):
"""
returns state based on command
"""
if cmd.lower() in ('y', 'yes'):
action = 'pictures'
else:
@@ -212,14 +241,23 @@ def control_game(cmd):
return action
def print_winner(data):
"""
Displays the winning message
"""
for player in data['finished']:
print(f"{'YOUR' if 'YOU' == player else 'MY'} BUG IS FINISHED.")
print("I HOPE YOU ENJOYED THE GAME, PLAY IT AGAIN SOON!!")
def exit_game(_):
"""
Exists the game regardless of input
"""
return 'exit'
def print_centered(msg, width=PAGE_WIDTH):
"""
Prints given message centered to given width
"""
spaces = " " * ((width - len(msg)) // 2)
print(spaces + msg)
@@ -228,4 +266,45 @@ def print_table(rows):
print(*row, sep="\t")
if __name__ == '__main__':
main()
# The main states in the game
states = {
# Initial state of the game
'start': (print_start, control_start, update_state),
# displays game instructions
'instructions': (print_instructions, goto_game, update_state),
# the main game state
'game': (print_game, control_game, update_game),
# displays pictures before returning to game
'pictures': (print_pictures, goto_game, update_state),
# Displays the winning players and message
'won': (print_winner, exit_game, update_state)
}
# body part types used by the game to work out whether a player's body part can be added
partTypes = (
Bodypart(name="BODY", count=1 , depends=None),
Bodypart(name="NECK", count=1 , depends=0),
Bodypart(name="HEAD", count=1 , depends=1),
Bodypart(name="FEELERS", count=2 , depends=2),
Bodypart(name="TAIL", count=1 , depends=0),
Bodypart(name="LEGS", count=6 , depends=0)
)
# all the data used by the game
data = {
'state': 'start',
'partNo': None,
'players': {
'YOU': [0] * len(partTypes),
'I': [0] * len(partTypes)
},
'partTypes': partTypes,
'finished': [],
'logs': []
}
main(states, data)