player vs ai tic-tac-toe game using minimax logic full code in matlab

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 chars
245 lines

You can run the code in a Matlab environment. Medical and home editions come with Matlab environment.

gistlibby LogSnag