📄 solver.java
字号:
return true;
}
} // for n
} // for j
} // for i
return false;
}
private boolean applyStrategy_3_locked_candidates_1()
{
// Some masive copy+paste code, but better than offuscate too much
// Not more computer efficient, but more similar to lazzy human behaviour
// Goal is to apply minimum times this test, not to the whole board.
// After one single hit and change, we exit to start with the easier tests again.
// CONSTS.log("----------------------------- Start Strategy_3_locked_candidates_1");
boolean posValsChanged = false;
for (int num = 1; num <= 9; num++)
{
///////////// check lines ///////////////////////
for (int line = 0; line < 9; line+=3)
{
for (int col = 0; col < 9; col+=3)
{
if( ( posVals[line][col+0][num] == 1 || // num is in one row of box
posVals[line][col+1][num] == 1 ||
posVals[line][col+2][num] == 1)
&&
( posVals[line+1][col+0][num] != 1 && // and not in the othe rows
posVals[line+1][col+1][num] != 1 &&
posVals[line+1][col+2][num] != 1 &&
posVals[line+2][col+0][num] != 1 &&
posVals[line+2][col+1][num] != 1 &&
posVals[line+2][col+2][num] != 1))
{
// CONSTS.log("removeNumFromRow line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromRow( num, line, col);
if( posValsChanged)
{
logStrategy( 3);
return true;
}
// is not the most efficient way,
// but human behaviour:
// after finding a new number, start over
// with the easier test, not continue here.
// Important to rate difficult level
} else
if(( posVals[line+1][col+0][num] == 1 || // num is in one row of box
posVals[line+1][col+1][num] == 1 ||
posVals[line+1][col+2][num] == 1)
&&
( posVals[line][col+0][num] != 1 && // and not in the othe rows
posVals[line][col+1][num] != 1 &&
posVals[line][col+2][num] != 1 &&
posVals[line+2][col+0][num] != 1 &&
posVals[line+2][col+1][num] != 1 &&
posVals[line+2][col+2][num] != 1))
{
// CONSTS.log("removeNumFromRow line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromRow( num, line+1, col);
if( posValsChanged)
{
logStrategy(3);
return true;
}
} else
if(( posVals[line+2][col+0][num] == 1 || // num is in one row of box
posVals[line+2][col+1][num] == 1 ||
posVals[line+2][col+2][num] == 1)
&&
( posVals[line][col+0][num] != 1 && // and not in the othe rows
posVals[line][col+1][num] != 1 &&
posVals[line][col+2][num] != 1 &&
posVals[line+1][col+0][num] != 1 &&
posVals[line+1][col+1][num] != 1 &&
posVals[line+1][col+2][num] != 1))
{
// CONSTS.log("removeNumFromRow line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromRow( num, line+2, col);
if( posValsChanged)
{
logStrategy(3);
return true;
}
}
} // for col
} // for line
///////////// End check lines ///////////////////////
///////////// check cols ///////////////////////
for (int col = 0; col < 9; col+=3)
{
for (int line = 0; line < 9; line+=3)
{
if( ( posVals[line+0][col][num] == 1 || // num is in one row of box
posVals[line+1][col][num] == 1 ||
posVals[line+2][col][num] == 1)
&&
( posVals[line+0][col+1][num] != 1 && // and not in the othe rows
posVals[line+1][col+1][num] != 1 &&
posVals[line+2][col+1][num] != 1 &&
posVals[line+0][col+2][num] != 1 &&
posVals[line+1][col+2][num] != 1 &&
posVals[line+2][col+2][num] != 1))
{
// CONSTS.log("removeNumFromCol line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromCol( num, col, line);
if( posValsChanged)
{
logStrategy(3);
return true;
}
} else
if( ( posVals[line+0][col+1][num] == 1 || // num is in one row of box
posVals[line+1][col+1][num] == 1 ||
posVals[line+2][col+1][num] == 1)
&&
( posVals[line+0][col+0][num] != 1 && // and not in the othe rows
posVals[line+1][col+0][num] != 1 &&
posVals[line+2][col+0][num] != 1 &&
posVals[line+0][col+2][num] != 1 &&
posVals[line+1][col+2][num] != 1 &&
posVals[line+2][col+2][num] != 1))
{
// CONSTS.log("removeNumFromCol line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromCol( num, col+1, line);
if( posValsChanged)
{
logStrategy(3);
return true;
}
} else
if( ( posVals[line+0][col+2][num] == 1 || // num is in one row of box
posVals[line+1][col+2][num] == 1 ||
posVals[line+2][col+2][num] == 1)
&&
( posVals[line+0][col+1][num] != 1 && // and not in the othe rows
posVals[line+1][col+1][num] != 1 &&
posVals[line+2][col+1][num] != 1 &&
posVals[line+0][col+0][num] != 1 &&
posVals[line+1][col+0][num] != 1 &&
posVals[line+2][col+0][num] != 1))
{
// CONSTS.log("removeNumFromCol line " + line + " col " + col + " num " + num);
posValsChanged = removeNumFromCol( num, col+2, line);
if( posValsChanged)
{
logStrategy(3);
return true;
}
}
} // for line
} // for col
///////////// End check cols ///////////////////////
} // for num
return false;
}
/**
* @param i
*/
private void logStrategy(int diff)
{
strategiesUsed += diff;
if( diff > 2) difficulty += diff*4;
else if( diff == 2)difficulty += 1;
// CONSTS.log("*** Strategy " + diff + " appl. Difficulty: " + difficulty + " filled " + filled + " - "+ strategiesUsed );
}
private boolean applyStrategy_4_locked_candidates_2()
{
// CONSTS.log("----------------------------- Start Strategy_4_locked_candidates_2");
boolean posValsChanged = false;
for (int num = 1; num <= 9; num++)
{
///////////// check rows ///////////////////////
for (int line = 0; line < 9; line++)
{
if( ( posVals[line][0][num] == 1 ||
posVals[line][1][num] == 1 ||
posVals[line][2][num] == 1)
&&
( posVals[line][3][num] != 1 &&
posVals[line][4][num] != 1 &&
posVals[line][5][num] != 1 &&
posVals[line][6][num] != 1 &&
posVals[line][7][num] != 1 &&
posVals[line][8][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox line " + line + " box 1" + " num " + num);
posValsChanged = removeNumFromBox( num, line, 0, line, -1);
if( posValsChanged)
{
logStrategy(4);
return true;
}
} else
if( ( posVals[line][3][num] == 1||
posVals[line][4][num] == 1||
posVals[line][5][num] == 1)
&&
( posVals[line][0][num] != 1 &&
posVals[line][1][num] != 1 &&
posVals[line][2][num] != 1 &&
posVals[line][6][num] != 1 &&
posVals[line][7][num] != 1 &&
posVals[line][8][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox line " + line + " box 2" + " num " + num);
posValsChanged = removeNumFromBox( num, line, 3, line, -1);
if( posValsChanged)
{
logStrategy(4);
return true;
}
} else
if( ( posVals[line][6][num] == 1||
posVals[line][7][num] == 1||
posVals[line][8][num] == 1)
&&
( posVals[line][0][num] != 1 &&
posVals[line][1][num] != 1 &&
posVals[line][2][num] != 1 &&
posVals[line][3][num] != 1 &&
posVals[line][4][num] != 1 &&
posVals[line][5][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox line " + line + " box 3" + " num " + num);
posValsChanged = removeNumFromBox( num, line, 6, line, -1);
if( posValsChanged)
{
logStrategy(4);
return true;
}
}
}
///////////// end check rows ///////////////////////
///////////// check cols ///////////////////////
for (int col = 0; col < 9; col++)
{
if( ( posVals[0][col][num] == 1||
posVals[1][col][num] == 1||
posVals[2][col][num] == 1)
&&
( posVals[3][col][num] != 1 &&
posVals[4][col][num] != 1 &&
posVals[5][col][num] != 1 &&
posVals[6][col][num] != 1 &&
posVals[7][col][num] != 1 &&
posVals[8][col][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox col " + col + " box 1" + " num " + num);
posValsChanged = removeNumFromBox( num, 0, col, -1, col);
if( posValsChanged)
{
logStrategy(4);
return true;
}
} else
if( ( posVals[3][col][num] == 1||
posVals[4][col][num] == 1||
posVals[5][col][num] == 1)
&&
( posVals[0][col][num] != 1 &&
posVals[1][col][num] != 1 &&
posVals[2][col][num] != 1 &&
posVals[6][col][num] != 1 &&
posVals[7][col][num] != 1 &&
posVals[8][col][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox col " + col + " box 2" + " num " + num);
posValsChanged = removeNumFromBox( num, 3, col, -1, col);
if( posValsChanged)
{
logStrategy(4);
return true;
}
} else
if( ( posVals[6][col][num] == 1||
posVals[7][col][num] == 1||
posVals[8][col][num] == 1)
&&
( posVals[0][col][num] != 1 &&
posVals[1][col][num] != 1 &&
posVals[2][col][num] != 1 &&
posVals[3][col][num] != 1 &&
posVals[4][col][num] != 1 &&
posVals[5][col][num] != 1 )
)
{
// CONSTS.log("removeNumFromBox col " + col + " box 3" + " num " + num);
posValsChanged = removeNumFromBox( num, 6, col, -1, col);
if( posValsChanged)
{
logStrategy(4);
return true;
}
}
}
///////////// end check cols ///////////////////////
}
return false;
}
private boolean applyStrategy_5_naked_pairs()
{
// CONSTS.log("----------------------------- Start applyStrategy_5_naked_pairs");
// CONSTS.log( toString());
// CONSTS.log( posibleValsToString());
boolean posibleValsChanged = false;
for (int n = 0; n < 27; n++)
{
posibleValsChanged = checkGroupForNakedPairs( groups[n]);
if( posibleValsChanged )
{
logStrategy(5);
return true;
}
}
return false;
}
private boolean applyStrategy_6_hidden_pairs()
{
// *** warning!
// TODO: this method is almost identical than applyStrategy_5_naked_pairs -> merge
//
// CONSTS.log("----------------------------- Start applyStrategy_6_hidden_pairs");
// CONSTS.log( toString());
// CONSTS.log( posibleValsToString());
boolean posibleValsChanged = false;
for (int n = 0; n < 27; n++)
{
posibleValsChanged = checkGroupForHiddenPairs( groups[n]);
if( posibleValsChanged )
{
logStrategy(6);
return true;
}
}
return false;
}
private boolean checkGroupForHiddenPairs(int[][] group)
{
boolean posibleValsChanged = false;
int[][] pairs = getAllPairsFromGroup( group);
for (int p = 0; p < pairs.length; p++)
{
int found1, found2 = -1;
for (int n = 0; n < group.length; n++)
{
if( group[n][0] < 2) continue;
if( group[n][ pairs[p][0]] == 1 && group[n][ pairs[p][1]] == 1 )
{
found1 = n;
for (int m = n+1; m < group.length; m++)
{
if( group[m][0] < 2) continue;
if( group[m][ pairs[p][0]] == 1 && group[m][ pairs[p][1]] == 1 )
{
found2 = m;
// check if exists one of the vals in another cell
for (int x = 0; x < 9; x++)
{
if( x == found1 || x == found2) continue;
if( group[x][ pairs[p][0]] == 1 || group[x][ pairs[p][1]] == 1 )
{
found2 = -1;
break;
}
}
if( found2 != -1) // we found a real hidden pair -> check if we can remove a posible val.
{
// CONSTS.log("HIDDEN PAIR found: " + pairs[p][0] + " " + pairs[p][1]);
if( group[found1][0] > 2 || group[found2][0] > 2)
{
Arrays.fill( group[found1], 0); // clear array
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -