我目前正在为我的Data Structures类工作的作业的目标是创建一个Quantum Tic Tac Toe,其中AI可以获胜。
目前,我在寻找代表州的最有效方式时遇到了一些麻烦。
当前结构概述:
AbstractGame
AbstractBoard
AbstractPlayer
StateTransveralPool
州
所以原则是 每行可以用二进制数000-111表示,其中0表示开放空间,1表示封闭空间。
因此,对于不完整的TTT板:
From the Set<Integer> board perspective:
X_X R1 might be: 101
OO_ R2 might be: 110
X_X R3 might be: 101, where 1 is an open space, and 0 is a closed space
From the Set<Integer> xMoves perspective:
X_X R1 might be: 101
OO_ R2 might be: 000
X_X R3 might be: 101, where 1 is an X and 0 is not
From the Set<Integer> oMoves perspective:
X_X R1 might be: 000
OO_ R2 might be: 110
X_X R3 might be: 000, where 1 is an O and 0 is not
然后我们看到x {R1,R2,R3}&amp; o {R1,R2,R3} =&gt;板{R1,R2,R3}
问题是快速生成GameTree的下一个状态。如果我有玩家Max(x)与棋盘{R1,R2,R3},那么获得R1,R2和R3的下一个行状态很简单..
Set<Integer> R1nextStates = StateTransversalPool.get(R1);
问题是我必须将这些状态中的每一个与R1和R2组合在一起。
除了我可以使用的Set之外,还有更好的数据结构吗?总的来说是否有更有效的方法?我还发现Point&lt; - &gt;州调解很麻烦。我可以尝试另一种方法吗?
谢谢!
这是我的ConcretePlayer类的代码。它可能有助于解释玩家如何通过移动产生新状态,使用StateProducer(可能需要成为StateFactory或StateBuilder)。
public class ConcretePlayerGeneric extends AbstractPlayer {
@Override
public BinaryState makeMove() {
// Given a move and the current state, produce a new state
Point playerMove = super.strategy.evaluate(this);
BinaryState currentState = super.getInGame().getBoard().getState();
return StateProducer.getState(this, playerMove, currentState);
}
}
编辑:我从正常的TTT开始,转向量子TTT。给定框架,它应该像创建几个新的Concrete类和调整一些东西一样简单。
答案 0 :(得分:3)
我的建议:
+1 == O
,-1 == X
和0
表示空方块。 这允许您通过检查水平,垂直或对角线行的总和是等于+3
还是-3
来检测结束状态。修改强>
我感到无聊,于是决定写一些“玩具代码”来实现游戏板,包括确定它是否处于终端状态的方法,以及在下一次移动后生成一组板状态。它应该推广到任何规模的董事会,虽然我没有尝试过。享受......
示例输出
$ java Board
Creating board:
---
---
---
Initialising board:
-OX
O--
XO-
Terminal state: false
Generating next move states:
XOX
O--
XO-
-OX
OX-
XO-
-OX
O-X
XO-
-OX
O--
XOX
<强>代码强>
import java.util.List;
import java.util.LinkedList;
import java.util.Random;
public class Board {
private final int[] squares;
public Board() {
this.squares = new int[9];
}
protected Board(int[] squares) {
this.squares = squares;
}
public void init() {
Random rnd = new Random();
int turn = 1; // 'O' always goes first.
for (int i=0; i<squares.length; ++i) {
double d = rnd.nextDouble();
if (d < 0.75) {
squares[i] = turn;
turn = turn == 1 ? -1 : 1; // Flip to other player's turn.
} else {
squares[i] = 0; // Empty square.
}
if (isTerminalState()) {
break;
}
}
}
public boolean isTerminalState() {
boolean ret = false;
boolean foundEmpty = false;
int hSum = 0;
int[] vSum = new int[3];
for (int i=0; i<squares.length; ++i) {
hSum += squares[i];
if (isWinningRow(hSum)) {
ret = true;
break;
} else if (i == 2 || i == 5) {
hSum = 0;
}
int col = i % 3;
vSum[col] += squares[i];
if (isWinningRow(vSum[col])) {
ret = true;
break;
}
if (squares[i] == 0) {
foundEmpty = true;
}
}
if (!ret) {
if (!foundEmpty) {
ret = true;
} else {
int diag1 = 0;
int diag2 = 0;
int rowSz = (int)Math.sqrt(squares.length);
for (int i=0; i<squares.length; ++i) {
if (i % (rowSz + 1) == 0) {
diag1 += squares[i];
if (isWinningRow(diag1)) {
ret = true;
break;
}
}
if (i > 0 && i % (rowSz - 1) == 0) {
diag2 += squares[i];
if (isWinningRow(diag2)) {
ret = true;
break;
}
}
}
}
}
return ret;
}
private boolean isWinningRow(int rowSum) {
return rowSum == 3 || rowSum == -3;
}
public List<Board> getNextStates() {
List<Board> ret = new LinkedList<Board>();
int tmp = 0;
for (int i=0; i<squares.length; ++i) {
tmp += squares[i];
}
// Next turn is 'O' (i.e. +1) if the board sums to 0.
// Otherwise it's 'X's turn.
int turn = tmp == 0 ? 1 : -1;
if (!isTerminalState()) {
for (int i=0; i<squares.length; ++i) {
if (squares[i] == 0) { // Empty square
int[] squaresA = new int[squares.length];
System.arraycopy(squares, 0, squaresA, 0, squares.length);
squaresA[i] = turn;
ret.add(new Board(squaresA));
}
}
}
return ret;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<squares.length; ++i) {
if (squares[i] == 1) {
sb.append('O');
} else if (squares[i] == -1) {
sb.append('X');
} else {
assert squares[i] == 0;
sb.append('-');
}
if (i == 2 || i == 5) {
sb.append('\n');
}
}
return sb.toString();
}
public static void main(String[] args) {
System.err.println("Creating board:\n");
Board bd = new Board();
System.err.println(bd);
System.err.println("\nInitialising board:\n");
bd.init();
System.err.println(bd);
System.err.println("Terminal state: " + bd.isTerminalState() + '\n');
System.err.println("\nGenerating next move states:\n");
List<Board> nextStates = bd.getNextStates();
for (Board bd1 : nextStates) {
System.err.println(bd1.toString() + '\n');
}
}
}
答案 1 :(得分:0)
每个方格不应只有三种可能的状态(,X,O)吗?
存储三态方格的网格,或存储2个移动列表。您不需要存储整个电路板,因为它是由移动定义的。
另外,你的意思是:
为...生成下一个状态 对局树
什么是GameTree?什么是“下一个州”的例子?