diff --git a/CMakeLists.txt b/CMakeLists.txt index ffd75686..0f757945 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ endif() # to configure and compile files in the respective folders add_subdirectory(hash) add_subdirectory(misc) +add_subdirectory(games) add_subdirectory(sorting) add_subdirectory(graphics) add_subdirectory(searching) diff --git a/games/CMakeLists.txt b/games/CMakeLists.txt new file mode 100644 index 00000000..ca45ee49 --- /dev/null +++ b/games/CMakeLists.txt @@ -0,0 +1,24 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) + +foreach( testsourcefile ${APP_SOURCES} ) + string( REPLACE ".c" "" testname ${testsourcefile} ) + string( REPLACE ".C" "" testname ${testname} ) + string( REPLACE " " "_" testname ${testname} ) + + add_executable( ${testname} ${testsourcefile} ) + + if(OpenMP_C_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_C) + endif() + + if(MATH_LIBRARY) + target_link_libraries(${testname} ${MATH_LIBRARY}) + endif() + install(TARGETS ${testname} DESTINATION "bin/games") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/games/tic-tac-toe.c b/games/tic-tac-toe.c new file mode 100644 index 00000000..c37db5f2 --- /dev/null +++ b/games/tic-tac-toe.c @@ -0,0 +1,438 @@ +/** + * @file tic-tac-toe.c + * @author [vivekboss99](github.com/vivekboss99) + * @author [Krishna Vedala](https://github.com/kvedala) + * @brief [Tic-Tac-Toe game](https://en.wikipedia.org/wiki/Tic-tac-toe) + * implementation in C + * @details Tic-Tac-Toe Game,where the user can decide to play with the + * computer(single player mode) or with other user(double player mode) , the + * code as an array named 'game_table' which is the table and user needs to enter the + * position inside the array(from 1-9) where he/she wants to place 'X' or 'O' on the + * table. + */ +#include +#include +#include + +// Functions Declarations +static void singlemode(); +static void doublemode(); +static void placex(int); // used for placing position of X by the 1st player +static void place(); // used by the computer to place O +static void placey(int); // used in Double Player mode by the 2nd player to + // place the position of O +int checkwin(); // checks everytime when a player or computer places 'X' or 'O' + +/** Tic-Tac-Toe table, so basically we are using variable 'game_table' as the table(size:3X3) and + * updating it regularly + */ +static char game_table[9]; + +/** + * Main program function. + * @returns 0 on clean exit. + * @note No checks are included for program execution failures! + */ +int main() +{ srand(time(NULL)); + int l = 0; + do + { + int n = 0; + + // filling the table with multiple asterisks + for (int i = 0; i < 9; i++) game_table[i] = '*'; + + // displaying the main menu + printf("***************************************\n"); + printf("*************TIC TAC TOE***************\n"); + printf("***************************************\n"); + printf("***********1. YOU vs COMPUTER ***********\n"); + printf("***********2. YOU vs PLAYER ***********\n"); + printf("***********3.EXIT *********************\n"); + printf("Enter your choice : "); + scanf("%d", &n); + + switch (n) // switch case to select between single player mode or + // double player mode + { + case 1: + singlemode(); + break; + case 2: + doublemode(); + break; + default: + printf("THANK YOU and EXIT!"); + } + + printf("Next game ? : "); + printf("Enter 1 – YES and 0 - NO "); + scanf("%d", &l); + + } while (l == 1); + + return 0; +} + +/** + * @brief Implementation of game vs computer + * + * @returns None + */ +void singlemode() +{ + int m; + int k = 0; + int table_fill_count=0; + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + printf("%c ", game_table[k]); + k++; + } + + printf("\n"); + } + + for (int x = 1; x < 10; x++) + { + k = 0; + + printf("Where would you like to place 'x' "); + scanf("%d", &m); + + placex(m); + if(table_fill_count<4) + { + place(); + } + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + printf("%c ", game_table[k]); + k++; + + } + + printf("\n"); + } + table_fill_count++; + int o = checkwin(); + + if (o == -1 || o == -2) + { + if (o == -1) + { + printf("YOU WIN\n"); + } + if (o == -2) + { + printf("YOU LOSE\n"); + } + + break; + } + + if (table_fill_count==4) + { + printf("\nDRAW "); + break; + } + } +} + +/** + * @brief Implementation of game vs another player. + * + * @returns None + */ +void doublemode() +{ + int m; + int e1; + int k = 0; + int doublemode_table_count=0; + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + printf("%c ", game_table[k]); + k++; + } + + printf("\n"); + } + for (int x = 1; x < 10; x++) + { + k = 0; + + printf("PLAYER1 - where would you like to place 'x' : "); + scanf("%d", &m); + + placex(m); + if(doublemode_table_count<4) + { + printf("PLAYER2 - where would you like to place 'o' : "); + scanf("%d", &e1); + + placey(e1); + } + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + printf("%c ", game_table[k]); + k++; + } + + printf("\n"); + } + doublemode_table_count++; + int o = checkwin(); + + if (o == -1 || o == -2) + { + if (o == -1) + { + printf("Player 1 WIN\n"); + } + if (o == -2) + { + printf("Player 2 WIN\n"); + } + + break; + } + if (doublemode_table_count==4) + { + printf("\nDRAW "); + break; + } + } +} + +/** + * @brief Update table by placing an `X` + * + * @param m location to place `X` + * + * @returns None + */ +void placex(int m) +{ + int n1; + if (m >= 1 && m <= 9) + { + if (game_table[m - 1] != 'x' && game_table[m - 1] != 'o') + { + game_table[m - 1] = 'x'; + } + else + { + printf("Invalid move\n"); + + printf("Enter new position : "); + scanf("%d", &n1); + + placex(n1); + } + } + else + { + printf("Invalid move \n"); + + printf("Enter new position : "); + scanf("%d", &n1); + + placex(n1); + } +} +/** + * @brief Update table by placing an `O` + * + * @returns None + */ +void place() +{ + + int e = rand() % 9; + + if (e >= 0 && e <= 8) + { + if (game_table[e] != 'x' && game_table[e] != 'o') + { + game_table[e] = 'o'; + printf("\n Computer placed at %d position\n", e + 1); + } + else + { + place(); + } + } +} +/** + * @brief Update table by placing an `O` + * + * @param e1 location to place `O` + * + * @returns None + */ +void placey(int e1) +{ + int n1; + if (e1 >= 1 && e1 <= 9) + { + if (game_table[e1 - 1] != 'x' && game_table[e1 - 1] != 'o') + { + game_table[e1 - 1] = 'o'; + } + else + { + printf("Invalid move \n"); + + printf("Enter new position : "); + scanf("%d", &n1); + + placey(n1); + } + } + else + { + printf("Invalid move \n"); + + printf("Enter new position : "); + scanf("%d", &n1); + + placey(n1); + } +} +/** + * @brief Implementation of win conditon checker for 'X' or 'O' whenever the table is updated + * + * @returns -1: if 'X' won + * @returns -2: if 'O' won + * @returns 0: if there is no win condition for 'X' or 'O' + */ +int checkwin() +{ + if (game_table[0] == game_table[1] && game_table[1] == game_table[2]) + { + if (game_table[0] == 'x' && game_table[1] == 'x' && + game_table[2] == 'x') + { + return -1; + } + + if (game_table[0] == 'o' && game_table[1] == 'o' && + game_table[2] == 'o') + { + return -2; + } + } + else if (game_table[0] == game_table[4] && game_table[4] == game_table[8]) + { + if (game_table[0] == 'x' && game_table[4] == 'x' && + game_table[8] == 'x') + { + return -1; + } + + if (game_table[0] == 'o' && game_table[4] == 'o' && + game_table[8] == 'o') + { + return -2; + } + } + else if (game_table[0] == game_table[3] && game_table[3] == game_table[6]) + { + if (game_table[0] == 'x' && game_table[3] == 'x' && + game_table[6] == 'x') + { + return -1; + } + + if (game_table[0] == 'o' && game_table[3] == 'o' && + game_table[6] == 'o') + { + return -2; + } + } + else if (game_table[3] == game_table[4] && game_table[4] == game_table[5]) + { + if (game_table[3] == 'x' && game_table[4] == 'x' && + game_table[5] == 'x') + { + return -1; + } + + if (game_table[3] == 'o' && game_table[4] == 'o' && + game_table[5] == 'o') + { + return -2; + } + } + else if (game_table[6] == game_table[7] && game_table[7] == game_table[8]) + { + if (game_table[6] == 'x' && game_table[7] == 'x' && + game_table[8] == 'x') + { + return -1; + } + + if (game_table[6] == 'o' && game_table[7] == 'o' && + game_table[8] == 'o') + { + return -2; + } + } + else if (game_table[1] == game_table[4] && game_table[4] == game_table[7]) + { + if (game_table[1] == 'x' && game_table[4] == 'x' && + game_table[7] == 'x') + { + return -1; + } + + if (game_table[1] == 'o' && game_table[4] == 'o' && + game_table[7] == 'o') + { + return -2; + } + } + else if (game_table[2] == game_table[5] && game_table[5] == game_table[8]) + { + if (game_table[2] == 'x' && game_table[5] == 'x' && + game_table[8] == 'x') + { + return -1; + } + + if (game_table[2] == 'o' && game_table[5] == 'o' && + game_table[8] == 'o') + { + return -2; + } + } + else if (game_table[2] == game_table[4] && game_table[4] == game_table[6]) + { + if (game_table[2] == 'x' && game_table[4] == 'x' && + game_table[6] == 'x') + { + return -1; + } + + if (game_table[2] == 'o' && game_table[4] == 'o' && + game_table[6] == 'o') + { + return -2; + } + } + return 0; +}