如何在循环中创建对象并应用方法

3
我使用pygame在python中创建了一个井字棋游戏的版本,最终游戏效果比预期要好,我感到很高兴。然而,代码看起来相当混乱,我想对其进行整理。为了让代码正常工作,我创建了9个精灵类(sprite class)的对象。但是,每当我需要对它们应用一个方法时,我就必须写出同样的一行代码九次,只有一个数字不同。为了解决这个问题,我想知道是否有任何方法可以运行相同的脚本来操作这九个对象。程序首先通过创建这些对象来启动:
board_0 = classes.sprite.Sprite(x = 250, y = 200)
board_0.set_image('board.png')
board_1 = classes.sprite.Sprite(x = 350, y = 200)
board_1.set_image('board.png')
board_2 = classes.sprite.Sprite(x = 450, y = 200)
board_2.set_image('board.png')
board_3 = classes.sprite.Sprite(x = 250, y = 300)
board_3.set_image('board.png')
board_4 = classes.sprite.Sprite(x = 350, y = 300)
board_4.set_image('board.png')
board_5 = classes.sprite.Sprite(x = 450, y = 300)
board_5.set_image('board.png')
board_6 = classes.sprite.Sprite(x = 250, y = 400)
board_6.set_image('board.png')
board_7 = classes.sprite.Sprite(x = 350, y = 400)
board_7.set_image('board.png')
board_8 = classes.sprite.Sprite(x = 450, y = 400)
board_8.set_image('board.png')

是否可以使用for循环在几行代码中创建这些内容,而不是需要18行。相同的解决方案希望能在代码的其他地方也适用,我有这两个部分需要针对每个对象重复9次:

if board_0.mouse_hover() and grid[0] == 0:
        if   turn == 0: board_0.set_image('cross.png')
        elif turn == 1: board_0.set_image('nought.png')
    else:
        if grid[0] == 0:  board_0.set_image('board.png')

if board_0.mouse_click() and grid[0] == 0:
    if  turn == 0:
        board_0.set_image('cross.png')
        grid[0] = 'X'
        turn = 1
    elif turn == 1:
        board_0.set_image('nought.png')
        grid[0] = 'O'
        turn = 0

对于那些想知道的人,我在代码开头设置了gridgrid = [0, 0, 0, 0, 0, 0, 0, 0, 0]。那么要实现我想要的结果,有什么方法呢?我相信我以前遇到过这个问题,但当时我不知道Stack Overflow,所以如果确实有解决办法,我将更新一些其他程序。


4
可以做到。如果你为你的对象创建一些集合,而不是每个对象都有一个唯一的变量,那么这可能会更容易。 - sco1
你建议作为集合的是什么样的东西,我不太确定你的意思? - George Willcox
集合是任何作为 -er - 对象集合的复合数据结构。例如 listdicttuple 等。 - juanpa.arrivillaga
1
就像将变量放入容器中,或在容器中创建类的实例一样,例如:container = [classes.sprite.Sprite(x = 250, y = 200), classes.sprite.Sprite(x = 350, y = 200) ... ] - George Willcox
我认为你应该在http://codereview.stackexchange.com/上发布你的完整代码,以获得更多建议。 - skrx
显示剩余2条评论
2个回答

5
你可以使用列表推导式并迭代你的参数来创建所有 Sprite 的实例。
from itertools import product

x_coords = [250, 350, 450]
y_coords = [200, 300, 400]

boards = [classes.sprite.Sprite(x=x, y=y) for x, y in product(x_coords, y_coords)]

for board in boards:
    board.set_image('board.png')

board_0因此变成了boards[0]。使用itertools.product就是为了简化你在示例中编写的x,y对。


2
你也必须更改 y 坐标。 - skrx
1
@skrx 是的,不需要使用 repeat,只需使用 (200, 300, 400) - juanpa.arrivillaga

3
我注意到您说“应用方法”,但实际上,您正在对类型的实例调用方法。
您可以尝试类似以下的代码:
def set_my_sprites(x_start, y_start)
    sprites = []
    for y_mx in range(1, 4):
        for x_mx in range(1, 4):
            board_x = classes.sprite.Sprite(x = x_start*x_mx, y = y_start*y_mx)
            board_x.set_image('board.png')
            sprites.append(board_x)
     return sprites

然后稍后只需调用此函数,如下:

set_my_sprites(x_start=250, y_start=200)

您可以尝试更改调用签名等内容以获得更多的灵活性。

在这种情况下,我返回精灵数组,在以后需要时您可以对其进行操作,但如果没有要求,我想您可能不需要它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接