Files
examples/C/Sudoku/sudoku.cpp
2012-01-22 16:14:32 -05:00

170 lines
3.4 KiB
C++

/**
* sudoku.cpp
*
* This program will be used to solve sudoku puzzles
*
* @date oct, 25, 2011
* @author ricky barrette
*/
#include <iostream>
#include "sudoku.h"
int mPuzzle[PUZZLE_SIZE][PUZZLE_SIZE] = { {6,0,0, 8,3,0, 0,4,0},
{0,8,5, 1,0,0, 0,0,0},
{0,0,0, 0,0,0, 0,0,0},
{4,0,0, 0,6,0, 0,8,0},
{0,0,0, 0,0,8, 0,0,3},
{1,6,0, 0,0,2, 0,0,0},
{0,0,9, 0,0,3, 0,1,0},
{0,5,0, 6,0,0, 0,0,0},
{0,1,0, 0,4,0, 2,9,0} };
int mCount = 0;
/**
* Main function
*/
int main(){
std::cout << "\nHello World, Sudoku!\n\n\n";
printPuzzle(mPuzzle);
if(solve(mPuzzle) == 0) {
std::cout << "NO SOLUTION\n";
std::cout << mCount;
std::cout << " trys\n\n";
} else {
std::cout << "\nSolved in ";
std::cout << mCount;
std::cout << " trys\n\n";
printPuzzle(mPuzzle);
}
return 1;
}
/**
* Checks the Row
* @returns 1 if legal, 0 if illegal
* @author ricky barrette
*/
int checkRow(int n, int r, int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
for(int index = 0; index < PUZZLE_SIZE; index++)
if(n == puzzle[r][index])
return 0;
return 1;
}
/**
* Checks the Column
* @returns 1 if legal, 0 if illegal
* @author ricky barrette
*/
int checkColumn(int n, int c, int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
for(int index = 0; index < PUZZLE_SIZE; index++)
if(n == puzzle[index][c])
return 0;
return 1;
}
/**
* Checks the "Box"
* @returns 1 if legal, 0 if illegal
* @author ricky barrette
*/
int checkBox(int n, int r, int c, int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
r = (r/BOX_SIZE)*BOX_SIZE;
c = (c/BOX_SIZE)*BOX_SIZE;
for(int ri = 0; ri < BOX_SIZE; ri++)
for(int ci = 0; ci < BOX_SIZE; ci++)
if(n == puzzle[r+ri][c+ci])
return 0;
//no violations
return 1;
}
/**
* Solves a sudoku puzzle
* @returns 1 if solvable, 0 if not
* @author ricky barrette
*/
int solve(int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
return solve(0,0, puzzle);
}
/**
* Solves a sudoku puzzle
* @returns 1 if solvable, 0 if not
* @author ricky barrette
*/
int solve(int r, int c, int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
if(DEBUG){
sleep(1);
printPuzzle(puzzle);
}
mCount++;
if (r == PUZZLE_SIZE) {
r = 0;
if (++c == PUZZLE_SIZE)
return 1;
}
//skip filled cells
if (puzzle[r][c] != 0)
return solve(r+1,c,puzzle);
for (int n = 1; n <= PUZZLE_SIZE; n++) {
if (legal(n,r,c,puzzle) == 1) {
puzzle[r][c] = n;
if (solve(r+1,c,puzzle) == 1)
return 1;
}
}
//reset on backtrack
puzzle[r][c] = 0;
return 0;
}
/**
* Prints the puzzle onto the screen
* @author ricky barrette
*/
void printPuzzle(int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
for(int ri = 0; ri < PUZZLE_SIZE; ri++){
for(int ci = 0; ci < PUZZLE_SIZE; ci++){
std::cout << puzzle[ri][ci];
//format: break for groups of BOX_SIZE
if(ci % BOX_SIZE == 2)
std::cout <<" ";
}
//format: break columns of BOX_SIZE
if(ri % BOX_SIZE == 2)
std::cout <<"\n";
//format: break for new row
std::cout << "\n";
}
std::cout <<"\n-------------\n";
}
/**
* Checks the puzzle if it is legal
* @returns 1 if legal; 0 if not
* @author ricky barrette
*/
int legal(int n, int r, int c, int puzzle[PUZZLE_SIZE][PUZZLE_SIZE]){
if(checkRow(n, r, puzzle) == 1)
if(checkColumn(n, c, puzzle) == 1)
if(checkBox(n, r, c, puzzle) == 1)
return 1;
return 0;
}