Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Tic Tac Toe make move function

Subject: Tic Tac Toe make move function

From: Jian Du

Date: 13 Sep, 2010 11:29:04

Message: 1 of 6

Hey guys, first time posting hope I'm doing it right.

For an assignment I have to use Matlab to program a 'make move' function for a tic tac toe simulator.

There is another function called check_win which will check to see if a player has won, 1 for player 1 and -1 for player 2.

I need to write a 'make move' function that chooses the 'best' move to make. It needs to find the move that will win (if there is one) or choose a blocking move if the other opponent is one move away from winning (if there is one) otherwise make a random move.

Here is my code, commented with what it should work as, and my coding comments. Any help would be appreciated to see what is wrong with it (not filling up when making vector one move away from winning) and there are no errors.

I'm not sure if the break is used correctly, to escape the if statement and repeat the process.

function board = make_move(board, player)
%MAKE_MOVE Determine the next move of a player for tic tac toe
% Given a board setup and a player, determine the "best" move for the
% current player and update and return the board setup after this move
% has been made.
%
% The process is :
% 1. Find a winning position. If found, make the move and exit
% the function;
% 2. Find a position to block the other player from winning. If
% found, make the move and exit the function;
% 3. Otherwise, make a move to a random free location
%
 n= size(board,1);
 m= size(board,1);
 rand1 = randi(n);
 rand2 = randi(m);
done = 0;

while done ~= 1; % Checking to see if while loop should still be running
for i = 1:n % For each row
    for j = 1:m % For each column, in each row
        if board(i,j) == 0 % Is the vector 0, eg: empty?
            board(i,j) = player; % If it is, let's try making a move here with the player value
            check_win(board); % Is this a winning move? Has the game finished?
            if check_win(board) == player % If check_win says player value (1 or -1) has won, return
                return
            else % Let's try a blocking attempt
                board(j,i) = -1*player; % Switching the rows and column values around, and placing a move as opponent
                if check_win(board) == -1*player % Checking to see if this is a winning move for opponent
                    board(j,i) = player; % If this is a winning move, block it by placing your move here
                    return
                else % If cannot make winning move or cannot block a win
                    if board(m,n) == 0 % Use rand to generate vector position, checking to see if it is 0 (empty)
                        board(m,n) = player; % Place a move here
                        return
                    end
                end
            end
        else
            break
            done = 0; % Should restart the process again if the original vector is not empty
        end
    end
end
end

Subject: Tic Tac Toe make move function

From: Sean

Date: 13 Sep, 2010 13:06:04

Message: 2 of 6

"Jian Du" <jiandu1991@gmail.com> wrote in message <i6l1u0$kd9$1@fred.mathworks.com>...
> Hey guys, first time posting hope I'm doing it right.
>
> For an assignment I have to use Matlab to program a 'make move' function for a tic tac toe simulator.
>
> There is another function called check_win which will check to see if a player has won, 1 for player 1 and -1 for player 2.
>
> I need to write a 'make move' function that chooses the 'best' move to make. It needs to find the move that will win (if there is one) or choose a blocking move if the other opponent is one move away from winning (if there is one) otherwise make a random move.
>
> Here is my code, commented with what it should work as, and my coding comments. Any help would be appreciated to see what is wrong with it (not filling up when making vector one move away from winning) and there are no errors.
>
> I'm not sure if the break is used correctly, to escape the if statement and repeat the process.
>
> function board = make_move(board, player)
> %MAKE_MOVE Determine the next move of a player for tic tac toe
> % Given a board setup and a player, determine the "best" move for the
> % current player and update and return the board setup after this move
> % has been made.
> %
> % The process is :
> % 1. Find a winning position. If found, make the move and exit
> % the function;
> % 2. Find a position to block the other player from winning. If
> % found, make the move and exit the function;
> % 3. Otherwise, make a move to a random free location
> %
> n= size(board,1);
> m= size(board,1);
> rand1 = randi(n);
> rand2 = randi(m);
> done = 0;
>
> while done ~= 1; % Checking to see if while loop should still be running
> for i = 1:n % For each row
> for j = 1:m % For each column, in each row
> if board(i,j) == 0 % Is the vector 0, eg: empty?
> board(i,j) = player; % If it is, let's try making a move here with the player value
> check_win(board); % Is this a winning move? Has the game finished?
> if check_win(board) == player % If check_win says player value (1 or -1) has won, return
> return
> else % Let's try a blocking attempt
> board(j,i) = -1*player; % Switching the rows and column values around, and placing a move as opponent
> if check_win(board) == -1*player % Checking to see if this is a winning move for opponent
> board(j,i) = player; % If this is a winning move, block it by placing your move here
> return
> else % If cannot make winning move or cannot block a win
> if board(m,n) == 0 % Use rand to generate vector position, checking to see if it is 0 (empty)
> board(m,n) = player; % Place a move here
> return
> end
> end
> end
> else
> break
> done = 0; % Should restart the process again if the original vector is not empty
> end
> end
> end
> end

The glory of MATLAB is that the endless loops aren't necessary:

