首页 > 解决方案 > 为什么我的 pygame.group 在循环中时有一个空值?

问题描述

我目前正在编写奥赛罗的 pygame 版本。我试图实现一个函数“flip_piece”,它将单件从白色翻转到黑色,反之亦然。但是,它涉及找到要翻转的部分,并且在这样做时我必须遍历我的部分列表,然后尽管我已经填充了它,但它返回一个空值。

为什么会这样,我能做些什么来解决它?

import pygame

white = (255, 255, 255)
black = (0, 0, 0)


class Piece(pygame.sprite.Sprite):
    def __init__(self, colour, x, y):
        super().__init__()
        self.colour = colour
        self.x = x
        self.y = y


def set_up_pieces(piece_list):
    s = Piece(white, 4, 4)
    piece_list.add(s)
    s = Piece(black, 5, 4)
    piece_list.add(s)
    s = Piece(white, 5, 5)
    piece_list.add(s)
    s = Piece(black, 4, 5)
    piece_list.add(s)
    return piece_list


def flip_piece(piece_list, move, i, flip, player):
    for p in piece_list:
        if p.x == move[0] + (i + 1) * flip[0] and p.y == move[1] + (i + 1) * flip[1]:
            new_piece = Piece(player, p.x, p.y)
            piece_list.add(new_piece)
            piece_list.remove(p)
            return piece_list


def main():
    piece_list = pygame.sprite.Group()
    piece_list = set_up_pieces(piece_list)
    player_to_move = white
    # this simulates a move
    move = [5, 3]
    new_piece = Piece(player_to_move, move[0], move[1])
    piece_list.add(new_piece)
    flip = [-1, 0, 2]
    for i in range(flip[2]):
        piece_list = flip_piece(piece_list, move, i, flip, player_to_move)


main()

注意:翻转变量包含 x、y 的翻转方向以及所需的翻转次数。理解该解释可能需要奥赛罗知识。

标签: pythonpython-3.xpygame

解决方案


piece_list正在成为None,因为它被设置为输出flip_piece()

...
def flip_piece(piece_list, move, i, flip, player):
    for p in piece_list:
        if p.x == move[0] + (i + 1) * flip[0] and p.y == move[1] + (i + 1) * flip[1]:
            new_piece = Piece(player, p.x, p.y)
            piece_list.add(new_piece)
            piece_list.remove(p)
            return piece_list
...
def main():
    ...
    for i in range(flip[2]):
        piece_list = flip_piece(piece_list, move, i, flip, player_to_move)
    ...

如果至少修改了一项,则问题是flip_piece()返回列表。这是因为 return 语句位于 if 语句中,因此在调用 flip_piece 时最多修改了一个片段。piece_list()

但是,piece_list如果没有翻转任何棋子,则不会返回。在python中,如果没有return语句,则函数返回一个None对象。正是这个对象正在创建错误消息。

根据奥赛罗的规则(以及对代码功能的一些理解),我相信您的函数应该如下所示:

def flip_piece(piece_list, move, i, flip, player):
    for p in piece_list:
        if p.x == move[0] + (i + 1) * flip[0] and p.y == move[1] + (i + 1) * flip[1]:
            new_piece = Piece(player, p.x, p.y)
            piece_list.add(new_piece)
            piece_list.remove(p)
            return piece_list
    return piece_list

这将使它始终有一个返回列表,并解决问题。

然而pygame.sprite.Group() 是一个可变对象。这意味着当您在 中添加或删除piece_listflip_piece(),该变量已经在 中更新main()。因此,您可以通过不返回任何内容来简化代码。

这是您的代码的完整版本。

import pygame

white = (255, 255, 255)
black = (0, 0, 0)


class Piece(pygame.sprite.Sprite):
    def __init__(self, colour, x, y):
        super().__init__()
        self.colour = colour
        self.x = x
        self.y = y


def set_up_pieces(piece_list):
    s = Piece(white, 4, 4)
    piece_list.add(s)
    s = Piece(black, 5, 4)
    piece_list.add(s)
    s = Piece(white, 5, 5)
    piece_list.add(s)
    s = Piece(black, 4, 5)
    piece_list.add(s)
    return piece_list


def flip_piece(piece_list, move, i, flip, player):
    for p in piece_list:
        if p.x == move[0] + (i + 1) * flip[0] and p.y == move[1] + (i + 1) * flip[1]:
            new_piece = Piece(player, p.x, p.y)
            piece_list.add(new_piece)
            piece_list.remove(p)
            return

def main():
    piece_list = pygame.sprite.Group()
    piece_list = set_up_pieces(piece_list)
    player_to_move = white
    # this simulates a move
    move = [5, 3]
    new_piece = Piece(player_to_move, move[0], move[1])
    piece_list.add(new_piece)
    flip = [-1, 0, 2]
    for i in range(flip[2]):
        flip_piece(piece_list, move, i, flip, player_to_move)


main()

推荐阅读