In such cases, I usually fill all the empty cells with the probable numbers that can fit in that cell. For eg, I place the numbers 278 if these three numbers have a chance of being placed in a cell. With all empty cells having such probable numbers, it is easy to apply some deduction logic to narrow down the correct numbers.
Filling in the probable numbers is a tedious task. I came up with a simple java code that would help in filling the numbers (just the hint, not the actual answers).
Instruction to use the code:
- Install watij as mentioned at http://watij.com/webspec-api/
- Copy the java code I had placed in the comment section (placed in 3 comments due to comment size restriction)
- run the java code along with the classpath pointing to watij class and jars
- This will open a window and websudoku site is opened
- Settings page is accessed automatically and few settings are tweaked
- once you get the puzzle page, play it as you would do in normal manner
- When you get stuck, click on the 'Done' button in the top panel. The button name is marked as 'pauseUntil'
- we should have numbers filled now. Once that happens, continue with the game
Happy sudoku.
6 comments:
package open.sudoku.hint;
import org.watij.webspec.dsl.Tag;
import org.watij.webspec.dsl.WebSpec;
/**
* @author Jeya Balaji
* jeya.balaji@gmail.com
*
* 18th Jul 2011
*/
/**
* purpose : to open up a browser with http://www.websudoku.com
* and if required, fill the blank cells with possible numbers
*/
public class SudokuHint {
public static final int NUM_COLS = 9;
public static final int NUM_ROWS = 9;
public static final int MATRIX_SIZE = 9;
public static final int GRID_SIZE = 3;
public static final int MAX_HINT_SIZE = 5;
public static final int MAX_TRY = 5;
private void openBrowser() {
WebSpec spec = new WebSpec().mozilla();
// WebSpec spec = new WebSpec().ie();
changeSettings(spec);
waitForUserRequest(spec);
}
private void changeSettings(WebSpec spec) {
spec.open("http://view.websudoku.com/?select=1&level=4");
spec.find().input().with().name("goto").click();
spec.find().input().with().name("showopts").click();
spec.find().input().with().type("radio").with().name("options1").at(0).set.checked(true);
spec.find().input().with().type("checkbox").with().name("options3").set.checked(true);
spec.find().input().with().name("saveopts").click();
}
/*
* user need to press 'Done' button to get sudoku hints
*/
private void waitForUserRequest(WebSpec spec) {
while(true)
{
spec.pauseUntilDone();
fillHints(spec);
}
}
private void fillHints(WebSpec spec) {
int[][] givenMatrix = captureMatrix(spec);
String[][] hintMatrix = prepareHints(givenMatrix);
displayHint(spec, hintMatrix);
}
/*
* collect numbers from the webpage
*/
private int[][] captureMatrix(WebSpec spec) {
System.out.println("Capturing matrix");
int[][] matrix = new int[NUM_COLS][NUM_ROWS];
for(int col=0; col < NUM_COLS; col++)
{
for(int row=0; row < NUM_ROWS; row++)
{
String val = getValue(spec, col, row);
if(val == null || "".equals(val))
val = "0";
try
{
matrix[col][row] = Integer.parseInt(val);
}
catch(Exception ex)
{
matrix[col][row] = 0;
}
System.out.print(".");
}
}
System.out.println("");
return matrix;
}
private void displayHint(WebSpec spec, String[][] hintMatrix) {
System.out.println("display hints");
for(int col=0; col < NUM_COLS; col++)
{
for(int row=0; row < NUM_ROWS; row++)
{
if(hintMatrix[col][row] == null || "".equals(hintMatrix[col][row])) continue;
setValue(spec, col, row, hintMatrix[col][row]);
}
}
}
private String[][] prepareHints(int[][] givenMatrix) {
System.out.println("Preparing hints");
String[][] hintMatrix = new String[NUM_COLS][NUM_ROWS];
for(int col=0; col < NUM_COLS; col++)
{
for(int row=0; row < NUM_ROWS; row++)
{
if(givenMatrix[col][row] == 0)
hintMatrix[col][row] = prepateHint(givenMatrix, col, row);
}
}
return hintMatrix;
}
/*
* generate the hint for a particular empty cell
*/
private String prepateHint(int[][] givenMatrix, int col, int row) {
String hint = "";
for(int num = 1; num <= MATRIX_SIZE; num++)
{
if(! hasOccured(givenMatrix, col, row, num))
hint += num;
}
// if(hint.length() > MAX_HINT_SIZE) hint = "X";
return hint;
}
/*
* checks if a number has occurred in the col or row or in the grid
*/
private boolean hasOccured(int[][] givenMatrix, int givenCol, int givenRow, int givenNum) {
for(int col = 0; col < NUM_COLS; col++)
{
if(col != givenCol && givenMatrix[col][givenRow] == givenNum)
return true;
}
for(int row = 0; row < NUM_ROWS; row++)
{
if(row != givenRow && givenMatrix[givenCol][row] == givenNum)
return true;
}
int startCol = (givenCol / GRID_SIZE) * GRID_SIZE;
int startRow = (givenRow / GRID_SIZE) * GRID_SIZE;
for(int col = startCol; col < startCol + GRID_SIZE; col++)
{
for(int row = startRow; row < startRow + GRID_SIZE; row++)
{
if(col == givenCol && row == givenRow) continue;
if(givenMatrix[col][row] == givenNum) return true;
}
}
return false;
}
private String getValue(WebSpec spec, int col, int row) {
String id = composeId(col, row);
for(int i=0; i < MAX_TRY; i++)
{
try
{
return spec.findWithId(id).get().value();
}
catch(Exception ex)
{
//
// ex.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("Attempting again " + i);
}
System.out.println("Error while getting value from col=" + col + ", row=" + row);
return "";
}
private void setValue(WebSpec spec, int col, int row, String value) {
String id = composeId(col, row);
for(int i=0; i < MAX_TRY; i++)
{
try
{
Tag cell = spec.findWithId(id);
cell.set().value(value);
cell.call().onKeyUp();
return;
}
catch(Exception ex)
{
//
// ex.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("Attempting again " + i);
}
System.out.println("Error while setting value at col=" + col + ", row=" + row);
}
/*
private String getValue(WebSpec spec, int col, int row) {
String id = composeId(col, row);
try
{
return spec.findWithId(id).get().value();
}
catch(Exception ex)
{
// System.out.println("Error while checking col=" + col + ", row=" + row);
// ex.printStackTrace();
}
return "";
}
private void setValue(WebSpec spec, int col, int row, String value) {
String id = composeId(col, row);
Tag cell = spec.findWithId(id);
cell.set().value(value);
cell.call().onKeyUp();
// for(int i = 0; i < value.length(); i++)
// {
// spec.findWithId(id).set().value(spec.findWithId(id).get().value() +
// value.charAt(i));
// }
}
*/
private String composeId(int col, int row) {
return "f" + col + row;
}
/**
* @param args
*/
public static void main(String[] args) {
SudokuHint sudokuHint = new SudokuHint();
sudokuHint.openBrowser();
// sudokuHint.testing();
}
public void testing()
{
WebSpec spec = new WebSpec().mozilla();
// WebSpec spec = new WebSpec().ie();
spec.open("http://www.websudoku.com/?select=1&level=4");
// System.out.println(spec.source());
Tag src = spec.find().frameset().find().frame();
System.out.println(src.exists());
System.out.println(src.get("src"));
System.out.println(src.find().html().toString());
src.find().input().with().name("goto").click();
src.find().input().with().name("showopts").click();
//
// spec.find().input().with().type("radio").with().name("options1").at(0).set.checked(true);
// spec.find().input().with().type("checkbox").with().name("options3").set.checked(true);
// spec.find().input().with().name("saveopts").click();
}
}
Whoo-hooo! I love sudokus! Thanks!
WoW! That's really great I will say. I am sure you quite worked hard to get this on place. Just tweeted to my twitter. Please do keep up this work.
Regards,
Anam
sudoku makes me crazy, I didn't even recognize the time while I am playing with this game, takes for the hints!
Zero Dramas
Post a Comment