我有一个2D数组,代表一个数独游戏。
我正在尝试检查游戏中的错误,就像典型的数独游戏一样:
在行,列或3x3平方内不重复数字(1-9)。 没有空单元格。
我对Java很陌生,所以我对这方面的知识有限。我打算尝试比较所有细胞的长期if,else语句。这没用,因为-1重复了。 (-1表示空方块)。我试图绕过这个,但意识到这个if语句太乱了,必须有更好的方法。
我现在认为最好的方法是使用嵌套的for循环遍历每一行,每列和3x3平方。另一方面,检查空单元格,我想我已经想通了。 (嵌套用于在2D数组中检查-1的语句)。
我还在考虑将行中的所有数字,col或3x3平方加起来,如果它不等于45那么游戏是否仍然不完整?
就检查重复值而言,我不确定如何实现嵌套for。
编辑:让我澄清一点,我真的不想检查每个说法的重复值,我只是希望游戏在重复值时保持不完整。 (例如,允许重复值,只是没有像真正的数独谜题那样赢得游戏)。我觉得添加45方法效果最好。答案 0 :(得分:4)
如果你没有检查整个游戏板是否没有重复,你可以真正简化一些事情,而是只检查一个特定的行,列和3x3方块只有在放置一个新值时才会有重复项(由玩家或从文件加载游戏时)。
这样你只需要三个非嵌套循环。一个用于检查所放置的新值在其行,列和3x3平方中是否已存在。
您也永远不必担心检查-1(假设您已经错误检查值1-9的输入)。
注意:“检查行,列或3x3方块是否合计为45”不起作用。这是一个不错的主意,但它没有捕获多个重复项(例如,所有5个行中的一行都会通过)。
答案 1 :(得分:0)
这是一个很好的问题,我很无聊,所以这里有一个相当完整的描述方法。当然,还有很多其他人!这种方法很有效但不是特别优雅。我想看看其他人想出什么。
1)为每行,每列和3x3正方形制作一个BitSet
对象。将这些放在数组中,如下所示:
// 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 th 行和j th 列,我们将设置位和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;
}
答案 2 :(得分: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
初始化2D数组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;
}
这显然不是一种有效的方法,但对于初学者来说它很简单易懂。
答案 3 :(得分:0)
感应正确的一种简单方法是将9个值加载到数组中,然后执行以下操作:
然后你可以检查3件事以保证这些值是有效的: