main.m %% Tic-Tac-Toe Game with Minimax AI
% This is a MATLAB implementation of the Tic-Tac-Toe game with an AI player
% that uses the Minimax algorithm. This implementation is based on a 3x3
% board, but it can be easily modified to handle larger boards.
% First, we start by initializing the board, and displaying it:
board = ['-' '-' '-';
'-' '-' '-';
'-' '-' '-'];
print_board(board);
%% Minimax Algorithm for the AI Player
% The Minimax algorithm recursively searches the entire game tree, and
% selects the move that maximizes the AI player's expected outcome, given
% that the opponent also plays optimally. The algorithm is called Minimax,
% because it assumes that the opponent is trying to minimize the AI player's
% outcome, and it selects the move that maximizes the minimum outcome.
%
% The Minimax algorithm can be implemented using recursion, but since we are
% dealing with a relatively small game tree, we can use a simple iterative
% algorithm that evaluates all the possible moves in order, and selects the
% best one.
function [score, best_row, best_col] = minimax(board, depth, maximizing_player)
% Returns the optimal score, row, and col for the maximizing player
% (1), or the minimizing player (-1)
% First, we check whether we have reached a terminal state (win or draw),
% or a maximum search depth:
if check_win(board, 'X')
score = 1;
return;
elseif check_win(board, 'O')
score = -1;
return;
elseif check_draw(board)
score = 0;
return;
elseif depth == 0
score = evaluate(board);
return;
end
% If we haven't reached a terminal state or a maximum search depth, we
% continue with the search:
if maximizing_player
% We are currently maximizing player (X)
best_score = -Inf;
for i = 1:3
for j = 1:3
if board(i,j) == '-'
board(i,j) = 'X';
[score, ~, ~] = minimax(board, depth-1, false);
board(i,j) = '-';
if score > best_score
best_score = score;
best_row = i;
best_col = j;
end
end
end
end
score = best_score;
else
% We are currently minimizing player (O)
best_score = Inf;
for i = 1:3
for j = 1:3
if board(i,j) == '-'
board(i,j) = 'O';
[score, ~, ~] = minimax(board, depth-1, true);
board(i,j) = '-';
if score < best_score
best_score = score;
best_row = i;
best_col = j;
end
end
end
end
score = best_score;
end
end
%% Game Loop with Minimax AI
% Now that we have implemented the Minimax algorithm, we can use it to play
% the game. We loop over the players, and alternately play the X player
% and the O player.
turn = 'X';
num_moves = 0;
while ~check_win(board, 'X') && ~check_win(board, 'O') && ~check_draw(board)
if turn == 'X'
% X Player's turn:
% First, we let the player choose the move:
[row,col] = get_player_move(board, turn);
% Then, we make the move:
board(row,col) = turn;
% Increment the number of moves:
num_moves = num_moves + 1;
else
% O Player's turn:
% We use the Minimax algorithm to choose the best move for the AI player:
depth = numel(find(board == '-'));
[score, row, col] = minimax(board, depth, false);
% Then, we make the move:
board(row,col) = turn;
% Increment the number of moves:
num_moves = num_moves + 1;
end
% Print the board after the move:
print_board(board);
% Switch the turn to the other player:
if turn == 'X'
turn = 'O';
else
turn = 'X';
end
end
% Check the game outcome:
if check_win(board, 'X')
fprintf('X Wins!\n');
elseif check_win(board, 'O')
fprintf('O Wins!\n');
else
fprintf('Draw!\n');
end
%% Helper Functions
% Here are the helper functions used in the main code:
% Print the board
function print_board(board)
fprintf(' %c | %c | %c \n', board(1,:));
fprintf('---+---+---\n');
fprintf(' %c | %c | %c \n', board(2,:));
fprintf('---+---+---\n');
fprintf(' %c | %c | %c \n', board(3,:));
fprintf('\n');
end
% Check if the game is a draw
function result = check_draw(board)
result = isempty(find(board == '-'));
end
% Check if the game is won by a player
function result = check_win(board, player)
if board(1,1) == player && board(1,2) == player && board(1,3) == player
result = true;
elseif board(2,1) == player && board(2,2) == player && board(2,3) == player
result = true;
elseif board(3,1) == player && board(3,2) == player && board(3,3) == player
result = true;
elseif board(1,1) == player && board(2,1) == player && board(3,1) == player
result = true;
elseif board(1,2) == player && board(2,2) == player && board(3,2) == player
result = true;
elseif board(1,3) == player && board(2,3) == player && board(3,3) == player
result = true;
elseif board(1,1) == player && board(2,2) == player && board(3,3) == player
result = true;
elseif board(3,1) == player && board(2,2) == player && board(1,3) == player
result = true;
else
result = false;
end
end
% Get the player's move
function [row,col] = get_player_move(board, turn)
fprintf('%s Player''s turn\n', turn);
valid_input = false;
while ~valid_input
row = input('Enter row: ');
col = input('Enter column: ');
if board(row,col) ~= '-'
fprintf('Invalid move: slot is already occupied\n');
else
valid_input = true;
end
end
end
% Evaluate the board
function score = evaluate(board)
% This is a heuristic function that evaluates the board and returns a
% score for the Max player. It counts the number of open lines that are
% in danger of being blocked by the Min player, and the number of open
% lines that are threatening to win for the Max player.
% Count the number of open lines for each player:
max_open_lines = count_open_lines(board, 'X');
min_open_lines = count_open_lines(board, 'O');
% Compute the score as the difference between the Max player's open
% lines and the Min player's open lines:
score = max_open_lines - min_open_lines;
end
% Count the number of open lines for a player
function open_lines = count_open_lines(board, player)
% Count the number of open rows, columns, and diagonals for a player
open_rows = 0;
open_cols = 0;
open_diag1 = true;
open_diag2 = true;
for i = 1:3
if all(board(i,:) == player) || all(board(:,i) == player)
% A row or column is filled by the player
open_rows = open_rows + 1;
end
if board(i,i) ~= player
open_diag1 = false;
end
if board(i,4-i) ~= player
open_diag2 = false;
end
end
open_diag = open_diag1 || open_diag2;
open_lines = open_rows + open_cols + open_diag;
end
8246 chars245 lines
You can run the code in a Matlab environment. Medical and home editions come with Matlab environment.
gistlibby LogSnag