#include #include #include #include #include "sudoku.h" #define SIZE_OF_GAMEBORD_AXIS_X 9 #define SIZE_OF_GAMEBORD_AXIS_Y 9 #define AVAILABLE_DIFFICULTIES 3 #define AVAILABLE_LEVELS 3 #define EMPTY 0 #define LEVEL_NUMBER 3 int selected_difficulty; int selected_level; bool check_solved; bool test_help = false; int test_row_e; int test_col_e; int test_num; void Game_loop(); //is instead of main void Level_Pool(int selected_difficulty); void Level_Selection(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void initializeGrid(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void create_playing_field(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y], int selected_difficulty, int level); void Player_actions_for_playing(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void giving_hints_to_player(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void write_userinput_into_Sudoku(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void printGrid(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); void check_if_Sudoku_solved(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]); int availableLevels[AVAILABLE_DIFFICULTIES][AVAILABLE_LEVELS][SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y] = { { //easy {{0, 0, 3, 0, 2, 1, 8, 0, 0}, {6, 0, 0, 0, 7, 0, 1, 3, 2}, {9, 2, 1, 5, 0, 0, 7, 6, 4}, {7, 6, 0, 3, 0, 0, 4, 0, 0}, {8, 5, 4, 1, 9, 7, 0, 0, 0}, {1, 0, 0, 4, 0, 6, 0, 0, 0}, {2, 9, 0, 8, 1, 5, 0, 0, 6}, {0, 4, 8, 2, 0, 9, 5, 0, 0}, {5, 0, 0, 7, 0, 3, 2, 0, 0}}, {{7, 0, 2, 0, 0, 0, 9, 5, 0}, {0, 8, 0, 7, 5, 0, 2, 1, 6}, {0, 0, 5, 5, 2, 8, 7, 0, 3}, {5, 1, 8, 4, 3, 0, 6, 0, 0}, {0, 0, 6, 1, 0, 0, 5, 3, 0}, {0, 0, 0, 0, 6, 2, 0, 8, 1}, {0, 9, 0, 2, 0, 4, 0, 0, 5}, {0, 2, 0, 0, 9, 5, 0, 7, 4}, {0, 5, 1, 0, 0, 0, 0, 9, 2}}, {{4, 2, 5, 0, 9, 7, 1, 3, 0}, {0, 7, 0, 1, 0, 3, 0, 0, 6}, {0, 6, 1, 4, 8, 2, 0, 0, 0}, {1, 0, 0, 0, 3, 0, 0, 6, 0}, {7, 0, 8, 0, 2, 0, 0, 1, 3}, {9, 3, 0, 0, 4, 1, 5, 7, 2}, {0, 0, 7, 9, 6, 5, 0, 0, 0}, {0, 0, 4, 3, 7, 0, 2, 0, 5}, {0, 0, 0, 2, 1, 0, 0, 0, 0}}}, {//medium {{0, 0, 3, 0, 2, 1, 8, 0, 0}, {6, 0, 0, 0, 0, 0, 1, 3, 2}, {0, 2, 1, 0, 0, 0, 7, 6, 4}, {7, 6, 0, 3, 0, 0, 4, 0, 0}, {0, 5, 0, 1, 0, 7, 0, 0, 0}, {1, 0, 0, 4, 0, 6, 0, 0, 0}, {2, 0, 0, 8, 0, 0, 0, 0, 6}, {0, 4, 0, 0, 0, 9, 5, 0, 0}, {5, 0, 0, 7, 0, 3, 2, 0, 0}}, {{7, 0, 2, 0, 0, 0, 9, 5, 0}, {0, 0, 0, 7, 5, 0, 2, 0, 6}, {0, 0, 5, 0, 2, 8, 7, 0, 3}, {5, 1, 8, 0, 3, 0, 6, 0, 0}, {0, 0, 6, 1, 0, 0, 0, 3, 0}, {0, 0, 0, 0, 6, 2, 0, 8, 1}, {0, 9, 0, 2, 0, 4, 0, 0, 5}, {0, 0, 0, 0, 9, 0, 0, 0, 4}, {0, 5, 1, 0, 0, 0, 0, 9, 2}}, {{4, 2, 5, 0, 9, 7, 1, 3, 0}, {0, 0, 0, 1, 0, 3, 0, 0, 6}, {0, 6, 0, 4, 0, 2, 0, 0, 0}, {1, 0, 0, 0, 3, 0, 0, 6, 0}, {7, 0, 8, 0, 2, 0, 0, 1, 3}, {0, 3, 0, 0, 0, 1, 0, 7, 2}, {0, 0, 7, 9, 6, 0, 0, 0, 0}, {0, 0, 4, 3, 7, 0, 2, 0, 5}, {0, 0, 0, 2, 1, 0, 0, 0, 0}} }, {//hard {{0, 0, 3, 0, 2, 0, 8, 0, 0}, {6, 0, 0, 0, 0, 0, 0, 3, 0}, {9, 2, 1, 5, 0, 0, 7, 6, 4}, {0, 0, 0, 3, 0, 0, 0, 0, 0}, {0, 5, 4, 1, 0, 7, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0, 0}, {2, 0, 0, 0, 1, 5, 0, 0, 6}, {0, 4, 0, 2, 0, 0, 0, 0, 0}, {5, 0, 0, 0, 0, 3, 2, 0, 0}}, {{7, 0, 2, 0, 0, 0, 9, 0, 0}, {0, 0, 0, 7, 0, 0, 0, 1, 6}, {0, 0, 5, 0, 0, 8, 7, 0, 3}, {5, 0, 0, 4, 0, 0, 6, 0, 0}, {0, 0, 6, 1, 0, 0, 5, 3, 0}, {0, 0, 0, 0, 0, 2, 0, 0, 1}, {0, 9, 0, 2, 0, 4, 0, 0, 0}, {0, 2, 0, 0, 0, 5, 0, 7, 0}, {0, 5, 0, 0, 0, 0, 0, 9, 2}}, {{4, 0, 5, 0, 9, 7, 1, 3, 0}, {0, 0, 0, 0, 0, 3, 0, 0, 6}, {0, 6, 1, 4, 0, 2, 0, 0, 0}, {1, 0, 0, 0, 3, 0, 0, 6, 0}, {0, 0, 8, 0, 0, 0, 0, 0, 3}, {9, 3, 0, 0, 4, 1, 5, 7, 2}, {0, 0, 7, 9, 0, 5, 0, 0, 0}, {0, 0, 4, 3, 0, 0, 2, 0, 5}, {0, 0, 0, 2, 1, 0, 0, 0, 0}} } }; int solutionLevels[AVAILABLE_DIFFICULTIES][AVAILABLE_LEVELS][SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y] = { { //easy {{4, 7, 3, 6, 2, 1, 8, 5, 9}, {6, 8, 5, 9, 7, 4, 1, 3, 2}, {9, 2, 1, 5, 3, 8, 7, 6, 4}, {7, 6, 9, 3, 5, 2, 4, 8, 1}, {8, 5, 4, 1, 9, 7, 6, 2, 3}, {1, 3, 2, 4, 8, 6, 9, 7, 5}, {2, 9, 7, 8, 1, 5, 3, 4, 6}, {3, 4, 8, 2, 6, 9, 5, 1, 7}, {5, 1, 6, 7, 4, 3, 2, 9, 8}}, {{7, 3, 2, 6, 4, 1, 9, 5, 8}, {9, 8, 4, 7, 5, 3, 2, 1, 6}, {1, 6, 5, 9, 2, 8, 7, 4, 3}, {5, 1, 8, 4, 3, 7, 6, 2, 9}, {2, 4, 6, 1, 8, 9, 5, 3, 7}, {3, 7, 9, 5, 6, 2, 4, 8, 1}, {8, 9, 7, 2, 1, 4, 3, 6, 5}, {6, 2, 3, 8, 9, 5, 1, 7, 4}, {4, 5, 1, 3, 7, 6, 8, 9, 2}}, {{4, 2, 5, 6, 9, 7, 1, 3, 8}, {8, 7, 9, 1, 5, 3, 4, 2, 6}, {3, 6, 1, 4, 8, 2, 7, 5, 9}, {1, 5, 2, 7, 3, 9, 8, 6, 4}, {7, 4, 8, 5, 2, 6, 9, 1, 3}, {9, 3, 6, 8, 4, 1, 5, 7, 2}, {2, 8, 7, 9, 6, 5, 3, 4, 1}, {6, 1, 4, 3, 7, 8, 2, 9, 5}, {5, 9, 3, 2, 1, 4, 6, 8, 7}}}, {//medium {{4, 7, 3, 6, 2, 1, 8, 5, 9}, {6, 8, 5, 9, 7, 4, 1, 3, 2}, {9, 2, 1, 5, 3, 8, 7, 6, 4}, {7, 6, 9, 3, 5, 2, 4, 8, 1}, {8, 5, 4, 1, 9, 7, 6, 2, 3}, {1, 3, 2, 4, 8, 6, 9, 7, 5}, {2, 9, 7, 8, 1, 5, 3, 4, 6}, {3, 4, 8, 2, 6, 9, 5, 1, 7}, {5, 1, 6, 7, 4, 3, 2, 9, 8}}, {{7, 3, 2, 6, 4, 1, 9, 5, 8}, {9, 8, 4, 7, 5, 3, 2, 1, 6}, {1, 6, 5, 9, 2, 8, 7, 4, 3}, {5, 1, 8, 4, 3, 7, 6, 2, 9}, {2, 4, 6, 1, 8, 9, 5, 3, 7}, {3, 7, 9, 5, 6, 2, 4, 8, 1}, {8, 9, 7, 2, 1, 4, 3, 6, 5}, {6, 2, 3, 8, 9, 5, 1, 7, 4}, {4, 5, 1, 3, 7, 6, 8, 9, 2}}, {{4, 2, 5, 6, 9, 7, 1, 3, 8}, {8, 7, 9, 1, 5, 3, 4, 2, 6}, {3, 6, 1, 4, 8, 2, 7, 5, 9}, {1, 5, 2, 7, 3, 9, 8, 6, 4}, {7, 4, 8, 5, 2, 6, 9, 1, 3}, {9, 3, 6, 8, 4, 1, 5, 7, 2}, {2, 8, 7, 9, 6, 5, 3, 4, 1}, {6, 1, 4, 3, 7, 8, 2, 9, 5}, {5, 9, 3, 2, 1, 4, 6, 8, 7}} }, {//hard {{4, 7, 3, 6, 2, 1, 8, 5, 9}, {6, 8, 5, 9, 7, 4, 1, 3, 2}, {9, 2, 1, 5, 3, 8, 7, 6, 4}, {7, 6, 9, 3, 5, 2, 4, 8, 1}, {8, 5, 4, 1, 9, 7, 6, 2, 3}, {1, 3, 2, 4, 8, 6, 9, 7, 5}, {2, 9, 7, 8, 1, 5, 3, 4, 6}, {3, 4, 8, 2, 6, 9, 5, 1, 7}, {5, 1, 6, 7, 4, 3, 2, 9, 8}}, {{7, 3, 2, 6, 4, 1, 9, 5, 8}, {9, 8, 4, 7, 5, 3, 2, 1, 6}, {1, 6, 5, 9, 2, 8, 7, 4, 3}, {5, 1, 8, 4, 3, 7, 6, 2, 9}, {2, 4, 6, 1, 8, 9, 5, 3, 7}, {3, 7, 9, 5, 6, 2, 4, 8, 1}, {8, 9, 7, 2, 1, 4, 3, 6, 5}, {6, 2, 3, 8, 9, 5, 1, 7, 4}, {4, 5, 1, 3, 7, 6, 8, 9, 2}}, {{4, 2, 5, 6, 9, 7, 1, 3, 8}, {8, 7, 9, 1, 5, 3, 4, 2, 6}, {3, 6, 1, 4, 8, 2, 7, 5, 9}, {1, 5, 2, 7, 3, 9, 8, 6, 4}, {7, 4, 8, 5, 2, 6, 9, 1, 3}, {9, 3, 6, 8, 4, 1, 5, 7, 2}, {2, 8, 7, 9, 6, 5, 3, 4, 1}, {6, 1, 4, 3, 7, 8, 2, 9, 5}, {5, 9, 3, 2, 1, 4, 6, 8, 7}} } }; void Game_loop() { int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]; selected_level = 0; while (1) { printf("\nDifficulty Function - Choose difficulty:\n"); printf("1. Easy\n2. Medium\n3. Hard\n"); printf("Enter the corresponding number or type 'quit' to exit: "); if(!test_help){ char input[10]; scanf("%s", input); if (strcmp(input, "quit") == 0) { break; } selected_difficulty = input[0] - '0'; // Convert the first character to an integer if ((selected_difficulty >= 1 && selected_difficulty <= 3) && input[1] == '\0') { Level_Pool(selected_difficulty); Level_Selection(Sudoku_grid); Player_actions_for_playing(Sudoku_grid); } else { printf("Invalid input. Please enter a number between 1 and 3.\n"); } } if(test_help){ Level_Pool(selected_difficulty); break; } } } void Level_Pool(int selected_difficulty) { printf("\nAvailable Levels for Difficulty %d:\n", selected_difficulty); for (int i = 0; i < LEVEL_NUMBER; i++) { printf("%d. Level %d\n", i + 1, i + 1); } } void Level_Selection(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { int level = 0; printf("\nSelect a level:\n"); while (true){ if(!test_help){ char level_select[10]; scanf("%s", level_select); level = level_select[0] - '0'; // Convert the first character to an integer if ((level >= 1 && level <= 3) && level_select[1] == '\0') { selected_level = level; level--; // Adjust to 0-based index create_playing_field(Sudoku_grid, selected_difficulty, selected_level); break; } else { printf("Invalid input. Please enter a number between 1 and 3.\n"); } } if(test_help){ selected_level = level; level--; create_playing_field(Sudoku_grid, selected_difficulty, selected_level); break; } } } void initializeGrid(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { Sudoku_grid[i][j] = EMPTY; } } } void create_playing_field(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y], int selected_difficulty, int level) { initializeGrid(Sudoku_grid); if(!test_help){ for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { Sudoku_grid[i][j] = availableLevels[selected_difficulty - 1][level - 1][i][j]; } } } for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { printf("%d", Sudoku_grid[i][j]); } printf("\n"); } } void Player_actions_for_playing(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { while (1) { printf("\nTurn function - Choose an action:\n"); printf("1. Hints\n"); printf("2. Insert Number into Game\n"); printf("3. Print Sudoku grid\n"); printf("4. Check if your Solution is correct\n"); printf("5. Select level\n"); printf("6. Quit\n"); int action; if(test_help){ printGrid(Sudoku_grid); check_if_Sudoku_solved(Sudoku_grid); break; } if(!test_help){ while (true){ char action_str[10]; scanf("%s", action_str); action = action_str[0] - '0'; // Convert the first character to an integer if ((action >= 1 && action <= 6) && action_str[1] == '\0') { break; } else { printf("Invalid input. Please enter a number between 1 and 6.\n"); } } switch (action) { case 1: giving_hints_to_player(Sudoku_grid); break; case 2: write_userinput_into_Sudoku(Sudoku_grid); break; case 3: printGrid(Sudoku_grid); break; case 4: check_if_Sudoku_solved(Sudoku_grid); break; case 5: Level_Selection(Sudoku_grid); break; case 6: printf("Exiting Sudoku program.\n"); exit(0); default: printf("Invalid input. Please enter a number between 1 and 6.\n"); } } } } void giving_hints_to_player(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { printf("\nTip function - Choose an option:\n"); printf("1. Set the user-specified cell to the right value\n"); printf("2. Set the user-specified 3x3 field to the right values\n"); printf("3. Solve the entire puzzle for the current level\n"); if(test_help){ initializeGrid(Sudoku_grid); for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { Sudoku_grid[i][j] = solutionLevels[selected_difficulty - 1][selected_level - 1][i][j]; } } printf("Puzzle solved. \n"); } int option = 0; if(!test_help){ while (true){ char tip_str[10]; scanf("%s", tip_str); option = tip_str[0] - '0'; // Convert the first character to an integer if ((option >= 1 && option <= 3) && tip_str[1] == '\0') { break; } else { printf("Invalid input. Please enter a number between 1 and 3.\n"); } } switch (option) { case 1: printf("Enter the coordinates (row and column) separated by space:\n"); int row, col; while (true){ char row_str[10]; char col_str[10]; scanf("%s %s", row_str, col_str); row = row_str[0] - '0'; // Convert the first character to an integer col = col_str[0] - '0'; // Convert the first character to an integer if (((row >= 1 && row <= 9) && row_str[1] == '\0') && ((col >= 1 && col <= 9) && col_str[1] == '\0')) { break; } else { printf("Invalid input. Please enter a number between 1 and 9.\n"); } } Sudoku_grid[row - 1][col - 1] = solutionLevels[selected_difficulty - 1][selected_level - 1][row - 1][col - 1]; printf("Value set successfully.\n"); break; case 2: printf("Enter the coordinates (top-left cell of the 3x3 field) separated by space:\n"); int startRow, startCol; while (true){ char row_squ[10]; char col_squ[10]; scanf("%s %s", row_squ, col_squ); startRow = row_squ[0] - '0'; // Convert the first character to an integer startCol = col_squ[0] - '0'; // Convert the first character to an integer if (((startRow >= 1 && startRow <= 9) && row_squ[1] == '\0') && ((startCol >= 1 && startCol <= 9) && col_squ[1] == '\0')) { break; } else { printf("Invalid input. Please enter a number between 1 and 9.\n"); } } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Sudoku_grid[startRow - 1 + i][startCol - 1 + j] = solutionLevels[selected_difficulty - 1][selected_level - 1][startRow - 1 + i][startCol - 1 + j]; } } printf("3x3 field set successfully.\n"); break; case 3: for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { Sudoku_grid[i][j] = solutionLevels[selected_difficulty - 1][selected_level - 1][i][j]; } } printf("Puzzle solved. \n"); break; default: printf("Invalid option. Please enter a number between 1 and 3.\n"); } } } void write_userinput_into_Sudoku(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { printf("\nInput function - Choose an action:\n"); printf("1. Insert value in an empty field\n"); printf("2. Clear an already filled field\n"); if(test_help){ initializeGrid(Sudoku_grid); Sudoku_grid[test_row_e -1][test_col_e -1] = test_num; printGrid(Sudoku_grid); } int action; if(!test_help){ while (true){ char in_str[10]; scanf("%s", in_str); action = in_str[0] - '0'; // Convert the first character to an integer if ((action >= 1 && action <= 2) && in_str[1] == '\0') { break; } else { printf("Invalid input. Please enter a number between 1 and 2.\n"); } } switch (action) { case 1: printf("Enter the coordinates (row and column) separated by space:\n"); int row_e, col_e, num; while (true){ char rowe_str[10]; char cole_str[10]; scanf("%s %s", rowe_str, cole_str); row_e = rowe_str[0] - '0'; // Convert the first character to an integer col_e = cole_str[0] - '0'; // Convert the first character to an integer if (((row_e >= 1 && row_e <= 9) && rowe_str[1] == '\0') && ((col_e >= 1 && col_e <= 9) && cole_str[1] == '\0')) { break; } else { printf("Invalid input. Please enter a number between 1 and 9.\n"); } } printf("Enter the value to insert (1-9):\n"); while (true){ char nume_str[10]; scanf("%s", nume_str); num = nume_str[0] - '0'; // Convert the first character to an integer if ((num >= 1 && num <= 9) && nume_str[1] == '\0') { Sudoku_grid[row_e - 1][col_e - 1] = num; printf("Value inserted successfully.\n"); break; } else { printf("Invalid input. Please enter a number between 1 and 9.\n"); } } break; case 2: printf("Enter the coordinates (row and column) separated by space:\n"); int row_d, col_d; while (true){ char rowd_str[10]; char cold_str[10]; scanf("%s %s", rowd_str, cold_str); row_d = rowd_str[0] - '0'; // Convert the first character to an integer col_d = cold_str[0] - '0'; // Convert the first character to an integer if (((row_d >= 1 && row_d <= 9) && rowd_str[1] == '\0') && ((col_d >= 1 && col_d <= 9) && cold_str[1] == '\0')) { Sudoku_grid[row_d - 1][col_d - 1] = 0; printf("Cell cleared successfully.\n"); break; } else { printf("Invalid input. Please enter a number between 1 and 9.\n"); } } break; default: printf("Invalid input. Please enter 1 or 2.\n"); } printGrid(Sudoku_grid); } } void printGrid(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { printf("\nSudoku Grid:\n"); for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { printf("%d ", Sudoku_grid[i][j]); } printf("\n"); } } void check_if_Sudoku_solved(int Sudoku_grid[SIZE_OF_GAMEBORD_AXIS_X][SIZE_OF_GAMEBORD_AXIS_Y]) { printf("\nDone function - Checking if the solution is correct...\n"); for (int i = 0; i < SIZE_OF_GAMEBORD_AXIS_X; i++) { for (int j = 0; j < SIZE_OF_GAMEBORD_AXIS_Y; j++) { if (Sudoku_grid[i][j] != solutionLevels[selected_difficulty - 1][selected_level - 1][i][j]) { printf("Incorrect solution. Keep trying!\n"); check_solved = false; return; } } } check_solved = true; printf("Congratulations! Sudoku is solved correctly.\n"); } int mainn(){ Game_loop(); return 0; }