考虑对称性,在Java中生成所有可能未完成的tic tac toe位置列表

考虑对称性,在Java中生成所有可能未完成的tic tac toe位置列表,java,recursion,tic-tac-toe,Java,Recursion,Tic Tac Toe,鉴于此 一个棋盘是可能的,如果它可能发生在一个Tic-Tac-Toe游戏中 一个空的电路板算作一个有效的解决方案 电路板不能“完成”(即,任何一侧都不能有三个连续件) 如果两块板仅因反射或旋转而不同,则视为同一位置 有多少这样的职位存在,我如何才能得到他们的名单。我试过这个: import java.util.ArrayList; import java.util.Arrays; public class Second { static ArrayList<int[]> arr

鉴于此

  • 一个棋盘是可能的,如果它可能发生在一个Tic-Tac-Toe游戏中
  • 一个空的电路板算作一个有效的解决方案
  • 电路板不能“完成”(即,任何一侧都不能有三个连续件)
  • 如果两块板仅因反射或旋转而不同,则视为同一位置
有多少这样的职位存在,我如何才能得到他们的名单。我试过这个:

import java.util.ArrayList;
import java.util.Arrays;

public class Second {
static ArrayList<int[]> arr = new ArrayList<int[]>();
static int[] board = new int[9];

public static void main(String[] args) {
    for(int i = 0; i < 19683; ++i){
        int c = i;
        for (int j = 0; j < 9; ++j){
            board[j] = c%3;
            c /= 3;
        }  

        //Check for Xs and Os
        int diff = 0;
        for(int x : board){
            if(x==1){
                diff++;
            }else if(x==2){
                diff--;
            }
        }
        if(diff==0 || diff==1){
            add(board);
        }
    }   
    System.out.println(arr.size());
}

public static void add(int[] board){
    //If the board is won by either side
    if(isCompleted(board)){return;}

    //Get all possible arrangements
    int[] board1 = {board[6],board[7],board[8],   board[3],board[4],board[5],   board[0],board[1],board[2]};
    int[] board2 = {board[2],board[1],board[0],   board[5],board[4],board[3],   board[8],board[7],board[6]};
    int[] board3 = {board[8],board[5],board[2],   board[7],board[4],board[1],   board[6],board[3],board[0]};
    int[] board4 = {board[0],board[3],board[6],   board[1],board[4],board[7],   board[2],board[5],board[8]};
    int[] board5 = {board[2],board[5],board[8],   board[1],board[4],board[7],   board[0],board[3],board[6]};
    int[] board6 = {board[8],board[7],board[6],   board[5],board[4],board[3],   board[2],board[1],board[0]};
    int[] board7 = {board[6],board[3],board[0],   board[7],board[4],board[1],   board[8],board[5],board[2]};

    int[][] boards = {board1, board2, board3, board4, board5, board6, board7};

    //Find the smallest of the 8 possible arrangements
    int[] smallestBoard = board;
    for(int k=0; k<7; k++){
        if(isGreater(boards[k], smallestBoard)){
            smallestBoard = boards[k];
        }
    }

    for(int[] x : arr){
        if(Arrays.equals(x, smallestBoard)){
            return;
        }
    }
    arr.add(smallestBoard);     
}

public static boolean isCompleted(int[] board){
    int piece = 1;

    if(isAll(piece, new int[]{board[0], board[1], board[2]})){return true;}
    if(isAll(piece, new int[]{board[3], board[4], board[5]})){return true;}
    if(isAll(piece, new int[]{board[6], board[7], board[8]})){return true;}
    if(isAll(piece, new int[]{board[0], board[3], board[6]})){return true;}
    if(isAll(piece, new int[]{board[1], board[4], board[7]})){return true;}
    if(isAll(piece, new int[]{board[2], board[5], board[8]})){return true;}
    if(isAll(piece, new int[]{board[0], board[4], board[8]})){return true;}
    if(isAll(piece, new int[]{board[2], board[4], board[6]})){return true;}

    piece = 2;

    if(isAll(piece, new int[]{board[0], board[1], board[2]})){return true;}
    if(isAll(piece, new int[]{board[3], board[4], board[5]})){return true;}
    if(isAll(piece, new int[]{board[6], board[7], board[8]})){return true;}
    if(isAll(piece, new int[]{board[0], board[3], board[6]})){return true;}
    if(isAll(piece, new int[]{board[1], board[4], board[7]})){return true;}
    if(isAll(piece, new int[]{board[2], board[5], board[8]})){return true;}
    if(isAll(piece, new int[]{board[0], board[4], board[8]})){return true;}
    if(isAll(piece, new int[]{board[2], board[4], board[6]})){return true;}

    return false;
}

public static boolean isGreater(int[] first, int[] second){
    for(int j=0; j<9; j++){
        if(first[j]>second[j]){return true;}
        if(second[j]>first[j]){return false;}
    }
    return true;
}

public static boolean isAll(int value, int[] arr){
    for(int x : arr){
        if(x != value){
            return false;
        }
    }
    return true;
}

}
import java.util.ArrayList;
导入java.util.array;
公共二等舱{
静态ArrayList arr=新ArrayList();
静态int[]板=新int[9];
公共静态void main(字符串[]args){
对于(int i=0;i<19683;++i){
int c=i;
对于(int j=0;j<9;++j){
董事会[j]=c%3;
c/=3;
}  
//检查Xs和Os
int-diff=0;
用于(int x:板){
如果(x==1){
diff++;
}else如果(x==2){
差异--;
}
}
if(diff==0 | | diff==1){
增加(董事会);
}
}   
System.out.println(arr.size());
}
公共静态无效添加(int[]板){
//如果任何一方都赢了董事会
if(isCompleted(board)){return;}
//做好一切可能的安排
int[]board1={board[6],board[7],board[8],board[3],board[4],board[5],board[0],board[1],board[2]};
int[]board2={board[2],board[1],board[0],board[5],board[4],board[3],board[8],board[7],board[6]};
int[]board3={board[8],board[5],board[2],board[7],board[4],board[1],board[6],board[3],board[0]};
int[]board4={board[0],board[3],board[6],board[1],board[4],board[7],board[2],board[5],board[8]};
int[]board5={board[2],board[5],board[8],board[1],board[4],board[7],board[0],board[3],board[6]};
int[]board6={board[8],board[7],board[6],board[5],board[4],board[3],board[2],board[1],board[0]};
int[]board7={board[6],board[3],board[0],board[7],board[4],board[1],board[8],board[5],board[2]};
int[][]板={board1、board2、board3、board4、board5、board6、board7};
//在8种可能的安排中找出最小的一种
int[]smallestBoard=board;
对于(int k=0;kfirst[j]){return false;}
}
返回true;
}
公共静态布尔值isAll(int值,int[]arr){
用于(整数x:arr){
如果(x!=值){
返回false;
}
}
返回true;
}
}

