如何判断任意方向连续有5个相同的字符?

问题描述 投票:0回答:1

我正在努力创建一个简单的 OMOK 游戏。我有一个 2D 数组,当玩家填充时,有机会连续出现 5 个相同的角色。它可以是对角线、水平或垂直的。我想在玩家设置一个棋子后检查周围的元素,以便在每次设置棋子时不检查整个棋盘,但如果这是不可能的,则不能检查整个棋盘 太糟糕了。 以下是我认为这样的事情如何运作的不同想法。

public static boolean areFiveConnected(String [][] tablero, int x, int y){
        return hasFiveInARowVertical(tablero,x,y) || northeastDiagonal(tablero,x,y) || southwestDiagonal(tablero, x, y) || hasFiveInARowHorizontal(tablero, x, y);

    }
    private static boolean hasFiveInARowVertical(String[][] array, int row, int col) {
        // Check if the current element and the next 4 elements in the row are all the same symbol.
        for (String [] line: array){
            System.out.println(Arrays.toString(line));
            for (int i = 0; i < line.length - 4; i++) {
                System.out.println(!line[i].equals(".")+line[i]+"here");
                if (!line[i].equals(".") || line[i].equals(line[i + 1]) && line[i + 1].equals(line[i + 2]) && line[i + 2].equals(line[i + 3]) &&line[i + 3].equals(line[i + 4])) {
                    return true;
                }
            }
        }

        // If we reach here, there are 5 of the same symbols in a row horizontally.
        return false;
    }
    private static boolean hasFiveInARowHorizontal(String[][] array, int row, int col) {
        // Check if the current element and the next 4 elements in the column are all the same symbol.
        for (int i = 0; i < 5; i++) {
            if (row + i >= array.length || !array[row + i][col].equals(array[row][col]) || array[row][col].equals(".")) {
                return false;
            }
        }

        // If we reach here, there are 5 of the same symbols in a row vertically.
        return true;
    }
    private static boolean northeastDiagonal(String[][] tablero, int row, int col) {
        // ascendingDiagonalCheck
        for (int i = 0; i < 5; i++) {
            // Check northeast diagonal.
            if (row + i >= tablero.length || col + i >= tablero[row].length || !tablero[row + i][col + i].equals(tablero[row][col]) || tablero[row][col].equals(".")) {
                return false;
            }
        }
        return true;
    }
    private static boolean southwestDiagonal(String[][] tablero, int row, int col) {
        // ascendingDiagonalCheck
        for (int i = 0; i < 5; i++) {
            // Check northeast diagonal.
            if (row - i < 0 || col + i >= tablero[row].length || !tablero[row - i][col + i].equals(tablero[row][col]) || tablero[row][col].equals(".")) {
                return false;
            }
        }
        return true;
    }

以下任何“字符串”都会导致“true”输出。 “X”代表一名玩家,“O”代表对手。

    a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
