【问题标题】:If-else alternativeIf-else 替代方案
【发布时间】:2010-10-14 04:56:28
【问题描述】:

我正在编写一个程序,它的工作原理是填充一个二维数组来检查获胜条件,它是 noughts 和 crosss,所以二维数组在单击按钮时填充,1 代表一个圆圈, 2 为交叉,则 checkWin() 将按此原理工作,而不是实际代码...

if (myArray[0][0] == 1 && myArray[0][1] == 1 && myArray[0][2] == 1){
    setBoolWinVal = true;
} else {
    if(myArray[0][0] == 2 && myArray[0][1] == 2 && myArray[0][2] == 2){
    setBoolWinVal = true;
}

您可以立即看到,对于每个获胜条件,这将是一团糟,有没有办法重写这个获胜检查以缩短它一点?

【问题讨论】:

  • 是的,忘了说这是明确的作业,虽然不是为了改进这一点,我可以按原样提交,但我想自己编写更好的代码,为输入人员欢呼,顺便说一句:我没想到完整的代码解决方案,所以谢谢:p

标签: java arrays if-statement


【解决方案1】:

这看起来像家庭作业,所以我不会完全放弃它。但请注意以下几点:

  • 当你在一行、一列或沿对角线上拥有三个相同的东西时,你就赢了。

  • 不是你需要检查一行中是否有三个零或三个十字,而是一行中有三个相同的东西

您可以从编写一个函数开始,该函数确定行、列或对角线是否具有三个相同类型的事物(并且该事物不是空白单元格)。然后为每一行、每一列和每一对角线调用一次该函数。

【讨论】:

    【解决方案2】:

    这是(未经测试的)代码。这肯定不是生产质量:)

    注意其他答案的一些优化:

    1. for 循环的使用
    2. 我们检查相等的玩家值,而不是特定的玩家值
    3. 对角线获胜必须通过单元格[1][1]

    .

    int find_winner(int[][] arr) {
    
        // check rows
        for (int i = 0; i < 3; ++i) {
            int player = arr[i][0];
            if (player < 1) continue; // nb: prior version didn't check for empty cells
            if (arr[i][1] == player && arr[i][2] == player) return player;
        }
    
        // check cols
        for (int i = 0; i < 3; ++i) {
            int player = arr[0][i];
            if (player < 1) continue;
            if (arr[1][i] == player && arr[2][i] == player) return player;
        }
    
        // check diagonals
        int player = arr[1][1];
        if (player < 1) return -1;
    
        if ((arr[0][0] == player && arr[2][2] == player) ||
            (arr[2][0] == player && arr[0][2] == player)) return player;
    
        // no winner found
        return -1;
    }
    

    【讨论】:

    • @basszero - 当我开始回答这个问题时,它没有被标记为作业
    【解决方案3】:

    显而易见的方法是循环遍历行、列或对角线中的 3 个元素并检查它们是否相同。

    另一种方法是使用更紧凑的表示 - 例如,一个 int,其中 9 个单元由每个 2 位表示,或者两个短裤,每个玩家一个。然后使用查找表或按位运算,将状态映射为赢输。

    如果单个位表示一个单元格,并且您有一个填充位,则每个玩家的图块都是 3 个十六进制数字 0-7。

    对角线是:

    cells & 0x421 == 0x421
    cells & 0x124 == 0x124
    

    垂直线是:

    cells & (cells>>4) & (cells>>8) != 0
    

    水平线

    cells & (cells>>1) & (cells>>2) != 0
    

    使用 64 位模式使用类似的技术来表示国际象棋游戏中可能的移动。

    【讨论】:

      【解决方案4】:

      给你两个有趣的想法:(我假设底层的一维数组,因为它让生活更轻松。)

      首先:对要测试的位置进行编码。就像你有描述你的领域的一维数组一样:

      diag[] = { { 0, 1, 2}, {3, 4, 5}, {6, 7, 8},
                 { 0, 3, 6}, {1, 4, 7}, {2, 5, 8},
                 { 0, 4, 8}, {6, 4, 2}};
      

      然后遍历 diag:对于其中的每个元素,测试三个相应的字段(使用 diag[i] 作为字段数组的索引)。

      第二:使用位域来表示你的域。像 java.util.BitSet。然后将解决方案编码为位域,如 {1, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 1, 0, 0, 0} 等。然后你可以测试(循环)如果(field &amp; solution[i] == solution[i])。对于第二个玩家,只需在 if 语句中使用!field

      很有趣,不是吗? p.s.:由你来制作工作 Java 代码!

      【讨论】:

        【解决方案5】:

        家庭作业的味道。

        小提示 - 使用 for 循环,它适用于您想要的任何大小。如果您改用递归,则可以加分。

        定义: 递归 -> 参见递归

        【讨论】:

          【解决方案6】:

          因此,如果您考虑一下,您正在检查以下条件:

          www   xxx   xxx  wxx
          xxx   www   xxx  xwx
          xxx   xxx   www  xxw
          

          其中 w 是要检查是否获胜的,而 x 是要忽略的。

          (0,0),(0,1),(0,2) 是第一个正确解中“w”的位置。 1,0, 1,1 和 1,2 是第二个等等。

          这在我看来应该是数据而不是代码。 诀窍在于,如何有效地输入和存储数据。

          请注意,此数据开始看起来像您的数组索引。

          假设您有一个“解决方案”数组,其中包含 8 个 x,y 对(每对都表示获胜的解决方案组合)

          然后您所要做的就是遍历这个集合,提取三个 x,y 对并测试它们。所以它与你所拥有的类似,但在你有数字的地方使用变量。

          if(myArray[x0][y0] == 2 && myArray[x1][y1] == 2 && myArray[x2][y2] == 2){
              win();
          

          当您对其进行迭代时,索引变量将被您的数据的下一行替换。

          由于您不想在获胜后报告失败,因此您将不得不稍微调整一下逻辑以确保您的循环停止,但这对于家庭作业式问题可能已经有太多帮助了.

          【讨论】:

            【解决方案7】:
            1. 将 board 表示为 0..19683(第 3 到第 9)中的 int
            2. 预先生成获胜图板并确定谁是每个图板中的获胜者,也许是手动的
            3. 在运行时在预先计算的地图中查找当前板

            【讨论】:

              【解决方案8】:

              对于 n X n 矩阵...

              //Check all horizontal rows
              for(i=0; i<n && !setBoolWinVal; i++) //row
              {
                  setBoolWinVal = true;
                  for(j=0; j<n-1; j++)
                  {
                      if( myArray[i][j] != myArray[i][j+1] ) //column
                      {
                          setBoolWinVal = false;
                          break;
                      }
                  }
              
                  if(setBoolWinVal) declareWinner(myArray[i][0]);
              }
              
              //Check all vertical columns
              if(!setBoolWinVal)
              {
                  for(i=0; i<n && !setBoolWinVal; i++) //column
                  {
                      setBoolWinVal = true;
                      for(j=0; j<n-1; j++) //row
                      {
                          if( myArray[j][i] != myArray[j+1][i] ) 
                          {
                              setBoolWinVal = false;
                              break;
                          }
                      }
                  }
              
                  if(setBoolWinVal) declareWinner(myArray[0][i]);
              }
              
              
              //Check forward diagonal
              if(!setBoolWinVal)
              {
                  setBoolWinVal = true;
                  for(i=0; i<n-1; i++)
                  {
                      if( myArray[i][i] != myArray[i+1][i+1])
                      {
                          setBoolWinVal = false;
                          break;
                      }
                  }
              
                  if(setBoolWinVal) declareWinner(myArray[0][0]);
              }
              
              //Check reverse diagonal
              if(!setBoolWinVal)
              {
                  setBoolWinVal = true;
                  for(i=0, j=n-1; i<n-1 && j>0; i++, j--)
                  {
                      if( myArray[i][j] != myArray[i+1][j-1])
                      {
                          setBoolWinVal = false;
                          break;
                      }
                  }
              
                  if(setBoolWinVal) declareWinner(myArray[0][n-1]);
              }
              

              【讨论】:

                【解决方案9】:

                你也可以反复解决这个问题:

                1. 为每个列、行和对角线的每种类型的标记生成一个数组。初始化为零。
                2. 对于网格中的每个条目,如果它有一个标记,则为该标记增加相应的列、行和对角线条目。
                3. 如果其中任何一个条目等于棋盘的尺寸,则该标记获胜。

                【讨论】:

                  【解决方案10】:

                  一个简单而优雅的解决方案 - 您可以通过以下方式将数字 1 到 9 分配给您的电路板:

                  8 1 6
                  3 5 7
                  4 9 2

                  这个正方形有一个独特的特点,即每一行、每一列、每一对角线 总和为 15,并且没有办法从三个单元格中得到 15 的总和 除非 它们共享一行、一列或对角线。

                  为每个玩家保留两个布尔数组:

                  boolean squarePairs[PAIRSMAXSUM+1];
                  boolean chosenSquares[NUMSQUARES+1];
                  

                  其中 PAIRSMAXSUM = 9+8 和 NUMSQUARES = 9

                  然后,您可以通过调用此函数轻松检查获胜棋步:

                  boolean hasWon(int squareIndex) {
                      return squarePairs[WINNINGSUM - squareIndex];
                  }
                  

                  其中 WINNNINGSUM 为 15。如果该函数返回 false,则通过调用此函数更新布尔数组:

                  void update(int squareIndex) {
                      for (int i = 1; i <= NUMSQUARES; i++) {
                          if (chosenSquares[i]) {     {
                              squarePairs[i + squareIndex] = true;
                          }
                      }
                      chosenSquares[squareIndex] = true;
                  }
                  


                  就这么简单!

                  【讨论】:

                    【解决方案11】:

                    这听起来确实有点像家庭作业,但我会帮助解决遍历行和列的简单问题,检查它们是否都已满,对角线稍微难一些,我把它留给你。 同样,我相信嵌套的 for 循环是最好的主意:

                    java.util.Arrays;
                    
                    public yourClass{
                    
                    public void findAnswer{
                    
                    int initialVal = 0;
                    
                    int copy = 0;
                    
                    int column = 0;
                    
                    boolean columnVal = true;
                    
                    boolean rowVal = false;
                    
                    for (int j = 0; j< myArray.length; j++){ //presuming myArray and myArray[] are same length
                    
                    boolean firstRun = true;
                    
                        for (int i = 0; i <myArray.length; i++){
                    
                            initialVal = myArray[i][column];
                            if (firstRun == true){
                                copy = intialVal; //makes a copy for the first time, to compare
                                firstRun = false;
                            }
                            if (intialVal != copy){
                                columnVal = false; //realises this column isnt a full column i.e. 3 1's or 2's in column
                                return;
                            }else
                                columnVal = true;
                    
                            }//end nested for loop
                    
                        rowVal = findRow(j); 
                        if(rowVal = true)
                        return;
                    }
                    
                    public boolean findRow(int row){
                    
                        int[] tempRow1, tempRow2;
                        Arrays.fill(tempRow1, 1); 
                        Arrays.fill(tempRow2, 2); //fills temp arrays for comparison
                        boolean answer = false;
                        if (Arrays.equals(myArray[], tempRow1) || Arrays.equals(myArray[], tempRow2) //this tests either, || being logical OR
                            answer = true;
                        return answer;
                    }
                    }
                    

                    n.b.这段代码没有测试,而且很快就编码了,所以看起来不太好,可以细化,我也没有实现对角线。 p.s.如果是家庭作业,最好是在网上查资料,自己动手做,而不是找别人帮你做。

                    【讨论】:

                      【解决方案12】:

                      如果数组的长度都相同,那么以下应该会有所帮助。

                      Arrays.equals(myArray[0], {1,1,1})
                      

                      否则,编写一个循环遍历myArray[0] 中所有值的函数。

                      【讨论】:

                      • 不起作用。如果三个获胜元素位于一列而不是一行怎么办?
                      • 没有意识到这是一种可能性 - 两个示例都使用了行。谢谢你的收获。
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-05-30
                      • 2014-05-22
                      • 1970-01-01
                      • 2013-09-16
                      • 1970-01-01
                      相关资源
                      最近更新 更多