So this is just the beginning of a long line of questions I know that I am going to have. In this text based adventure I would like to eventually have puzzles and multiple branching paths, factions you can eventually join, choice dialogue that affects the morality of situations(like mass effect or kotor but.. text based-ish), etc., etc., but I feel like the early set up is VERY important for this learning journey. I also would like to eventually convert it over to PYQT5 and maybe eventually host it with a UI on a website I've built for my portfolio. I just wanted to get that out of the way in case you see me on here a lot. PM me with advice for that if you'd like(Because I definitely could use the help from a patron saint!).
I have a list of races to choose from:
races = ['Human', 'Dwarf', 'Elf', 'Dragonborn', 'Tiefling', 'Half-Elf']
I would like for it to ask the player to 'Choose a race'. After the player types what they want to play it asks 'Are you sure?' |Here is where I am stuck| If the player says 'yes' it ends the program and I can attempt to continue building this application. If the player types 'no', it doesn't return back to the original question and allow them to answer it again.
So, the things I have tried are defined as different methods:
Character.charRace()
Character.charDict()
Character.charTry()
I think my poor code attempts speak for themselves in terms of what I've been trying.
class Character:
def charRace():
raceOptions = ['Human', 'Dwarf', 'Elf', 'Dragonborn', 'Tiefling', 'Half-Elf']
raceChoice = input(f'Choose a Race: {raceOptions} \n')
if raceChoice == 'Human':
res = input(
"""
Choose Human?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
if res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
res = input(
"""
Choose Human?
(Y / N)
""")
if raceChoice == 'Dwarf':
res = input(
"""
Choose Dwarf?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
if res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
if raceChoice == 'Elf':
res = input(
"""
Choose Elf?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
if res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
if raceChoice == 'Dragonborn':
res = input(
"""
Choose Dragonborn?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
if res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
if raceChoice == 'Tiefling':
res = input(
"""
Choose Tiefling?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
if res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
if raceChoice == 'Half-Elf':
res = input(
"""
Choose Half-Elf?
(Y / N)
""")
if res == 'Y':
print(f'You Chose {raceChoice}!')
while res == 'N':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
res = input(
"""
Choose Half-Elf?
(Y / N)
""")
if raceChoice == 'Orc':
res = input(
"""
Choose Orc?
(Y / N)
""")
while res:
if res == 'y':
print(f'You Chose {raceChoice}!')
break
if res == 'n':
del raceChoice
raceChoice = input(f'Choose a Race: {raceOptions} \n')
res = input(
"""
Choose Orc?
(Y / N)
""")
def charDict():
raceOptions = ['Human', 'Dwarf', 'Elf', 'Dragonborn', 'Tiefling', 'Half-Elf']
raceChoice = input(f'Choose a Race: {raceOptions} \nRace: ')
if raceChoice == 'Human' or 'human' or 'h':
print(f'Choose {raceChoice}?\n')
ans = input()
if ans != 'Yes' or 'yes' or 'y':
print(f'You chose {raceChoice}! ')
elif ans == 'No' or 'no' or 'n':
return raceChoice
if raceChoice != 'Human' or 'human' or 'h' or 'Dwarf' or 'dwarf' or 'd' or 'Elf' or 'elf' or 'e' or 'Dragonborn' or 'dragonborn' or 'DB' or 'Tiefling' or 'tiefling' or 't':
return 'That is not a race that can be chosen at this time!'
def charTry():
races = ['Human', 'Dwarf', 'Elf', 'Dragonborn', 'Tiefling', 'Half-Elf']
res = input(f'Choose a Race: {races}. \nRace: ')
race = res.capitalize()
if race in races:
if race == 'human' or 'Human' or 'h':
print(f'Do you want to choose {race}? ')
Character.charRace()
Character.charDict()
Character.charTry()
>>> f'Choose a race {races}!:
>>> Human
>>> Do you want to play a Human?
>>> (Y / N)
>>> N
>>> Continue to browse...
>>> Choose a race: Human, Dwarf, Elf, Dragonborn, Tiefling, Half-Elf
>>> Dwarf
>>> Do want to play a Dwarf?
>>> Y
>>> You have chosen to play a Dwarf!
I've tried a few different methods to acquire the desired result but they don't seem to work. Should I build a finite state machine? How would I do that? What is the best method for longevity and making the code modular for future update?
What you are try to do is to build a menu, where the user may make choices and confirm and retry their choices as often as necessary.
The way to do this is with an infinite while loop. Essentially, you just want to keep repeating the same set of options until the user makes a selection, or quits.
Also, try to keep your code indifferent to the particular selection that the user makes. We care that they select an item from the list; we don't need to care which item, as long as we have some way of retrieving it when necessary. In the following code, note that there is no explicit mention of the individual races except in the original list.
class Character:
RACES = ['Human', 'Dwarf', 'Elf', 'Dragonborn', 'Tiefling', 'Half-Elf']
def choose(self):
# list choices as (0) Human, (1) Dwarf etc
choices = ', '.join([f'({i}) {race}' for i, race in enumerate(self.RACES)])
# Loop forever!
while True:
choice = input(f'Choose a race: {choices} ')
choice = choice.upper()
if choice == 'Q':
print('Bye!')
# Break out of the loop
break
elif not(choice.isdigit()):
# Not a number
print('Sorry, please choose a number')
elif not 0 <= int(choice) <= len(self.RACES):
# Number outside the range of choices
print('Sorry, please choose again')
else:
# The number input by the user matches the position
# of their choice in the list of races
selection = self.RACES[int(choice)]
confirm = input(f'You chose {selection} - confirm (Y/N)? ')
if confirm.upper() == 'Y':
print(f'Confirmed - you\'re a {selection}!')
# Break out of the loop
break
else:
print('OK, let\'s try again')
return