tictactoe

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mtictactoe.h | 26+++++++++++++-------------
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; }