diff --git a/src/c/ticTacToe.c b/src/c/ticTacToe.c new file mode 100644 index 0000000..610a8ec --- /dev/null +++ b/src/c/ticTacToe.c @@ -0,0 +1,903 @@ +#include +#include +#include +#include + +#include "ticTacToe.h" + + +void printPrompt(){ + printf("Let's play Tic Tac Toe. You will use O, I will use X.\nJust enter the number of the field you choose as row col.\nYou start.\n"); +} + +void printField(char field[3][3]){ + for (int i = 0; i < 3; i++){ + for (int j = 0; j < 3; j++){ + printf("%c", field[i][j]); + if (j < 2) { + printf("|"); + } + } + printf("\n"); + } + printf("/n"); +} + +void initField(char field[3][3]) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + field[i][j] = '-'; + } + } +} + +void getPlayerInput(char field[3][3]){ + int row, col; + bool valid = false; + while (!valid){ + printf("Enter the field as row col: "); + scanf("%d %d", &row, &col); + row -= 1; + col -= 1; + if(validatePlayerInput(row, col)){ + field[row][col] = 'O'; + valid = validatePlayerInput(row, col); + } + } +} + +bool validatePlayerInput(int row, int col){ + if (row < 3 && row >= 0){ + if (col < 3 && col >= 0){ + return true; + } + } + return false; +} + +int wasGameWon(char field[3][3]){ + int winner = NOWINNERYET; + bool fieldFull = true; + for (int i = 0; i < 3; i++){ + for (int j = 0; j < 3; j++){ + if(field[i][j]=='-'){ + fieldFull = false; + } + } + } + if (fieldFull == true) winner = DRAW; + if(field[0][0] == 'O' || field[0][0] == 'X'){ + if (field[0][0] == field[0][1] && field[0][2] == field[0][1]){ + if (field[0][0] == 'O'){ + winner = PLAYER; + } + else if (field[0][0] == 'X'){ + winner = COMPUTER; + } + } + if (field[0][0] == field[1][0] && field[1][0] == field[2][0]){ + if (field[0][0] == 'O'){ + winner = PLAYER; + } + else if (field[0][0] == 'X'){ + winner = COMPUTER; + } + } + if (field[0][0] == field[1][1] && field[1][1] == field[2][2]){ + if (field[0][0] == 'O'){ + winner = PLAYER; + } + else if (field[0][0] == 'X'){ + winner = COMPUTER; + } + } + } + if(field[2][2] == 'O' || field[2][2] == 'X'){ + if (field[2][2] == field[2][1] && field[2][2] == field[2][0]){ + if (field[2][2] == 'O'){ + winner = PLAYER; + } + else if (field[2][2] == 'X'){ + winner = COMPUTER; + } + } + if (field[2][2] == field[1][2] && field[1][2] == field[0][2]){ + if (field[2][2] == 'O'){ + winner = PLAYER; + } + else if (field[2][2] == 'X'){ + winner = COMPUTER; + } + } + } + if(field[1][1] == 'O' || field[1][1] == 'X'){ + if (field[1][1] == field[0][1] && field[0][1] == field[2][1]){ + if (field[1][1] == 'O'){ + winner = PLAYER; + } + else if (field[1][1] == 'X'){ + winner = COMPUTER; + } + } + if (field[1][1] == field[1][0] && field[1][0] == field[1][2]){ + if (field[1][1] == 'O'){ + winner = PLAYER; + } + else if (field[1][1] == 'X'){ + winner = COMPUTER; + } + } + if (field[2][0] == field[1][1] && field[1][1] == field[0][2]){ + if (field[1][1] == 'O'){ + winner = PLAYER; + } + else if (field[1][1] == 'X'){ + winner = COMPUTER; + } + } + } + return winner; +} + +void getComputerInput(char field[3][3]){ + bool symbolSet = false, *pt = &symbolSet; + fillAlmostFull(field, pt); + while (!symbolSet){ + int row, col; + row = rand() % 3; + col = rand() % 3; + if (field[row][col] == '-'){ + field[row][col] = 'X'; + symbolSet = true; + } + } +} + + +void fillAlmostFull(char field[3][3], bool* pt) { + if (field[0][0] == 'X') { + if (field[0][1] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][0] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'X') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[0][1] == 'X') { + if (field[0][0] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[0][2] == 'X') { + if (field[0][0] == 'X') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][0] == 'X') { + if (field[1][1] == 'X') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][1] == 'X') { + if (field[1][0] == 'X') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'X') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'X') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'X') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][2] == 'X') { + if (field[1][0] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][0] == 'X') { + if (field[2][1] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'X') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][0] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][1] == 'X') { + if (field[2][0] == 'X') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][2] == 'X') { + if (field[2][0] == 'X') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'X') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'X') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'X') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'X') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'X') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + + if (field[0][0] == 'O') { + if (field[0][1] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][0] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'O') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[0][1] == 'O') { + if (field[0][0] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[0][2] == 'O') { + if (field[0][0] == 'O') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][0] == 'O') { + if (field[1][1] == 'O') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][1] == 'O') { + if (field[1][0] == 'O') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'O') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'O') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'O') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[2][0] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[1][2] == 'O') { + if (field[1][0] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[1][0] == '-'){ + field[1][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][0] == 'O') { + if (field[2][1] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'O') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[1][0] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][1] == 'O') { + if (field[2][0] == 'O') { + if( field[2][2] == '-'){ + field[2][2] = 'X'; + *pt = true; + return; + } + } + else if (field[2][2] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[0][1] == '-'){ + field[0][1] = 'X'; + *pt = true; + return; + } + } + else if (field[0][1] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } + if (field[2][2] == 'O') { + if (field[2][0] == 'O') { + if( field[2][1] == '-'){ + field[2][1] = 'X'; + *pt = true; + return; + } + } + else if (field[2][1] == 'O') { + if( field[2][0] == '-'){ + field[2][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][2] == 'O') { + if( field[1][2] == '-'){ + field[1][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][2] == 'O') { + if( field[0][2] == '-'){ + field[0][2] = 'X'; + *pt = true; + return; + } + } + else if (field[1][1] == 'O') { + if( field[0][0] == '-'){ + field[0][0] = 'X'; + *pt = true; + return; + } + } + else if (field[0][0] == 'O') { + if( field[1][1] == '-'){ + field[1][1] = 'X'; + *pt = true; + return; + } + } + } +} + +int play() { + printPrompt(); + int counter = 0; + char field[3][3]; + initField(field); + int winner = NOWINNERYET; + while (winner == NOWINNERYET) { + if (counter % 2 == 0) { + printField(field); + getPlayerInput(field); + winner = wasGameWon(field); + } + else if (counter % 2 == 1) { + printField(field); + getComputerInput(field); + winner = wasGameWon(field); + } + counter += 1; + } + printField(field); + printWinner(winner); + return winner; +} + +void printWinner(int winner){ + if(winner == PLAYER){ + printf("You won\n"); + } + else if(winner == COMPUTER){ + printf("I won\n"); + } + else if(winner == DRAW){ + printf("It's a draw\n"); + } +} \ No newline at end of file diff --git a/src/c/ticTacToe.h b/src/c/ticTacToe.h new file mode 100644 index 0000000..7033e57 --- /dev/null +++ b/src/c/ticTacToe.h @@ -0,0 +1,23 @@ +#ifndef TICTACTOE_H +#define TICTACTOE_H +#include + +enum Winner{ + PLAYER, + COMPUTER, + NOWINNERYET, + DRAW +}; + +void printPrompt(); +void printField(char field[3][3]); +void initField(char field[3][3]); +void getPlayerInput(char field[3][3]); +bool validatePlayerInput(int row, int col); +int wasGameWon(char field[3][3]); +void getComputerInput(char field[3][3]); +void fillAlmostFull(char field[3][3], bool *pt); +int play(); +void printWinner(int winner); + +#endif \ No newline at end of file diff --git a/test/c/test_ticTacToe.c b/test/c/test_ticTacToe.c new file mode 100644 index 0000000..140ce7a --- /dev/null +++ b/test/c/test_ticTacToe.c @@ -0,0 +1,108 @@ +#ifdef TEST +#include "unity.h" +#include "ticTacToe.h" +#include + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_ticTacToe_validUserInput(void) +{ + /* arrange */ + bool result; + int row = 2, col = 0; + + /* act */ + result = validatePlayerInput(row, col); + + /* assert */ + TEST_ASSERT_EQUAL_INT(true, result); +} + +void test_ticTacToe_invalidUserInput(void) +{ + /* arrange */ + bool result; + int row = 1, col = 3; + + /* act */ + result = validatePlayerInput(row, col); + + /* assert */ + TEST_ASSERT_EQUAL_INT(false, result); +} + +void test_ticTacToe_playerWins(void) +{ + /* arrange */ + int result; + char field[][3] = { + {'O', 'O', '-'}, + {'-', 'O', '-'}, + {'-', '-', 'O'} + }; + + /* act */ + result = wasGameWon(field); + + /* assert */ + TEST_ASSERT_EQUAL_INT(PLAYER, result); +} + +void test_ticTacToe_ComputerWins(void) +{ + /* arrange */ + int result; + char field[][3] = { + {'X', '-', '-'}, + {'X', '-', '-'}, + {'X', '-', '-'} + }; + + /* act */ + result = wasGameWon(field); + + /* assert */ + TEST_ASSERT_EQUAL_INT(COMPUTER, result); +} + +void test_ticTacToe_NooneWins(void) +{ + /* arrange */ + int result; + char field[][3] = { + {'X', 'O', 'O'}, + {'O', 'X', 'X'}, + {'X', 'O', 'O'} + }; + + /* act */ + result = wasGameWon(field); + + /* assert */ + TEST_ASSERT_EQUAL_INT(DRAW, result); +} + +void test_ticTacToe_NoWinnerYet(void) +{ + /* arrange */ + int result; + char field[][3] = { + {'X', 'O', 'O'}, + {'O', '-', 'X'}, + {'X', 'O', 'O'} + }; + + /* act */ + result = wasGameWon(field); + + /* assert */ + TEST_ASSERT_EQUAL_INT(NOWINNERYET, result); +} + +#endif // TEST \ No newline at end of file