You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为文字版《植物大战僵尸》实现攻击函数与僵尸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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 05:48:24