Othello

Othello Code: Table of Contents

 

Othello.m

bot_move.m

calc_pieces_to_capture.m

calculate_score.m

capture_pieces.m

check_direction.m

is_board_full.m

player_move.m

take_turn.m

*to run the game simpleGameEngine.m and OthelloNewBoard.png are also necessary

 

 

Othello.m

 

clc

clear

close all

 

% Initialize scene

my_scene = simpleGameEngine(‘OthelloNewBoard.png’,79,84);

 

% Set up variables to name various sprites

empty_sprite = 1;

black_sprite = 2;

white_sprite = 3;

 

% Display empty board

board_display = empty_sprite * ones(8,8);

 

% Display starting board

board_display(4,4) = white_sprite;

board_display(5,5) = white_sprite;

board_display(4,5) = black_sprite;

board_display(5,4) = black_sprite;

drawScene(my_scene,board_display)

 

% Set initial player types to people

player_1_type = 0;

player_2_type = 0;

 

% Input which players are bots

fprintf(‘Type 1 if player is a bot, type 0 if player is a person.\n’);

fprintf(‘Players are assumed to be people, unless specified.\n’);

player_1_type = input(‘Is player 1 a bot? [1/0]: ‘);

player_2_type = input(‘Is player 2 a bot? [1/0]: ‘);

 

% Take player turns

% As long as the board has at least one empty spot, continue gameplay

while ~is_board_full(board_display)

    board_display = take_turn(my_scene, board_display, white_sprite, black_sprite, player_1_type);

    if ~is_board_full(board_display)

    board_display = take_turn(my_scene, board_display, black_sprite, white_sprite, player_2_type);

    end

end

 

% Calculate the final score

score_white = calculate_score(board_display, white_sprite);

score_black = calculate_score(board_display, black_sprite);

 

% Display final scores

fprintf(‘Final Score: %i for white, %i for black.\n’, score_white, score_black)

 

% Display who wins

if score_white > score_black

    fprintf(‘White wins!\n’)

    fprintf(‘Black gets second place!\n’)

elseif score_white < score_black

    fprintf(‘Black wins!\n’)

    fprintf(‘White gets second place!\n’)

else fprintf(‘Tie! \nThe true winner was in your hearts the whole time!\n’)

    fprintf(‘Play again if that isnt good enough for you!\n’)

end

 

 

bot_move.m

 

function [row, column, pieces_to_capture] = bot_move(my_scene, board_display, player_color, opponent_color)

% Capture the maximum number of pieces possible

%   Establish that a move must capture at least one piece, or it is invalid

%   Create an array with all moves that capture the maximum number of pieces

%   Check each empty spot on the board to see if it is a valid move

%   Of the valid moves, add those which maximize pieces captured to the array above

%   Pick a random move out of those that maximize capturing

%   Return the randomly chosen row and column of the array of best moves

%   From the piece chosen to be played, return the pieces this play captures

    

    pause(1);

    empty_sprite = 1;

    best_moves = [];

    best_move_capture_count = 1;

    

    % Check every place on the board to see if it is empty

    for row = 1:8

        for column = 1:8

            if board_display(row, column) == empty_sprite

                % Once determined empty, calculate pieces captures form possible plays

                pieces_to_capture = calc_pieces_to_capture(board_display, row, column, player_color, opponent_color);

                capture_count = size(pieces_to_capture,1);

                % Replace the array of best moves with the new move if it captures more pieces

                if capture_count > best_move_capture_count

                    best_moves = [row, column;];

                    best_move_capture_count = capture_count;

                % Add the new move to the array of best move if it captures the same amount of pieces

                elseif capture_count == best_move_capture_count

                    best_moves = [best_moves; row, column;];

                % Ignore any moves that capture less pieces than the current best move

                end

            end

        end

    end

    

    % When at least one move is possible, choose a random move from the best moves array

    if ~isempty(best_moves)

        move_index = randi([1, size(best_moves,1)]);

        move = best_moves(move_index,:);

        % Return the row and column of chosen best move

        row = move(1);

        column = move(2);

        % Return pieces determined best move captures

        pieces_to_capture = calc_pieces_to_capture(board_display, row, column, player_color, opponent_color);

    else

        % Return no pieces to capture if there are no valid moves

        row = 0;

        column = 0;

        pieces_to_capture = [];

    end

end

 

 

calc_pieces_to_capture.m

 

function [pieces_to_capture] = calc_pieces_to_capture(board_display, row, column, player_color, opponent_color)

% Check all directions for opponent pieces

%   Call on check_direction and input coordinates for each direction

%   Add all opponent pieces found in check_direction to an array of points

%   Continue adding to the array as more opponents’ pieces are found

 

% check North

 pieces_to_capture = check_direction(board_display, row, column, player_color, opponent_color, -1, 0);

% check NorthEast

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, -1, 1)];

% check East

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, 0, 1)];

% check SouthEast

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, 1, 1)];

% check South

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, 1, 0)];

% check SouthWest

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, 1, -1)];

% check West

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, 0, -1)];

% check NorthWest

 pieces_to_capture = [pieces_to_capture; check_direction(board_display, row, column, player_color, opponent_color, -1, -1)];

 

