如何为文字版《植物大战僵尸》实现攻击函数与僵尸HP系统?
文字版《植物大战僵尸》开发难题
我正在开发一款控制台运行的文字版《植物大战僵尸》,目前碰到两个核心问题:
- 无法实现单行道内植物与僵尸的攻击逻辑
- 不知道怎么给每个僵尸做可持久化的当前HP系统
我尝试用嵌套循环遍历作为地图的嵌套数组,检测到豌豆射手(Peashooter)和僵尸(Zombie)时打印伤害信息并让僵尸承受随机伤害,但现在代码会重复打印“A lane”超过30次,完全无法正常运行。
现有代码
import random peashooter = {'shortform' : 'PEASH', 'name': 'Peashooter', 'maxHP': 5, 'min_damage': 1, 'max_damage': 4, 'price': 5 } zombie = {'shortform': 'ZOMBI', 'name': 'Zombie', 'maxHP': 15, 'min_damage': 3, 'max_damage': 6, 'moves' : 1, 'reward': 2 } field = [ [("PEASH"," 5/5 "), None, None, None, ("ZOMBI", "15/15"), None, None], [None, ("PEASH"," 5/5 "), None, None, None, None, ("ZOMBI", "15/15")], [None, None, ("PEASH"," 5/5 "), None, None, ("ZOMBI", "15/15"), None], [None, ("PEASH"," 5/5 "), None, None, ("ZOMBI", "15/15"), None, None], [("PEASH"," 5/5 "), None, None, None, None, None, ("ZOMBI", "15/15")] ] num_rows=len(field) num_columns=len(field[0]) row_indexes="ABCDE" # 用来给每行命名 def defender_attack(defender_name, field, row, column): damage= random.randint(1,4) print('{} in lane {} shoots {} for {} damage'.format(defender_name['shortform'], row_indexes[x], zombie['shortform'], damage)) #zombie 'currenthp' -= damage # 还没搞懂怎么实现存储所有僵尸HP的系统 #if zombie[' hp '] <= 0: #print('someone died') #element = None return # 主逻辑开始 x=0 for row in field: isPeash, isZombi = False, False for cell in row: if cell: name, hp = cell if name == 'PEASH': isPeash = True elif name == 'ZOMBI': isZombi = True if isPeash and isZombi == True: for column in row: defender_attack(peashooter,field,row,column)
期望实现效果
豌豆射手在D路射击僵尸,造成4点伤害! D路的僵尸前进! 1 2 3 4 5 6 7 +-----+-----+-----+-----+-----+-----+-----+ A| | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+ B| | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+ C| | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+ D|PEASH| | | | |ZOMBI| | | 5/5 | | | | |11/15| | +-----+-----+-----+-----+-----+-----+-----+ E| | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+
问题解决思路
1. 修复重复攻击的逻辑问题
原代码中,一旦检测到某行同时存在豌豆和僵尸,就会遍历整行所有单元格触发攻击,导致重复执行。正确逻辑应为:每行仅触发一次攻击,且只有当豌豆在僵尸左侧时才生效。
修改后的主循环示例:
x=0 for row in field: peash_pos = -1 zombie_pos = -1 # 记录该行内豌豆和僵尸的位置 for idx, cell in enumerate(row): if cell: name, _ = cell if name == 'PEASH' and peash_pos == -1: peash_pos = idx # 记录最左侧的豌豆位置 elif name == 'ZOMBI': zombie_pos = idx # 记录最靠近豌豆的僵尸位置 # 豌豆在僵尸左侧时才触发攻击 if peash_pos != -1 and zombie_pos != -1 and peash_pos < zombie_pos: defender_attack(peashooter, field, x, zombie_pos) x += 1
2. 实现僵尸HP持久化
原代码用元组存储单位信息,元组不可修改,无法更新HP。改为用列表存储,直接修改当前HP值:
修改后的字段与攻击函数示例:
# 用列表存储单位信息:[标识, 当前HP, 最大HP] field = [ [["PEASH", 5, 5], None, None, None, ["ZOMBI", 15, 15], None, None], [None, ["PEASH", 5, 5], None, None, None, None, ["ZOMBI", 15, 15]], [None, None, ["PEASH", 5, 5], None, None, ["ZOMBI", 15, 15], None], [None, ["PEASH", 5, 5], None, None, ["ZOMBI", 15, 15], None, None], [["PEASH", 5, 5], None, None, None, None, None, ["ZOMBI", 15, 15]] ] def defender_attack(defender_name, field, row_idx, zombie_col_idx): damage = random.randint(defender_name['min_damage'], defender_name['max_damage']) zombie = field[row_idx][zombie_col_idx] zombie[1] -= damage # 更新僵尸当前HP print('{} in lane {} shoots {} for {} damage'.format(defender_name['shortform'], row_indexes[row_idx], zombie[0], damage)) # 僵尸死亡则移除 if zombie[1] <= 0: print('{} in lane {} has been defeated!'.format(zombie[0], row_indexes[row_idx])) field[row_idx][zombie_col_idx] = None
3. 实现地图打印功能
添加专门的打印函数生成网格格式:
def print_field(field): print(" 1 2 3 4 5 6 7") print(" +-----+-----+-----+-----+-----+-----+-----+") for row_idx, row in enumerate(field): line1 = f"{row_indexes[row_idx]}|" line2 = " |" for cell in row: if cell: line1 += f"{cell[0]:<5}|" hp_str = f"{cell[1]}/{cell[2]}" line2 += f"{hp_str:^5}|" else: line1 += " |" line2 += " |" print(line1) print(line2) print(" +-----+-----+-----+-----+-----+-----+-----+")
攻击逻辑执行后调用print_field(field)即可输出期望的地图样式。
内容的提问来源于stack exchange,提问作者user19198861
相关产品推荐
相关产品推荐

