简体   繁体   English

如何使if语句更小并避免对Java中的相同原因使用太多循环

[英]How to make if statements smaller and avoid using too many loops for the same cause in java

This code is for one of my assignments (connect four). 此代码用于我的一项任务(连接四项)。 I need to make this code less than 25 lines and also make the 'if' statements shorter. 我需要使这段代码少于25行,并且还要使'if'语句更短。 Also, the board has 6 rows and 7 columns. 此外,该板有6行7列。 My code is trying to figure out if a person has won. 我的代码试图弄清楚一个人是否赢了。

I have tried to merge all the loops into one loop, but that does not give me a correct answer. 我试图将所有循环合并为一个循环,但这并没有给我正确的答案。

public static boolean determineWin(String[][] board) {
    boolean won = false;

    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 4; j++) {
            if (board[i][j] != ". ") {
                if (board[i][j].equals(board[i][j+1]) && board[i][j+1].equals(board[i][j+2]) && board[i][j+2].equals(board[i][j+3])) {
                    won = true;
                    break;
                }
            }
        }
    }

    for (int i = 5; i > 2; i--) {
        for (int j = 6; j > 2; j--) {
            if (board[i][j] != ". ") {
                if (board[i][j].equals(board[i-1][j-1]) && board[i-1][j-1].equals(board[i-2][j-2]) && board[i-2][j-2].equals(board[i-3][j-3])){
                    won = true;
                    break;
                }
            }
        }

        for (int j = 0; j < 4; j++) {
            if (board[i][j] != ". ") {
                if (board[i][j].equals(board[i-1][j+1]) && board[i-1][j+1].equals(board[i-2][j+2]) && board[i-2][j+2].equals(board[i-3][j+3])){
                    won = true;
                    break;
                }
            }
        }

        for (int j = 0; j < 7; j++) {
            if (board[i][j] != ". ") {
                if (board[i][j].equals(board[i-1][j]) && board[i-1][j].equals(board[i-2][j]) && board[i-2][j].equals(board[i-3][j])){
                    won = true;
                    break;
                }
            }
        }
    }

    return won;
}

The result should be the same as the code above, but I just need the code to be a bit smaller (25 lines) and the if statements to be shorter. 结果应该与上面的代码相同,但是我只需要代码小一些(25行),而if语句要短一些。

The code above is inefficient because it has 4 separate for loops (to track the 4 directions in which you can win: 1) Left to right, 2) Top to bottom, 3) Diagonal 4) Diagonal/other direction -AND- because the if statements must check 4 consecutive positions. 上面的代码效率低下,因为它有4个单独的for循环(跟踪您可以赢的4个方向:1)从左到右,2)从上到下,3)对角线4)对角线/其他方向-AND-,因为if语句必须检查4个连续位置。

To optimize the solution you can recognize that you can maintain the state for how many consecutive same pieces have occurred at each position in the board, for each of the 4 possible directions you can win (4 unique states). 为了优化解决方案,您可以认识到可以维持statehow many consecutive same pieces在板上的每个位置上出现how many consecutive same pieces ,您可以赢得4个可能的方向中的每个方向(4个唯一状态)。

Consider as an example winning in the horizontal direction. 以在水平方向上获胜为例。 As you move left to right along the same row, the state counter increments by 1 if the piece to the left is the same. 当您沿同一行从左向右移动时,如果左侧的块相同,则状态计数器将增加1。 If there is ever a '.', the counter resets to 0. If there is a different piece, the counter resets to 1. You are in a winning position if any of these 4 state counters gets to 4. 如果存在'。',则计数器将重置为0。如果存在其他片段,则计数器将重置为1。如果这4个状态计数器中的任何一个达到4,则您处于获胜位置。

The code below is complete for the winning directions of horizontal (state variable 0), and vertical (state variable 1). 以下代码针对水平(状态变量0)和垂直(状态变量1)的获胜方向完成。 It is left as an exercise to complete the two rows which represent each of the diagonal directions (state variables 2 and 3). 剩下的练习是完成代表对角线方向(状态变量2和3)的两行。

public static boolean determineWin(String[][] board) {

    int[][][] counters = new int[board[0].length+1][board.length+1][4];

    for (int y=0; y<board.length; y++) {
        for (int x=0; x<board[0].length; x++) {
            if (!board[y][x].equals(".")) {
                counters[y][x][0] = (x>0 && board[y][x].equals(board[y][x-1])) ? counters[y][x-1][0] + 1 : 1;
                counters[y][x][1] = (y>0 && board[y][x].equals(board[y-1][x])) ? counters[y-1][x][1] + 1 : 1;
                // Diagonal 1 TODO:  counters[y][x][2] = 
                // Diagonal 2 TODO:  counters[y][x][3] = 
                if (counters[y][x][0] == 4 || counters[y][x][1] == 4 || counters[y][x][2] == 4 || counters[y][x][3] == 4)
                    return true;
            }
        }
    }
    return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM