# The smallest Chess arbiter

Write a program, which, upon gazing at a chess table, can say whether there is a check or a checkmate.

Input: a chess table in text form, the last line of the input being the first rank (the starting line of White)

The starting position in this input would look like this (space is an empty square, capital letters are White): why aren't the spaces displayed here?

rnbqkbnr
pppppppp

PPPPPPPP
RNBQKBNR


The program should print one or more of the following (without quotes, of course), depending on the situation:

• "The White King is in check!" (if already in checkmate, don't display this!)
• "The Black King is in check!" (if already in checkmate, don't display this!)
• "The White King is in checkmate!"
• "The Black King is in checkmate!"
• "White is in stalemate!" (There would be a stalemate if White moved - optional)
• "Black is in stalemate!" (There would be a stalemate if Black moved - optional)
• "Both kings are safe for now." (if none of the above apply)

The input is guaranteed to be correct and be a legal chess position (no two kings of the same color, no two kings in check, etc.).

Score:

The score is the character count, lowest wins, not sooner than 10 days after the first valid answer. If the optional stalemate evaluation is implemented, the size will be decreased by 20% (for this situation, assume en-passant cannot be performed).

• I believe that stalemate can depend on who is to move (i.e. I could move out of check into a position that would be stalemate except that it is now my opponent turn to move and he'll have to change something). I'll try to manufacture such a state. – dmckee Nov 7 '12 at 14:26
• @dmckee : This is why I separated white and black. You have to print "white is in stalemate" if there would be a stalemate if white moved. I'll edit it to make it more clear. – vsz Nov 7 '12 at 14:35
• What about unconditional stalemate (e.g. only kings left on the board)? Edit: ah, "one or more". Still, it would be good to include this in the test cases which I'm sure you're going to add. – Peter Taylor Nov 7 '12 at 16:42
• @PeterTaylor: Well they are not technically a stalemate. One that occasion, we would have to include the King + one Knight or Bishop vs King, which is also a draw. And then the eternal check. And so on. Ok, If you want to implement it (and the unavoidable mate in x also?) you are free to do it, but I will not make them to a strict requirement. So in that case I'll accept the "Both kings are safe for now." output in case of only kings left on board. – vsz Nov 7 '12 at 17:12
• What if the check was made by a pawn eligible for en passant capture? Is it safe to assume this does not occur? – Steven Rumbalski Nov 7 '12 at 20:24

## C, 837-20%=669.6 chars

Based on this answer. You can see some explanations about the implementation there.
The original is golfed quite well, the modifications not so much, so there's room for improvement.
I also wouldn't be surprised to find bugs, my QA wasn't very rigorous.

char*r=" KPNBRQ  kpnbrq $,&)$wxy()879()8(6:GI(",B[256],*b=B,i,Q,s,*X[]={"Stalemate","Checkmate","","Check"};
e(x,d,m,V,c,r,n,p){
p=b[x];
return(m/r?
n=x+d*r,
p-2-8*(d<0)&&!(n&136)&&(b[n]?r=8,p&8^b[n]&8&&c&65^64:c&65^65)&&
((V?v(n,x):b[n]%8==1&&(s&=~((b[n]>7?8:2)))),e(x,d,m,V,c,r+1))
:0)||d>0&&e(x,-d,m,V,c,1);
}
d(x,v,m,i)char*m;{
(i=*m-40)? e(x,i%64,b[x]%8-2?b[x]&4?7:1:(x/16-1)%5|i%2?1:2,v,i,1),d(x,v,m+1):0;
}
v(t,f){
b[t]%8-1?
(s&(b[f]>7?8:2))==0?
bcopy(B,b+=128,128),
s|=(b[f]>7?8:2),
b[f]^=b[t]=b[f],
a(b[t]<8,63),
b=B
:0
:
(s|=b[f]>7?1:4);
}
a(c,n){
b[i=n*2-n%8]&&b[i]/8==c?d(i,!Q++,r+r[b[i]%8+15]-10),Q--:0;n--&&a(c,n);
}
p(c,t){
return(t=c?s%4:s/4)!=2&&printf("%s%s%s is in %s\n",t?"The ":"",c?"White":"Black",t?" king":"",X[t]);
}
main(){
for(;gets(b);b+=8)for(;*b;b++)*b=strchr(r,*b)-r;b=B;
a(0,63);
a(1,63);
p(0)||p(8)||puts("Both kings are safe for now");
}