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