int validmove(move m) { move_and_score *restore_sp = move_sp; genmoves(); while(move_sp>restore_sp) { move vm = popmove(); if (m == vm) { int r = wouldbeincheckfullp(m); if (r == 0) { move_sp = restore_sp; return 1; /* valid */ } else { move_sp = restore_sp; return -r; /* invalid move */ } } } return 0; /* move was not found */ }
/* returns -1 for stalemate or winner's color */ int playchess() { int use_pondering = 0; printboard_and_time(); for (;;) { long starttime, endtime; move m; int g; g = gameoverp(tomove()); if (g) { switch (g) { case END_CHECKMATE: if (tomove() == BLACK) { return end(WHITE, "white mates"); } else { return end(BLACK, "black mates"); } case END_STALEMATE: return end(-1, "stalemate"); case NON_MATERIAL: return end(-1, "insufficient material"); case REP_DRAW: if (!robo_mode) { printf("drawable position\n"); } if (computer[WHITE]||computer[BLACK]) { if (robo_mode) tellics("draw\n"); return end(-1, "draw by repetition of moves"); } break; } } starttime = get_ms(); if (computer[tomove()]) { m = bce(); if ((m!=dummymove)&&(validmove(m)==1)) { printf("move %s\n", movestring(m)); } else { if (robo_mode) { tellics("mailmoves\n"); tellics( "message madhacker valid? = %d, move = %s, wouldbeincheckp() = %d, wouldbeinfullcheckp() = %d, pv = %s\n", validmove(m), movestring(m), wouldbeincheckp(m), wouldbeincheckfullp(m), thoughts); tellics("abort\n"); } else { printf("BCE returned invalid move: %s\n", movestring(m)); printf("valid? = %d\n", validmove(m)); fprintf(stdout, "random seed = %ld\n", seed); fprintf(stdout, "hash = %lld\n", board->hash); fprintf(stdout, "draw? = %d g = %d\n", draw_by_rep(), g); computer[1] = computer[0] = 0; } } use_pondering = 1; } else { if ((ponder_mode && computer[opp(tomove())])&& use_pondering) { ponder(); use_pondering = 0; } m = usermove(); use_pondering = 0; } endtime = get_ms(); chessclock[tomove()] -= (endtime-starttime); chessclock[tomove()] += clockinc; if (m) { domove(m); update_state(m); printboard_and_time(); } } }