end

 

 

calculate_score.m

 

function [score] = calculate_score(board_display, player_color)

% Count up the number of each players’ pieces once the game is finished

%   Check each place on the board for the pieces of the current players’ color

%   Add up all of the players’ pieces as they are found

%   End once every spot on the board has been checked

 

%   Setting the initial score as 0

    score = 0;

    for row = 1:8

        for column = 1:8

            %   Adding one to the players’ score upon finding one of their pieces

            if board_display(row,column) == player_color

                score = score + 1;

            end

        end

    end

end

 

 

capture_pieces.m

 

function [board_display] = capture_pieces(board_display, player_color, pieces_to_capture)

% Flip all opponents’ pieces flanked by the new piece and another of that color

%   Call pieces_to_capture to get an array of pieces

%   Change all pieces in the array to the current players’ color

 

    for i = 1:size(pieces_to_capture,1)

        piece = pieces_to_capture(i,:);

        board_display(piece(1), piece(2)) = player_color;

    end 

end

 

 

 

check_direction.m

 

function [pieces_to_capture] = check_direction(board_display, row, column, player_color, opponent_color, row_increment, column_increment)

% Create an array of pieces to be captured based on the piece just played

%   Going in one direction, check for opponent pieces

%   Add these pieces to an array until finding a spot without an opponents’ piece

 

% Using the direction given in calc_pieces_to_capture

row = row + row_increment;

column = column + column_increment;

idx = 1;

 

% Setting the initial array of pieces_to_capture as empty

pieces_to_capture = [];

 

    % Confirming that the placement is inside the board

    while row >= 1 && row <= 8 && column >= 1 && column <=8 && board_display(row, column) == opponent_color

        pieces_to_capture(idx,:) = [row column];

        idx = idx + 1;

        row = row + row_increment;

        column = column + column_increment;

    end

 

    if  row < 1 || row > 8 || column < 1 || column > 8 || board_display(row, column) ~= player_color

        pieces_to_capture = [];

    end  

end

 

 

 

is_board_full.m

 

function [board_full] = is_board_full(board_display)

% Check to see if there are any empty places on the board

%   Look for any empty places

%   If any empty spots are found, continue game

%   Otherwise, report that no empty spots were found

 

    empty_sprite = 1;

    for row = 1:8

        for column = 1:8

            if board_display(row, column) == empty_sprite

                board_full = 0;

                % Upon finding an empty place on the board, resume turn taking

                return;

            end

        end

    end

    % If no empty spots were found:

    board_full = 1;

end

 

 

player_move.m

 

function [row, column, pieces_to_capture] = player_move(my_scene, board_display, player_color, opponent_color)

% Take mouse input until the player selected a valid place to take a turn

%   Use bot_move.m to determine if the player has a valid move

%   Allow the player to place a piece on any empty spots that result in capturing at least one piece

%   Inform the player if they cannot take a move or select an invalid spot

%   End the players’ turn if they have no possible moves

 

    % Use bot_move to determine if the player has a possible move

    [row, column, pieces_to_capture] = bot_move(my_scene, board_display, player_color, opponent_color);

    % If there is at least one piece to capture, continue turn

    if ~isempty(pieces_to_capture)

        empty_sprite = 1;

        is_valid_move = false;

        while ~is_valid_move

            [row,column] = getMouseInput(my_scene);

            

            % If the spot clicked is empty, continue

            if board_display(row,column) == empty_sprite

                pieces_to_capture = calc_pieces_to_capture(board_display, row, column, player_color, opponent_color);

                

                % The move is valid when meeting the previous conditions and capturing at least one piece

                if ~isempty(pieces_to_capture)

                    is_valid_move = true;

                else

                    % Tell the player that their clicked spot is invalid because it does not capture any pieces

                    fprintf(‘Please select another spot, that will capture pieces.\n’)

                end

            else

                % Tell the player that their clicked spot is invalid because there is already a piece there

                fprintf(‘Please select another spot, not already taken.\n’)

            end

        end

    end

end

 

 

take_turn.m

 

function [board_display] = take_turn(my_scene, board_display, player_color, opponent_color, player_type)

% Alternate between white and black turns

%   Make sure the mouse input move is game legal

%   Flip captured pieces appropriately

%   Skip a players’ turn if they have no valid moves

 

    % Make bot_player_type a bot

    bot_player_type = 1;

    

    % If it is a bots’ turn, take the turn

    if player_type == bot_player_type

        [row, column, pieces_to_capture] = bot_move(my_scene, board_display, player_color, opponent_color);

    else

        % Allow the player to take a turn

        [row, column, pieces_to_capture] = player_move(my_scene, board_display, player_color, opponent_color);

    end

    

    % Checking to see if the current player has any valid moves

    if ~isempty(pieces_to_capture)

        % Place new piece

        board_display(row, column) = player_color;

        % Capturing pieces

        board_display = capture_pieces(board_display, player_color, pieces_to_capture);

        % Displaying the result of the turn on the game board

        drawScene(my_scene, board_display);

    else

        % Ending a players’ turn if they have no valid moves

        fprintf(‘Player does not have a valid move.\n’)

    end

end