我已经用Java编写了一个tic-tac-toe游戏,我当前确定游戏结束的方法考虑了游戏结束的以下可能场景:
棋盘已满,尚未宣布获胜者:游戏是平局。
克罗斯赢了。
圆圈赢了。
不幸的是,为了做到这一点,它从一个表中读取了一组预定义的场景。考虑到棋盘上只有9个空格,因此表格有点小,这并不是很糟糕,但是有没有更好的算法来确定游戏是否结束了呢?确定某人是否获胜是问题的关键,因为检查9个空格是否已满是微不足道的。
表方法可能是解决方案,但如果不是,什么是解决方案?另外,如果棋盘的大小不是
什么?比方说,如果它是一个大得多的棋盘呢?
,依此类推,导致连续放置的项的数量为
等等?适用于所有人的通用算法
发布于 2009-06-29 10:33:35
您知道,只有在X或O进行了最近一次移动之后,才会出现获胜移动,因此在尝试确定获胜棋盘时,您只能搜索包含在该移动中的带有可选diag的行/列,以限制您的搜索空间。此外,由于在抽签的tic-tac-toe游戏中有固定的走法次数,一旦最后一步走完了,如果它不是获胜的走法,那么它默认是一个抽签游戏。
编辑:此代码适用于n×n的棋盘,其中n在一行中获胜(3x3棋盘要求连续3个棋盘,依此类推)
编辑:添加了检查反诊断的代码,我找不到一种非循环的方法来确定点是否在反诊断上,所以这就是为什么这一步被遗漏了。
public class TripleT {
enum State{Blank, X, O};
int n = 3;
State[][] board = new State[n][n];
int moveCount;
void Move(int x, int y, State s){
if(board[x][y] == State.Blank){
board[x][y] = s;
}
moveCount++;
//check end conditions
//check col
for(int i = 0; i < n; i++){
if(board[x][i] != s)
break;
if(i == n-1){
//report win for s
}
}
//check row
for(int i = 0; i < n; i++){
if(board[i][y] != s)
break;
if(i == n-1){
//report win for s
}
}
//check diag
if(x == y){
//we're on a diagonal
for(int i = 0; i < n; i++){
if(board[i][i] != s)
break;
if(i == n-1){
//report win for s
}
}
}
//check anti diag (thanks rampion)
if(x + y == n - 1){
for(int i = 0; i < n; i++){
if(board[i][(n-1)-i] != s)
break;
if(i == n-1){
//report win for s
}
}
}
//check draw
if(moveCount == (Math.pow(n, 2) - 1)){
//report draw
}
}
}
发布于 2009-06-29 02:20:58
你可以用一个魔方
http://mathworld.wolfram.com/MagicSquare.html
如果任何行、列或诊断相加为15,则表示玩家获胜。
发布于 2009-06-29 15:00:29
下面的伪代码如何:
玩家在(x,y)位置放下棋子后:
col=row=diag=rdiag=0
winner=false
for i=1 to n
if cell[x,i]=player then col++
if cell[i,y]=player then row++
if cell[i,i]=player then diag++
if cell[i,n-i+1]=player then rdiag++
if row=n or col=n or diag=n or rdiag=n then winner=true
我将使用char数组
n,n
,用O、X和空格表示空。
很简单。
一个循环。
5个简单变量:4个整数和一个布尔值。
缩放到任意大小的n。
仅检查当前部分。
没有魔法。:)
https://stackoverflow.com/questions/1056316
复制相似问题