#include "sudoku.h" void Sudoku::createGrid(Grid &gameboard) { ifstream fin; // File input stream. string tempstring; // Holds input filepath. int tempint; // Holds integers in array one by one. int choice; // Enter input method. cout << "Please enter 1 to load Sudoku from a file." << endl; cout << "Please enter 2 to manually input numbers." << endl; cin >> choice; switch (choice) { case 1: // Filepath. cout << "Please enter Sudoku file: "; cin >> tempstring; fin.open(tempstring.c_str()); gameboard.gameboard.resize(9); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { fin >> tempint; gameboard.gameboard[i].push_back(tempint); } } // Displays original puzzle. cout << "The original Sudoku puzzle is: " << endl; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (j % 3 == 0) { cout << " "; } cout << " " << gameboard.gameboard[i][j]; } if ((i + 1) % 3 == 0) { cout << endl; } cout << endl; } cout << "Press any key to solve" << endl; getch(); // Hit any key break; case 2: // One by one. cout << "Please enter values one by one, from left to right, top to bottom." << endl; cout << "Enter 0's for empty spaces." << endl; gameboard.gameboard.resize(9); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { cout << "Number: "; cin >> tempint; gameboard.gameboard[i].push_back(tempint); system("cls"); // Clear screen. } } // Displays original puzzle. cout << "The original Sudoku puzzle is: " << endl; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (j % 3 == 0) { cout << " "; } cout << " " << gameboard.gameboard[i][j]; } if ((i + 1) % 3 == 0) { cout << endl; } cout << endl; } cout << "Press any key to solve" << endl; getch(); // Press any key. break; default: system("cls"); createGrid(gameboard); // Calls again if neither choice selected. } } void Sudoku::place_next(int &loc, int &loc2, Grid *pboard) { int temp = loc * loc2; while (pboard ->gameboard[loc][loc2] != 0 && temp < 65) // Moves past values already filled in. { if (loc2 == 8) { if (loc == 8) { temp++; // If at end last square calls a new integer, temp, so that // vector does not go out of scope. This program is converted // from a 1-dimensional array program which is why it doesn't // use vector functions - and hence scope is a factor. } else // If last column, move to first column of new line. { loc2 = 0; loc++; temp = loc * loc2; } } else if (loc2 < 8) // Move to next spot. { loc2++; temp = loc * loc2; } } } bool Sudoku::row_check(int loc, int val, Grid *pboard) { for (int j = 0; j < 9; j++) { if (pboard -> gameboard[loc][j] == val) // Checks if value already exists in row. { return false; } } return true; } bool Sudoku::column_check(int loc2, int val, Grid *pboard) { for (int j = 0; j < 9; j++) { if (pboard -> gameboard[j][loc2] == val) // Checks if value already exists in column. { return false; } } return true; } // This function is a mess - it basically checks each square to see if a number // already exists in that square. bool Sudoku::square_check(int loc, int loc2, int val, Grid *pboard) { if (loc == 0 || loc == 3 || loc == 6) { if (loc2 == 0 || loc2 == 3 || loc2 == 6) { if(val == pboard -> gameboard[loc + 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 + 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 + 2] && val > 0) { return false; } } else if (loc2 == 1 || loc2 == 4 || loc2 == 7) { if(val == pboard -> gameboard[loc + 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 + 1] && val > 0) { return false; } } else if (loc2 == 2 || loc2 == 5 || loc2 == 8) { if(val == pboard -> gameboard[loc + 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 - 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 2][loc2 - 2] && val > 0) { return false; } } } else if (loc == 1 || loc == 4 || loc == 7) { if (loc2 == 0 || loc2 == 3 || loc2 == 6) { if(val == pboard -> gameboard[loc - 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 + 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 + 2] && val > 0) { return false; } } else if (loc2 == 1 || loc2 == 4 || loc2 == 7) { if(val == pboard -> gameboard[loc - 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 + 1] && val > 0) { return false; } } else if (loc2 == 2 || loc2 == 5 || loc2 == 8) { if(val == pboard -> gameboard[loc - 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 - 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc + 1][loc2 - 2] && val > 0) { return false; } } } else if (loc == 2 || loc == 5 || loc == 8) { if (loc2 == 0 || loc2 == 3 || loc2 == 6) { if(val == pboard -> gameboard[loc - 1 ][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 + 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 + 2] && val > 0) { return false; } } else if (loc2 == 1 || loc2 == 4 || loc2 == 7) { if(val == pboard -> gameboard[loc - 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 + 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 + 1] && val > 0) { return false; } } else if (loc2 == 2 || loc2 == 5 || loc2 == 8) { if(val == pboard -> gameboard[loc - 1][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 1][loc2 - 2] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 - 1] && val > 0) { return false; } else if(val == pboard -> gameboard[loc - 2][loc2 - 2] && val > 0) { return false; } } } return true; } int Sudoku::Solve(int loc, int loc2, int num, Grid &gameboard) { if (num > 9) // Exits if values 1-9 don't work. { return 0; } place_next(loc, loc2, &gameboard); // Moves ahead. // Checks if number can be entered in spot. if (row_check(loc, num, &gameboard) && column_check(loc2, num, &gameboard) && square_check(loc, loc2, num, &gameboard)) { gameboard.gameboard[loc][loc2] = num; // Enters number. // This loop checks if all values have been filled in. for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (gameboard.gameboard[i][j] != 0) { counter++; } } } // Prints out solution or resets counter. if (counter == 81) { system("cls"); print_solution(&gameboard); counter = 0; } else { counter = 0; } // Tries new locations, then next number at present location in none work for next. Recursive. if (loc2 < 8) { Solve(loc, loc2 + 1, 1, gameboard); gameboard.gameboard[loc][loc2] = 0; Solve(loc, loc2, num + 1, gameboard); } // Tries new locations, then next number at present location in none work for next. Recursive. else if (loc < 8) { Solve(loc+1, 0, 1, gameboard); gameboard.gameboard[loc][loc2] = 0; Solve(loc, loc2, num + 1, gameboard); } } else // Tries next number if present doesn't work. { Solve(loc, loc2, num + 1, gameboard); } } void Sudoku::print_solution(Grid *pboard) { cout << "Solution found!!!!" << endl; for (int i = 0; i < 30; i++) { cout << "-"; } cout << endl; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (j % 3 == 0) { cout << " "; } cout << " " << pboard->gameboard[i][j]; } if ((i + 1) % 3 == 0) { cout << endl; } cout << endl; } }