diff --git a/8 Tic Tac Toe/tic-tac-toe.c b/8 Tic Tac Toe/tic-tac-toe.c index c2b62fe..753f472 100644 --- a/8 Tic Tac Toe/tic-tac-toe.c +++ b/8 Tic Tac Toe/tic-tac-toe.c @@ -1,248 +1,425 @@ -#include -#include -#include +#include +#include +#include -#define BOARD_SIZE 3 -#define X 'X' -#define O 'O' +int difficulty; typedef struct { - int player; - int computer; - int draw; + int player; + int computer; + int draw; } Score; -int difficulty; -Score score = {.player = 0, .computer = 0, .draw = 0}; +Score score = {0, 0, 0}; -void input_difficulty(); +void get_difficulty(); void clear_screen(); -void print_board(char board[BOARD_SIZE][BOARD_SIZE]); -int check_win(char board[BOARD_SIZE][BOARD_SIZE], char player); -int check_draw(char board[BOARD_SIZE][BOARD_SIZE]); -void play_game(); -void player_move(char board[BOARD_SIZE][BOARD_SIZE]); -void computer_move(char board[BOARD_SIZE][BOARD_SIZE]); -int is_valid_move(char board[BOARD_SIZE][BOARD_SIZE], int row, int col); - -int main() { - srand(time(NULL)); - int choice; - input_difficulty(); - do { - play_game(); - printf("\nPlay again? (1 for yes, 0 for no): "); - scanf("%d", &choice); - } while (choice == 1); - printf("\nBye Bye, thanks for playing."); +void print_board(char board[3][3]); +int checkwin(char board[3][3], char player); +int checkdraw(char board[3][3]); +void playgame(); +void playermove(char board[3][3]); +void computermove(char board[3][3]); +void two_player_move(char board[3][3], char player); +int validmove(char board[3][3], int row, int col); + + +int main(){ + srand(time(NULL)); + int choice; + get_difficulty(); + do { + + playgame(); + + printf("\nDo you want to play again ? (1 for yes, 2 for no): "); + scanf(" %d", &choice); + + } while(choice == 1); + + printf("\nDeveloped by HUSSAIN"); + printf("\nThanks for playing"); + + return 0; } -void play_game() { - char board[BOARD_SIZE][BOARD_SIZE] = { - {' ', ' ', ' '}, - {' ', ' ', ' '}, - {' ', ' ', ' '}, - }; - char current_player = rand() % 2 == 0 ? X : O; - - print_board(board); - while (1) { - if (current_player == X) { - player_move(board); - print_board(board); - if (check_win(board, X)) { - score.player++; - print_board(board); - printf("Congratulation You have won.!!!"); - break; - } - current_player = O; - } else { - computer_move(board); - print_board(board); - if (check_win(board, O)) { - score.computer++; - print_board(board); - printf("I won !!! But you played well..."); - break; - } - current_player = X; +void playgame(){ + char board[3][3] = { + {' ', ' ', ' '}, + {' ', ' ', ' '}, + {' ', ' ', ' '}, + }; + + char current_player = 'X'; + + if(difficulty == 1 || difficulty == 2) { + if(rand() % 2 == 0) { + current_player = 'X'; + } else { + current_player = 'O'; + } + } + + while(1){ + print_board(board); + + if(difficulty == 3) { + two_player_move(board, current_player); + + if(checkwin(board, current_player)) { + + if(current_player == 'X') { + score.player++; + print_board(board); + printf("\nCONGRATULATIONS Player %c won the game", current_player); + return; + + } else { + + score.computer++; + print_board(board); + printf("\nCONGRATULATIONS Player %c won the game", current_player); + return; + } + } + + if(checkdraw(board)) { + score.draw++; + print_board(board); + printf("\nIt's a draw!"); + return; } - if (check_draw(board)) { - score.draw++; - print_board(board); - printf("\nIt's a draw!"); - break; + current_player = (current_player == 'X') ? 'O' : 'X'; + } else { + + if(current_player == 'X'){ + playermove(board); + + + if(checkwin(board,'X')){ + score.player++; + print_board(board); + + printf("\nCONGRATULATIONS Player X won the game"); + return; + } + + current_player = 'O'; + + } else { + computermove(board); + + + if(checkwin(board,'O')) { + score.computer++; + print_board(board); + + printf("\nCONGRATULATIONS Player O (COMPUTER) won the game"); + return; + } + + current_player = 'X'; + } + + if(checkdraw(board)){ + score.draw++; + print_board(board); + + printf("\nIts a draw!"); + return; + } + } + } } - } + +int validmove(char board[3][3], int row, int col){ + return !(row < 0 || + row > 2 || + col < 0 || + col > 2 || + board[row][col] != ' '); } -int is_valid_move(char board[BOARD_SIZE][BOARD_SIZE], int row, int col) { - return !(row < 0 || col < 0 || - row > 2 || col > 2 || - board[row][col] != ' '); + +void two_player_move(char board[3][3], char player){ + + int row, col; + + do{ + printf("\nPlayer %c's turn", player); + printf("\nEnter row and column (1-3) for %c : ", player); + scanf(" %d %d", &row, &col); + + row--; + col--; + } while(!validmove(board, row, col)); + + board[row][col] = player; + } -void player_move(char board[BOARD_SIZE][BOARD_SIZE]) { - int count = 0, x, y; - for (int i = 0; i < BOARD_SIZE; i++) { - for (int j = 0; j < BOARD_SIZE; j++) { - if (board[i][j] == ' ') { - count++; - x = i; - y = j; - } - } +void playermove(char board[3][3]){ + + int count = 0, x, y; + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + if(board[i][j] == ' '){ + count++; + x = i; + y = j; + } + } + } + + if(count == 1){ + board[x][y] = 'X'; + return; + } + + int row, col; + do { + printf("\nPlayer X's turn"); + + printf("\nEnter row and column (1-3) for X : "); + scanf(" %d", &row); + scanf(" %d", &col); + + row--; + col--; + + }while(!validmove(board, row, col)); + + board[row][col] = 'X'; +} + +void computermove(char board[3][3]){ + + // 1.IMMEDIATE WIN + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + + if(board[i][j] == ' '){ + board[i][j] = 'O'; + if(checkwin(board, 'O')){ + return; + } + board[i][j] = ' '; + } + } } + - if (count == 1) { - board[x][y] = X; - return; + // 2.IMMEDIATE BLOCK + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + + if(board[i][j] == ' '){ + board[i][j] = 'X'; + if(checkwin(board, 'X')){ + board[i][j] = 'O'; + return; + } + board[i][j] = ' '; + } + } } - int row, col; - do { - printf("\nPlayer X's turn."); - printf("\nEnter row and column (1-3) for X: "); - scanf("%d", &row); - scanf("%d", &col); - row--; col--; // converting to zero based - } while (!is_valid_move(board, row, col)); - board[row][col] = X; -} + if(difficulty == 2){ + -void computer_move(char board[BOARD_SIZE][BOARD_SIZE]) { - // 1. Play for Immediate win - for (int i = 0; i < BOARD_SIZE; i++) { - for (int j = 0; j < BOARD_SIZE; j++) { - if (board[i][j] == ' ') { - board[i][j] = O; - if (check_win(board, O)) { - return; + //3. TAKE CENTER IF POSSIBLE + if(board[1][1] == ' '){ + board[1][1] = 'O'; + return; + } + + // 4.Take opposite corner if player took one corner + if(board[0][0] == 'X' && board[2][2] == ' '){ + board[2][2] = 'O'; + return; + } + if(board[2][2] == 'X' && board[0][0] == ' '){ + board[0][0] = 'O'; + return; + } + if(board[0][2] == 'X' && board[2][0] == ' '){ + board[2][0] = 'O'; + return; + } + if(board[2][0] == 'X' && board[0][2] == ' '){ + board[0][2] = 'O'; + return; } - board[i][j] = ' '; - } - } - } - // 2. Play for Immediate Block - for (int i = 0; i < BOARD_SIZE; i++) { - for (int j = 0; j < BOARD_SIZE; j++) { - if (board[i][j] == ' ') { - board[i][j] = X; - if (check_win(board, X)) { - board[i][j] = O; - return; + + // 5.If player takes opposite corners, take any side to prevent fork + if((board[0][0] == 'X' && board[2][2] == 'X') || + (board[0][2] == 'X' && board[2][0] == 'X')){ + if(board[0][1] == ' '){ + board[0][1] = 'O'; + return; + } + if(board[1][0] == ' '){ + board[1][0] = 'O'; + return; + } + if(board[1][2] == ' '){ + board[1][2] = 'O'; + return; + } + if(board[2][1] == ' '){ + board[2][1] = 'O'; + return; + } } - board[i][j] = ' '; - } - } - } - // GOD Mode - if (difficulty == 2) { - // 3. Play Center if available - if (board[1][1] == ' ') { - board[1][1] = O; - return; - } - // 4. Play Corner if available - int corner[4][2] = { - {0, 0}, - {0, 2}, - {2, 0}, - {2, 2} - }; - for (int i = 0; i < 4; i++) { - if (board[corner[i][0]][corner[i][1]] == ' ') { - board[corner[i][0]][corner[i][1]] = O; - return; - } - } - } + // 6.Prioritize remaining corners - // 5. Play first available move - for (int i = 0; i < BOARD_SIZE; i++) { - for (int j = 0; j < BOARD_SIZE; j++) { - if (board[i][j] == ' ') { - board[i][j] = O; - return; - } - } - } -} + if(board[0][0] == ' '){ + board[0][0] = 'O'; + return; + } + + if(board[0][2] == ' '){ + board[0][2] = 'O'; + return; + } + + if(board[2][0] == ' '){ + board[2][0] = 'O'; + return; + } + + if(board[2][2] == ' '){ + board[2][2] = 'O'; + return; + } -int check_win(char board[BOARD_SIZE][BOARD_SIZE], char player) { - for (int i = 0; i < BOARD_SIZE; i++) { - if (board[i][0] == player && board[i][1] == player && board[i][2] == player) { - return 1; - } - if (board[0][i] == player && board[1][i] == player && board[2][i] == player) { - return 1; + + // 7.Take sides if no corner is free + if(board[0][1] == ' '){ + board[0][1] = 'O'; + return; + } + if(board[1][0] == ' '){ + board[1][0] = 'O'; + return; + } + if(board[1][2] == ' '){ + board[1][2] = 'O'; + return; + } + if(board[2][1] == ' '){ + board[2][1] = 'O'; + return; + } +} + //8.TAKE FIRST AVAIABLE MOVE + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + + if(board[i][j] == ' '){ + board[i][j] = 'O'; + return; + } + } } - } + +} - if ((board[0][0] == player && board[1][1] == player && board[2][2] == player) || - (board[2][0] == player && board[1][1] == player && board[0][2] == player)) { - return 1; - } - return 0; +int checkdraw(char board[3][3]){ + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + if(board[i][j] == ' '){ + return 0; + } + } + } + + return 1; } -int check_draw(char board[BOARD_SIZE][BOARD_SIZE]) { - for (int i = 0; i < BOARD_SIZE; i++) { - for (int j = 0; j < BOARD_SIZE; j++) { - if (board[i][j] == ' ') { - return 0; - } - } - } - return 1; +int checkwin(char board[3][3], char player){ + + for(int i = 0; i < 3; i++){ + if(board[i][0] == player && board[i][1] == player && board[i][2] == player){ + return 1; + } + + if(board[0][i] == player && board[1][i] == player && board[2][i] == player){ + return 1; + } + } + + if((board[0][0] == player && board[1][1] == player && board[2][2] == player) || + (board[0][2] == player && board[1][1] == player && board[2][0] == player)){ + + return 1; + } + + return 0; } -void print_board(char board[BOARD_SIZE][BOARD_SIZE]) { - clear_screen(); - printf("Score - Player X: %d, Computer: %d, Draws: %d", score.player, score.computer, score.draw); - printf("\nTic-Tac-Toe\n"); - - for (int i = 0 ; i < BOARD_SIZE; i++) { - printf("\n"); - for (int j = 0; j < BOARD_SIZE; j++) { - printf(" %c ", board[i][j]); - if (j < BOARD_SIZE - 1) { - printf("|"); - } - } - if (i < BOARD_SIZE - 1) { - printf("\n---+---+---"); - } - } - printf("\n\n"); +void print_board(char board[3][3]){ + + clear_screen(); + if(difficulty == 3) { + printf("Score : PLAYER X = %d , PLAYER O = %d , DRAW (O/X) = %d", + score.player, score.computer, score.draw); + } else { + printf("Score : PLAYER (X) = %d , COMPUTER (O) = %d , DRAW (O/X) = %d", + score.player, score.computer, score.draw); + } + + + printf("\n==================\nTIC_TAC_TOE (O/X)\n==================\n"); + + for(int i = 0; i < 3; i++){ + printf("\n"); + if(i != 0){ + printf("---+---+---\n"); + } + for(int j = 0; j < 3; j++){ + if(j != 0){ + printf("|"); + } + printf(" %c ", board[i][j]); + } + } + printf("\n\n"); } -void input_difficulty() { - while (1) { - printf("\nSelect difficulty level:"); - printf("\n1. Human (Standard)"); - printf("\n2. God (Impossible to win)"); - printf("\nEnter your choice: "); - scanf("%d", &difficulty); - - if (difficulty != 1 && difficulty != 2) { - printf("\nIncorrect choice enter (1/2)!!"); - } else { - break; - } - }; +void get_difficulty(){ + + while(1){ + printf("\n==================\nTIC_TAC_TOE (O/X)\n==================\n"); + printf("\nChoose difficulty level: "); + printf("\n1. Computer (Standard) "); + printf("\n2. Computer (Impossible To Win) "); + printf("\n3. Two Player Mode"); + printf("\nEnter your choice : "); + scanf(" %d", &difficulty); + + if(difficulty != 1 && difficulty != 2 && difficulty != 3){ + printf("\nInvalid input. Please enter (1/2/3):\n"); + } else { + break; + } + + } + } -void clear_screen() { - #ifdef _Win32 - system("cls"); - #else - system("clear"); - #endif -} \ No newline at end of file +void clear_screen(){ + + #ifdef _WIN32 + system("cls"); + + #else + system("clear"); + + #endif +}