📄 queen.m
字号:
function varargout = Queen(method, varargin)
% Queen The queen objects.
% This m-function contains the variables and methods for all queens.
%
% Inputs:
% * method ... What the queen instance wants (i.e move, best_move,init,...).
% * varargin ... parameters required for the method(i.e from, to, ...)
% * global board ... chess board and related information
%
% Outputs:
% * varargout ... outputs generated by the method (i.e. best move, legal move,...)
% * global board ... updated chess board and related information
%
% Example
% Add a white queen on field c4 [5,3].
% |Queen('init',[5 3],1,'Bc4')|
%
% Move the queen from c4 [5,3] to c5 [3 3].
% |Queen('move',[5 3],[3 3])|
%
% Determine the queens best move from c4
% |Queen('best_move',[5 3])|
%
% See also: Chess, legal_move, show, remove_figure, Value_of_Figure
%
%% Signature
% Author: W.Garn
% E-Mail: wgarn@yahoo.com
% Date: 2006/03/23 12:00:00
%
% Copyright 2006 W.Garn
%
if nargin<1
Chess;
return;
end
persistent pos; % nx2 matrix of all knights
persistent instances; % cell array - names of all the knights
persistent color; % array of colors (0=black,1=white)
persistent handle; % array of handles to knights
% classic example that there is a big difference beween object orientated
% languages and procedural languages. I have to take care of all the
% instances, hence instance variables myself.
% the escape route is to copy all the variables, which by the way is
% Matlabs object approach, but it's a lot of copying, persistent variables
% offer the reference approach, that is why I stick to it.
global board;
switch method
case 'clear'
pos = []; instances = []; color = [];
for k = 1:length(handle)
try delete(handle);
catch end
end
handle = [];
case 'init'
% varargin: 1: pos, 2: color, 3: instance
n = length(instances)+1; % which instance number
instances{n} = varargin{3};
pos = [pos; varargin{1}]; %matrix position (i.e. [2 3]=c7)
color = [color; varargin{2}]; %color
if color(n), fig='Q'; else fig='q'; end
if color(n), board.white(pos(n,1),pos(n,2))=9;
else board.black(pos(n,1),pos(n,2))=9; end
board.figures(pos(n,1),pos(n,2)) = fig;
handle = [handle, show('Queen',varargin{1},color(n))];
set(handle,'ButtonDownFcn','cursorListener(gcbo,[],guidata(gcbo))');
case 'legal_move'
varargout{1} = legal_move(varargin{1},varargin{2});
case 'move'
remove_figure( varargin{2} );
pos = move_figure(varargin{1}, varargin{2}, pos, handle);
case 'best_move'
from = varargin{1};
P = possible(from);
cur_color = getColor(from);
if cur_color %white
[b,gain] = best(P,board.black);
else %black
[b,gain] = best(P,board.white);
end
varargout{1}=b;
varargout{2}=gain;
case 'remove'
k = findPos(pos,varargin{1});
if ~isempty(k)
pos(k,:)=[];
instances(k)=[];
color(k)=[];
delete(handle(k));
handle(k)=[];
end
otherwise
disp('Method is not defined.');
end
%--------------------------------------
function pos = move_figure(from, to, pos, handle)
% from, to ... matrix notation
% moves the figure from a field to a other field
% it is assumed that the legality of the move was checked
% if a opponent figure is on the field it will be first removed.
global board
p = findPos(pos, from);
pos(p,:) = to;
setFiguresPosition(handle(p),to);
% set board
color = getColor(from);
% to
board.figures(to(1),to(2)) = board.figures(from(1),from(2));
if color %white
board.white(to(1),to(2)) = board.white(from(1),from(2));
else
board.black(to(1),to(2)) = board.black(from(1),from(2));
end
% from
board.figures(from(1),from(2)) = ' ';
if color %white
board.white(from(1),from(2)) = 0;
else
board.black(from(1),from(2)) = 0;
end
%--------------------------------------
function P = possible(from)
% checks whether there is no own figure on field
global board
logFlag=0;
P = [];
f1 = from(1); f2 = from(2);
color = getColor(from);
if color, opfig=board.black; else opfig=board.white; end
% check out all four directions
if logFlag, fprintf(1,'go down/left\n'); end
%go down/left matrix notation
eaten=0; t1=f1+1; t2=f2-1; no_own_figure=1;
while ~eaten && t1<=8 && t2>=1 && no_own_figure
if board.figures(t1,t2)==' '%free field
P=[P;[t1 t2]];
eaten = 0;
elseif opfig(t1,t2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t1 t2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t1=t1+1; t2=t2-1;
end
if logFlag, fprintf(1,'go up/left\n'); end
%go up/left matrix notation
eaten=0; t1=f1-1; t2=f2-1; no_own_figure=1;
while ~eaten && t1>=1 && t2>=1 && no_own_figure
if board.figures(t1,t2)==' '%free field
P=[P;[t1 t2]];
eaten = 0;
elseif opfig(t1,t2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t1 t2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t1=t1-1; t2=t2-1;
end
if logFlag, fprintf(1,'go down/right\n'); end
%go down/right matrix notation
eaten=0; t1=f1+1; t2=f2+1; no_own_figure=1;
while ~eaten && t1<=8 && t2<=8 && no_own_figure
if board.figures(t1,t2)==' '%free field
P=[P;[t1 t2]];
eaten = 0;
elseif opfig(t1,t2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t1 t2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t1=t1+1; t2=t2+1;
end
if logFlag, fprintf(1,'go up/right\n'); end
%go up/right matrix notation
eaten=0; t1=f1-1; t2=f2+1; no_own_figure=1;
while ~eaten && t1>=1 && t2<=8 && no_own_figure
if board.figures(t1,t2)==' '%free field
P=[P;[t1 t2]];
eaten = 0;
elseif opfig(t1,t2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t1 t2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t1=t1-1; t2=t2+1;
end
% check out all four directions
if logFlag, fprintf(1,'go down\n'); end
%go down
eaten=0; t=f1+1; no_own_figure=1;
while ~eaten && t<=8 && no_own_figure
if board.figures(t,f2)==' '%free field
P=[P;[t f2]];
eaten = 0;
elseif opfig(t,f2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t f2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t=t+1;
end
if logFlag, fprintf(1,'go up\n'); end
%go up
eaten=0; t=f1-1; no_own_figure=1;
while ~eaten && t>=1 && no_own_figure
if board.figures(t,f2)==' '%free field
P=[P;[t f2]];
eaten = 0;
elseif opfig(t,f2)>0 % eat opponents figure (if no other figure in between)
P=[P;[t f2]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t=t-1;
end
if logFlag, fprintf(1,'go left\n'); end
%go left
eaten=0; t=f2-1; no_own_figure=1;
while ~eaten && t>=1 && no_own_figure
if board.figures(f1,t)==' '%free field
P=[P;[f1 t]];
eaten = 0;
elseif opfig(f1,t)>0 % eat opponents figure (if no other figure in between)
P=[P;[f1 t]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t=t-1;
end
if logFlag, fprintf(1,'go right\n'); end
%go right
eaten=0; t=f2+1; no_own_figure=1;
while ~eaten && t<=8 && no_own_figure
if board.figures(f1,t)==' '%free field
P=[P;[f1 t]];
eaten = 0;
elseif opfig(f1,t)>0 % eat opponents figure (if no other figure in between)
P=[P;[f1 t]];
eaten = 1;
else % there is a own figure
no_own_figure = 0;
end
t=t+1;
end
%------------------------------------------------------------------
% Edis intelligence (ok. I admit, quite simple)
function [b,gain] = best(P, board)
% one move best
% Inputs:
% * board ... values of opponent
%
% Outputs:
% * b ... best field to go to
% * gain ... what the gain would be
b=[]; gain=-inf;
if ~isempty(P)
values = zeros(1, size(P,1));
for k = 1:size(P,1)
values(k) = board(P(k,1),P(k,2));
end
[M I] = max(values);
% take randomly one of the best
j = ceil(length(I)*rand); %(0,1]
b = P(I(j),:);
gain = values(I(j));
end
%------------------------------------------------------------------
function answer = legal_move(from, to)
P = possible(from);
I = find( sum((P == ones(size(P,1),1)*to),2) == 2 );
if isempty(I), answer=0; % not legal
else answer = 1; % legal move
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -