2

我有一个二维数组,它代表一个数独游戏。

我正在尝试像典型的数独游戏一样检查游戏中的错误:

行、列或 3x3 正方形内没有数字 (1-9) 重复。没有空单元格。

我对 Java 很陌生,所以我的知识有限。我打算尝试一个很长的 if,else 语句来比较所有单元格。那没有用,因为 -1 被重复了。(-1 代表一个空的正方形)。我试图解决这个问题,但意识到这个 if 语句太混乱了,必须有更好的方法。

我现在认为最好的方法是使用嵌套的 for 循环遍历每一行、每一列和 3x3 正方形。另一方面,检查空单元格,我想我已经弄清楚了。(嵌套用于在 2D 数组中检查 -1 的语句)。

我还在考虑将所有数字连续、col 或 3x3 平方相加,如果不等于 45,那么游戏是否仍然不完整?

至于检查重复值,我不确定如何实现嵌套。

编辑:让我澄清一下,我真的不想检查重复值,我只是希望游戏在存在重复值时保持不完整。(例如,允许重复值,只是不会像真正的数独游戏那样为您赢得游戏)。我觉得添加到 45 的方法效果最好。

4

4 回答 4

4

如果您不检查整个游戏板是否没有所有重复项,则可以真正简化事情,而是仅在放置新值时检查特定行、列和 3x3 方格是否没有重复项(通过播放器,或从文件加载游戏时)。

这样,您只需要三个非嵌套循环。一个,用于检查所放置的新值是否已存在于其行、列和 3x3 正方形中。

您也永远不需要担心检查 -1(假设您已经错误检查了值 1-9 的输入)。

注意:“检查行、列或 3x3 正方形是否加起来为 45”不起作用。这是一个好主意,但它不会捕获多个重复项(例如,所有 5 的一行都会通过)。

于 2012-10-16T02:44:53.513 回答
0

这是一个很好的问题,我很无聊,所以这里有一个相当完整的描述一种方法。当然,还有很多!这种方法很有效,但不是特别优雅。我想看看其他人的想法。

1)BitSet为每行、每列和 3x3 正方形制作一个对象。将它们放入数组中,如下所示:

// Initialize arrays
BitSet[] rows = new BitSet[9];
BitSet[] cols = new BitSet[9];
BitSet[] squares = new BitSet[9];
// Initialize the array elements
for(int i=0;i<9;i++){
    rows[i] = new BitSet(9);
    cols[i] = new BitSet(9);
    squares[i] = new BitSet(9);
}

现在我们可以一次遍历网格并在适当的行、列和正方形中设置一个位。“适当”的意思是,如果我们正在查看第 i行和j列,我们将在 and 中设置rows[i]cols[j]。为了索引正方形的元素,我们将使用以下布局:

0 1 2
3 4 5
6 7 8

我们可以通过简单地将 i 和 j 除以 3 得到上述布局中的行和列。所以我们想要的索引是i / 3 + 3 * ( j / 3 )。请注意,整数除法在这里起作用,因此7 / 3 == 8 / 3 == 2,这意味着 i 和 j 等于 8,我们有例如8 / 3 + 3 * ( 8 / 3 ) = 2 + 3 * 2 = 8

综上所述,我们可以编写方法来检查谜题是否未解决,如下所示:

public boolean hasRepeats(){
            // ...
        // initialize rows, cols, and squares as above
            // ...

    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            int gridValue = grid[i + 9 * j];
            if( gridValue == -1 ){
                // Skip empty squares
                continue;
            }
            // Check for repeats
            if( rows[i].get(gridValue) ){
                return true; 
            }
            rows[i].set(gridValue);
            if( cols[j].get(gridValue) ){
                return true;
            }
            cols[j].set(gridValue);
            BitSet square = squares[ i / 3 + 3 * ( j / 3 ) ]
            if( square.get( gridValue ) ){
                return true;
            }
            square.set( gridValue );
        }
    }
    return false;
}
于 2012-10-16T03:20:06.517 回答
0

通过归纳正确的一种简单方法是将 9 个值加载到数组中,然后执行以下操作:

  1. 转换为集合以确保没有重复
  2. 转换回数组
  3. 对数组进行排序

然后你可以检查 3 件事来保证这些值是有效的:

  1. 检查第一个数字(即最小的)是否为 1
  2. 检查最后一个数字(即最高)是否为 9
  3. 检查数组的长度是否为 9(事实上,您确实存在所有 9 个数字)
于 2012-10-16T03:58:20.293 回答
0

由于您是 java 新手,我假设您使用 2D 整数数组来存储 3x3 正方形。您的目标是验证正方形中是否存在任何重复的整数(-1 除外)。

private static final int WIDTH = 3;
private static final int HEIGHT = 3;
private static int[][] cells = new int[WIDTH][HEIGHT];

您可以通过 -1 初始化二维数组

for (int i = 0; i < WIDTH; i++) {
    for (int j = 0; j < HEIGHT; j++) {
        cells[i][j] = -1;
    }
}

一个简单的方法是使用一个列表来临时存储用户输入,并检查添加的输入是否已经存在。

private static boolean validateCells() {
    boolean isValid = true;
    List<Integer> inputValues = new ArrayList<Integer>();
    for (int i = 0; i < WIDTH; i++) {
        for (int j = 0; j < HEIGHT; j++) {
            int inputValue = cells[i][j];
            if (inputValue != -1) {
                if (inputValues.contains(inputValue)) {
                    isValid = false;
                    break;
                } else {
                    inputValues.add(inputValue);
                }
            }
        }
    }
    return isValid;
}

这显然不是一种有效的方法,但对于 java 初学者来说,它很简单而且很容易理解。

于 2012-10-16T03:30:54.723 回答