我正在尝试用 Python 编写黑白棋游戏。谁能给我一些简单,好且易于使用的基本想法和策略?
我会很感激任何帮助,因为我已经走了一点路,但被困在代码之间,而且它也变得更加复杂。我认为我在某些应该相当简单的部分做得过火了。所以....
黑白棋是一款优雅简单的游戏。我将使用伪 C#/Java 语言来解释一些概念,但您可以将它们转换为 Python。
要将其分解为最简单的组件,您有两个基本的东西:
代表游戏板的二维数组:
gameBoard[10,10]
以及某种形式的枚举,用于存储游戏板中每个图块的状态:
enum tile
{
none,
white,
black
}
为了渲染棋盘,你循环遍历 gameBoard 数组,增加棋子大小的偏移量:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
// The Piece to draw would be at gameBoard[i,j];
// Pixel locations are calculated by multiplying the array location by an offset.
DrawPiece(gameBoard[i,j],i * Width of Tile, j * width of tile);
}
}
同样,将鼠标单击解析回数组中的某个位置也是类似的,使用鼠标位置和偏移量来计算您所在的实际图块。
每次放置瓷砖时,您都会扫描整个阵列,并根据新颜色应该是什么应用一个基于简单规则的引擎。(这是真正的挑战,我会留给你。)
AI 可以利用假设动作进行阵列扫描,让它扫描大约 10 个可能的动作,然后选择产生最佳结果的动作。尽量不要让它变得聪明,因为当你让它在脑海中玩完整个游戏时,它很容易制造出无与伦比的 AI。
当阵列中不再有任何空闲位置时,您结束游戏。
维基百科页面包含所有规则和一些体面的黑白棋策略建议。基本上,您需要某种数据结构来表示棋盘状态,即棋盘上所有棋子在游戏中任意时刻的位置。正如其他人所建议的那样,二维数组可能是一个不错的选择,但只要它是一种对您有意义的表示形式,它并不重要。一些困难的事情是找出哪些空间是有效的移动,然后哪些部分要翻转,但是,维基百科页面再次包含所有细节,所以它不应该太难实现。
如果你想为你的游戏创建一个 AI,那么我建议你看看某种带有 Alpha-Beta 修剪的极小极大类型算法。网络上有大量的资源,使用极小极大和良好评估功能的人工智能将能够轻松击败大多数人类玩家,因为它可以在很短的时间内至少领先 8 或 9 步。minimax 上还有一些其他更高级的变体,例如 negamax 或 negascout,它们甚至可以比基本的 minimax 做得更好,但我会从更简单的变体开始。维基百科有关于所有这些算法的页面,并且有大量关于所有这些算法的信息,因为许多 AI 课程将它们用于奥赛罗或类似的东西。一个特别有用的页面是这个 Java Applet. 它允许您在带有和不带有 alpha-beta 修剪的样本状态树上逐步完成 minimax 和 negamax 的步骤。
如果这些都没有意义,请告诉我。
你需要一个二维数组。当心 [[0] * 8] * 8,而是使用 [[0 for _ in [0] * 8] for _ in [0] * 8]
白色应该是 1,黑色应该是 -1(当然反之亦然)。这样,您可以使用 *=-1 进行翻转并保持空白 双四循环将能够计算总分并确定游戏是否做得很好。map(sum,map(sum,board)) 会给你净分数
不要忘记检查玩家是否可以在回合开始时移动
不要被多暗阵列解决方案所吸引。我已经写了一个带有 multi-dim 的井字游戏,它工作得很好,但是当我开始我自己的 othello 版本时,我做了一个线性整数数组,它的速度几乎快了 2 倍。
我已经把所有东西大部分都用 PHP 编码了,但仍然在研究 Idea's for the AI 作为像井字游戏那样的蛮力解决方案是行不通的。
您甚至不需要线性阵列。两个 64 位 java long 值就足够了(一个用于白色,一个用于黑色。assert (white&black)==0 。
您可以通过计算不是连接到角落的棋子,而是计算无法取走的棋子来使游戏更强大。
您可能还希望考虑应用“模糊逻辑”循环来分析位置。Reversi/Othello 因强迫玩家考虑某些战略收益而不是战略损失而臭名昭著,并且将一个积极的举动优先于另一个。
模糊系统将通过设置各种设置来让您更好地控制测试移动选择,并让您能够通过改变各种权重来创建多个“个性”来对抗。