【问题标题】:How to increase efficiency by using for loops?如何通过使用 for 循环来提高效率?
【发布时间】:2017-03-05 01:39:42
【问题描述】:

我是一名初学者 Java 程序员,我正在使用 2D 数组制作一个简单的井字游戏,这些是我的 if 语句来检查玩家 1 或玩家 2 是否获胜。我相信这可以通过使用 for 循环来简化,但是我不明白如何使用该方法。

if ((grid[0][0] == 1 && grid[0][1] == 1 && grid[0][2] == 1)
            || (grid[1][0] == 1 && grid[1][1] == 1 && grid[1][2] == 1)
            || (grid[2][0] == 1 && grid[2][1] == 1 && grid[2][2] == 1)
            || (grid[0][0] == 1 && grid[1][1] == 1 && grid[2][2] == 1)
            || (grid[0][2] == 1 && grid[1][1] == 1 && grid[2][0] == 1)
            || (grid[0][0] == 1 && grid[1][0] == 1 && grid[2][0] == 1)
            || (grid[0][1] == 1 && grid[1][1] == 1 && grid[2][1] == 1)
            || (grid[0][2] == 1 && grid[1][2] == 1 && grid[2][2] == 1)
            && won == false) {
        title.setText("X wins!");
        won = true;
    } else if ((grid[0][0] == 2 && grid[0][1] == 2 && grid[0][2] == 2)
            || (grid[1][0] == 2 && grid[1][1] == 2 && grid[1][2] == 2)
            || (grid[2][0] == 2 && grid[2][1] == 2 && grid[2][2] == 2)
            || (grid[0][0] == 2 && grid[1][1] == 2 && grid[2][2] == 2)
            || (grid[0][2] == 2 && grid[1][1] == 2 && grid[2][0] == 2)
            || (grid[0][0] == 2 && grid[1][0] == 2 && grid[2][0] == 2)
            || (grid[0][1] == 2 && grid[1][1] == 2 && grid[2][1] == 2)
            || (grid[0][2] == 2 && grid[1][2] == 2 && grid[2][2] == 2)
            && won == false) {
        title.setText("O wins!");
        won = true;
    }

以下是修改后的代码,使用的 if 语句和条件要少得多。

public static boolean hasWon(int[][] grid) {
    for (int a = 1; a <= 2; a++) {
        for (int b = 0; b < grid.length; b++) {
            // Checking for win in horizontal, then vertical, then diagonal
            if (grid[b][0] == a && grid[b][1] == a && grid[b][2] == a) {
                won = true;
            } else if (grid[0][b] == a && grid[1][b] == a && grid[2][b] == a) {
                won = true;
            } else if ((grid[0][0] == a && grid[1][1] == a && grid[2][2] == a
                    || (grid[0][2] == a && grid[1][1] == a && grid[2][0] == a))) {
                won = true;
            }
        }
    }
}

【问题讨论】:

  • 未涵盖所有条件。我认为(真或假)比(1 或 2)更容易。
  • 使用两个 for-loops 并将语句 ifelse-if 放在内部循环中。
  • 代码现在满足所有条件。将使用 for 循环解决方案来清理它。
  • 如果(第 0 行全为 1)和(第 1 行全为 2)会发生什么?
  • 如果第 0 行(顶行)全为 1,则 X 获胜,如果第 1 行(中间行)全为 2,则 O 获胜。

标签: java arrays if-statement multidimensional-array


【解决方案1】:

不是该问题的直接答案。 (因为这不是“一次检查所有”的风格)

为了简化,
1. 检查单元格被点击的时间。
2. 条件取决于被单击的单元格的位置以及单击该单元格的人。
3. 如果有人获胜,则结束游戏。


代码示例

// Part of codes.(not tested.)
// Each cell has three states (0, 1, or 2)

int player = 1; // (Not written here but) switch this each turn (1 or 2)

