📄 tictactoe.m
字号:
function tictactoe(job)
% Pick15, TicTacToe, and Magic3.
%
% Pick15. Pick single digit numbers. Each digit can be chosen
% only once. Generate a total of 15 using exactly three digits.
%
% TicTacToe. Traditional X's and O's, but with blue and green.
% Try to get three in a row, column, or diagonal.
%
% Magic3. Magic square of order three shows that Pick15 and
% TicTacToe are actually the same game.
% The primary variables in the program are X, game, B, and job.
% X is a 3-by-3 matrix with X(i,j) =
% -1 for blue choices,
% 0 for not chosen yet,
% +1 for green choices.
% game =
% 1 for Pick15,
% 2 for TicTacToe,
% 3 for Magic3.
% B is a 3-by-3 array of handles for the numeric push buttons.
% job is initially empty and subsequently set by callbacks.
if nargin == 0
X = zeros(3,3);
game = 1;
B = buttons;
job = '';
else
[X,game,B] = getgame;
end
switch job
case 'green'
[i,j] = find(gcbo == B);
if winner(X) || X(i,j)
return
end
X(i,j) = 1;
savegame(X,game,B)
tictactoe('blue')
return
case 'blue'
if winner(X)
return
end
[i,j] = strategy(X,-1);
X(i,j) = -1;
case 'game'
game = mod(game,3)+1;
case 'start'
X = zeros(3,3);
case 'exit'
close(gcf)
return
end
savegame(X,game,B)
% ------------------------
function w = winner(X)
% w = winner(X) returns
% w = 0, no winner yet,
% w = -1, blue has won,
% w = 1, green has won,
% w = 2, game is a draw.
% In logical expressions, 0 is false and nonzero is true.
for w = [-1 1]
win = all(diag(X) == w) || all(diag(fliplr(X)) == w);
for k = 1:3
win = win || all(X(:,k) == w) || all(X(k,:) == w);
end
if win, return, end
end
if all(X(:) ~= 0)
w = 2;
else
w = 0;
end
% ------------------------
function [i,j] = winningmove(X,p);
% [i,j] = winningmove(X,p) finds any winning move for player p.
i = [];
j = [];
s = 2*p;
if sum(diag(X)) == s
i = find(diag(X) == 0);
j = i;
elseif sum(diag(fliplr(X))) == s
i = find(diag(fliplr(X)) == 0);
j = 4 - i;
else
for k = 1:3
if sum(X(:,k)) == s
i = find(X(:,k) == 0);
j = k;
break
elseif sum(X(k,:)) == s
i = k;
j = find(X(k,:) == 0);
break
end
end
end
% ------------------------
function [i,j] = strategy(X,p);
% [i,j] = strategy(X,p) is a good, but not perfect, move for player p.
% Appear to think.
pause(0.5)
% If possible, make a winning move.
[i,j] = winningmove(X,p);
% Block any winning move by opponent.
if isempty(i)
[i,j] = winningmove(X,-p);
end
% Otherwise, make a random move.
if isempty(i)
[i,j] = find(X == 0);
m = ceil(rand*length(i));
i = i(m);
j = j(m);
end
% ------------------------
function B = buttons
% Initialize push buttons and text.
clf
shg
B = zeros(3,3);
M = magic(3);
for k = 1:9
[i,j] = find(k == M);
B(i,j) = uicontrol('style','pushbutton','units','normal', ...
'fontsize',16,'callback','tictactoe(''green'')');
end
uicontrol('style','text','units','normal','pos',[0.30 0.82 0.40 0.10], ...
'fontsize',20,'background',get(gcf,'color'),'tag','toptext');
uicontrol('style','text','units','normal','pos',[0.20 0.72 0.60 0.10], ...
'fontsize',10,'background',get(gcf,'color'),'tag','toptext','string', ...
['Pick single digit numbers. Each digit can be chosen only once. ' ...
'Generate a total of 15 using exactly three digits.'])
uicontrol('style','pushbutton','units','normal','string','Game', ...
'fontsize',12,'position',[.23 .12 .15 .07], ...
'callback','tictactoe(''game'')');
uicontrol('style','pushbutton','units','normal','string','Start', ...
'fontsize',12,'position',[.43 .12 .15 .07], ...
'callback','tictactoe(''start'')');
uicontrol('style','pushbutton','units','normal','string','Exit', ...
'fontsize',12,'position',[.63 .12 .15 .07], ...
'callback','tictactoe(''exit'')');
% ------------------------
function [X,game,B] = getgame
% Restore the state of the game.
ud = get(gcf,'userdata');
X = ud{1};
game = ud{2};
B = ud{3};
% ------------------------
function savegame(X,game,B)
% Update the display and save the state of the game.
M = magic(3);
for k = 1:9
[i,j] = find(k == M);
switch game
case 1 % Pick15
pos = [0.10*k-0.055 0.50 0.10 0.1333];
str = int2str(k);
case 2 % TicTacToe
pos = [0.10*j+0.25 0.1333*(4-i)+0.17 0.10 0.1333];
str = '';
case 3 % Magic3
pos = [0.10*j+0.25 0.1333*(4-i)+0.17 0.10 0.1333];
str = int2str(k);
end
switch X(i,j)
case -1
bg = 'blue';
case 0
bg = 'white';
case 1
bg = 'green';
end
set(B(i,j),'position',pos,'string',str,'background',bg)
end
T = flipud(findobj(gcf,'tag','toptext'));
set(T(2),'visible','off')
switch winner(X)
case 0,
switch game
case 1, set(T(1),'string','Pick15')
set(T(2),'visible','on')
case 2, set(T(1),'string','TicTacToe')
case 3, set(T(1),'string','Magic3')
end
case -1, set(T(1),'string','Blue wins')
case 1, set(T(1),'string','Green wins')
case 2, set(T(1),'string','Draw')
end
set(gcf,'userdata',{X,game,B})
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -