Java:如何检查2D阵列中的对角连接四赢

Java:如何检查2D阵列中的对角连接四赢,java,arrays,multidimensional-array,Java,Arrays,Multidimensional Array,我有一个Connect-Four“board”,它是一个6*7 2D字符数组,填充有空格、X或O。当一行中垂直、水平或对角有四个X或四个O时,就会满足win条件。我已经成功地检查了垂直和水平的win条件,其中Wing char通过以下方法返回: private char CheckVerticalWinner(char[][] currentBoard) { // check vertical (move down one row, same column) char vWinn

我有一个Connect-Four“board”,它是一个6*7 2D字符数组,填充有空格、X或O。当一行中垂直、水平或对角有四个X或四个O时,就会满足win条件。我已经成功地检查了垂直和水平的win条件,其中Wing char通过以下方法返回:

private char CheckVerticalWinner(char[][] currentBoard) {
    // check vertical (move down one row, same column)
    char vWinner = ' ';
    for (int col=0; col<7; col++) {
        int vCount = 0;
        for (int row=0; row<5; row++) {
            if (currentBoard[row][col]!=' ' &&
                currentBoard[row][col] == currentBoard[row+1][col]) {
                vCount++;
                System.out.println("VERT "+vCount); //test
            } else {
                vCount = 1;
            }

            if (vCount>=4) {
                vWinner = currentBoard[row][col];
            }
        }
    }
    return vWinner;
}


private char CheckHorizontalWinner(char[][] currentBoard) {
    // check horizontal (move across one column, same row)
    char hWinner = ' ';
    for (int row=0; row<6; row++) {
        int hCount = 0;
        for (int col=0; col<6; col++) {
            if (currentBoard[row][col]!=' ' &&
                currentBoard[row][col] == currentBoard[row][col+1]) {
                hCount++;
                System.out.println("HORIZ "+hCount); //test
            } else {
                hCount = 1;
            }

            if (hCount>= 4) {
                hWinner = currentBoard[row][col];
            }
        }
    }
    return hWinner;
}

任何帮助都将不胜感激

首先,您不需要在任何给定时间检查整个电路板,我认为这是在您的代码中完成的。要优化代码并使其对您和计算机都更简单,您可以执行以下操作:

在检查电路板上的任何方向之前,首先用用户输入填充电路板。这意味着每次你得到新的输入,你要做的第一件事就是使用这些输入并更新你的矩阵。这样,我们总是更新矩阵,我们可以做我们下一步要做的事情:

从用户处获取输入的x和y。这意味着,若用户选择第2行,那个么您将填充第2行和第4列上的矩阵。我们用这些坐标做什么?我们使用它们并将它们发送给方法,这些方法将检查矩阵中的4行。这使我们能够不检查整个矩阵,而只检查填充的矩阵

在垂直检查中,现在只能从这些坐标向下检查,例如:

boolean winner = false;

count = 1;

if (x > 3) 

for (i = 0; i < 3; i++) {

    if (A[x][y-i] == 'X')

        count ++;

    if (count == 4) {

        winner = true;

        return;

    }
boolean-winner=false;
计数=1;
如果(x>3)
对于(i=0;i<3;i++){
如果(A[x][y-i]='x')
计数++;
如果(计数=4){
胜利者=真;
返回;
}
对于水平检查,执行相同的操作,但是水平。您需要两个循环,用于检查左侧和右侧

对于对角线检查,现在只需要检查包含设置坐标的对角线。例如,如果用户输入了第4行和第5列,对于左对角线,我们需要检查(5,4)、(6,3)和(7,2)

使用坐标检查赢家要简单得多,它只允许我们检查矩阵中填充的部分


很抱歉,这是从电话上写的,我可以在以后更新并添加更多的示例。首先,您不需要在任何给定时间检查整个电路板,我认为这是在您的代码中完成的。要优化您的代码并使您和计算机都更简单,您可以执行以下操作:

在检查电路板上的任何方向之前,首先使用用户输入填充电路板。这意味着每次您获得新输入时,您首先要做的是使用该输入并更新矩阵。这样,我们总是更新了矩阵,我们可以做下一步要做的事情:

从用户处获取输入的x和y。这意味着,如果用户选择第2行,您将填充第2行和第4列上的矩阵。我们如何处理这些坐标?我们使用它们并将它们发送给检查矩阵中4行的方法。这使我们不必检查整个矩阵,而只检查填充的矩阵

在垂直检查中,现在只能从这些坐标向下检查,例如:

boolean winner = false;

count = 1;

if (x > 3) 

for (i = 0; i < 3; i++) {

    if (A[x][y-i] == 'X')

        count ++;

    if (count == 4) {

        winner = true;

        return;

    }
boolean-winner=false;
计数=1;
如果(x>3)
对于(i=0;i<3;i++){
如果(A[x][y-i]='x')
计数++;
如果(计数=4){
胜利者=真;
返回;
}
对于水平检查,执行相同的操作,但是水平。您需要两个循环,用于检查左侧和右侧

对于对角线检查,现在只需要检查包含设置坐标的对角线。例如,如果用户输入了第4行和第5列,对于左对角线,我们需要检查(5,4)、(6,3)和(7,2)

使用坐标检查赢家要简单得多,它只允许我们检查矩阵中填充的部分


很抱歉,这是从电话里写出来的,如果您愿意,我可以稍后更新并添加更多示例。

最简单的算法可能是:

for every direction
    for every coordinate
        check whether the next 3 elements in this direction exist and are the same
代码:

final int maxx = 7;
final int maxy = 6;

char winner(char[][] board) {
    int[][] directions = {{1,0}, {1,-1}, {1,1}, {0,1}};
    for (int[] d : directions) {
        int dx = d[0];
        int dy = d[1];
        for (int x = 0; x < maxx; x++) {
            for (int y = 0; y < maxy; y++) {
                int lastx = x + 3*dx;
                int lasty = y + 3*dy;
                if (0 <= lastx && lastx < maxx && 0 <= lasty && lasty < maxy) {
                    char w = board[x][y];
                    if (w != ' ' && w == board[x+dx][y+dy] 
                                 && w == board[x+2*dx][y+2*dy] 
                                 && w == board[lastx][lasty]) {
                        return w;
                    }
                }
            }
        }
    }
    return ' '; // no winner
}
final int maxx=7;
最终整数最大值=6;
char winner(char[][]板){
int[][]方向={{1,0},{1,-1},{1,1},{0,1};
对于(int[]d:方向){
int dx=d[0];
int-dy=d[1];
对于(int x=0;x如果(0最简单的算法可能是:

for every direction
    for every coordinate
        check whether the next 3 elements in this direction exist and are the same
代码:

final int maxx = 7;
final int maxy = 6;

char winner(char[][] board) {
    int[][] directions = {{1,0}, {1,-1}, {1,1}, {0,1}};
    for (int[] d : directions) {
        int dx = d[0];
        int dy = d[1];
        for (int x = 0; x < maxx; x++) {
            for (int y = 0; y < maxy; y++) {
                int lastx = x + 3*dx;
                int lasty = y + 3*dy;
                if (0 <= lastx && lastx < maxx && 0 <= lasty && lasty < maxy) {
                    char w = board[x][y];
                    if (w != ' ' && w == board[x+dx][y+dy] 
                                 && w == board[x+2*dx][y+2*dy] 
                                 && w == board[lastx][lasty]) {
                        return w;
                    }
                }
            }
        }
    }
    return ' '; // no winner
}
final int maxx=7;
最终整数最大值=6;
char winner(char[][]板){
int[][]方向={{1,0},{1,-1},{1,1},{0,1};
对于(int[]d:方向){
int dx=d[0];
int-dy=d[1];
对于(int x=0;x如果(0)不是一个简单的问题,那就是阻止一个NXM板,你只需要考虑代码< >(0,0)< /代码>的子矩阵到<代码>(N-4,M- 4)< /代码>右对角线,例如,“扫描”。从左上到右下。作为建议,我建议您创建一个方法,该方法接受网格的起始行和起始列,然后“扫描”在一个特定的方向上,至少有4个值。当一行中有4个值时,它可以返回布尔值。提示:尝试提出更有意义的抽象:对于您的目的,使用两维字符数组是一种非常低级的抽象。相反,您可以使用枚举来表示板中的单元格。换句话说,不要使用枚举“立即”的想法是一个矩阵必须是一个两个模糊数组。花了一些时间思考如果一个不同的组织单元的形式可能会使其他事情变得更容易。这不是一个简单的问题,阻止自己超过该板的范围吗?对于一个nxm板,你只需要考虑<代码>(0,0)< /代码>的子矩阵到<代码>。(N-4,M-4)
例如,对于右对角线和从左上到右下的“扫描”。作为建议,我建议您使用一种方法,该方法接受t的起始行和起始列