commit ccc8a5e9822326c15197e154340e307e18c5a48e
parent 812bd5d20a182ea1b6e3cb5dbc8a06ce7b203106
Author: Wilson Gheen <wilson@wilsonrgheen.com>
Date: Thu, 22 Dec 2022 12:55:11 -0600
End WIP. Finish (hopefully) unbeatable AI. No detected way for it to lose yet, but there is no random element to its moves
Diffstat:
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/tictactoe.h b/tictactoe.h
@@ -179,29 +179,29 @@ char get_winning_move_else_block_else_random(char *board, char player) {
}
static struct move minimax_best_move(char *board, char player, int *legal_moves, int lm_cnt) {
char winning_moves[10] = "";
- get_winner_or_winning_moves(board, winning_moves);
- int his_wm_cnt = 0;
int i;
+ char winner = get_winner_or_winning_moves(board, winning_moves);
+ int his_wm_cnt = 0;
+ int blocking_move = -1;
for(i=0; i < 9; i++) {
/* As good as won */
if((winning_moves[i] & player) == player) {
struct move m = {.move_ind = i, .winner = player};
return m;
}
- /* `player` can't block both moves, so it's a loss */
- if(winning_moves[i] == OPPONENT && ++his_wm_cnt > 1) {
- struct move m = {.move_ind = i, .winner = OPPONENT};
- return m;
+ if(winning_moves[i] == OPPONENT) {
+ his_wm_cnt++;
+ blocking_move = i;
}
}
- i = 0;
- for(int empties=0; i < 9; i++)
- if(board[i] == ' ' && ++empties > 2) break;
- if(i >= 9) {
+ if(lm_cnt <= 2) {
/* If there's <= 2 moves remaining, and no opportunity
- * to win next turn, it's a draw. (If the opponent has
- * exactly one winning move, we will block it.) */
- struct move m = {.move_ind = -1, .winner = 0};
+ * to win next turn, it's a draw. If the opponent has
+ * exactly one winning move, we will block it.
+ * If more than one, opponent wins. */
+ struct move m;
+ m.winner = his_wm_cnt > 1 ? OPPONENT : 0;
+ m.move_ind = his_wm_cnt > 0 ? blocking_move : legal_moves[0];
return m;
}