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