function varargout = tictactoe(varargin)
% TICTACTOE Application M-file for tictactoe.fig
% FIG = TICTACTOE launch tictactoe GUI.
% TICTACTOE('callback_name', ...) invoke the named callback.
% Last Modified by GUIDE v2.0 27-Nov-2001 16:22:23
if nargin == 0 % LAUNCH GUI
fig = openfig(mfilename,'reuse');
% Use system color scheme for figure:
set(fig,'Color',get(0,'defaultUicontrolBackgroundColor'));
% Generate a structure of handles to pass to callbacks, and store it.
handles = guihandles(fig);
handles.rows = zeros(2,8);
%rows field (n - player number):
%rows(n,1) - number of Xs or Os in the 1st row of the board
%rows(n,2) - number of Xs or Os in the 2nd row of the board
%rows(n,3) - number of Xs or Os in the 3rd row of the board
%rows(n,4) - number of Xs or Os in the 1st column of the board
%rows(n,5) - number of Xs or Os in the 2nd column of the board
%rows(n,6) - number of Xs or Os in the 3rd column of the board
%rows(n,7) - number of Xs or Os in the main diagonal of the board
%rows(n,8) - number of Xs or Os in the 2nd diagonal of the board
handles.game_is_over = 0; %0 - game is in process,
%1 - game is over
handles.movenum= 0; % move number
guidata(fig, handles);
if nargout > 0
varargout{1} = fig;
end
elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK
try
if (nargout)
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
else
feval(varargin{:}); % FEVAL switchyard
end
catch
disp(lasterr);
end
end
%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.
% --------------------------------------------------------------------
function varargout = pushbutton1_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,1) = handles.rows(turn,1) + 1;
handles.rows(turn,4) = handles.rows(turn,4) + 1;
handles.rows(turn,7) = handles.rows(turn,7) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton2_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,1) = handles.rows(turn,1) + 1;
handles.rows(turn,5) = handles.rows(turn,5) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton3_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,1) = handles.rows(turn,1) + 1;
handles.rows(turn,6) = handles.rows(turn,6) + 1;
handles.rows(turn,8) = handles.rows(turn,8) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton4_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,2) = handles.rows(turn,2) + 1;
handles.rows(turn,4) = handles.rows(turn,4) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton5_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,2) = handles.rows(turn,2) + 1;
handles.rows(turn,5) = handles.rows(turn,5) + 1;
handles.rows(turn,7) = handles.rows(turn,7) + 1;
handles.rows(turn,8) = handles.rows(turn,8) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton6_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,2) = handles.rows(turn,2) + 1;
handles.rows(turn,6) = handles.rows(turn,6) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton7_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,3) = handles.rows(turn,3) + 1;
handles.rows(turn,4) = handles.rows(turn,4) + 1;
handles.rows(turn,8) = handles.rows(turn,8) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton8_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,3) = handles.rows(turn,3) + 1;
handles.rows(turn,5) = handles.rows(turn,5) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton9_Callback(h, eventdata, handles, varargin)
if handles.game_is_over == 1
errordlg('Game is over! To start new game push ''New game'' button.')
elseif square_is_busy(h) ~= 1
turn = str2num(get(handles.text3,'String'));
set(h,'UserData',1)
handles.rows(turn,3) = handles.rows(turn,3) + 1;
handles.rows(turn,6) = handles.rows(turn,6) + 1;
handles.rows(turn,7) = handles.rows(turn,7) + 1;
guidata(handles.figure1,handles) % Save the handles structure
turn = make_move(h,turn,handles);
end
% --------------------------------------------------------------------
function varargout = pushbutton10_Callback(h, eventdata, handles, varargin)
pb_handles = findobj('Style','pushbutton');
for i = 2:10 %1st handle is for 'New game' button
set(pb_handles(i), 'String', '') %clear all squares
set(pb_handles(i), 'UserData', 0) %all squares are not busy
end
%set message to initial one - Player1's move
set(handles.text2,'ForegroundColor','r')
set(handles.text3,'ForegroundColor','r')
set(handles.text2,'String','Player')
set(handles.text3,'String','1')
set(handles.text7,'String',',')
set(handles.text4,'String', ...
'please make your move by clicking on one of the empty squares')
set(handles.text4,'FontWeight','normal')
set(handles.text4, 'HorizontalAlignment', 'left')
%start counting again
handles.rows = zeros(2,8);
handles.game_is_over = 0;
handles.movenum = 0;
guidata(handles.figure1,handles) % Save the handles structure
% --------------------------------------------------------------------
function turn = flip_turn(turn)
if turn == 1
turn = 2;
elseif turn == 2
turn = 1;
else
error('Turn error in flip_turn');
end
% --------------------------------------------------------------------
function turn = make_move(h,turn,handles)
handles.movenum = handles.movenum + 1;
guidata(handles.figure1,handles) % Save the handles structure
if turn == 1
set(h,'ForegroundColor','r')
set(h,'String','X')
if check_game_end(turn,handles) == 0
set(handles.text2,'ForegroundColor',[.25 .50 .25])
set(handles.text3,'ForegroundColor',[.25 .50 .25])
set(handles.text3,'String','2')
turn = flip_turn(turn);
end
elseif turn == 2
set(h,'ForegroundColor',[.25 .50 .25])
set(h,'String','O')
if check_game_end(turn,handles) == 0
set(handles.text2,'ForegroundColor','r')
set(handles.text3,'ForegroundColor','r')
set(handles.text3,'String','1')
turn = flip_turn(turn);
end
else
error('Turn error in make_move');
end
% --------------------------------------------------------------------
function e = check_game_end(turn,handles)
e = 0;
for i = 1:8
if handles.rows(turn,i) == 3
set(handles.text4,'FontWeight','demi')
set(handles.text4,'String','Congratulations! You win!')
e = 1;
handles.game_is_over = 1; %end of game
guidata(handles.figure1,handles) % Save the handles structure
break
end
end
if e == 0 & handles.movenum == 9
set(handles.text2,'String','')
set(handles.text3,'String','')
set(handles.text7,'String','')
set(handles.text4,'String','It''s a draw!')
set(handles.text4,'FontWeight','demi')
set(handles.text4, 'HorizontalAlignment', 'center')
e = 1;
handles.game_is_over = 1; %end of game
guidata(handles.figure1,handles) % Save the handles structure
end
% --------------------------------------------------------------------
function b = square_is_busy(h)
b = 0;
if get(h, 'UserData') == 1
errordlg('Please choose an empty square!')
b = 1;
end