I've posted this some time ago. Here is the new version that I made based on all the comments that were made. Another look would be much appreciated, especially on:
Getting rid of the
global
statementsI read about the use of the
return
statement which is bad practice in some situations (see code). Is that correct?The
if
elif
else
way of coding the menu (at the bottom) which was proposed to be put in a list and then calling the list items. I did not manage to get the first option of actually playing the game to work.
import random
import time
from itertools import cycle
class Die:
def __init__(self, name):
self.name = name
self.options = []
self.pick = 0
def add(self):
print('Enter {0} and press enter. Enter "q" when done.\n'.format(self.name))
while True:
additem = input('Add: ')
if additem.lower() == 'q':
break
elif additem == '':
continue
else:
self.options.append(additem.lower().replace(' ', '_'))
def roll(self):
self.pick = random.choice(self.options)
def addactions():
print('Add actions to the dice. Enter "q" when done')
while True:
nextitem = input("Add: ")
if nextitem == '':
continue
elif nextitem.lower() == 'q':
break
else:
actionDie.options.append(nextitem.lower().replace(' ', '_'))
def addbp():
print('Add body parts to the dice. Enter "q" when done')
while True:
nextitem = input("Add: ")
if nextitem == '':
continue
elif nextitem.lower() == 'q':
break
else:
bpDie.options.append(nextitem.lower().replace(' ', '_'))
def load():
# Load each one in its correct list and players in each variable
# What is already in the lists will still be there
while True:
loadfile = input('Enter file name to LOAD (including ".txt"): ')
print()
if loadfile.lower() == 'q':
return # It was told to me that using return like this is bad, true?
try:
with open(loadfile, 'rt') as file:
for line in file:
errormessage = line
line = line.split()
if 'action:' in line:
line.remove('action:')
newitem = ''
newitem = newitem.join(line)
actionDie.options.append(newitem)
elif 'bodypart:' in line:
line.remove('bodypart:')
newitem = ''
newitem = newitem.join(line)
bpDie.options.append(newitem)
elif 'player1:' in line:
line.remove('player1:')
newitem = ''
newitem = newitem.join(line)
global player1
player1 = newitem
elif 'player2:' in line:
line.remove('player2:')
newitem = ''
newitem = newitem.join(line)
global player2
player2 = newitem
else:
print("ERROR: item", errormessage, "not loaded")
except FileNotFoundError:
print("That didn't work out! File does not exist or wrong file location.")
print("Did you forget to add .txt?")
print("Try again, or enter 'q' to return to main menu.")
print()
break
global players
players = cycle([player1, player2])
# Tell user what is loaded
print('Loaded players:')
print('-', player1)
print('-', player2)
print()
print('Action die now contains:')
for item in actionDie.options:
print('-', item)
print()
print('Body parts die now contains:')
for item in bpDie.options:
print('-', item)
print()
print('Loading complete')
print()
# Set list to cycle through (since enterplayers() was not used)
global playerlist
playerlist = [player1, player2]
global player
player = cycle(playerlist)
def printdice():
print('The body part die contains the following:')
for item in bpDie.options:
print('\t- {0}'.format(item))
print()
print('The actions die contains the following:')
for item in actionDie.options:
print('\t- {0}'.format(item))
def removeactions():
print("Removing from the actions die.\n")
while True:
print('The action die currently contains:')
for index, item in enumerate(actionDie.options):
print('{0} - {1}'.format(index + 1, item))
print()
try:
indexnr = int(input("Type the number of the item you wish to remove or enter '0' to quit: "))
except ValueError:
print('Please enter a number!\n')
continue
if indexnr == 0:
break
indexnr -= 1
try:
actionDie.options.remove(actionDie.options[indexnr])
except IndexError:
print('Invalid number!\n')
continue
def removebodyparts():
print("Removing from the body parts die.\n")
while True:
print('The body parts die currently contains:')
for index, item in enumerate(bpDie.options):
print('{0} - {1}'.format(index + 1, item))
print()
try:
indexnr = int(input("Type the number of the item you wish to remove or enter '0' to quit: "))
except ValueError:
print('Please enter a number!\n')
continue
if indexnr == 0:
break
indexnr -= 1
try:
bpDie.options.remove(bpDie.options[indexnr])
except IndexError:
print('Invalid number!\n')
continue
def save():
print()
print("Save including '.txt', any existing file will be overwritten!\n")
while True:
savename = input('SAVE to what file? ')
if '.txt' in savename:
break
print("Don't forget .txt!\n")
with open(savename, 'wt') as file:
try:
file.write('player1: {0}\n'.format(player1))
file.write('player2: {0}\n'.format(player2))
except NameError:
pass
for item in actionDie.options:
file.write('action: {0}\n'.format(item))
for item in bpDie.options:
file.write('bodypart: {0}\n'.format(item))
print('\nSuccessfully saved the following data to file "{0}":'.format(savename))
try:
print('Player 1:', player1)
print('Player 2:', player2)
print()
except NameError:
pass
for item in actionDie.options:
print('Action:', item)
print()
for item in bpDie.options:
print('Body part:', item)
print()
def setplayers():
global player1
player1 = input('Enter player 1 name: ')
global player2
player2 = input('Enter player 2 name: ')
return cycle([player1, player2])
MAIN_MENU = '''
- - - - - - - - - - - -
MAIN MENU
1. Start game
2. Enter player names
3. Show dice
4. Add actions
5. Add body parts
6. Remove actions
7. Remove body parts
8. Load data
9. Save data
i. Print instructions
q. Quit
- - - - - - - - - - - -
'''
INSTRUCTIONS = '''
Before starting the game you must set the following:
- Names of the players
- Actions (touch, kiss, etc.)
- Body parts
You can also just load a file with game data.
You do not need to capitalize, this is done automatically.
When this is done you can play the game!
Notice that when you use the load function,
all previously loaded data will be removed.
'''
bpDie = Die('body part')
actionDie = Die('action')
player1 = ''
player2 = ''
if __name__ == '__main__':
while True:
print(MAIN_MENU)
menuchoice = input('Choice: ')
if menuchoice == '1':
if player1 == '' or player2 == '':
print("\nPlayer name(s) not set!\n")
time.sleep(2)
continue
if not actionDie.options:
print("\nNo actions in die!\n")
time.sleep(2)
continue
if not bpDie.options:
print("\nNo body parts in die!\n")
time.sleep(2)
continue
print('- - - - - - - -')
print('STARTING GAME!')
while True:
nextplayer = input('Enter name of first player or press enter to pick randomly: ')
if nextplayer in (player1, player2):
# Set "next(players)" to the correct one (the person that will come after the first player)
nextplayercheck = nextplayer
nextplayer = next(players)
if nextplayer != nextplayercheck:
nextplayer = next(players)
break
elif nextplayer == '':
topickfrom = [player1, player2]
nextplayer = random.choice(topickfrom)
nextplayercheck = nextplayer
print('\nThe first player is {0}!'.format(nextplayer))
# If the next player is not next in the `cycle()`, then sets it so.
nextplayer = next(players)
if nextplayer != nextplayercheck:
nextplayer = next(players)
break
else:
print('That person is not playing!')
# START PICKING AND RETURNING THE ITEMS HERE
while True:
actionDie.roll()
bpDie.roll()
print('\nOkay {0}\n,'.format(nextplayer))
time.sleep(1)
nextplayer = next(players)
print(actionDie.pick + " ", end="", flush=True)
time.sleep(1)
print(nextplayer + "'s ", end="", flush=True)
time.sleep(1)
print(bpDie.pick, end=' ', flush=True)
time.sleep(1)
print(str(random.randrange(1, 11)) + ' times!')
time.sleep(1)
print('\n\n')
anotherone = input('Press enter for another, type anything to quit to main menu.')
if anotherone == '':
print()
continue
else:
print('\nReturning to main menu')
print()
break
elif menuchoice == '2':
players = setplayers()
player1 = next(players)
player2 = next(players)
elif menuchoice == '3':
printdice()
elif menuchoice == '4':
addactions()
elif menuchoice == '5':
addbp()
elif menuchoice == '6':
removeactions()
elif menuchoice == '7':
removebodyparts()
elif menuchoice == '8':
load()
elif menuchoice == '9':
save()
elif menuchoice.lower() == 'i':
print(INSTRUCTIONS)
elif menuchoice.lower() == 'q':
quit()
else:
print('Please pick a valid number or letter\n')
lowercase_with_underscores
(PEP 8). And spell out the name ofaddbp
asadd_body_parts
, to matchremove_body_parts
. \$\endgroup\$