这给出了628个可能位置的结果。然而,给出了630个位置的答案,包括我没有的三个位置。我的程序还将[2,2,2,2,2,2,2,2,2]作为有效位置输出,这是不可能的。

基本问题是您永远不会回溯。你从一块空棋盘开始,做一个九步的线性脚本集,填满棋盘。没有更多可能的移动,因此算法终止,只保留arr这九个位置,正方形按顺序排列

要获得适当的覆盖率,请将board设置为动态变量,而不是类的静态属性。将其作为一个参数传递到playThrough,以便每个实例都有自己的副本。这不是空间问题:调用堆栈的最大深度为10

动态处理棋盘将让运行时堆栈管理您的回溯(因为每个实例都维护自己的部分游戏状态)


我真的希望你准备好了大量的解决方案;9! 按某些标准来说不是很大,但是你的数组是9!整数数组的大小9是要考虑的。< / P >?我已经看到了这一点;不过,我不确定我的代码出了什么问题@我想知道你是否把这个问题看作是打印出所有0到19683之间的基数3。其中0对应空方块1是O,2是X。欢迎使用StackOverflow。请阅读并遵循帮助文档中的发布指南。适用于这里。在您发布MCVE代码并准确描述问题之前,我们无法有效地帮助您。@Prune我发布了我的代码。很抱歉,我已经更改了问题。然而,提到我以前的问题,我确实将board作为参数传递给playThrough;这就扼杀了你的回溯。哦。静态是什么意思?我得到一个错误,“无法对非静态字段板进行静态引用”“在这里,让我为您搜索…”我知道如何使用谷歌。我还是不明白这和我的计划有什么关系。如果我改变它,使它没有静态变量,它仍然不起作用。