我在为Python编程课程编写一个项目时有一个问题。我正在编写一个黑白棋引擎,它会提前查看几步棋,然后选择它认为最佳的走法。虽然我明白Python并不是这种任务的理想语言(因为它不如其他一些语言快),但我认为可以编写出至少功能性的代码,尽管可能速度会稍慢一些。
话虽如此,我正在尝试创建两个表:一个游戏棋盘(可以想象成一个矩阵)和一个存储整数的游戏树。我希望使用一种内存高效且快速添加、删除和读取条目的方法。
我目前使用的棋盘效率不高。我想询问大家有什么模块建议(并附上使用说明),以编写一个在内存占用上更轻的等效版本(例如:array, numpy;但我不知道如何使用这些):
self.board = [[0, 0, 0, 0, 0, 0, 0, 0,], [0, 0, 0, 0, 0, 0, 0, 0,], [0, 0, 0, 0, 0, 0, 0, 0,], [0, 0, 0, 1, 2, 0, 0, 0,], [0, 0, 0, 2, 1, 0, 0, 0,], [0, 0, 0, 0, 0, 0, 0, 0,] [0, 0, 0, 0, 0, 0, 0, 0,], [0, 0, 0, 0, 0, 0, 0, 0,]]
对于游戏树,我有一些想法,具体取决于列表的列表应该有多轻。我正在使用的标准Python编写的想法类似于:
tree_zero = %tree_one = [%, %, %]tree_two = [[%, %, %], [%, %, %], [%, %, %]]tree_thre = [[[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]]],tree_four = [[[[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]]], [[[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]]], [[[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]], [[%, %, %], [%, %, %], [%, %, %]]]]
其中每个%将是上述棋盘之一(并且比理想情况更好:不是每个回合都有确切的三个选项)。但这是一个缓慢且沉重的对象,Python很难高效地使用内存(特别是如果我深入到超过4步棋的情况)。
如果有人之前使用过这样的程序或有关于高效模块导入的想法,请告诉我!
关于游戏树的例子,可以参考维基百科页面,特别是页面上的第一张图片。
编辑:理想情况下,我希望能看到超过四步棋的预测,这只是前四级的示例。此外,将有多个给定树的副本在使用。速度对于这种指数级增长的任务非常重要。
回答:
在我看来,Python非常适合这种工作!也就是说,我用Python为棋盘游戏做AI时,非常有趣且高效。
我的第一个建议是探索位板。虽然这里的应用示例是国际象棋,但这个概念完全可以转移到黑白棋上。使用零和一来表示固定大小棋盘上的棋子存在,不仅可以降低内存占用,还可以提高计算速度(位运算比等式运算更快)。
此外,你应该重新设计你的模型,以某种方式实现递归(通过评分函数促进)。这样的实现意味着你可以编写一个单一的函数,并允许它扩展到无限的移动深度(或者说,不受你的设计限制,仅受资源限制),而不是预期并硬编码1、2、3、4步的逻辑。一个设计良好的函数可以适用于双方(玩家),然后可以暂停以选择符合阈值的最佳选项(根据你选择的任何标准暂停,如计算的位置/实时花费的时间)。
作为参考,这是我制作的一个名为Thud的棋盘游戏的GitHub,需求几乎与你的程序完全相同。在这里,我使用了一个17×17的棋盘,三种不同的棋子和两种不同的策略——我们都可以看到,这已经比黑白棋的规则更复杂了。
哦,一个好的递归模型还可以支持多线程!