【问题标题】:Bad practice? Leaving out for loop condition不好的做法?省略循环条件
【发布时间】:2014-01-07 07:21:16
【问题描述】:

我正在做一个国际象棋游戏,现在我正在制作一种方法来检查国王的方向,如果发现威胁则返回 true,如果没有发现威胁则返回 false。 此方法需要两个整数来增加 x 和 y。并且此方法将从起始位置沿给定方向((1,0)向上,(1,1)向上和向右,(0,1)向下)。

我的问题是,这个方法用for循环检查路径,最终会碰到棋局的边界,并找到障碍,否则会找到一个棋子。无论哪种方式,这都是 for 循环应该如何结束。但是那么 for 循环中会出现什么条件呢? 我觉得把它排除在外可能是不好的做法,但唯一合乎逻辑的条件是确保 x 和 y 都在 1-8 的范围内。但这会使代码看起来像: for(int i = begx + xdiff, j = begy + ydiff; (i < 8 && i > 1) && (j < 8 && j > 1); i += xdiff, j += ydiff) { .. }

这将是我看到的唯一其他选择,这本身对我来说似乎也是不好的做法。因为,它看起来过于复杂和挤在一起。而且这个条件永远不应该被打破,那么如果它永远不会成为循环中断的原因,我为什么要把它放在那里呢?我不希望其他程序员阅读我的代码并认为这可能是他们必须注意的事情,而实际上,我只是不需要那里的条件并将其放入以进行双重检查。

这是整个方法,供参考:

public boolean incheckPath(Location l1, int xdiff, int ydiff) {
    int begx = l1.getX();
    int begy = l1.getY();

    String team = board[begx][begy].getTeam();

    for(int i = begx + xdiff, j = begy + ydiff; ; i += xdiff, j += ydiff) {
        if(board[i][j].getType() != ' ') {

            if(board[i][j].getType() == '#') {
                return false;
            }
            if(board[i][j].getTeam().equals(team)) {
                return false;
            }
            if(board[i][j].getType() == 'Q' || board[i][j].getType() == 'R') {
                return true;
            }

        }
    }

}

编辑 已经改进了实现一个while循环,但是现在如何改进呢?有人建议使用 break and continue,所以我在我看到的地方实现了它。但是,有人说我不应该循环返回。如果不做一个变量来保存返回值,这怎么可能?

public boolean incheckPath(Location l1, int xdiff, int ydiff) {
    int x = l1.getX();
    int y = l1.getY();

    String team = board[x][y].getTeam();

    while(true) {
        x += xdiff;
        y += ydiff;

        if(board[x][y].getType() == '#' || board[x][y].getTeam().equals(team)) {
            break;
        }

        if(board[x][y].getType() == 'Q' || board[x][y].getType() == 'R') {
            return true;
        }

    }

    return false;

}

【问题讨论】:

  • 所以,我不清楚。你只是想要一种方法来遍历这件作品的可能动作吗?
  • @GGrec - 代码确实可以编译,它是一个完全可用的国际象棋游戏,我只是改变了一些方法。你有什么建设性的要说吗?
  • 当终止条件是breakreturn 时,省略循环条件或将其设置为true 或任何其他内容绝对没有错。 (我们将把关于从循环内部返回的争论留到另一天。)
  • @MatthewC 是的。避免硬编码字符串。学习使用continue 提高代码可读性,使用break 提高性能。结合这些 IF 语句。你的代码很好。
  • 我倾向于不使用for,而是使用while(true) 并在外部设置循环控制变量。事实上,它们很难在 for 中跟踪,并且会更清楚地划分为单独的行。

标签: java for-loop syntax conditional-statements chess


【解决方案1】:

我会比较从敌方棋子到国王位置的可能移动,而不是每个棋子从国王位置可能的移动。 小图要展示,因为我不知道如何表达。

       C        C
       C     C   
   "P" C  C       //P is Pawn
 C  C "K" C  C  C //K is King
    C  C  C       //C is where you (potentially) had to check
 C     C     C   



   "P"            //P is Pawn
 C    "K"         //K is King
                  //C is where you (potentially) had to check

现在,我认为这种情况对我有利,因为只有一件,而且它会随着件数的增加而变化。但我这样做的原因是:

一旦你有了可能的动作列表,你也可以将它用于其他事情,例如确保一个动作是有效的,并为哪个动作最好打分。 (您甚至可能已经为此目的创建了一个列表或数组)

我意识到这意味着重新编码你所拥有的大部分内容。 (听起来它已经在工作了),但我想我会把它扔在那里。

【讨论】:

  • 这将占用两倍的代码并且效率低下。你的图表让它看起来更快,检查的地方更少,但那是因为敌人只有一块。有了更多,并且无法判断哪些在国王的范围内,您将不得不测试敌方队伍每一个部分的每一个动作。而不是我们国王的一举一动。
  • @MatthewC 当您仅考虑这种情况时,您是正确的(正如我在帖子中也指出的那样),但我坚持我所说的。棋子移动后检查国王,因此您只需要检查移动的棋子的移动,以及被移动的棋子阻挡的棋子的移动。如果您为每个棋子保留一个可用动作列表(例如用于 AI 目的),那么无论如何您都在更新类似的逻辑。
【解决方案2】:

对于这种问题,最好使用while循环

使用boolean loop = True;

while(循环){...};

然后您可以使用 return 语句退出循环

【讨论】:

    【解决方案3】:

    你想要做的是更易读的while循环:

        int i = begx + xdiff;
        int j = begy + ydiff;
        while (true) {
            if(board[i][j].getType() != ' ') {
                if(board[i][j].getType() == '#') {
                    return false;
                }
                if(board[i][j].getTeam().equals(team)) {
                    return false;
                }
                if(board[i][j].getType() == 'Q' || board[i][j].getType() == 'R') {
                    return true;
                }
            }
            i += xdiff; 
            j += ydiff;
        }
    

    【讨论】:

      【解决方案4】:

      如果您根据您编写的其他代码自行确定for 循环何时结束,那么您应该声明一个布尔值

      boolean keepLooping = true

      并在您希望循环停止时将其设置为 false。请注意,您必须在 for 循环中执行此操作。

      现在将循环的条件设为您刚刚创建的变量。换句话说,它会说...; keepLooping ; ...

      另外,我不确定您对 getType 的实现,它可能会返回一个字符。如果它返回一个字符串,您可能并不是要使用== 来比较字符串。您想使用oneString.equals(anotherString) 检查它们是否等效。使用 == 实际上检查它们是否实际上是内存中的相同变量。可能这不是你想要的。

      所以在这种情况下你的代码看起来像

      if(board[i][j].getType().equals("Q")   ......
      

      但如果 getType 返回一个字符,则本段不适用。

      【讨论】:

      • 我认为getType() == 'Q' 表示它返回的是一个字符 Q 而不是一个字符串。这应该没问题。否则我同意使用 while 循环和布尔值。
      • getType 返回一个字符,那部分没问题。
      • 我忽略了单引号 String str = 'contentsOfMyString' 在 java 中无效,已编辑答案。
      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多