I’m starting a rudimentary text adventure game. I got a prototype working, but because each choice is a function, I can’t figure out how to safely save my place in a file.
I considered saving the function’s name to a file, but I can’t think of a good way to get the function from its name as a
str after reading the file.
eval on an arbitrary
str is notoriously unsafe. I considered a
dict mapping every function to its name as a
str, but it seems that as more choices pile up, this
dict is gonna bloat my script.
def choice1(): while True: text = input("A or B?: ") if text == "A": return False, choice2 elif text == "B": saygameover() return True, None elif askedforsave(text): return True, choice1 else: saytryagain() def choice2(): while True: text = input("C or D?: ") if text == "C": print("you win!") return True, None elif text == "D": saygameover() return True, None elif askedforsave(text): return True, choice2 else: saytryagain() def askedforsave(text): if text == "save": return True else: return False def saytryagain(): print("try again...") def saygameover(): print("game over.") def play(choice = choice1): done = False while not done: done, choice = choice() if choice != None: save(choice) def save(choice): pass def load(file): pass return choice
This is what I got so far.
isidentifier is probably unnecessary when I’m already checking for a name in
globals() but it’s a good trick for making sure you’re working with a valid Python name instead of an expression.
import types def load(string): # if string is valid Python name if (string.isidentifier() and # if string in this global scope's symbol table string in (thisglobal := globals()) and # if object is a non-builtin function isinstance(something := thisglobal[string], types.FunctionType)): return something else: return nogame def nogame(): return True, None