Python文本RPG:基于playerCharacter字典实现循环复用的技术求助
Hey 👋,很高兴能帮你优化这个游戏的代码结构!从你的描述和代码来看,你已经有了很好的开局,但确实可以通过一些简单的模式来避免重复编写循环逻辑,让代码更易维护和扩展。
核心思路是:用一个「位置-处理函数」的映射字典,配合一个全局的主循环,这样不管有多少个新地点,都不需要重复写判断和循环的代码。下面一步步来拆解实现:
1. 构建「位置处理映射表」
首先,我们把每个地点对应的处理函数存到一个字典里,替代原来一堆if playerCharacter['Location'] == 'XXX'的判断逻辑。这样新增地点时只需要在字典里加一条记录就行:
# 定义位置与处理函数的映射表 location_handlers = { 'I': introduction, # 初始界面 'BT': beginingTownRng, # 初始城镇随机事件 'LCR': town_crossroads, # Lemphyll镇十字路口 'G': general_store, # 杂货店 # 以后加新地点直接在这里追加键值对即可 }
2. 编写全局主循环
然后写一个统一的主循环,它会持续运行,根据当前角色位置自动调用对应的处理函数。所有地点的逻辑都复用这个循环,不用每个函数里都单独写while循环:
def main_game_loop(): while True: current_loc = playerCharacter['Location'] # 从映射表中获取当前位置的处理函数 handler = location_handlers.get(current_loc) if handler: handler() # 执行对应地点的交互逻辑 else: print(f"未知地点:{current_loc},游戏结束") break # 遇到未知地点时退出循环
3. 重构现有函数适配主循环
现在需要把你原来的函数稍微调整一下,去掉函数内部不必要的循环(除了等待用户输入的交互逻辑),让函数执行完后回到主循环,由主循环根据新的位置继续处理:
示例1:调整初始界面函数
保留等待用户输入Y/N的循环,当用户确认开始后,设置位置并退出函数,主循环会自动处理下一个地点:
def introduction(): print("Hello adventurer and welcome to the realm of Illandria.\n") while playerCharacter['Location'] == 'I': playerCharacter['Name'] = str(input("Whats your name?\n")) startDec = str(input(f"If you are ready to begin this quest, {playerCharacter['Name']}, then just let me know\n(Y)es or (N)o\n")).upper() if startDec == 'N': print("What else is there left to do?") elif startDec == 'Y': print("Great! Exciting things await on your journey's\n") playerCharacter['Location'] = 'BT' break # 退出当前函数,回到主循环
示例2:拆分城镇逻辑
把原来的town_1拆成两个单一职责的函数,让代码更清晰:
def beginingTownRng(): global RNG RNG = random.randint(1,1) if RNG == 1: print("You ride into a small town called, Lemphyll, you notice a board that reads General Store to the east,\nChurch to the West, The Pitted Fall straight along.") playerCharacter['Location'] = 'LCR' # 设置位置为十字路口,回到主循环 def town_crossroads(): global playerInput playerInput = input("Would you like to go to the (G)eneral Store, or maybe the (C)hurch, or the (P)itted Fall:\n").upper() # 根据用户输入更新位置,主循环会自动调用对应处理函数 if playerInput in ['G', 'C', 'P']: playerCharacter['Location'] = playerInput else: print("无效输入,请重新选择!")
示例3:单独抽离杂货店逻辑
把杂货店的交互逻辑单独做成函数,完成后更新位置回到十字路口:
def general_store(): global playerInput print("\nYou walk into a small but well kept General Store. After a walk through you see ordinary supplies light weaponry and food.\nThere is a chubby clean shaven man behind the counter with an eerie grin. He waves at you to come over to him.") playerInput = input("Would you like to go up to the (S)hop Keep, or (L)eave Abruptly\n").upper() if playerInput == 'S': print("\n'Well that's a face I've never seen' say's the Shop Keep.\n'My name is Charlain, but most people call me Charlie. What's your name?'\n") playerInput = input("Do you want to tell him your (N)ame, or (A)sk about supplies?\n").upper() if playerInput == 'N': playerInput = input(f"\n'My name is {playerCharacter['Name']} I'm just coming through looking to see if you had any (R)umors?\nor looking to see what you're (S)elling?'\n").upper() if playerInput == 'R': print("\n'Well I don't know about any rumors but I have heard some people talking about a strange man who just moved in above the bar, The Pitted Fall\nHe says he was contacted by something while walking in the woods'\n") playerInput = input("Would you like to (T)hank him, or (A)sk about supplies").upper() if playerInput == 'T': print("'Thanks for the warm welcome Charlie' you say as you head out the door.\n") repGain(1,'lemphyll') gainXp(1) playerCharacter['Location'] = 'LCR' # 回到十字路口 elif playerInput == 'A': # 处理购买逻辑... pass elif playerInput == 'L': print("'What's the rush stranger I was just trying to have a chat!\nYou leave abruptly and are back at the crossroads of the town.'") repLoss(1,'Lemphyll') gainXp(1) playerCharacter['Location'] = 'LCR' # 回到十字路口
4. 启动游戏
最后只需要调用主循环即可,不用再写一堆零散的if判断:
if __name__ == "__main__": main_game_loop()
额外的小优化建议
- 尽量减少
global变量的使用,可以把playerCharacter作为参数传给函数(比如def repGain(totalRep, townName, player):),避免全局变量的副作用。 - 修复
levelUp函数的判断:现在是if playerCharacter['Xp'] == 10,改成>=10更合理,不然一次获得超过10经验就无法升级了。 - 统一输入的大小写处理(比如用
input().upper()),这样用户输入小写也能被识别。
这样调整后,你新增任何地点只需要两步:写对应的处理函数、在location_handlers里加映射,完全不用重复写循环和位置判断的代码,非常高效!
内容的提问来源于stack exchange,提问作者Chris McLernon
相关产品推荐
相关产品推荐

