I'm making a tic tac toe game and I'm bombarded with various errors everytime I try to debug. I'm not sure where the problem is. The main error is either
Index exceeds matrix dimensions
or
Subscript indices must either be real positive integers or logicals
in line 8 of my 'checktaken' function. Below is my code, where tttGame is the main function, boardplot does the plotting, and checkwintest/check taken see if a position is taken or if there is a win. I have asked many people for help and most haven't a clue whats wrong. Examples/code of your answers will help. Thanks! Main function:
function tttGame
%%
%This function determines which players turn it is and whether there is a
%win or not
wonX = 0;
wonO = 0;
tttArray = zeros(3);
tttXArray = zeros(3);
tttOArray = zeros(3);
while wonX ~= 1 || wonO ~= 1
%%
%Initialize values
pXInputRow = 0;
pXInputCol = 0;
pOInputRow = 0;
pOInputCol = 0;
%%
%Show prompt to input values
pXInputRow = input('Player X Enter Row: ');
pXInputCol = input('Player X Enter Column: ');
%Plot and prompt Player X
boardplot(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol)
%Check taken location
checktaken(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol);
%If place is taken, prompt player to input again
if checktaken(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol) == 1
%Show prompt to input values
msgbox('That spot is taken')
pXInputRow = input('Enter Row: ');
pXInputCol = input('Enter Column: ');
%Otherwise, continue and change taken/player position on board
else
tttArray(pXInputRow, pXInputCol) = 1; %Set the position as taken
tttXArray(pXInputRow, pXInputCol) = 1; %Set the position for X
end
%Check if theres a win
checkwintest(tttXArray, tttOArray)
%Reset values
pXInputRow = 0;
pXInputCol = 0;
%%
%Show prompt to input values
pOInputRow = input('Player O Enter Row: ');
pOInputCol = input('Player O Enter Column: ');
%Prompt and plot Player O
boardplot(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol)
%Check taken location
checktaken(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol);
%If place is taken, prompt player to input again
if checktaken(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol) == 1
%Show prompt to input values
msgbox('That spot is taken')
pOInputRow = input('Enter Row: ');
pOInputCol = input('Enter Column: ');
%Otherwise, continue and change taken/player position on board
else
tttArray(pOInputRow, pOInputCol) = 1;%Set the position as taken
tttOArray(pOInputRow, pOInputCol) = 1;%Set the position for O;
end
%%
%Check win again
checkwintest(tttXArray, tttOArray)
%Reset values
pOInputRow = 0;
pOInputCol = 0;
end
end
Winning function
function [wonX, wonO] = checkwintest(tttXArray, tttOArray, tttGame)
%Test to see whether this format of win testing works
%Find any nonzero value in the tttX/OArray matrix. Returns 1 if true.
%All Columns, rows, diagonals
if any(all(tttXArray)) || any(all(tttXArray, 2)) || any(all(diag(tttXArray)))...
|| any(all(diag(fliplr((tttXArray)))));
wonX = 1;
elseif any(all(tttOArray)) || any(all(tttOArray, 2)) || any(all(diag(tttOArray)))...
|| any(all(fliplr(diag(tttOArray))));
wonO = 1;
else
wonX = 0;
wonO = 0;
end
%Send a message if a player won
if wonX == 1
playerXWonMessage = 'Congratulations Player X, you win!';
msgbox(playerXWonMessage)
exit(tttGame);
elseif wonO == 1
playerOWonMessage = 'Congratulations Player O, you win!';
msgbox(playerOWonMessage)
exit(tttGame);
end
end
Then
function [spotTaken] = checktaken(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol)
%Function used to check if spot is taken
%Setup Error Messages
errorMessage = 'This spot is taken, please choose another spot';
errorMessageTitle = 'Spot Taken';
spotTaken = 0;
if (tttArray(pXInputRow, pXInputCol) == 1) || (tttArray(pOInputRow, pOInputCol) == 1)
msgbox(errorMessage, errorMessageTitle)
spotTaken = 1;
end
end
and
function boardplot(tttArray, pXInputRow, pXInputCol, pOInputRow, pOInputCol)
%Setup the window for the game
close all;
clc;
figure('Name','Tic Tac Toe');
plot(-1. -1)
axis([0 3 0 3])
set(gca,'xTick',1:3)
set(gca,'yTick',1:3)
set(gca,'xTickLabel',[1 2 3])
set(gca,'yTickLabel',[1 2 3])
grid on
hold on
shg
%Plot
plot(pXInputRow - 0.5, pXInputCol - 0.5,'x', 'MarkerSize', 50)
hold on
plot(pOInputRow - 0.5, pOInputCol - 0.5,'o', 'MarkerSize', 50)
hold on
end
So I solved the problem and rewrote most of my code. First I did not pass the proper inputs to the function checktaken (and other functions) which obviously led to some errors. Then I rewrote my user input statements to use only 2 variables for rows/cols rather than 4, where there are 2 for each player. checktaken is rewritten as follows:
And I take the input via
and call it like this
where x and y are the rows/cols and can be used as matrix indices in checktaken. This prevented any matrix index errors and limited the issue with 'not enough input arguments'.