Python纸牌游戏开发中字典索引列表触发KeyError问题求助
问题排查与修复方案
1. KeyError触发的核心原因
你在remove_card函数中重复做了索引转换,直接导致查询字典失败:
- 在
choose_card函数中,你已经通过change字典把输入的字母转成了0-7的数字索引,赋值给了v1、v2两个参数 - 到了
remove_card函数里,你又把已经是数字的v1、v2当成字母去查change字典,而change字典只有'A'-'H'的字符串键,没有数字键,自然就触发KeyError。
2. 其他需要修复的逻辑错误
- 无效嵌套问题:你定义
piles的时候把每个牌堆又额外套了一层列表:piles = [[pile1], [pile2], ...],完全冗余,直接改成piles = [pile1, pile2, pile3, pile4, pile5, pile6, pile7, pile8]即可,否则会导致后续索引取值多写不必要的层级,容易出问题。 - 函数调用不匹配:
spill()函数里调用的是velg_kort(),但你实际定义的处理输入的函数是choose_card(),直接运行会触发NameError,要把调用处改成choose_card()。 - 执行顺序错误:你在定义
choose_card、remove_card两个函数之前就调用了spill(),运行时会找不到这两个函数,要把spill()的调用移到所有函数定义之后。 - 输入大小写兼容问题:如果用户输入小写的a、b等字符,你的
change字典只有大写键,也会触发KeyError,建议把输入的字符转大写后再查询字典,同时增加非法字符校验。 - 多余的重复赋值:
spill()执行完你又重新给piles赋值了一次,完全没有必要,可以删掉。
3. 修复后的核心代码示例
import random SPAR_SYMBOL = '\u2660' RUTER_SYMBOL = '\u2666' KLØVER_SYMBOL = '\u2663' HJERTER_SYMBOL = '\u2665' kortstokk = [] pile1 = [] pile2 = [] pile3 = [] pile4 = [] pile5 = [] pile6 = [] pile7 = [] pile8 = [] for kort in range(7, 15): kortstokk.append(f'\u2660{kort}') kortstokk.append(f'\u2666{kort}') kortstokk.append(f'\u2663{kort}') kortstokk.append(f'\u2665{kort}') # 修正piles定义,去掉多余嵌套 piles = [pile1, pile2, pile3, pile4, pile5, pile6, pile7, pile8] def del_ut(): random.shuffle(kortstokk) # 简化冗余的if判断,直接用索引操作牌堆 for j in range(4): for i in range(8): piles[i].append(kortstokk.pop()) def tap(): pass def seier(): pass def lagre(): pass def last_inn(): pass def choose_card(): global piles cards = input("choose two piles of cards: ").upper() # 转大写兼容小写输入 change= {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7} # 增加输入合法性校验,避免非法字符触发KeyError if len(cards) == 2 and cards[0] in change and cards[1] in change: v1 = change[cards[0]] v2 = change[cards[1]] remove_card(v1, v2) else: print("Invalid input.") def remove_card(v1, v2): global piles # 去掉多余的change查询,直接用传入的数字索引 if v1 != v2 and piles[v1][-1][-1] == piles[v2][-1][-1]: piles[v1].pop(-1) piles[v2].pop(-1) # 可增加判断所有牌堆为空时触发胜利逻辑 if all([len(p) == 0 for p in piles]): seier() def spill(): del_ut() while True: # 取值简化,去掉多余的嵌套层级 print("A: ", piles[0][-1]) print("B: ", piles[1][-1]) print("C: ", piles[2][-1]) print("D: ", piles[3][-1]) print("E: ", piles[4][-1]) print("F: ", piles[5][-1]) print("G: ", piles[6][-1]) print("H: ", piles[7][-1]) choose_card() # 修正函数名调用 # spill()调用移到所有函数定义之后 spill()
关于问题表述的建议
你的表述非常清晰,已经把需求、预期效果、遇到的问题都讲清楚了,还附上了完整可复现的代码,完全符合技术提问的要求,不需要调整。
内容的提问来源于stack exchange,提问作者Sondre
相关产品推荐
相关产品推荐

