首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >确定Tic Tac Toe游戏结束时间的算法

确定Tic Tac Toe游戏结束时间的算法
EN

Stack Overflow用户
提问于 2009-06-29 10:18:22
回答 24查看 226.6K关注 0票数 108

我已经用Java编写了一个tic-tac-toe游戏,我当前确定游戏结束的方法考虑了游戏结束的以下可能场景:

棋盘已满,尚未宣布获胜者:游戏是平局。

克罗斯赢了。

圆圈赢了。

不幸的是,为了做到这一点,它从一个表中读取了一组预定义的场景。考虑到棋盘上只有9个空格,因此表格有点小,这并不是很糟糕,但是有没有更好的算法来确定游戏是否结束了呢?确定某人是否获胜是问题的关键,因为检查9个空格是否已满是微不足道的。

表方法可能是解决方案,但如果不是,什么是解决方案?另外,如果棋盘的大小不是

什么?比方说,如果它是一个大得多的棋盘呢?

,依此类推,导致连续放置的项的数量为

等等?适用于所有人的通用算法

EN

回答 24

Stack Overflow用户

回答已采纳

发布于 2009-06-29 10:33:35

您知道,只有在X或O进行了最近一次移动之后,才会出现获胜移动,因此在尝试确定获胜棋盘时,您只能搜索包含在该移动中的带有可选diag的行/列,以限制您的搜索空间。此外,由于在抽签的tic-tac-toe游戏中有固定的走法次数,一旦最后一步走完了,如果它不是获胜的走法,那么它默认是一个抽签游戏。

编辑:此代码适用于n×n的棋盘,其中n在一行中获胜(3x3棋盘要求连续3个棋盘,依此类推)

编辑:添加了检查反诊断的代码,我找不到一种非循环的方法来确定点是否在反诊断上,所以这就是为什么这一步被遗漏了。

代码语言:javascript
运行
复制
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
        }
    }
}
票数 144
EN

Stack Overflow用户

发布于 2009-06-29 02:20:58

你可以用一个魔方

http://mathworld.wolfram.com/MagicSquare.html

如果任何行、列或诊断相加为15,则表示玩家获胜。

票数 48
EN

Stack Overflow用户

发布于 2009-06-29 15:00:29

下面的伪代码如何:

玩家在(x,y)位置放下棋子后:

代码语言:javascript
运行
复制
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。

仅检查当前部分。

没有魔法。:)

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1056316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档