我正在创建一个数独生成器,使用"蛮力"随机方法。我已经能够使用代码检查x/y轴是否有重复的数字:
for(l=0; l<9; l++){//Makes all vertical work.
if(sudoku[l][j] == temp){
isUsed=true;
}
}
for(m=0; m<9; m++){//makes all horizontal work
if(sudoku[i][m] == temp){
isUsed=true;
}
}
我决定执行"框"或"区域"检查(你从原点检查每3x3个正方形),我似乎无法将我的头绕在代码上。这是我目前所做的。我只是不能完全弄清楚我的逻辑错误在哪里(为了记录程序将运行此代码,但不会正确检查区域)
rowbase = i-(i%3);
if(i==2 || i==5 || i==8 ){
if(rowbase == 0 || rowbase == 3 || rowbase == 6){
isUsed= RegionCheck.RegCheck(rowbase, sudoku);
}
}
regionCheck.java:
目录 boolean okay = false;
int[] regionUsed = new int[9];
int i=0, j=0, regionTester=0, counter=0, numcount;
for (i=regionTester; i<regionTester+3; i++){
for (; j<3; j++){
regionUsed[counter]=sudoku[i][j];
counter++;
}
}
for(i=0; i<9; i++){
numcount=regionUsed[i];
for(j=0; j<9; j++){
if(j==i){
//null
}
else if(numcount == regionUsed[j]){
okay=false;
}
}
}
return okay;
在路上的某个地方,我只是迷路了,不理解如何"选择"一个区域并迭代区域。
完整的源代码在这里:http://ideone.com/FYLwm
任何关于如何简单地"选择"一个区域进行测试,然后迭代它将非常感激,因为我真的没有想法。
您需要稍微抽象一下。可以这样考虑,任何区域(框、列、行)都只是一个值(和空值)的列表。为了检查值x
是否可以插入到区域R
中,只需将R
中的所有值表示为值L
的列表。现在你需要做的就是检查L
是否包含x
祝你好运!
我不明白你的意思测试一个区域,我假设test意味着每个区域都有从1到9的每一个数字,没有重复。
我们可以实现:
- 在垂直、水平和3x3区域使用for循环。
- 使用有位置到每个区域的表,包括水平或垂直的。
我推荐第二个。如果您有一个表,则访问区域的循环实现一次。另一方面,第一个需要为垂直/水平/3x3实现3个类似的循环。
下面是生成表的代码:for(int i=0, k=0; i<9; i++) {
// generate vertical regions
for(int j=0; j<9; j++)
table[k][j] = new table_t(i, j);
k++;
// generate horizontal regions
for(int j=0; j<9; j++)
table[k][j] = new table_t(j, i);
k++;
// generate 3x3 regions
for(int j=0; j<9; j++)
table[k][j] = new table_t((i/3)*3+j/3, (i%3)*3+j%3);
k++;
}
生成垂直或水平区域的代码易于阅读。虽然3x3区域的生成应该描述。变量i
取0到8,((i/3)*3
, (i%3)*3
)分别指向一个3x3区域的角。(+j/3
, +j%3
)移动区域内的每个框。
您可以通过以下代码测试矩阵sudoku
是否符合:
boolean okey = true;
for(int i=0; i<27; i++) {
int [] counter = new int[10];
for(int j=0; i<10; i++)
counter[i]=0;
for(int j=0; j<9; j++)
counter[ sudoku[table[i][j].x][table[i][j].y] ] ++;
boolean ok = true;
for(int j=0; j<9; j++)
if(counter[j+1]!=1)
ok = false;
if(!ok)
okey = false;
}
数组counter
计算每个数字出现的次数(我认为0
是一些特殊的含义,1
和9
之间的数字是有效的)