深度复制带有精灵的二维数组(板)
Deepcopying a 2d arrary (board) with sprites on it
我目前正在学校做我的期末项目,所以我正在用 pygame 制作游戏。
该游戏包括一个带有基地、殖民地和防御工事的棋盘,所有这些都是精灵对象。
在项目中,我们被要求添加 2 个机器学习算法,其中一个是 minimax。
正如您可能知道的那样,要使用 minimax,您需要 copy.deepcopy
板几次并计算每个板的启发值,并在最大值时找到最好的板,在最小值时找到最差的板。
我面临的问题是一个简单的事实,即 copy.deepcopy
可能无法对具有 sprite 属性的对象进行操作。
这是显示的错误消息:
TypeError: can't pickle pygame.Surface objects
它在我的代码中将我定位到这一行:
b = copy.deepcopy(Board)
我真的不知道在这种情况下该怎么办,我不能回去更改板,因为我有大约 1700 行代码+完成的图形并将所有对象更改为非 sprite 对象是太多了。
所以我基本上需要你的帮助,必须解决这个问题才能继续
这是游戏开始时棋盘上单行的例子;只是为了帮助您理解我在说什么:
[None, "<"Colony sprite(in 2 groups)">", None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, "<"Colony sprite(in 2 groups)">", None]
一个殖民地的例子class,精灵相关的代码在最后一段:
class Colony(pg.sprite.Sprite):
def __init__(self, x, y, clan, type):
self.clan = clan
if self.clan == 1:
name = "joogadars"
else:
name = "klagars"
self.type = type
if type == 1:
type_name = "doorks"
else:
type_name = "gorgs"
self.lvl = 1
self.attackable = True
self.rates = array_from_txt_colonies("Colonies Data.txt", self.type, 'Rates')
self.prices = array_from_txt_colonies("Colonies Data.txt", self.type, 'Prices')
self.hps = array_from_txt_colonies("Colonies Data.txt", self.type, 'Hps')
self.hp = self.hps[self.lvl - 1]
self.rate = self.rates[self.lvl - 1]
self.position = (x, y)
full_name = type_name + '/' + name + '/' + name + " " + type_name + " colony lvl " + str(self.lvl) + " use.png"
pg.sprite.Sprite.__init__(self)
img = 'C:/Users/ariel/Desktop/Ariel/12th/Python/final proj/graphics/islands/colonies/' + full_name
self.image = pg.image.load(img)
self.rect = self.image.get_rect(center=self.position)
如果您不想或不能将所需的游戏状态与您的绘图代码(a.k.a。精灵)分开,一个简单的解决方案是将图像路径存储在您的精灵中:
...
self.position = (x, y)
full_name = type_name + '/' + name + '/' + name + " " + type_name + " colony lvl " + str(self.lvl) + " use.png"
pg.sprite.Sprite.__init__(self)
self.img = 'C:/Users/ariel/Desktop/Ariel/12th/Python/final proj/graphics/islands/colonies/' + full_name
self.image = pg.image.load(self.img)
self.rect = self.image.get_rect(center=self.position)
...
然后在尝试复制精灵之前,删除图像,并在复制后重新加载;像这样:
for sprite in Board.sprites:
sprite.image = None
b = copy.deepcopy(Board)
for sprite in Board.sprites:
sprite.image = pygame.load(sprite.img)
for sprite in b.sprites:
sprite.image = pygame.load(sprite.img)
你会明白的。此外,您可能也应该缓存图像,这样您就不必每次都从磁盘加载它们。
另一种方法是实现__deepcopy__
to prevent the deepcopy
function from trying to copy the image
attribute; you read about it e.g. here and (但您必须在复制后加载图像)。
使用适合您的任何东西。
我目前正在学校做我的期末项目,所以我正在用 pygame 制作游戏。
该游戏包括一个带有基地、殖民地和防御工事的棋盘,所有这些都是精灵对象。
在项目中,我们被要求添加 2 个机器学习算法,其中一个是 minimax。
正如您可能知道的那样,要使用 minimax,您需要 copy.deepcopy
板几次并计算每个板的启发值,并在最大值时找到最好的板,在最小值时找到最差的板。
我面临的问题是一个简单的事实,即 copy.deepcopy
可能无法对具有 sprite 属性的对象进行操作。
这是显示的错误消息:
TypeError: can't pickle pygame.Surface objects
它在我的代码中将我定位到这一行:
b = copy.deepcopy(Board)
我真的不知道在这种情况下该怎么办,我不能回去更改板,因为我有大约 1700 行代码+完成的图形并将所有对象更改为非 sprite 对象是太多了。 所以我基本上需要你的帮助,必须解决这个问题才能继续
这是游戏开始时棋盘上单行的例子;只是为了帮助您理解我在说什么:
[None, "<"Colony sprite(in 2 groups)">", None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, "<"Colony sprite(in 2 groups)">", None]
一个殖民地的例子class,精灵相关的代码在最后一段:
class Colony(pg.sprite.Sprite):
def __init__(self, x, y, clan, type):
self.clan = clan
if self.clan == 1:
name = "joogadars"
else:
name = "klagars"
self.type = type
if type == 1:
type_name = "doorks"
else:
type_name = "gorgs"
self.lvl = 1
self.attackable = True
self.rates = array_from_txt_colonies("Colonies Data.txt", self.type, 'Rates')
self.prices = array_from_txt_colonies("Colonies Data.txt", self.type, 'Prices')
self.hps = array_from_txt_colonies("Colonies Data.txt", self.type, 'Hps')
self.hp = self.hps[self.lvl - 1]
self.rate = self.rates[self.lvl - 1]
self.position = (x, y)
full_name = type_name + '/' + name + '/' + name + " " + type_name + " colony lvl " + str(self.lvl) + " use.png"
pg.sprite.Sprite.__init__(self)
img = 'C:/Users/ariel/Desktop/Ariel/12th/Python/final proj/graphics/islands/colonies/' + full_name
self.image = pg.image.load(img)
self.rect = self.image.get_rect(center=self.position)
如果您不想或不能将所需的游戏状态与您的绘图代码(a.k.a。精灵)分开,一个简单的解决方案是将图像路径存储在您的精灵中:
...
self.position = (x, y)
full_name = type_name + '/' + name + '/' + name + " " + type_name + " colony lvl " + str(self.lvl) + " use.png"
pg.sprite.Sprite.__init__(self)
self.img = 'C:/Users/ariel/Desktop/Ariel/12th/Python/final proj/graphics/islands/colonies/' + full_name
self.image = pg.image.load(self.img)
self.rect = self.image.get_rect(center=self.position)
...
然后在尝试复制精灵之前,删除图像,并在复制后重新加载;像这样:
for sprite in Board.sprites:
sprite.image = None
b = copy.deepcopy(Board)
for sprite in Board.sprites:
sprite.image = pygame.load(sprite.img)
for sprite in b.sprites:
sprite.image = pygame.load(sprite.img)
你会明白的。此外,您可能也应该缓存图像,这样您就不必每次都从磁盘加载它们。
另一种方法是实现__deepcopy__
to prevent the deepcopy
function from trying to copy the image
attribute; you read about it e.g. here and
使用适合您的任何东西。