// In some place (activity.onCreate() etc)
{
    // For on click event(0, 0)
    cell_0_0.setOnClickListener(
        new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                grid[0][0] = player;
                final boolean isEnd = checkEnd_0_0();
                if (isEnd) {
                    // Call some function to end the game.
                    // Calling title.setText() in game end function maybe good.
                    // (as not needed to write many times.)
                    if (player == 1) {
                        title.setText("X wins!");
                    } else {
                        title.setText("O wins!");
                    }
                } else {
                    switchPlayer(); // Not written in this code.
                }
            }
        };
    );
    ...
}

// Call this on cell(0, 0) click event
// Returns true if someone wins.
boolean checkEnd_0_0() {
    // Omit checking grid[0][0] is 1 or 2 as it is clear.
    // Check horizontal.
    if (grid[0][1] == player) {
        if (grid[0][2] == player) {
            return true; // This is the case shown in question.
        }
    }
    // Check other cases (vertical, diagonal)
    ...
    // No match.
    return false;
}

【讨论】:

    【解决方案2】:

    是的,你是对的。 For循环是要走的路。这是您可以实现它的一种方法。

        public class tictactoe {
    
        public static void main(String[] args) {
    
            int[][] grid = {{1, 2, 1},
                    {1, 2, 1},
                    {2, 0, 1}};
            boolean won = hasWon(grid);
    
    
        }
    
        public static boolean hasWon(int[][] grid){
            for (int player = 1; player <= 2; player++){
                boolean playerWon = false;
                for(int i = 0; i < 3; i++){
                    //Horizonal win
                    playerWon = (grid[i][0] == player && grid[i][1] == player && grid[i][2] == player) || playerWon;
    
                    //Vertical Win
                    playerWon = (grid[0][i] == player && grid[1][i] == player && grid[i][2] == player) || playerWon;
    
                }
                //Diagonal Win
                playerWon = (grid[0][0] == player && grid[1][1] == player && grid[2][2] == player) || playerWon;
                playerWon = (grid[0][2] == player && grid[1][1] == player && grid[2][0] == player) || playerWon;
    
                if(playerWon){
                    if(player == 1){
                        System.out.println("X wins!");
                        return true;
                    }
                    else{
                        System.out.println("O wins!");
                        return true;
                    }
                }
            }
            //neither have won
            return false;
        }
    }
    

    【讨论】:

      【解决方案3】:

      为了帮助您自己找到解决方案,我现在给您一些提示。

      提示 #1:想想获胜意味着什么。玩家必须连续获得 3 个令牌 - 水平、垂直或对角线。想想如何在你的程序中表现出来。

      提示 #2:考虑如何将问题分解为更小更易于管理的部分。想想每个获胜场景的共同点,并将该逻辑分离成一个可以多次调用的方法。

      提示 #3:考虑是什么让每个获胜场景独一无二,以及如何使用 grid 生成更容易检查获胜的空间表示。

      如果您不确定 for 循环的工作原理或 Java 语言的其他方面,您可以在 Oracle's site 上找到教程

      【讨论】:

      • 谢谢,我已经用我的新解决方案编辑了 OP。
      • 很高兴能提供帮助。如果您想增加一个额外的挑战级别,只是为了让自己更加伸展,您可以考虑以下内容:您将如何编写通用代码,以便您可以将电路板更改为任意大小的矩形?
      • 我是否将按钮数组和网格数组的列和行的值设置为等于在顶部/开头声明的可配置值?
      • 是的,你会这样开始。您还需要修改任何依赖于 3 行和 3 列的逻辑,使其更通用。
      • 当棋盘不是正方形时,您还必须决定如何处理对角线。为简单起见,你可以决定你要强加一个规则,其中只有两个是有效的 - 这真的取决于你,因为矩形板完全超出了正常规则。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      • 2015-10-08
      • 2019-12-05
      相关资源
      最近更新 更多