function out = makeMove(in)
%SCd
%09/13/2010
%
%in is a 3x3 matrix (1 for player; 0 for open; computer is -1);

out = in; %set out == in to modify it

%first see if you can win
any_rows = sum(in==-1,2)==2 & any(in==0,2);
any_cols = sum(in==-1,1)==2 & any(in==0,1);
diagLU = sum(in([3,5,7])) == 2 & any(in([3 5 7])==0,2); %lower to upper
diagUL = sum(in([1,5,9])) == 2 & any(in([1 5 9])==0,2); %upper to lower

if any_rows
    out = out(any_rows,:)== -1;
elseif any_cols
    out = out(:,any_cols)== -1;
elseif diagUL
    out = out([1 5 9])== -1;
elseif diagLU
    out = out([3 5 7])== -1;
    
%If you can't win; make sure to block
%elseif do you need to block?
%You write this!
    
else
    %Find a random place == 0 and set it to -1
    out(randsample(find(in==0),1)) = -1;
end


end


%%%%%
Break down what was done in the definition of any_rows, any_cols etc. If you can wrap your head around the logic used there; writing how to find where to block is trivial.

To work on it; run each piece of each line with a sample 'in' matrix. It should be obvious. Use >>help any;>> help randample etc to figure out what those functions do!

Subject: Tic Tac Toe make move function

From: Sean

Date: 13 Sep, 2010 13:21:19

Message: 3 of 6

"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message
> The glory of MATLAB is that the endless loops aren't necessary:
>
> function out = makeMove(in)
> %SCd
> %09/13/2010
> %
> %in is a 3x3 matrix (1 for player; 0 for open; computer is -1);
>
> out = in; %set out == in to modify it
>

My fingers outran my brain! ;) The engine should read like this:
%Time for another cup of coffee

%first see if you can win
rows = sum(in==-1,2)==2 & any(in==0,2);
cols = sum(in==-1,1)==2 & any(in==0,1);
diagLU = sum(in([3,5,7])) == 2 & any(in([3 5 7])==0,2); %lower to upper
diagUL = sum(in([1,5,9])) == 2 & any(in([1 5 9])==0,2); %upper to lower

if any(rows)
    out(rows,:)= -1;
elseif any(cols)
    out(:,cols)= -1;
elseif diagUL
    out([1 5 9])= -1;
elseif diagLU
    out([3 5 7])= -1;
    
> %If you can't win; make sure to block
> %elseif do you need to block?
> %You write this!
>
> else
> %Find a random place == 0 and set it to -1
> out(randsample(find(in==0),1)) = -1;
> end
>
>
> end
>
>
> %%%%%
> Break down what was done in the definition of any_rows, any_cols etc. If you can wrap your head around the logic used there; writing how to find where to block is trivial.
>
> To work on it; run each piece of each line with a sample 'in' matrix. It should be obvious. Use >>help any;>> help randample etc to figure out what those functions do!

Subject: Tic Tac Toe make move function

From: Jian Du

Date: 13 Sep, 2010 14:20:21

Message: 4 of 6

Hi Sean,

Shouldn't I be referring to each position as in(1,1), in(1,2) ... in(3,3)? I'm not sure how they can be referred to as single digits in the engine part.

Thanks for the quick reply!

Jian

Subject: Tic Tac Toe make move function

From: Sean

Date: 13 Sep, 2010 14:44:22

Message: 5 of 6

"Jian Du" <jiandu1991@gmail.com> wrote in message <i6lbv5$35$1@fred.mathworks.com>...
> Hi Sean,
>
> Shouldn't I be referring to each position as in(1,1), in(1,2) ... in(3,3)? I'm not sure how they can be referred to as single digits in the engine part.
>
> Thanks for the quick reply!
>
> Jian

That would be one way to do it and it would be more "readable". What I used was linear indexing which allows for single indexes. The linear indices of a matrix work from 1:numel(matrix) working down the columns. Here's an example matrix with each linear index:
[1 4 7;
2 5 8;
3 6 9];

Thus if you type:
A = magic(3);
A(7)
You'll see that it returns 6 or the number in position (1,3).

In order to use row/col indexing like you said you would need to call sub2ind which converts your sub indices to liner indices; an added computation:
A(sub2ind(size(A),[1 2 3],[1 2 3]);

I didn't do this since for my example because 3x3 matrix is easy. If this was an nxn matrix where it's not easy to identify the linear indices I would've used what you suggested:
n = 100;
A = magic(n)
diagUL = A(sub2ind(size(A),1:n,1:n));
diagLU = A(sub2ind(size(A),n:-1:1,1:n);

I know this may be all above the scope of your project but it's important to know and understand for use in the MATLAB world.
Hope it helps!

Subject: Tic Tac Toe make move function

From: Jian Du

Date: 14 Sep, 2010 11:38:07

Message: 6 of 6

Hi Sean,

Thank you so much! I've altered the code to give two values (player 1 = 1, player 2 = -1) and places the moves accordingly.

For the blocking moves I checked to see if they were empty first (= 0) before placing a move. Its a little long but it works :P

Thanks again,
Jian

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us