Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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).

share|improve this question
    
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
1  
@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
2  
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
show 2 more comments

1 Answer

up vote 3 down vote accepted

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");
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.