【问题标题】:Java 2D array diagonals for game用于游戏的 Java 2D 数组对角线
【发布时间】:2012-12-04 14:43:35
【问题描述】:

为了澄清,我只想要一两个 for 循环来帮助我,最好是与我在垂直中使用的样式相同:)

我正在使用 2D 数组制作游戏,我需要检查以测试在当前位置(由绿色方块表示)该角色是否存在角色的对角线序列的一部分“l”更多.

【问题讨论】:

  • 对角线序列必须只在图的主对角线上,或者它可以在图上的任何地方?
  • 抱歉,我才意识到实际上并没有,但如果有人能给我一个 for 循环来执行所需的 4 项操作中的一项,那就太好了 :)
  • 它可以位于图表上的任何位置,具体取决于为“l”指定的长度,例如,在网格的右下角附近不可能有长度为 5 的次对角线。
  • 哦,当前位置必须是序列的一部分,不知道我是否澄清了这一点。
  • 您应该在帖子中添加一个问题。另外:通常,代码请求不是 SO 的一部分,我只是出于兴趣而回答... ;)

标签: java loops multidimensional-array logic diagonal


【解决方案1】:
public static boolean diagonals(char[][] b, int row, int col, int l) {

            int counter = 1; // because we start from the current position
            char charAtPosition = b[row][col];
            int numRows = b.length;
            int numCols = b[0].length;
            int topleft = 0;
            int topright = 0;
            int bottomleft = 0;
            int bottomright = 0;
            for (int i=row-1,j=col-1;i>=0 && j>=0;i--,j--) {
                if (b[i][j]==charAtPosition) {
                    topleft++;
                } else {
                    break;
                }
            }
            for (int i=row-1,j=col+1;i>=0 && j<=numCols;i--,j++) {
                if (b[i][j]==charAtPosition) {
                    topright++;
                } else {
                    break;
                }
            }
            for (int i=row+1,j=col-1;i<=numRows && j>=0;i++,j--) {
                if (b[i][j]==charAtPosition) {
                    bottomleft++;
                } else {
                    break;
                }
            }
            for (int i=row+1,j=col+1;i<=numRows && j<=numCols;i++,j++) {
                if (b[i][j]==charAtPosition) {
                    bottomright++;
                } else {
                    break;
                }
            }
            return topleft + bottomright + 1 >= l || topright + bottomleft + 1 >= l; //in this case l is 5
    }

我们的想法是我们朝四个方向走并计算步数。这可能不是最有效的实现,但至少看起来简洁且易于理解。

【讨论】:

    【解决方案2】:

    这是函数,它有效。解释在代码中的 cmets 中,但是如果您发现任何令人困惑的地方,请告诉我,我会解释它。

    public static boolean diagonals(char[][] b, int row, int col, int l) {
      int forwardCounter = 1; // this counts top right to bottom left
      int backCounter = 1; // this counts top left to bottom right
      int distance = 1;
      // 0 = topleft, 1 = topright, 2 = bottomleft, 3 = bottomright
      boolean[] checks = new boolean[]{true, true, true, true};
    
      char charAtPosition = b[row][col];
    
      while(checks[0] || checks[1] || checks[2] || checks[3]) {
        for(int i = 0; i < 4; i++) {
          if(checks[i]) {
            // This looks confusing but it's simply just converting i into
            // The four different directions
            checks[i] = checkSquare(b, row + (i < 2 ? -distance : distance),
                    col + (i % 2 == 0 ? -distance : distance), charAtPosition);
            if(checks[i]) {
              // If top left or bottom right
              if(i % 3 == 0) {
                backCounter++;
              } else {
                forwardCounter++;
              }
            }
          }
        }
    
        if (forwardCounter >= l || backCounter >= l) return true;
    
        distance++;
      }
    
      return false;
    }
    
    private static boolean checkSquare(char[][] b, int row, int col, char check) {
      if(row < 0 || row >= b.length) return false;
      if(col < 0 || col >= b[0].length) return false;
    
      return check == b[row][col];
    }
    

    【讨论】:

    • 哇,嵌套太多了。 :D
    • @brimborium: 不是真的,for 循环完成了你的四个if 语句的工作,只是因为我喜欢更混乱地删除代码的复制粘贴;)
    • 我没有批评,我只是陈述了一个事实。你基本上和我做同样的事情。 :) (虽然我更喜欢我的边界检查,因为它使用较少的检查)
    • brimorium: 啊 :) 无论如何,我测试了这个,它至少在@Ciphor 发布的两个示例上有效
    • 刚刚测试了你的代码。效果很好。由于 OP 的评论,我删除了我的:Added a previous method which does the same for a vertical, maybe you can adjust it? – Ciphor
    猜你喜欢
    • 2018-07-03
    • 1970-01-01
    • 2014-01-21
    • 2016-03-11
    • 2012-12-16
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多