diff --git a/src/main.cpp b/src/main.cpp index aba7e63..e11414f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,9 @@ +#include #include #include #include #include -#include -#define N 9 -#define M 9 + #define CELL_SIZE 80 struct Cell @@ -13,187 +12,177 @@ struct Cell int x; // obvious int y; // obvious bool isSelected; - bool isHighlighted; bool canBeChanged; Cell(int x1, int y1) { x = x1; y = y1; isSelected = false; - isHighlighted = false; canBeChanged = false; } }; std::vector cells; std::vector solution; +sf::Time elapsed1; // this variable for storing the time elapsed bool isSafe(std::vector &grid, int row, int col, int num) { - for (int x = 0; x <= 8; x++) - if (grid[row + x * 9].number == num) - return false; + for (int x = 0; x <= 8; x++) + if (grid[row + x * 9].number == num) + return false; - for (int x = 0; x <= 8; x++) - if (grid[x + col * 9].number == num) - return false; + for (int x = 0; x <= 8; x++) + if (grid[x + col * 9].number == num) + return false; - int startRow = row - row % 3, - startCol = col - col % 3; + int startRow = row - row % 3, + startCol = col - col % 3; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - if (grid[(i + startRow) + (j + startCol) * 9].number == num) - return false; - return true; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (grid[(i + startRow) + (j + startCol) * 9].number == num) + return false; + return true; } bool solveSudoku(std::vector &grid, int row, int col) { - if (row == 9 - 1 && col == 9) - return true; - - if (col == 9) - { - row++; - col = 0; - } + if (row == 9 - 1 && col == 9) + return true; - if (grid[row + col * 9].number > 0) - return solveSudoku(grid, row, col + 1); + if (col == 9) + { + row++; + col = 0; + } - for (int num = 1; num <= 9; num++) - { + if (grid[row + col * 9].number > 0) + return solveSudoku(grid, row, col + 1); - if (isSafe(grid, row, col, num)) - { + for (int num = 1; num <= 9; num++) + { - grid[row + col * 9].number = num; + if (isSafe(grid, row, col, num)) + { - if (solveSudoku(grid, row, col + 1)) - return true; - } + grid[row + col * 9].number = num; - grid[row + col * 9].number = 0; + if (solveSudoku(grid, row, col + 1)) + return true; } - return false; + + grid[row + col * 9].number = 0; + } + return false; } bool unUsedInBox(std::vector &grid, int rowStart, int colStart, int num) { - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) { - for (int j = 0; j < 3; j++) - { - if (grid[(rowStart + i) + (colStart + j) * 9].number == num) - { - return false; - } - } + if (grid[(rowStart + i) + (colStart + j) * 9].number == num) + { + return false; + } } - return true; + } + return true; } void fillBox(std::vector &grid, int row, int col) { - int num; - for (int i = 0; i < 3; i++) + int num; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) { - for (int j = 0; j < 3; j++) - { - do - { - num = (rand() % 9) + 1; - } while (!unUsedInBox(grid, row, col, num)); - grid[(row + i) + (col + j) * 9].number = num; - } + do + { + num = (rand() % 9) + 1; + } while (!unUsedInBox(grid, row, col, num)); + grid[(row + i) + (col + j) * 9].number = num; } + } } bool unUsedInRow(std::vector &grid, int i, int num) { - for (int j = 0; j < 9; j++) + for (int j = 0; j < 9; j++) + { + if (grid[i + j * 9].number == num) { - if (grid[i + j * 9].number == num) - { - return false; - } + return false; } - return true; + } + return true; } bool unUsedInCol(std::vector &grid, int j, int num) { - for (int i = 0; i < 9; i++) + for (int i = 0; i < 9; i++) + { + if (grid[i + j * 9].number == num) { - if (grid[i + j * 9].number == num) - { - return false; - } + return false; } - return true; + } + return true; } bool checkIfSafe(std::vector &grid, int i, int j, int num) { - return (unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) && - unUsedInBox(grid, i - i % 3, j - j % 3, num)); + return (unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) && + unUsedInBox(grid, i - i % 3, j - j % 3, num)); } void fillDiagonal(std::vector &grid) { - for (int i = 0; i < 9; i = i + 3) - { + for (int i = 0; i < 9; i = i + 3) + { - fillBox(grid, i, i); - } + fillBox(grid, i, i); + } } void removeKDigits(std::vector &grid, int k) { - while (k > 0) - { + while (k > 0) + { - int cellId = rand() % 81; - int i = cellId / 9; - int j = cellId % 9; - if (grid[i + j * 9].number != 0) - { - grid[i + j * 9].number = 0; - grid[i+j*9].canBeChanged = true; - k--; - } - } -} -void highlight(int num){ - for(auto nums: cells){ - if(nums.number == num){ - nums.isHighlighted = true; - } - } -} -void clearHighlight(){ -for(auto nums: cells){ - nums.isHighlighted = false; + int cellId = rand() % 81; + int i = cellId / 9; + int j = cellId % 9; + if (grid[i + j * 9].number != 0) + { + grid[i + j * 9].number = 0; + grid[i + j * 9].canBeChanged = true; + k--; } - + } } void sudokuGenerator(int k) { - fillDiagonal(cells); - solveSudoku(cells, 0,0); - solution = cells; - removeKDigits(cells, 50); + fillDiagonal(cells); + solveSudoku(cells, 0, 0); + solution = cells; + removeKDigits(cells, 50); } void clearSelected(int index) { cells[index].isSelected = false; } -bool checkForVictory(){ - for(auto nums: cells){ - if(nums.number == 0){ - return false ; - } - } - for(int i = 0 ; i<81 ; i++){ - if(cells[i].number != solution[i].number) - return false; +bool checkForVictory() +{ + for (auto nums : cells) + { + if (nums.number == 0) + { + return false; } - return true; + } + for (int i = 0; i < 81; i++) + { + if (cells[i].number != solution[i].number) + return false; + } + return true; } void fillCell() { @@ -210,26 +199,39 @@ int getMousPos(sf::RenderWindow &window) { int mouse_x = sf::Mouse::getPosition(window).x / CELL_SIZE; int mouse_y = sf::Mouse::getPosition(window).y / CELL_SIZE; - if(cells[mouse_x+mouse_y*9].canBeChanged) + if (cells[mouse_x + mouse_y * 9].canBeChanged) cells[mouse_x + mouse_y * 9].isSelected = true; return (mouse_x + mouse_y * 9); } -void drawRectangles(sf::RenderWindow &window) +void drawRectangles(sf::RenderWindow &window, bool isWin) { sf::Font font("assests/Greek-Freak.ttf"); sf::Text text(font); text.setCharacterSize(64); text.setFillColor(sf::Color::Black); + if (isWin) + { + text.setFillColor(sf::Color::White); + text.setString("YOU WIN!"); + text.setPosition({0, 0}); + window.draw(text); + int timeTaken = std::round(elapsed1.asSeconds()); + text.setString(std::to_string(timeTaken)); + text.setPosition({0, 100}); + window.draw(text); + return; + } sf::RectangleShape rectangle({CELL_SIZE, CELL_SIZE}); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { - if (cells[i + j * 9].isSelected){ - rectangle.setFillColor(sf::Color(99,99,99)); - } - else - rectangle.setFillColor(sf::Color::White); + if (cells[i + j * 9].isSelected) + { + rectangle.setFillColor(sf::Color(99, 99, 99)); + } + else + rectangle.setFillColor(sf::Color::White); if ((j % 3 == 0 && j != 0) || (i % 3 == 0 && i != 0)) { rectangle.setOutlineThickness(6); @@ -245,9 +247,10 @@ void drawRectangles(sf::RenderWindow &window) window.draw(rectangle); } text.setPosition({float(CELL_SIZE * i), float(CELL_SIZE * j)}); - if(cells[i+j*9].number!=0){ - text.setString(std::to_string(cells[i + j * 9].number)); - window.draw(text); + if (cells[i + j * 9].number != 0) + { + text.setString(std::to_string(cells[i + j * 9].number)); + window.draw(text); } } } @@ -257,6 +260,8 @@ int main() { srand(time(0)); fillCell(); + sf::Clock clock; + bool isWin = false; auto window = sf::RenderWindow(sf::VideoMode({9 * 80u, 9 * 80u}), "Sudoku"); window.setFramerateLimit(144); int index = -1; @@ -268,10 +273,16 @@ int main() { window.close(); } + if (checkForVictory()) + { + isWin = true; + elapsed1 = clock.getElapsedTime(); + clock.stop(); + } if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) { - if(index!=-1) - clearSelected(index); + if (index != -1) + clearSelected(index); index = getMousPos(window); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Num1)) @@ -279,7 +290,6 @@ int main() if (index != -1) { cells[index].number = 1; - highlight(1); clearSelected(index); index = -1; } @@ -288,7 +298,7 @@ int main() { if (index != -1) { - cells[index].number = 2;highlight(2); + cells[index].number = 2; clearSelected(index); index = -1; } @@ -297,7 +307,7 @@ int main() { if (index != -1) { - cells[index].number = 3;highlight(3); + cells[index].number = 3; clearSelected(index); index = -1; } @@ -306,7 +316,7 @@ int main() { if (index != -1) { - cells[index].number = 4;highlight(4); + cells[index].number = 4; clearSelected(index); index = -1; } @@ -315,7 +325,7 @@ int main() { if (index != -1) { - cells[index].number = 5;highlight(5); + cells[index].number = 5; clearSelected(index); index = -1; } @@ -324,7 +334,7 @@ int main() { if (index != -1) { - cells[index].number = 6;highlight(6); + cells[index].number = 6; clearSelected(index); index = -1; } @@ -333,7 +343,7 @@ int main() { if (index != -1) { - cells[index].number = 7;highlight(7); + cells[index].number = 7; clearSelected(index); index = -1; } @@ -342,7 +352,7 @@ int main() { if (index != -1) { - cells[index].number = 8;highlight(8); + cells[index].number = 8; clearSelected(index); index = -1; } @@ -351,14 +361,24 @@ int main() { if (index != -1) { - cells[index].number = 9;highlight(9); + cells[index].number = 9; + clearSelected(index); + index = -1; + } + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Num0)) + { + if (index != -1) + { + cells[index].number = 0; clearSelected(index); index = -1; } } + } window.clear(); - drawRectangles(window); + drawRectangles(window, isWin); window.display(); } }