【问题标题】:Booleans + while loops =?布尔值 + while 循环 =?
【发布时间】:2011-08-01 03:49:27
【问题描述】:

下面的代码有一个奇怪的问题(我已经删除了不相关的部分,并且引用的任何类/函数都按预期工作):

int curNumRooms = 0;

while(curNumRooms < numberOfRooms) {
    int w = Random.Range(minimumRoomSize, maximumRoomSize+1);
    int h = Random.Range(minimumRoomSize, maximumRoomSize+1);

    int x = Random.Range(0, (int)levelSize.x - w - 1);
    int y = Random.Range(0, (int)levelSize.y - h - 1);          

    Rectangle newRoom = new Rectangle(x,y,w,h);

    bool failed = false;

    foreach (Rectangle otherRoom in rooms) {
        if(otherRoom != null) {                 
            if (newRoom.Intersect(otherRoom)) {
                failed = true;
                break;
            }
        }
    }

    if (!failed) {          
        rooms[curNumRooms] = newRoom;
        curNumRooms++;
    }

}

由于某种原因,failed 总是评估为 true。我输入了几条调试消息,奇怪的是,两次失败的评估——第一次,在 foreach 循环中,它评估正确。第二次,它评估为假。如果我将 failed 初始化为 true,那么它第二次评估为 true,几乎就像 while 循环运行了两次,而第二次忽略了 foreach 循环。

这是为什么?


编辑 1:这是我的 Rectangle 类和相关变量:

public class Rectangle {
        public int x1;
        public int y1;
        public int x2;
        public int y2;

        public bool Intersect(Rectangle other) {
            return (x1 <= other.x2 && x2 >= other.x1 && y1 <= other.y2 && y2 <= other.y1);      
        }

        public Rectangle(int x, int y, int w, int h) {
            this.x1 = x;
            this.x2 = x+w;
            this.y1 = y;
            this.y2 = y + h;
        }

        public Rectangle() {

        }

        public Vector2 Center() {
            int centerX = (x1 + x2) / 2;
            int centerY = (y1 + y2) / 2;

            Vector2 center = new Vector2(centerX, centerY);

            return center;
        }
    }

这是我使用的变量:

public Vector2 levelSize = new Vector2(80,30);
public int maximumRoomSize = 10;
public int minimumRoomSize = 5;

【问题讨论】:

  • rooms 中的其他Rects 是什么?
  • 你的 Intersect 函数是什么样的?在你进入这段代码之前,minRoomSize、maxRoomSize 和 levelSize 的值是多少?如果没有这些信息,就很难说出为什么您的 Intersect 函数总是返回 true。
  • @FreeAsInBeer,只是更多的 Rects,在同一个 while 循环中创建并添加到 rooms 数组中。 rooms[curNumRooms] = newRoom; 是将当前 Rect 添加到 rooms 数组的行。 @Yasser,如果您需要 Intersect 函数和这些变量,我会对其进行编辑。但是,我发布的代码段似乎确实有错误 - Intersect 函数计算正确,但不知何故 failed 是无论其他任何值如何,都设置回 false。
  • 是的,如果您可以在其中编辑这些内容,就会更容易看到发生了什么。
  • 好的,会的。给我一分钟。

标签: c# boolean while-loop


【解决方案1】:

你的数学是错的。这个:

public bool Intersect(Rectangle other) {
    return (x1 <= other.x2 && x2 >= other.x1 && y1 <= other.y2 && y2 <= other.y1);
}

应该改成(注意我把语句后半部分的&lt;=改成&gt;=):

public bool Intersect(Rectangle other) {
    return (x1 <= other.x2 && x2 >= other.x1 && y1 <= other.y2 && y2 >= other.y1);
}

【讨论】:

  • 没问题。很高兴我能帮忙。我不时在代码上遇到这些问题,这些问题似乎很简单,但如果你不注意就会给你带来麻烦。
  • 如果每一个给我带来问题的脑筋急转弯我都能得到一分钱,我就会成为百万富翁。 :)
【解决方案2】:

我不肯定,但您对 Rectangle.Intersect 的使用可能不正确。 Intersect 返回一个矩形,表示两个指定矩形的交集,如果没有交集,则返回一个“空”矩形。你可以试试IntersectsWith - 这会返回一个布尔值。

【讨论】:

  • 但是返回的矩形如何评估为布尔值?
  • 我实际上在使用一个自定义的 Rectangle 类——我避免使用 Rect 作为我的类名,因为我认为这是一个标准类。也许我应该将其命名为 Rect,并避免使用 Rectangle。
  • @Bala:如果不是null,它很可能只是评估true。否则它将评估为false
【解决方案3】:

您的循环逻辑似乎没有任何问题会错误地设置failed。如果您确信该方法不会在第二个循环中失败,请检查您的辅助方法,特别是 Rectangle.Intersect。添加更多的跟踪输出对您的调试也很有用。

【讨论】:

    【解决方案4】:

    在while循环的每次迭代中失败被重新初始化为false

    【讨论】:

    • 这似乎是预期的行为; rooms 数组在 while 循环中填充了许多不相交的房间。
    【解决方案5】:

    我对两次评估感到困惑?在 break 之后肯定会退出 for 循环。也许尝试清理您的解决方案,删除隐藏的 obj 目录然后重建?

    【讨论】:

    • 我是这么想的,但显然不是。对于为什么 failed 总是设置为 false,我没有其他解释。
    • @Elliot Bonneville - 我以为你说失败总是评估为真?
    • 不,如果我将它初始化(ed)为真,它总是会评估为真;如果我将它初始化(ed)为假,它总是会评估为假;换句话说,Intercept 没有正确评估。
    【解决方案6】:

    如果不了解 Intersect 方法,我会说它一定是导致您的问题的原因。你说while循环的第一次迭代(我猜 - 你的问题部分含糊)给出了失败的正确评估(我猜这是在if (!failed)行)。此处未调用 Intersect 方法,因为房间数组中没有房间,因此您从失败变量的初始化中得到失败为假。然后在第二次通过 while 循环时,在 rooms 数组中有一个房间,Intersect 方法为您的目的计算错误,并且总是说有一个交叉点。我现在可以看到 @FreeAsInBeer 在 Intersect 方法中发现了一个错误。

    【讨论】:

      猜你喜欢
      • 2017-11-20
      • 2020-12-03
      • 2021-11-09
      • 2015-05-24
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 2018-08-19
      相关资源
      最近更新 更多