summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2022-11-21 20:32:51 -0800
committerKai Stevenson <kai@kaistevenson.com>2022-11-21 20:32:51 -0800
commit5bda952a19edb1a51aa04bca9231c41d811af632 (patch)
tree4f2cbfac5c53851b930d0f998c670d82db44196c
parentbd1eef9e049982028b78934f0de16c7e4369bdc2 (diff)
minimax logic, dynamic move getters
-rw-r--r--ttt.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/ttt.c b/ttt.c
index 843f6a3..c6f63e4 100644
--- a/ttt.c
+++ b/ttt.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
void draw_board(int boardState[3][3]) {
for(int r = 0; r < 3; r++) {
char* line = calloc(3, 1);
@@ -103,7 +104,7 @@ int get_game_state(int boardState[3][3]) {
return 0;
}
}
-int* user_input_pos() {
+int* user_input_pos(int boardState[3][3], int turn) {
int* ip = malloc(2 * sizeof(int));
printf("Enter X coordinate");
scanf("%d", &ip[0]);
@@ -111,6 +112,51 @@ int* user_input_pos() {
scanf("%d", &ip[1]);
return ip;
}
+struct PosInfo {
+ int* pos;
+ int eval;
+};
+struct PosInfo minimax(int boardState[3][3], int turn) {
+ int eval;
+ int* bestMove = calloc(2, sizeof(int));
+ int s = get_game_state(boardState);
+ if(s == turn + 1) {
+ eval = 10;
+ }
+ else if(s == (!turn) + 1) {
+ eval = -10;
+ }
+ else if(s == 4) {
+ eval = 0;
+ }
+ else {
+ int eval = 0;
+ for(int r = 0; r < 2; r++) {
+ for(int c = 0; c < 2; c++) {
+ int[3][3] simBoard;
+ memcpy(simBoard, boardState, sizeof(boardState));
+ if(simBoard[c][r] == 0) {
+ simBoard[c][r] = turn + 1;
+ struct PosInfo i = minimax(simBoard, !turn);
+ if(i.eval > eval) {
+ eval = i.eval;
+ bestMove[0] = c;
+ bestMove[1] = r;
+ }
+ }
+ }
+ }
+ }
+ //don't forget to clean up bestmove pointers
+ struct PosInfo posInfo;
+ posInfo.eval = eval;
+ posInfo.pos = bestMove;
+ return posInfo;
+}
+int* ai_input_pos(int boardState[3][3], int turn) {
+ struct PosInfo i = minimax(boardState, turn);
+ return i.pos;
+}
void clear_screen()
{
system("@cls||clear");
@@ -118,10 +164,11 @@ void clear_screen()
int main() {
int board[3][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
int turn = 0;
+ int* (*get_move_ptrs[2])(int[3][3], int) = { &user_input_pos, &ai_input_pos };
while(1) {
clear_screen();
draw_board(board);
- int* tl = user_input_pos();
+ int* tl = get_move_ptrs[turn](board, turn);
board[tl[0] - 1][3 - tl[1]] = turn + 1;
free(tl);
int s = get_game_state(board);