首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >植物大战僵尸模拟器

植物大战僵尸模拟器
EN

Code Review用户
提问于 2022-02-10 14:49:57
回答 1查看 310关注 0票数 6

我在做一个pvz模拟器。我们有一个游戏板,有1=农民和2=僵尸:

代码语言:javascript
复制
[[(1, <__main__.Plant object at 0x0000011F0FDDA4C0>), (2, <__main__.Zombie object at 0x0000011F0F73D100>), 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0]]

当农夫目标射击豌豆十次时,僵尸就会被打败并消失。如果它们不在同一排,或者农民在僵尸前面,豌豆对特定的僵尸没有影响。

我的代码:

代码语言:javascript
复制
class Object:
    def __init__(self, objtype, row, column, name=None):
        self.pos = self.row, self.column = row, column
        self.name = name
        self.setup = setup
        setup[row][column] = (objtype, self)


class Plant(Object):
    def __init__(self,row, column, name=None, aoe=1, damage=1):
        super().__init__(1, row, column, name)
        self.aoe = aoe
        self.damage = damage

    def shoot(self):
        location = self.setup[self.row][self.column]
        curr_column = self.column
        while True:
            try:
                if location[0] == 2:  # zombie
                    location[1].hit(self)
                    return
            except IndexError:
                pass

            try:
                location = self.setup[self.row][curr_column]
            except IndexError:
                return
            curr_column += 1


class PlantTypes:
    @staticmethod
    def peashooter(row, column, name=None):
        return Plant(row, column, name)


class Zombie(Object):
    def __init__(self, row, column, name=None, health=10):
        super().__init__(2, row, column, name)
        self.health = health

    def hit(self, plant):
        self.health -= plant.damage
        if self.health <= 0:
            setup[self.row][self.column] = 0


class ZombieTypes:
    @staticmethod
    def basezombie(row, column, name=None):
        return Zombie(row, column, name)


setup = [
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]
]

p0 = PlantTypes.peashooter(0, 0)
z0 = ZombieTypes.basezombie(0, 1)
print(setup)
for i in range(10):
    p0.shoot()

print(setup)

对可读性/性能/其他有何建议?

EN

回答 1

Code Review用户

回答已采纳

发布于 2022-02-10 19:30:20

shoot目前是Plant上的一种方法,但我认为这是一种错误的责任分配。该功能的大部分工作是在电网上,而不是在工厂上。考虑创建一个网格类,并将其与碰撞(如射击)结合起来。

类似地,让僵尸在死亡时将自己从网格中删除(重死?)是一种错误的责任分配。

objtype整数使用起来不方便,约束也不充分。考虑只保留对对象实例的直接引用,而不是网格中的类型对象元组。

捕获IndexError是一种代码嗅觉,也是不正确算法的指示。这可以通过适当的迭代来避免。

您的工厂和僵尸类型类是多余的,可以删除。

0作为网格中的默认条目没有多大意义,因为您希望所有条目都是类型对象对。如果网格只包含对象引用,那么单个None就更有意义了。

考虑在类中添加漂亮的打印方法。

建议

代码语言:javascript
复制
from numbers import Real
from typing import Optional


class Object:
    def __init__(self, row: int, column: int, name: Optional[str] = None) -> None:
        self.row, self.column = row, column
        self.name = name


class Plant(Object):
    def __init__(self, row: int, column: int, name: Optional[str] = None, aoe: Real = 1, damage: Real = 1) -> None:
        super().__init__(row, column, name)
        self.aoe = aoe
        self.damage = damage

    def __str__(self) -> str:
        return self.name[:3] if self.name else 'pla'


class Zombie(Object):
    def __init__(self, row: int, column: int, name: Optional[str] = None, health: Real = 10) -> None:
        super().__init__(row, column, name)
        self.health = health

    def hit(self, damage: Real) -> None:
        self.health -= damage

    def __str__(self) -> str:
        return f'Z{self.health:2d}'


class Grid:
    def __init__(self, m: int, n: int) -> None:
        self.m, self.n = m, n
        self.grid: list[list[Optional[Object]]] = [
            [None]*n
            for _ in range(m)
        ]

    def add(self, obj: Object) -> None:
        self.grid[obj.row][obj.column] = obj

    def shoot(self, plant: Plant) -> None:
        row = self.grid[plant.row]
        for col in range(1+plant.column, self.n):
            zombie = row[col]
            if isinstance(zombie, Zombie):
                zombie.hit(plant.damage)
                if zombie.health <= 0:
                    row[col] = None
                break

    def describe(self) -> str:
        return '\n'.join(
            ' '.join(
                f'{str(o):3s}' if o else ' . '
                for o in row
            )
            for row in self.grid
        )


def main() -> None:
    grid = Grid(m=3, n=4)

    p0 = Plant(row=0, column=0, name='peashooter')
    z0 = Zombie(row=0, column=1, name='basezombie')
    grid.add(p0)
    grid.add(z0)
    print(grid.describe())

    for _ in range(10):
        grid.shoot(p0)

    print()
    print(grid.describe())


if __name__ == '__main__':
    main()

输出

代码语言:javascript
复制
pea Z10  .   . 
 .   .   .   . 
 .   .   .   . 

pea  .   .   . 
 .   .   .   . 
 .   .   .   . 
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/273953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档