【发布时间】:2021-02-14 21:20:51
【问题描述】:
要从我的国际象棋引擎撤消移动,我在很大程度上依赖于良好的缓存系统,每次移动完成/撤消时都会更新该缓存系统。它还用于“回到过去”并查看较早的位置。更新代码如下所示:
self.cache.append([copy.deepcopy(self.board), ..., copy.deepcopy(self.brokenCastles)])
self.brokenCastles 是一个集合,self.board 是一个代表棋盘的二维列表。还有一些其他的列表和变量被存储(例如每一方的合法移动),因此不必在每次使用相同的棋盘时都计算它们。到目前为止,它们没有造成任何问题(或者我没有注意到它们)。
最大的问题在于self.board 和self.brokenCastles。如果我只是像所有其他变量一样附加它们,则会出现大量问题(例如国王被拿走和一些奇怪的东西),这可以通过分别制作列表/集合的深度复制来解决。仅使用内置的 pythons .copy() 或使用像 [:] 这样的切片并没有帮助。
我不太清楚为什么需要 deepcopy 并且无法在较小的环境中复制该问题。所以我的问题是是否需要 deepcopy,如果需要,有没有办法让它更快,因为它是我系统目前最大的瓶颈。
缓存读取函数如下所示:
def undo_move(self):
self.board = self.cache[-1][0]
... # A lot more
self.brokenCastles = self.cache[-1][4]
self.cache.pop()
如果有任何细节缺失,请告诉我。感谢您的帮助。
完整代码(一团糟)可在GitHub 获得。
【问题讨论】:
-
如果我是你,我会研究 Memento 设计模式,并为它做一个堆栈。简单来说,Memento 是一个对象,可以在其中存储您的动作,然后您甚至可以在其中创建撤消和重做功能。
-
也许你应该创建将
board转换为更小的函数 - 即字符串的平面列表/元组 - 并将其保存在缓存中。第二个函数将这个平面列表/元组转换回board。或者也许你应该只在没有全板的情况下保留缓存。但它需要撤消所有移动以获得旧板。 -
@furas 我现在想出了一个超级卡顿解决方案(请参阅我的回答),它实际上非常快。