【问题标题】:Comparing 2D boolean array values?比较二维布尔数组值?
【发布时间】:2015-04-17 10:25:02
【问题描述】:

我正在制作这个基本上是Connect 4 game 的程序。正如您在下面看到的,我有一组设置的圆圈 c0、c1、c2 等,以及一个重复的圆圈 c0d,它在每次按钮单击时产生并下降到一个可用的插槽。在“背景”中,我制作了一个 2d 矩阵,一个布尔数组,它可以帮助我决定何时赢得比赛(通过在一行中有 4 次相同的颜色。当然,我还有 6 个其他行具有相同的颜色功能也一样,但它们基本上是一样的。

Circle c0d = new Circle(64, 32, 32);

    TranslateTransition translate = new TranslateTransition(
            Duration.millis(750), c0d);
    translate.setToX(0);
    FadeTransition fade = new FadeTransition();
    fade.setDuration(Duration.seconds(1));

    GridPane.setConstraints(c0d, 0, 0);
    GridPane.setHalignment(c0d, HPos.CENTER);
    grid.getChildren().add(c0d);
    if (c0.getFill() == Color.YELLOW) {
        c0.setFill(Color.RED);
        c1.setFill(Color.RED);
        c2.setFill(Color.RED);
        c3.setFill(Color.RED);
        c4.setFill(Color.RED);
        c5.setFill(Color.RED);
        c6.setFill(Color.RED);
        c0d.setFill(Color.YELLOW);
        switch (x0) {
        case 0:
            translate.setToY(432);
            x0++;
            wl[5][0] = true;
            break;
        case 1:
            translate.setToY(360);
            x0++;
            wl[4][0] = true;
            break;
        case 2:
            translate.setToY(288);
            x0++;
            wl[3][0] = true;
            break;
        case 3:
            translate.setToY(216);
            x0++;
            wl[2][0] = true;
            break;
        case 4:
            translate.setToY(144);
            x0++;
            wl[1][0] = true;
            break;
        case 5:
            translate.setToY(72);
            x0++;
            wl[0][0] = true;
            butt0.setDisable(true);
            break;
        }
    } else {
        c0.setFill(Color.YELLOW);
        c1.setFill(Color.YELLOW);
        c2.setFill(Color.YELLOW);
        c3.setFill(Color.YELLOW);
        c4.setFill(Color.YELLOW);
        c5.setFill(Color.YELLOW);
        c6.setFill(Color.YELLOW);
        c0d.setFill(Color.RED);
        switch (x0) {
        case 0:
            translate.setToY(432);
            x0++;
            wl[5][0] = false;
            break;
        case 1:
            translate.setToY(360);
            x0++;
            wl[4][0] = false;
            break;
        case 2:
            translate.setToY(288);
            x0++;
            wl[3][0] = false;
            break;
        case 3:
            translate.setToY(216);
            x0++;
            wl[2][0] = false;
            break;
        case 4:
            translate.setToY(144);
            x0++;
            wl[1][0] = false;
            break;
        case 5:
            translate.setToY(72);
            x0++;
            wl[0][0] = false;
            butt0.setDisable(true);
            break;
        }
    }

    for (i = 5; i <= 0; i--) {
        if (wl[i][0] == wl[i - 1][0] == wl[i - 2][0] == wl[i - 3][0]) {
            System.out.println("WON");
            break;
        }

现在你可以看到,最后一个 for 循环通过比较一行中的位置来决定何时赢得比赛,如果它们都是“假”,这意味着红色或真,即黄色,应该赢在控制台上输出。由于某种原因它没有显示。我错过了什么吗?

【问题讨论】:

    标签: java arrays for-loop javafx boolean


    【解决方案1】:

    首先,您的 for 循环永远不会执行。你用i=5初始化,条件是i &lt;= 0。由于初始化时条件为假,因此循环退出而不执行。

    其次,if 中的条件没有按照您的想法执行。你需要一些布尔逻辑:你想要一些类似于

    的东西
    if (wl[i][0]==wl[i-1][0] && wl[i-1][0]==wl[i-2][0] && wl[i-2][0]==wl[i-3][0]) {
       // ...
    }
    

    实际评估的方式是评估wl[i][0]==wl[i-1][0],并评估为truefalse。然后将该值与wl[i-2][0] 进行比较,比较结果为truefalse。最后将该比较与wl[i-3] 进行比较。所以如果你有红色、红色、黄色、黄色(falsefalsetruetrue),那就是true。 (false==falsetrue,所以 (false==false)==true)是 true,等等。类似地,RED、YELLOW、RED、YELLOW 将评估为 true(读者练习......)。

    最后,其余的大部分逻辑对我来说并不是很清楚。您看起来正在尝试从 i=5 向下迭代到 i=0;但是随后访问数组的元素i-1i-2 等显然是行不通的。

    【讨论】:

    • 感谢您的输入 James,我在编写代码时并没有完全看透,您说得对,数组显然会越界,但我需要比较这些值从行中的所有位置,所以它可以是例如:位置 0 到 3 可以相同,2-5 可以相同,所以我必须做一个循环来检查所有位置。
    【解决方案2】:

    您的for 循环永远不会执行,因为条件i &lt;= 0 始终为假,假设您使用值5 初始化i

    但是,即使您解决了这个问题,您也会发现该语句存在问题,因为它并没有按照您的想法执行(并且无论如何它都会抛出 ArrayIndexOutOfBoundsException

    if (wl[i][0] == wl[i - 1][0] == wl[i - 2][0] == wl[i - 3][0]) { ...
    

    即使您修复了ArrayIndexOutOfBoundsException,它编译的唯一原因是因为wlboolean[]。该语句不会与任何其他类型的数组一起编译(例如int[][])。这是因为它被评估为:

    if (((wl[i][0] == wl[i - 1][0]) == wl[i - 2][0]) == wl[i - 3][0]) ...
    

    其实是这样的:

    1. 评估wl[i][0] == wl[i - 1][0]
    2. 获取该比较的boolean 结果并将其与wl[i - 2][0] 进行比较
    3. 并一直这样做直到它到达块的末尾

    因此,它实际上并没有按照您想要的方式将每个元素与下一个元素进行比较。这样,以下语句(与您的数组略有不同,但原理相同)返回true,即使您希望它返回false

    boolean arr[] = {false, false, true}; // note they are not all the same
    System.out.println(arr[0] == arr[1] == arr[2]); // outputs true
    

    您真正想要的是检查所有元素是否相同。我建议使用一个函数来执行此操作,例如:

    public static boolean fourInALine(boolean[][] arr, int index2)
    {
      for (int j = 0; j <= arr.length - 4; j++) {
        boolean allSame = true;
        boolean firstValue = arr[j][index2];
        for (int i = 1; allSame && i < 4; i++) {
          allSame = (arr[j+i][index2] == firstValue);
        }
        if (allSame) return true;
      }
      return false;
    }    ...
    // used like:
    if (fourInALine(wl, 0)) {
      System.out.println("WON");      
    }
    

    【讨论】:

    • 谢谢。由于这是一个按钮,我假设我必须在按钮之外编写这个函数?如果这个问题看起来很愚蠢,我深表歉意,我是 Java 新手并且是自学的。关于 if 语句,我可以只取 wl[i][0] 的布尔值并将该值与每个其他数组元素进行比较吗?但是由于数组一次越界,它仍然无法工作。是否有一种解决方法可以在不创建函数的情况下使用循环?
    • 该功能只是为了使其可重用,您可以将其放在任何可以访问的地方,以便您需要调用它。
    • @Ajay_C。我不太确定您对“关于 if 语句的评论是什么意思,我可以取 wl[i][0] 的布尔值并将该值与所有其他数组元素进行比较” .你不能像原来那样做一个长的组合 if 声明 - 它只是行不通,但是你可以减少这个功能(参见我的编辑版本)。您可以在没有函数的情况下执行我的方法(循环),但是像这样的函数是正确的做法 - 它是封装和可测试的,并传达了您的意图。
    • 谢谢!我理解它,除了一件事。 index2 持有什么值?而且由于我需要在行中比较 4 个值是否连续为真,这不只是比较最大两个并抛出“WON”吗?
    • @Ajay_C。随着我们的进行,您的问题发生了很大的变化——或者更确切地说,随着我们的进行,更多的相关信息正在被提供——这不是 SO 的设计目的。最初的问题是为什么您的 for 循环不起作用。如果现在已经回答了,您应该在新问题中提出任何进一步的问题。这次我可以回答你的第一点。 index2 是您将其解释为的“行”或“列”索引。对于第二点,它确实比较了整行,但您可以使用嵌套循环调整我给出的函数来测试 4 的连续范围而不是整行。
    猜你喜欢
    • 2022-01-23
    • 2016-05-05
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    相关资源
    最近更新 更多