0  [X] [.] [.] [.] [.] [.] [X] [.] [.] [.] [.] [.] [.] [.] [.] 
1  [X] [.] [.] [.] [.] [.] [.] [X] [.] [.] [.] [.] [.] [.] [.] 
2  [X] [.] [.] [.] [.] [.] [.] [.] [X] [.] [.] [.] [.] [.] [.] 
3  [X] [.] [.] [.] [.] [.] [.] [.] [.] [X] [.] [.] [.] [.] [.] 
4  [X] [.] [.] [.] [.] [.] [.] [.] [.] [.] [X] [.] [.] [.] [.] 
5  [.] [O] [O] [O] [O] [O] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
6  [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
7  [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
8  [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
9  [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
10 [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
11 [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
12 [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
13 [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 
14 [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] [.] 

我尝试阅读每一行,这在理论上是可行的,但代码现在还没有这样做。我更喜欢这样的解决方案:当玩家设置棋子时,代码可以检查该棋子是否创建了连续 5 个棋子的字符串。

我还尝试读取与最近设置的片段相邻的下 4 个字符,但仅检查边缘,而不检查字符串的中间,从而产生真实的输出。

java arrays game-development
1个回答
0
投票

检查正在放置的每个棋子的相邻插槽的想法是正确的。您遇到的问题是它不会检查字符串中间的部分。解决这个问题的一种方法是从棋子开始迭代每组方向,然后计算每个方向的棋子数量。这是垂直检查的示例。

private static boolean hasFiveInARowVertical(String[][] tablero, int row, int col) {
    //if the current tile is not a piece then there is not a set of 5 at that piece, so we return false
    if (tablero[row][col].equals("[.]")) {
        return false;
    }
    int x = col;
    int y = row;
    int count = 1;
    char piece = tablero[row][col].charAt(1);
    //iterates through all slots below the passed row and column that have the same piece and increments the count variable accordingly
    while (y<tablero.length && tablero[y+1][x].charAt(1)==piece) {
        y++;
        count++;
        //if the number of pieces found exceeds 5 then we can return true immediately and don't have to check anything else
        if (count>=5) {
            return true;
        }
    }
    //resets the x and y variables back to the current tile so we're not checking the same tiles twice 
    x = col;
    y = row;
    //iterates through all slots above the passed row and column and increments the count variable accordingly
    while (y>0 && tablero[y-1][x].charAt(1)==piece) {
        y--;
        count++;
        //same here, if the number of pieces found exceeds 5, then return true
        if (count>=5) {
            return true;
        }
    }
    return false;
}

此方法从传递的行和列开始,然后向上迭代,只要迭代的图块与玩家的棋子匹配即可。一旦它到达数组的末尾或图块不再与玩家的棋子匹配的点,它就会从传递的行和列开始返回,但这次它向下而不是向上迭代,沿途执行相同的检查。这可确保在将棋子放置在系列中的任何位置后,它会连续检查 5 个棋子。我将在下面介绍其余的方法(水平检查、东北检查和西北检查),但这些方法几乎都是相同的,除了变量递增的变化之外,因此您可以将其概括为更大的方法,如果您希望最大限度地减少复制粘贴代码的数量。其余方法如下:

private static boolean hasFiveInARowHorizontal(String[][] tablero, int row, int col) {
    //if the current tile is not a piece then there is not a set of 5 at that piece, so we return false
    if (tablero[row][col].equals("[.]")) {
        return false;
    }
    int x = col;
    int y = row;
    int count = 1;
    char piece = tablero[row][col].charAt(1);
    //iterates through all slots to the right of the passed row and column that have the same piece and increments the count variable accordingly
    while (x<tablero[0].length && tablero[y][x+1].charAt(1)==piece) {
        x++;
        count++;
        //if the number of pieces found exceeds 5 then we can return true immediately and don't have to check anything else
        if (count>=5) {
            return true;
        }
    }
    //resets the x and y variables back to the current tile so we're not checking the same tiles twice 
    x = col;
    y = row;
    //iterates through all slots to the left of the passed row and column and increments the count variable accordingly
    while (x>0 && tablero[y][x-1].charAt(1)==piece) {
        x--;
        count++;
        //same here, if the number of pieces found exceeds 5, then return true
        if (count>=5) {
            return true;
        }
    }
    return false;
}
private static boolean northeastDiagonal(String[][] tablero, int row, int col) {
    //if the current tile is not a piece then there is not a set of 5 at that piece, so we return false
    if (tablero[row][col].equals("[.]")) {
        return false;
    }
    int x = col;
    int y = row;
    int count = 1;
    char piece = tablero[row][col].charAt(1);
    //iterates through all slots down to the left of the passed row and column that have the same piece and increments the count variable accordingly
    while (y<tablero.length && x>0 && tablero[y+1][x-1].charAt(1)==piece) {
        y++;
        x--;
        count++;
        //if the number of pieces found exceeds 5 then we can return true immediately and don't have to check anything else
        if (count>=5) {
            return true;
        }
    }
    //resets the x and y variables back to the current tile so we're not checking the same tiles twice 
    x = col;
    y = row;
    //iterates through all slots up to the right of the passed row and column and increments the count variable accordingly
    while (y>0 && x<tablero[0].length && tablero[y-1][x+1].charAt(1)==piece) {
        y--;
        x++;
        count++;
        //same here, if the number of pieces found exceeds 5, then return true
        if (count>=5) {
            return true;
        }
    }
    return false;
}
private static boolean southwestDiagonal(String[][] tablero, int row, int col) {
    //if the current tile is not a piece then there is not a set of 5 at that piece, so we return false
    if (tablero[row][col].equals("[.]")) {
        return false;
    }
    int x = col;
    int y = row;
    int count = 1;
    char piece = tablero[row][col].charAt(1);
    //iterates through all slots down to the right of the passed row and column that have the same piece and increments the count variable accordingly
    while (y<tablero.length && x<tablero[0].length && tablero[y+1][x+1].charAt(1)==piece) {
        y++;
        x++;
        count++;
        //if the number of pieces found exceeds 5 then we can return true immediately and don't have to check anything else
        if (count>=5) {
            return true;
        }
    }
    //resets the x and y variables back to the current tile so we're not checking the same tiles twice 
    x = col;
    y = row;
    //iterates through all slots up to the left of the passed row and column and increments the count variable accordingly
    while (y>0 && x>0 && tablero[y-1][x-1].charAt(1)==piece) {
        y--;
        x--;
        count++;
        //same here, if the number of pieces found exceeds 5, then return true
        if (count>=5) {
            return true;
        }
    }
    return false;
}
© www.soinside.com 2019 - 2024. All rights reserved.