No BSD License  

Highlights from
TicTacToe Game

image thumbnail
from TicTacToe Game by Victoria Brumberg
Building a GUI example

tictactoe(varargin)
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


Contact us at files@mathworks.com