⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queen.m

📁 该程序提供了一个计算机下国际象棋的功能
💻 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 + -