Code covered by the BSD License  

Highlights from
Chess with "Greedy Edi"

image thumbnail

Chess with "Greedy Edi"

by

 

07 Nov 2009 (Updated )

Play chess against "Greedy Edi".

KingsInCheck
function [pos, colour, check] = KingsInCheck
% Examines whether King is in check.
%
% Input
% * global board
%
% Output
% * whether and which Kings are in check
% * pos ... position of King (matrix notation)
% * colour ... colour of King (0...black, 1...white)
% * check ... whether King is in check (0...not in check, 1...in check)
%
% Algorithm
% First we get all King positions (+colour). Then we do the following tests
% 1. straight lines is there any opponent rook or queen in line of sight
% 2. diagonals is there any opponent bishop or queen in line of sight
% 3. "small diagonals" is there any opponent pawn
% 4. Any Knight attacks
% 5. Any King attack
%

pos=[];colour=[];check=[];
for colourKing = 0:1 % black and white Kings
    posKings = King('getPosition',colourKing); % king(s)
    for k=1:size(posKings,1) % for all kings (normally it is only one)
        if StraightLineCheck(posKings(k,:), colourKing)
            inCheck=1;
        elseif DiagonalCheck(posKings(k,:),colourKing);
            inCheck=1;
        elseif PawnCheck(posKings(k,:),colourKing);       
            inCheck=1;
        elseif KnightCheck(posKings(k,:),colourKing);    
            inCheck=1;
        elseif KingCheck(posKings(k,:),colourKing);    
            inCheck=1;
        else
            inCheck=0;
        end
        pos = [pos; posKings(k,:)];
        colour = [colour; colourKing];
        check = [check; inCheck];
    end
end

function inCheck=KingCheck(posKing, colour)
global board;
inCheck=0;

if colour % shows white King
    opponentKing='k'; % black Knight
else
    opponentKing='K'; % white Knight
end
T = KingAttackFields(posKing);
for k = 1:size(T,1)
    if board.figures(T(k,1),T(k,2))==opponentKing
        inCheck=1;
        break; % as soon as a Knight has been found
    end
end

function T = KingAttackFields(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 =  sum((D > 0 & D < 9),2)==2 ; % only fields within the board
T = D(I,:);

function inCheck=KnightCheck(posKing, colour)
global board;
inCheck=0;
if colour % shows white King
    opponentKnight='n'; % black Knight
else
    opponentKnight='N'; % white Knight
end
T = KnightAttackFields(posKing);
for k = 1:size(T,1)
    if board.figures(T(k,1),T(k,2))==opponentKnight
        inCheck=1;
        break; % as soon as a Knight has been found
    end
end

function T = KnightAttackFields(position)
% determines all possibles fields a knight can atack a king witin the board

M = [[2 1 -1 -2 -2 -1 1 2]',[1 2 2 1 -1 -2 -2 -1]'];
e = ones(8,1);
D = e*position + M;
I =  sum((D > 0 & D < 9),2)==2 ; % only fields within the board
T = D(I,:);

function inCheck=PawnCheck(posKing, colour)
global board;
inCheck=0;
if colour % is white King
    left = posKing + [-1 -1];
    if left(1)>0 && left(2)>0
        f = board.figures(left(1),left(2));
        if f=='p', inCheck=1; end
    end
    if ~inCheck
        right = posKing + [-1 1];
        if right(1)>0 && right(2)<9
            f = board.figures(right(1),right(2));
            if f=='p', inCheck=1; end
        end
    end
else % black King
    left = posKing + [1 -1];
    if left(1)<9 && left(2)>0
        f = board.figures(left(1),left(2));
        if f=='P', inCheck=1; end
    end
    if ~inCheck
        right = posKing + [1 1];
        if right(1)<9 && right(2)<9
            f = board.figures(right(1),right(2));
            if f=='P', inCheck=1; end
        end
    end
end

function inCheck=DiagonalCheck(posKing,colour)
% diagonals is there any opponent bishop or queen in line of sight
global board;
inCheck = 0;

r = posKing(1); % row of king
c = posKing(2); % column of king% down,right

figures = {'Q','B'};
inCheck = 0; % King is not in check
% go thorough diagonals
% down, right (SE)        
kr=r+1; kc=c+1; f=' ';        
while kr<9 && kc<9 && f==' ' 
    f = board.figures(kr,kc);
    inCheck = CheckField(f, colour, figures);
    kr=kr+1; kc=kc+1;
end
if inCheck, return; end

% up, right(NE)        
kr=r-1; kc=c+1; f=' ';        
while kr>0 && kc<9 && f==' ' 
    f = board.figures(kr,kc);
    inCheck = CheckField(f, colour, figures);
    kr=kr-1; kc=kc+1;
end
if inCheck, return; end

% up, left(NW)        
kr=r-1; kc=c-1; f=' ';        
while kr>0 && kc>0 && f==' ' 
    f = board.figures(kr,kc);
    inCheck = CheckField(f, colour, figures);
    kr=kr-1; kc=kc-1;
end
if inCheck, return; end

% down, left(SW)        
kr=r+1; kc=c-1; f=' ';        
while kr<9 && kc>0 && f==' ' 
    f = board.figures(kr,kc);
    inCheck = CheckField(f, colour, figures);
    kr=kr+1; kc=kc-1;
end


function inCheck = StraightLineCheck(posKing, colour)
% Is there any opponent rook or queen in line of sight
%
% Input
% * posKing ... row, column
% * colour ... colour of King is 0=black or 1=white
%
% Output
% * inCheck ... 0=king not in check, 1=king in check
%
global board;
inCheck = 0;

rK = posKing(1); % row of king
cK = posKing(2); % column of king

part = board.figures(rK,cK+1:end); % row right
inCheck = RightPartStraightLineCheck(part,colour);
if inCheck, return; end

part = board.figures(rK,1:cK-1); % row left 
part = part(end:-1:1); % reverse it so we can use the previous alg.
inCheck = RightPartStraightLineCheck(part,colour);
if inCheck, return; end

part = board.figures(rK+1:end,cK); % down
part = part'; %transpose so we can use the same code
inCheck = RightPartStraightLineCheck(part,colour);
if inCheck, return; end

part = board.figures(1:rK-1,cK); % up
part = part(end:-1:1)'; %reverse and transpose so we can use the same code
inCheck = RightPartStraightLineCheck(part,colour);

function inCheck = RightPartStraightLineCheck(part,colour)
% Examines whether there is a check from the right side of the king.
inCheck = 0; %no check
k=1; f=' ';
while k<=length(part) && f==' '
    f = part(k);
    inCheck = CheckField(f, colour, {'Q','R'});
    % if f~=' ' then stop examination because any other figure (except Knight) blocks a check
    k=k+1;
end

function inCheck = CheckField(f, colour, figures)
inCheck=0;
if f~=' ' % not a free field
    if colour==1 % white King
        if f==lower(figures{1}) || f==lower(figures{2}) % e.g. black Queen or Rook
            inCheck=1;
        else % any other figure blocks possible checks (except night)
            inCheck=0;
        end
    else % black King
        if f==upper(figures{1}) || f==upper(figures{2}) % e.g. white Queen or Rook
            inCheck=1;
        else % any other figure blocks possible checks (except night)
            inCheck=0;
        end
    end
end

Contact us