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

📄 pawn.m

📁 国际象棋程序,解压到当前目录,在matlab窗口输入chess即可应用
💻 M
字号:
function varargout = Pawn(method, varargin)
% Pawn   The pawn objects.
% This m-function contains the variables and methods for all knights.
%
% Inputs:
% * method ... What the pawn 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 pawn on field c4 [5,3].
% |Pawn('init',[5 3],1,'Bc4')|
%
% Move the pawn from c4 [5,3] to c5 [3 3].
% |Pawn('move',[5 3],[3 3])|
%
% Determine the pawns best move from c4
% |Pawn('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
%
%% Last modifications
% * 30/3/2006 corrected removal of pawn
%
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;
global EDIs;
%logFlag=1; logFile=1;
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='P'; else fig='p'; end
        if color(n), board.white(pos(n,1),pos(n,2))=1;
        else board.black(pos(n,1),pos(n,2))=1; end
        board.figures(pos(n,1),pos(n,2)) = fig;
        handle = [handle, show('Pawn',varargin{1},color(n))];
        set(handle,'ButtonDownFcn','cursorListener(gcbo,[],guidata(gcbo))');
    case 'legal_move'
        varargout{1} = legal_move(varargin{1},varargin{2});
    case 'move'
        %if logFlag, fprintf(logFile,'Pawn will move from %s to %s.\n',matrix2chess(varargin{1}),matrix2chess(varargin{2})); end        
        % en passante
        from = varargin{1}; to = varargin{2};
        if abs(from(2)-to(2))==1 % pawn beats
            if board.figures(to(1),to(2))==' ' % there is no figure
                % then it is en passant
                remove_figure( [from(1), to(2)] );
            else
                remove_figure( varargin{2} );
            end
        end
        pos = move_figure(from, to , pos, handle);
        
        % possible transformation into other figure
        if to(1)==1 || to(1)==8
            % ask which figure 
            cur_color = getColor(to);
            if EDIs.color == cur_color, 
                fig='q'; 
            else                
                fig = ask_which_figure;
            end
            if cur_color, fig = upper(fig); else fig = lower(fig); end
            
            % remove old pawn
            remove_figure( to );

            % create Figure
            [name, handle_chess_figure] = getFigureName(fig);
            handle_chess_figure('init',[to(1) to(2)],cur_color,[fig matrix2chess(to)]); % matrix position, color, instance name
        end
        %if logFlag, fprintf(logFile,'Pawn moved from %s to %s.\n',matrix2chess(varargin{1}),matrix2chess(varargin{2})); end        
    case 'best_move'
        %if logFlag, fprintf(logFile,'Try to detect best pawn move from %s.\n',matrix2chess(varargin{1})); end        
        from = varargin{1};

        %if logFlag, fprintf(logFile,'to fields...\n'); end        
        T = toFields(from); % all possible moves within board
        cur_color = getColor(from);
        if cur_color %white
            %if logFlag, fprintf(logFile,'white possible fields...\n'); end        
            P = possible(from, T); % only moves, where there is no own figure
            [b,gain] = best(P,board.black,from);
        else %black
            %if logFlag, fprintf(logFile,'black possible fields...\n'); end        
            P = possible(from, T); % only moves, where there is no own figure
            [b,gain] = best(P,board.white,from);
        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 T = toFields(position)
% determines all possibles fields within the board (without regarding
% opponent figures)
% position ... current position of pawn
color = getColor(position);
if color %white
    M = [[-1 -1 -1]', [0 -1 +1]']; %one up, beat left, beat right
    if position(1)==7 % is allowed to move two fields up
        M = [M; [-2 0]];
    end
else %black
    M = [[1 1 1]', [0 -1 +1]']; %one down, beat left, beat right
    if position(1)==7 % is allowed to move two fields up
        M = [M; [-2 0]];
    end    
end
e = ones(size(M,1),1);
D = e*position + M;
I = find ( sum((D > 0 & D < 9),2)==2 ); % only fields within the board
T = D(I,:);

function P = possible(from, T)
% checks whether there is no own figure on field
% or between
% T ... fields a pawn can reach
% from ... original field of pawn
global board
global history

P =[];
color = getColor(from);
f1 = from(1); f2 = from(2);
for k = 1:size(T,1)
    i=T(k,1); j=T(k,2);
    
    if  f2-j==0 % straight forward
        % forward one field
        if ( abs(f1-i)==1 )
            if board.white(i,j)+board.black(i,j)==0 % no own or opponenet figure
                P = [P; T(k,:)];
            end
        elseif  abs(f1-i)==2 % forward two fields
            if color %white
                % no figure in between
                if board.white(i+1,j)+board.black(i+1,j)==0
                    if board.white(i,j)+board.black(i,j)==0 % no own or opponenet figure
                        P = [P; T(k,:)];
                    end
                end
            else % black
                if board.white(i-1,j)+board.black(i-1,j)==0
                    if board.white(i,j)+board.black(i,j)==0 % no own figure
                        P = [P; T(k,:)];
                    end
                end
            end
        end
    else    % beating left, right or enpassant
        if color %white
            if board.black(i,j)>0 % there is an opponents figure
                P = [P; T(k,:)];
            else % en passant
                if i==3 % only possible when white is in 4th[matrix notation] row
                    lm_nb = size(history.black_pos,1); % blacks last move number
                    bf  = history.black_pos{lm_nb,1};
                    bt  = history.black_pos{lm_nb,2};
                    bfig =  history.black_fig{k};

                    % black pawn tried to pass by with his last move
                    if bfig=='P' && j==bt(2) && i==bt(1)-1 && i==bf(1)+1 % same column, passed by, two fields
                        P = [P; T(k,:)];                        
                    end
                end
            end
        else %black
            if board.white(i,j)>0 % there is an opponents figure
                P = [P; T(k,:)];
            else % en passant
                if i==6 % only possible when white is in 4th[matrix notation] row
                    lm_nb = size(history.white_pos,1); % blacks last move number
                    wf  = history.white_pos{lm_nb,1};
                    wt  = history.white_pos{lm_nb,2};
                    wfig =  history.white_fig{k};

                    % white pawn tried to pass by with his last move
                    if wfig=='P' && j==wt(2) && i==wt(1)+1 && i==wf(1)-1 % same column, passed by, two fields
                        P = [P; T(k,:)];                        
                    end
                end
            end
        end
    end
end

%------------------------------------------------------------------
% Edis intelligence (ok. I admit, quite simple)
function [b,gain] = best(P, board,from)
% one move best
% Inputs:
% * board ... values of opponent
%
% Outputs:
% * b ... best field to go to
% * gain ... what the gain would be
b=[]; gain=-inf;
%disp('started best...');
if ~isempty(P)
    values = zeros(1, size(P,1));
    for k = 1:size(P,1)
        values(k) = board(P(k,1),P(k,2));
        if abs(from(2)-P(k,2))==1 % beats
            if board(P(k,1),P(k,2))==0 % but no figure
                %hence it is en passant
                values(k) = 1;
            end
        end
        % maybe a queen
        if P(k,1)== 8 || P(k,1)== 1
            values(k) = values(k) + 9; % choose queen  
        end
    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
%disp('finished best!');

%------------------------------------------------------------------

function answer = legal_move(from, to)
T = toFields(from); % all possible moves within board
color = getColor(from);
if color %white
    P = possible(from, T); % only moves, where there is no own figure
else %black
    P = possible(from, T); % only moves, where there is no own figure
end
if ~isempty(P)
    I = find( sum((P == ones(size(P,1),1)*to),2) == 2 );
else
    I = [];
end
if isempty(I), answer=0; % not legal
else answer = 1; % legal move
end



%------------------------------------------------------------------
function fig = ask_which_figure
    s = [];
    while isempty(s) % there is no cancle possible!
      s = listdlg('PromptString','Please choose your figure','SelectionMode','single','ListString',{'Queen','Rook','Bishop','Knight'},'Name','Pawn transformation','ListSize',[150,80]);
    end
      
  switch s
      case 1
          fig='q';
      case 2
          fig='r';
      case 3
          fig='b';
      case 4
          fig='n';
      otherwise
          fig='q';
  end

⌨️ 快捷键说明

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