void MirrorBoard(S_BOARD *pos) { int tempPiecesArray[64]; int tempSide = pos->side^1; int SwapPiece[13] = { EMPTY, bP, bN, bB, bR, bQ, bK, wP, wN, wB, wR, wQ, wK }; int tempCastlePerm = 0; int tempEnPas = NO_SQ; int sq; int tp; if (pos->castlePerm & WKCA) tempCastlePerm |= BKCA; if (pos->castlePerm & WQCA) tempCastlePerm |= BQCA; if (pos->castlePerm & BKCA) tempCastlePerm |= WKCA; if (pos->castlePerm & BQCA) tempCastlePerm |= WQCA; if (pos->enPas != NO_SQ) { tempEnPas = SQ120(Mirror64[SQ64(pos->enPas)]); } for (sq = 0; sq < 64; sq++) { tempPiecesArray[sq] = pos->pieces[SQ120(Mirror64[sq])]; } ResetBoard(pos); for (sq = 0; sq < 64; sq++) { tp = SwapPiece[tempPiecesArray[sq]]; pos->pieces[SQ120(sq)] = tp; } pos->side = tempSide; pos->castlePerm = tempCastlePerm; pos->enPas = tempEnPas; pos->posKey = GeneratePosKey(pos); UpdateListsMaterial(pos); ASSERT(CheckBoard(pos)); }
int ParseFen(char *fen, S_BOARD *pos){ int rank = RANK_8; int file = FILE_A; int piece = 0; int count = 0; int i = 0; int sq64 = 0; int sq120 = 0; ASSERT(fen!=NULL); ASSERT(pos!=NULL); ResetBoard(pos); while(( rank >= RANK_1) && *fen){ count = 1; switch(*fen){ case 'p': piece = bP; break; case 'r': piece = bR; break; case 'n': piece = bN; break; case 'b': piece = bB; break; case 'k': piece = bK; break; case 'q': piece = bQ; break; case 'P': piece = wP; break; case 'R': piece = wR; break; case 'N': piece = wN; break; case 'B': piece = wB; break; case 'K': piece = wK; break; case 'Q': piece = wQ; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': piece = EMPTY; count = *fen - '0'; break; case '/': case ' ': rank--; file = FILE_A; fen++; continue; default: printf("FEN error \n"); return -1; } for(i = 0; i < count; i++){ sq64 = rank * 8 + file; sq120 = SQ120(sq64); if(piece != EMPTY){ pos->pieces[sq120] = piece; } file++; } fen++; } ASSERT(*fen == 'w' || *fen == 'b'); pos->side = (*fen == 'w') ? WHITE : BLACK; fen += 2; for(i = 0; i < 4; i++){ if(*fen == ' '){ break; } switch(*fen){ case 'K': pos->castlePerm |= WKCA; break; case 'Q': pos->castlePerm |= WQCA; break; case 'k': pos->castlePerm |= BKCA; break; case 'q': pos->castlePerm |= BQCA; break; default: break; } fen++; } fen++; ASSERT(pos->castlePerm>=0 && pos->castlePerm <= 15); if(*fen != '-'){ file = fen[0] - 'a'; rank = fen[1] - '1'; ASSERT(file>=FILE_A && file <= FILE_H); ASSERT(rank>=RANK_1 && rank <= RANK_8); pos->enPas = FR2SQ(file,rank); } pos->posKey = GeneratePosKey(pos); return 0; }
int CheckBoard(const S_BOARD *pos) { int t_pceNum[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int t_bigPce[2] = { 0, 0}; int t_majPce[2] = { 0, 0}; int t_minPce[2] = { 0, 0}; int t_material[2] = { 0, 0}; int sq64,t_piece,t_pce_num,sq120,colour,pcount; U64 t_pawns[3] = {0ULL, 0ULL, 0ULL}; t_pawns[WHITE] = pos->pawns[WHITE]; t_pawns[BLACK] = pos->pawns[BLACK]; t_pawns[BOTH] = pos->pawns[BOTH]; // check piece lists for(t_piece = wP; t_piece <= bK; ++t_piece) { for(t_pce_num = 0; t_pce_num < pos->pceNum[t_piece]; ++t_pce_num) { sq120 = pos->pList[t_piece][t_pce_num]; ASSERT(pos->pieces[sq120]==t_piece); } } // check piece count and other counters for(sq64 = 0; sq64 < 64; ++sq64) { sq120 = SQ120(sq64); t_piece = pos->pieces[sq120]; t_pceNum[t_piece]++; colour = PieceCol[t_piece]; if( PieceBig[t_piece] == TRUE) t_bigPce[colour]++; if( PieceMin[t_piece] == TRUE) t_minPce[colour]++; if( PieceMaj[t_piece] == TRUE) t_majPce[colour]++; t_material[colour] += PieceVal[t_piece]; } for(t_piece = wP; t_piece <= bK; ++t_piece) { ASSERT(t_pceNum[t_piece]==pos->pceNum[t_piece]); } // check bitboards count pcount = CNT(t_pawns[WHITE]); ASSERT(pcount == pos->pceNum[wP]); pcount = CNT(t_pawns[BLACK]); ASSERT(pcount == pos->pceNum[bP]); pcount = CNT(t_pawns[BOTH]); ASSERT(pcount == (pos->pceNum[bP] + pos->pceNum[wP])); // check bitboards squares while(t_pawns[WHITE]) { sq64 = POP(&t_pawns[WHITE]); ASSERT(pos->pieces[SQ120(sq64)] == wP); } while(t_pawns[BLACK]) { sq64 = POP(&t_pawns[BLACK]); ASSERT(pos->pieces[SQ120(sq64)] == bP); } while(t_pawns[BOTH]) { sq64 = POP(&t_pawns[BOTH]); ASSERT( (pos->pieces[SQ120(sq64)] == bP) || (pos->pieces[SQ120(sq64)] == wP) ); } ASSERT(t_material[WHITE]==pos->material[WHITE] && t_material[BLACK]==pos->material[BLACK]); ASSERT(t_minPce[WHITE]==pos->minPce[WHITE] && t_minPce[BLACK]==pos->minPce[BLACK]); ASSERT(t_majPce[WHITE]==pos->majPce[WHITE] && t_majPce[BLACK]==pos->majPce[BLACK]); ASSERT(t_bigPce[WHITE]==pos->bigPce[WHITE] && t_bigPce[BLACK]==pos->bigPce[BLACK]); ASSERT(pos->side==WHITE || pos->side==BLACK); ASSERT(GeneratePosKey(pos)==pos->posKey); ASSERT(pos->enPas==NO_SQ || ( RanksBrd[pos->enPas]==RANK_6 && pos->side == WHITE) || ( RanksBrd[pos->enPas]==RANK_3 && pos->side == BLACK)); ASSERT(pos->pieces[pos->KingSq[WHITE]] == wK); ASSERT(pos->pieces[pos->KingSq[BLACK]] == bK); ASSERT(pos->castlePerm >= 0 && pos->castlePerm <= 15); ASSERT(PceListOk(pos)); return TRUE; }