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

📄 king.m

📁 国际象棋程序,解压到当前目录,在matlab窗口输入chess即可应用
💻 M
字号:
function varargout = King(method, varargin)
% King   The King objects.
% This m-function contains the variables and methods for all kings.
%
% Inputs:
% * method ... What the king 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 king on field c4 [5,3].
% |King('init',[5 3],1,'Bc4')|
%
% Move the king from c4 [5,3] to d5 [4 4].
% |King('move',[5 3],[4 4])|
%
% Determine the kings best move from c4
% |King('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='K'; else fig='k'; end
        if color(n), board.white(pos(n,1),pos(n,2))=inf;
        else board.black(pos(n,1),pos(n,2))=inf; end
        board.figures(pos(n,1),pos(n,2)) = fig;
        handle = [handle, show('King',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);
        % casteling
        if varargin{2}(2)-varargin{1}(2) > 1 %small
            from = [varargin{1}(1) 8];
            to = [varargin{1}(1) 6];
            Rook('move',from,to);
        elseif varargin{2}(2)-varargin{1}(2) < -1 %big
            from = [varargin{1}(1) 1];
            to = [varargin{1}(1) 4];
            Rook('move',from,to);            
        end        
    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
    case 'possible_moves'
        % returns all possible king moves without the king beeing checked.
        from = varargin{1};
        P = possible(from);
        % now look whether they are really possible
        R=[];
        for k=1:size(P,1)
            to = P(k,:);
            if ~is_in_check(from, to)
                R = [R; P(k,:)];
            end
        end
        varargout{1}=R; 
    case 'getPosition'
        in_color = varargin{1};
        I = find(color == in_color);
        varargout{1} = pos(I,:);
    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 T = toFields(from)
% determines all possibles fields within the board
% without regard whether there are other figures

%up,down,left,right - matrix notation
M = [[-1 -1 -1 1 1 1 0 0]',[-1 0 1 -1 0 1 -1 1]'];
e = ones(8,1);
D = e*from + M;
I = find ( sum((D > 0 & D < 9),2)==2 ); % only fields within the board
T = D(I,:);


%--------------------------------------
function P = possible(from)
% checks whether there is no own figure on field
global board

T = toFields(from);
color = getColor(from);
if color, ownfig=board.white; else ownfig=board.black; end
P =[];
for k = 1:size(T,1)
    if ownfig(T(k,1),T(k,2))==0
        if ~is_in_check(from, [T(k,:)]) % attention recursion
            P = [P; T(k,:)];
        end
    end
end

% casteling (careful close to recursion)
if color %white
    if from(1)==8 && from(2)== 5 % King is on original field
        if ~has_moved(from) % and has not moved yet
            
            % small casteling
            % fields are free
            a1=8; a2=6;   b1=8; b2=7;
            if board.black(a1,a2)+board.white(a1,a2) == 0 && ...
                board.black(b1,b2)+board.white(b1,b2) == 0     
                %then fields are free
                % but perhaps they are checked
                % whether King is in check, if it is moved
                if ~is_in_check(from, [a1 a2]) && ~is_in_check(from, [b1 b2])
                    if board.figures(8,8)=='R' % castle is there
                        if ~has_moved([8,8]) % and has not moved
                            P = [P; [8 7]];
                        end
                    end
                end
            end

            % big casteling
            % fields are free
            a1=8; a2=4;   b1=8; b2=3;
            if board.black(a1,a2)+board.white(a1,a2) == 0 && ...
                board.black(b1,b2)+board.white(b1,b2) == 0     
                %then fields are free
                % but perhaps they are checked
                % whether King is in check, if it is moved
                if ~is_in_check(from, [a1 a2]) && ~is_in_check(from, [b1 b2])
                    if board.figures(8,1)=='R' % castle is there
                        if ~has_moved([8,1]) % and has not moved
                            P = [P; [8 3]];
                        end
                    end
                end
            end
            
        end
    end
else
    if from(1)==1 && from(2)== 5 % King is on original field
        if ~has_moved(from) % and has not moved yet
            
            % small casteling
            % fields are free
            a1=1; a2=6;   b1=1; b2=7;
            if board.black(a1,a2)+board.white(a1,a2) == 0 && ...
                board.black(b1,b2)+board.white(b1,b2) == 0     
                %then fields are free
                % but perhaps they are checked
                % whether King is in check, if it is moved
                if ~is_in_check(from, [a1 a2]) && ~is_in_check(from, [b1 b2])
                    if board.figures(1,8)=='R' % castle is there
                        if ~has_moved([1,8]) % and has not moved
                            P = [P; [1 7]];
                        end
                    end
                end
            end

            % big casteling
            % fields are free
            a1=1; a2=4;   b1=1; b2=3;
            if board.black(a1,a2)+board.white(a1,a2) == 0 && ...
                board.black(b1,b2)+board.white(b1,b2) == 0     
                %then fields are free
                % but perhaps they are checked
                % whether King is in check, if it is moved
                if ~is_in_check(from, [a1 a2]) && ~is_in_check(from, [b1 b2])
                    if board.figures(1,1)=='R' % castle is there
                        if ~has_moved([1,1]) % and has not moved
                            P = [P; [1 3]];
                        end
                    end
                end
            end
            
        end
    end
    
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)
answer = 0;

P = possible(from); 
if ~isempty(P)
    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
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -