Last active
August 9, 2024 07:32
-
-
Save Lain62/bd932f13dc7ac6f5acf605e064322eca to your computer and use it in GitHub Desktop.
This is actually overengineered as hell istg and its AWFUL DONT USE AS REFERENCE PLEASE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdio.h" | |
#include "stdlib.h" | |
#include "time.h" | |
int WinningCondition[8][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {1, 4, 7}, {2, 5, 8}, {3, 6, 9}, {1, 5, 9}, {7, 5, 3}}; | |
typedef enum | |
{ | |
Xmarker, | |
Omarker | |
} Marker; | |
typedef enum | |
{ | |
BlankBoardTile = 0, | |
HoriBoardTile = 1, | |
VertiBoardTile = 2, | |
PlayerBoardTile = 3, | |
InputBoardTile = 4 | |
} MainboardRender; | |
// 7 x 7 board that looks like this | |
// - - - | |
// | | | | | |
// 1 2 3 | |
// | | | | | |
// 4 5 6 | |
// | | | | | |
// 7 8 9 | |
MainboardRender MainBoard[49] = { | |
0, 1, 0, 1, 0, 1, 0, 2, 3, 2, 3, 2, 3, 2, 0, 4, 0, 4, 0, 4, 0, 2, 3, 2, 3, | |
2, 3, 2, 0, 4, 0, 4, 0, 4, 0, 2, 3, 2, 3, 2, 3, 2, 0, 4, 0, 4, 0, 4, 0}; | |
typedef enum | |
{ | |
BlankTile, | |
UserTile, | |
ComputerTile | |
} TileState; | |
typedef enum | |
{ | |
UserTurn, | |
ComputerTurn | |
} CurrentTurn; | |
typedef struct Player | |
{ | |
Marker marker; | |
int tileBank[9]; | |
} Player; | |
char parseMarker(Marker marker); | |
Marker getUserMarker(); | |
Marker getComputerMarker(Marker userMarker); | |
void renderMainBoard(TileState gameBoard[9], Marker userMarker, | |
Marker computerMarker); | |
// im not sure if this is efficient but im bruteforcing it | |
// 0 == no win | |
// 1 == win found | |
int checkIfTileBankWin(int tileBank[]); | |
void placeMarker(TileState gameBoard[], int pos, CurrentTurn turn); | |
void playRound(TileState gameBoard[], Player *user, Player *computer, CurrentTurn firstTurn, int *turnNumber); | |
int getComputerInput(TileState gameBoard[]); | |
int getUserInput(TileState gameBoard[]); | |
int main() | |
{ | |
srand(time(NULL)); | |
printf("Welcome to tictactoe!\n"); | |
TileState gameBoard[9] = {BlankTile}; | |
Player userPlayer = {getUserMarker(), {0}}; | |
Player computerPlayer = {getComputerMarker(userPlayer.marker), {0}}; | |
CurrentTurn firstTurn = UserTurn; | |
int turnNumber = 0; | |
// renderMainBoard(gameBoard, userPlayer.marker, computerPlayer.marker); | |
if (userPlayer.marker == Xmarker) | |
firstTurn = UserTurn; | |
else | |
firstTurn = ComputerTurn; | |
renderMainBoard(gameBoard, userPlayer.marker, computerPlayer.marker); | |
while (turnNumber < 9) | |
{ | |
printf("turn %d\n", turnNumber); | |
playRound(gameBoard, &userPlayer, &computerPlayer, firstTurn, &turnNumber); | |
renderMainBoard(gameBoard, userPlayer.marker, computerPlayer.marker); | |
} | |
if (turnNumber == 9) | |
{ | |
printf("Its a draw!"); | |
return 0; | |
} | |
} | |
int getComputerInput(TileState gameBoard[]) | |
{ | |
int i = (rand() % 9) + 1; | |
while (gameBoard[i - 1] != BlankTile) | |
{ | |
i = (rand() % 9) + 1; | |
} | |
return i; | |
} | |
int getUserInput(TileState gameBoard[]) | |
{ | |
int i = 0; | |
printf("Your turn!\n"); | |
while (i <= 0 || i > 9 || gameBoard[i - 1] != BlankTile) | |
{ | |
printf("Please choose a number between 1-9: "); | |
scanf(" %d", &i); | |
} | |
return i; | |
} | |
void playRound(TileState gameBoard[], Player *user, Player *computer, CurrentTurn firstTurn, int *turnNumber) | |
{ | |
if (firstTurn == UserTurn) | |
{ | |
int i = getUserInput(gameBoard); | |
int j = 0; | |
while (user->tileBank[j] != 0) | |
{ | |
j++; | |
} | |
user->tileBank[j] = i; | |
placeMarker(gameBoard, i - 1, UserTurn); | |
int k = checkIfTileBankWin(user->tileBank); | |
if (k == 1) | |
{ | |
renderMainBoard(gameBoard, user->marker, computer->marker); | |
printf("You win!\n"); | |
exit(EXIT_SUCCESS); | |
} | |
*turnNumber = *turnNumber + 1; | |
if (*turnNumber == 9) | |
{ | |
return; | |
} | |
int a = getComputerInput(gameBoard); | |
int b = 0; | |
while (computer->tileBank[b] != 0) | |
{ | |
b++; | |
} | |
computer->tileBank[b] = a; | |
placeMarker(gameBoard, a - 1, ComputerTurn); | |
int c = checkIfTileBankWin(user->tileBank); | |
if (c == 1) | |
{ | |
renderMainBoard(gameBoard, user->marker, computer->marker); | |
printf("You Lost!\n"); | |
exit(EXIT_SUCCESS); | |
} | |
*turnNumber = *turnNumber + 1; | |
if (*turnNumber == 9) | |
{ | |
return; | |
} | |
} | |
else if (firstTurn == ComputerTurn) | |
{ | |
int a = getComputerInput(gameBoard); | |
int b = 0; | |
while (computer->tileBank[b] != 0) | |
{ | |
b++; | |
} | |
computer->tileBank[b] = a; | |
placeMarker(gameBoard, a - 1, ComputerTurn); | |
int c = checkIfTileBankWin(computer->tileBank); | |
if (c == 1) | |
{ | |
renderMainBoard(gameBoard, user->marker, computer->marker); | |
printf("You Lost!\n"); | |
exit(EXIT_SUCCESS); | |
} | |
renderMainBoard(gameBoard, user->marker, computer->marker); | |
*turnNumber = *turnNumber + 1; | |
if (*turnNumber == 9) | |
{ | |
return; | |
} | |
int i = getUserInput(gameBoard); | |
int j = 0; | |
while (user->tileBank[j] != 0) | |
{ | |
j++; | |
} | |
user->tileBank[j] = i; | |
placeMarker(gameBoard, i - 1, UserTurn); | |
int k = checkIfTileBankWin(user->tileBank); | |
if (k == 1) | |
{ | |
renderMainBoard(gameBoard, user->marker, computer->marker); | |
printf("You win!\n"); | |
exit(EXIT_SUCCESS); | |
} | |
*turnNumber = *turnNumber + 1; | |
if (*turnNumber == 9) | |
{ | |
return; | |
} | |
} | |
} | |
void placeMarker(TileState gameBoard[], int pos, CurrentTurn turn) | |
{ | |
if (turn == UserTurn) | |
{ | |
gameBoard[pos] = UserTile; | |
} | |
else if (turn == ComputerTurn) | |
{ | |
gameBoard[pos] = ComputerTile; | |
} | |
else | |
{ | |
fprintf(stderr, "Error placing marker"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
char parseMarker(Marker marker) | |
{ | |
switch (marker) | |
{ | |
case Xmarker: | |
return 'X'; | |
case Omarker: | |
return 'O'; | |
default: | |
fprintf(stderr, "Error getting marker"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
Marker getUserMarker() | |
{ | |
int i = 0; | |
while (i <= 0 || i > 2) | |
{ | |
printf("Would you like to go first or second?\n"); | |
printf("answer 1 / 2\n"); | |
scanf(" %d", &i); | |
}; | |
if (i == 1) | |
{ | |
return Xmarker; | |
} | |
else if (i == 2) | |
{ | |
return Omarker; | |
} | |
else | |
{ | |
fprintf(stderr, "Error getting user turn marker"); | |
exit(EXIT_FAILURE); | |
} | |
}; | |
Marker getComputerMarker(Marker userMarker) | |
{ | |
if (userMarker == Xmarker) | |
{ | |
return Omarker; | |
} | |
else if (userMarker == Omarker) | |
{ | |
return Xmarker; | |
} | |
else | |
{ | |
fprintf(stderr, "Error getting computer turn marker"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
void renderMainBoard(TileState gameBoard[9], Marker userMarker, | |
Marker computerMarker) | |
{ | |
int currentInput = 1; | |
int currentMainBoardIndex = 0; | |
int currentGameBoardIndex = 0; | |
printf("================\n"); | |
for (int i = 0; i < 7; i++) | |
{ | |
for (int j = 0; j < 7; j++) | |
{ | |
switch (MainBoard[currentMainBoardIndex]) | |
{ | |
case BlankBoardTile: | |
printf(" "); | |
break; | |
case HoriBoardTile: | |
printf("-"); | |
break; | |
case VertiBoardTile: | |
printf("|"); | |
break; | |
case PlayerBoardTile: | |
switch (gameBoard[currentGameBoardIndex]) | |
{ | |
case BlankTile: | |
printf(" "); | |
break; | |
case UserTile: | |
printf("%c", parseMarker(userMarker)); | |
break; | |
case ComputerTile: | |
printf("%c", parseMarker(computerMarker)); | |
break; | |
default: | |
fprintf(stderr, "Error Rendering main board has gone wrong"); | |
exit(EXIT_FAILURE); | |
break; | |
} | |
currentGameBoardIndex++; | |
break; | |
case InputBoardTile: | |
printf("%d", currentInput); | |
currentInput++; | |
break; | |
default: | |
fprintf(stderr, "Error Rendering main board has gone wrong"); | |
exit(EXIT_FAILURE); | |
break; | |
} | |
currentMainBoardIndex++; | |
} | |
printf("\n"); | |
} | |
printf("================\n"); | |
} | |
int checkIfTileBankWin(int tileBank[]) | |
{ | |
if (tileBank[0] == 0) | |
{ | |
return 0; | |
} | |
if (tileBank[1] == 0) | |
{ | |
return 0; | |
} | |
if (tileBank[2] == 0) | |
{ | |
return 0; | |
} | |
for (int i = 0; i < 8; i++) | |
{ | |
int wins = 0; | |
for (int j = 0; j < 3; j++) | |
{ | |
int l = 0; | |
while (tileBank[l] != 0) | |
{ | |
if (tileBank[l] == WinningCondition[i][j]) | |
{ | |
wins++; | |
break; | |
} | |
l++; | |
} | |
} | |
if (wins == 3) | |
{ | |
return 1; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment