我正在编写一个遗传算法程序,该程序将开发出解决Tic Tac Toe板的最佳解决方案。我已经做了很多研究,并且发现当考虑到电路板的对称性时,有765种可能的电路板组合。我需要编写一个代码来生成每个组合,但我无法弄清楚如何做到这一点。我是编码新手,无法弄清楚如何将对称性融入代码中。
你将如何创建一个能够生成Tic Tac Toe板的所有可能的独特板组合(考虑对称性)的代码?
Here是解释对称性的好文档:
谢谢
答案 0 :(得分:1)
您可以像在minimax中一样构建游戏树,但不是计算板的值,而是将它们放在首选数据结构中以存储所有765块板。一些示例代码,如果这有帮助:
//Where you'll save the unique boards
HashSet<Board> mySavedBoards = new HashSet<Board>();
mySavedBoards.add(emptyBoard) //add the original empty board
//player = 'X' or 'O'
public static void find_all_boards(Board board, String player) {
for (Move move : board.get_all_possible_moves()) {
board = board.applyMove(move, player);
my_saved_boards.add(board);
if(!board.isWin()) {
next_player = (player == 'O') ? 'X' : 'O';
find_all_boards(board, next_player);
}
}
}
get_all_possible_moves(board)
只返回网格中的空方格列表(允许玩家进入的任何地方)board.applyMove(move)
采取行动并返回与玩家一起玩的结果(&#39; X&#39;或&#39; O&#39;)isWin()
返回此委员会是否是某些玩家的胜利(即不再继续寻找更多的董事会)此代码将访问所有可能的tic-tac-toe板,但会有一些重复,因此您必须隐式地管理它(为您的Board类重写equals和hashCode以便为您执行此检查当您将棋盘添加到HashSet时,它不会添加重复项
这很大程度上取决于你对董事会的表述,采取行动以及参与者,但我希望这个一般性的想法有所帮助!
编辑:我现在看到你在询问如何生成对称板
我会在电路板上使用两种方法:flip()
,rotate()
。您可以使用此方法生成板的8种变体,如下面的答案中所示。您可以编写equals方法来检查给定的板是否在另一块板上的变体集中
boolean equals(Board other) {
//Insert normal checks for object type here
HashSet<Board> variantsOfOther = other.variants();
return variantsOfOther.contains(this)
}
答案 1 :(得分:0)
B板有1到8个对称变体,包括它自己。通过以90度增量旋转B可以获得三个。其他可以通过镜像原件然后再旋转三次来找到。 (并非所有旋转/反射都必须是唯一的:中间带有X的板和相同值的所有其他正方形没有其他变体。)
通过将其视为三元数,您还可以轻松地将0 ..(3 ^ 9)-1范围内的值分配给每个电路板。例如。如果你指定0 =空白,1 = O
,2 = X
并且你有一个董事会
X O _
_ X O
_ _ _
您可以将其解释为210021000
(基数3)= 15498
(基数为10)。
让variants(B)
成为接受B板并返回一组最多8个对称变量的函数。让value(B)
返回板B的整数值,如上所述。
现在你可以使用一个简单的粗暴算法:
U = {}
for B in the set of 19683 possible boards
// Set y to the minimum-valued variant of B.
y = argmin_{ x in variants(B) } . value(x)
U = U + y // add y to the unique variants.
完成后,U包含独特的电路板
答案 2 :(得分:0)
一点也不麻烦。并且有126种组合,而不是700或数千种。
(你可以在循环中逐一完成所有这些,我只是碰巧使用一种名为Dyalog APL的并行语言,所以我一起展示它们)
下面。二进制:
0 0 0 0 0 0 0 0 0 <- this is 0
0 0 0 0 0 0 0 0 1 <- this is 1
0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0 <- 6
0 0 0 0 0 0 1 1 1
0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 1 <- 9
...
0 0 1 0 0 1 1 0 1 <- 77
...
1 1 1 1 1 1 1 1 1 <- 511
你(计算机)是一个,对手是零。
以下是15个第一行(126个)保留,当对手开始游戏时(会占用太多空间来写入126行):
0 0 0 0 0 1 1 1 1
0 0 0 0 1 0 1 1 1
0 0 0 0 1 1 0 1 1
0 0 0 0 1 1 1 0 1
0 0 0 0 1 1 1 1 0
0 0 0 1 0 0 1 1 1
0 0 0 1 0 1 0 1 1
0 0 0 1 0 1 1 0 1
0 0 0 1 0 1 1 1 0
0 0 0 1 1 0 0 1 1
0 0 0 1 1 0 1 0 1
0 0 0 1 1 0 1 1 0
0 0 0 1 1 1 0 0 1
0 0 0 1 1 1 0 1 0
0 0 0 1 1 1 1 0 0
这里有所有行保留(对手开始),重新塑造成3个3个表 - 相同数据但略有不同:
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│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│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 0│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│0 1 1│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 0│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 0 1│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 0│1 1 1│1 1 1│1 1 1│1 1 1│1 1 1│1 1 1│
│0 0 1│0 1 0│0 1 1│0 1 1│0 1 1│1 0 0│1 0 1│1 0 1│1 0 1│1 1 0│1 1 0│1 1 0│1 1 1│1 1 1│1 1 1│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│0 1 1│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 0 1│1 0 1│1 1 0│1 1 0│1 1 0│1 1 1│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│0 1 1│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 0 1│1 0 1│1 1 0│1 1 0│1 1 0│1 1 1│0 0 0│0 0 0│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 1 0│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│0 1 1│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 0 1│1 0 1│1 1 0│1 1 0│1 1 0│1 1 1│0 0 0│0 0 0│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 1 0│0 0 0│0 0 0│0 0 0│0 0 1│0 0 1│0 0 1│0 1 0│0 1 0│0 1 0│0 1 1│1 0 0│1 0 0│1 0 0│1 0 1│1 1 0│0 0 0│0 0 0│0 0 0│0 0 1│0 1 0│1 0 0│
│1 1 1│1 1 1│0 1 1│1 0 1│1 1 0│1 1 1│0 1 1│1 0 1│1 1 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│1 1 1│0 1 1│1 0 1│1 1 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│1 1 1│0 1 1│1 0 1│1 1 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 0│1 1 1│0 1 1│1 0 1│1 1 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│0 0 0│0 0 0│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
看看这是怎么回事? :-)这些是你的“所有组合”。
因此游戏现在看起来像这样:
┌─┬─┬─┐
│0│0│ │
├─┼─┼─┤
│ │1│ │
├─┼─┼─┤
│ │ │ │
└─┴─┴─┘
或相同,扁平化:
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│0│0│ │ │1│ │ │ │ │ │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
仅保留与此匹配的行(即,第1列和第2列为0,第5列为1)。现在你只有这些行=这些可能的游戏结果:
0 0 0 0 1 0 1 1 1
0 0 0 0 1 1 0 1 1
0 0 0 0 1 1 1 0 1
0 0 0 0 1 1 1 1 0
0 0 0 1 1 0 0 1 1
0 0 0 1 1 0 1 0 1
0 0 0 1 1 0 1 1 0
0 0 0 1 1 1 0 0 1
0 0 0 1 1 1 0 1 0
0 0 0 1 1 1 1 0 0
0 0 1 0 1 0 0 1 1
0 0 1 0 1 0 1 0 1
0 0 1 0 1 0 1 1 0
0 0 1 0 1 1 0 0 1
0 0 1 0 1 1 0 1 0
0 0 1 0 1 1 1 0 0
0 0 1 1 1 0 0 0 1
0 0 1 1 1 0 0 1 0
0 0 1 1 1 0 1 0 0
0 0 1 1 1 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│0 0 0│0 0 0│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│0 0 1│
│0 1 0│0 1 1│0 1 1│0 1 1│1 1 0│1 1 0│1 1 0│1 1 1│1 1 1│1 1 1│0 1 0│0 1 0│0 1 0│0 1 1│0 1 1│0 1 1│1 1 0│1 1 0│1 1 0│1 1 1│
│1 1 1│0 1 1│1 0 1│1 1 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 1 1│1 0 1│1 1 0│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
这些都是游戏的可能结果,从此阶段开始。显然,你现在要计算每行,每列,对角线和对角线的数量。提取那些连续3个的替代品,然后从中选出一个,放置下一个X.不知道哪个,或者你如何优化 - 我猜你需要做一些mambo jambo :-)。应该很简单。这只是粗略的指导。
当仔细思考时,你需要保持两个数据集,因为你也想从对手的角度来处理,到阻碍他排在第3位。 IE浏览器。有一个类似的数据集,其中对手是1,你是0,计算行,列,对角线,并且做出反应,如果其中任何一个总和为3 - 那么你必须阻止他!相同的原则,只需管理一个根据需要有所不同。
(注意:与所有这些并行,你必须跟踪空闲插槽!例如,应该是简单的9长度阵列,其中1表示占用,例如。随着游戏的进展,只需更新它。它的目的是为了)定义计算机可以勾选标记的位置,以及b)验证对手使用空闲位置