Cinnamon  1.0
chess engine
ChessBoard.cpp
Go to the documentation of this file.
00001 #include "ChessBoard.h"
00002 
00003 ChessBoard::ChessBoard() {
00004     START_FEN=string(STARTPOS);
00005     memset(&structure, 0, sizeof(_Tboard));
00006     sideToMove = loadFen(START_FEN);
00007     uci = false;
00008 }
00009 
00010 ChessBoard::~ChessBoard() {
00011 }
00012 #ifdef DEBUG_MODE
00013 u64 ChessBoard::getBitBoard(int side) {
00014     return side?getBitBoard<WHITE>():getBitBoard<BLACK>();
00015 
00016 }
00017 
00018 int ChessBoard::getPieceAt(int side, u64 bitmapPos) {
00019     return side?getPieceAt<WHITE>(bitmapPos):getPieceAt<BLACK>(bitmapPos);
00020 }
00021 #endif
00022 
00023 void ChessBoard::setUci(bool b) {
00024     uci = b;
00025 }
00026 
00027 uchar ChessBoard::getRightCastle() {
00028     return RIGHT_CASTLE;
00029 }
00030 
00031 void ChessBoard::setRightCastle(uchar r) {
00032     RIGHT_CASTLE = r;
00033 }
00034 
00035 bool ChessBoard::getUci() {
00036     return uci;
00037 }
00038 
00039 u64 ChessBoard::makeZobristKey() {
00040     u64  x2,key = 0;
00041     int i, position;
00042     for (i = 0; i < 12; i++) {
00043         x2 = chessboard[i];
00044         while (x2) {
00045             position = BITScanForward(x2);
00046             updateZobristKey(&key, i, position);
00047             x2 &= NOTPOW2[position];
00048         }
00049     }
00050     if (enpassantPosition != -1)
00051         updateZobristKey(&key, 13, enpassantPosition);
00052     x2 = RIGHT_CASTLE;
00053     while (x2) {
00054         position = BITScanForward(x2);
00055         updateZobristKey(&key, 14, position);
00056         x2 &= NOTPOW2[position];
00057     }
00058     return key;
00059 }
00060 
00061 int ChessBoard::getPieceByChar(char c) {
00062     for(int i=0; i<12; i++)
00063         if(c==FEN_PIECE[i])return i;
00064     return -1;
00065 }
00066 
00067 void ChessBoard::display() {
00068     if (uci)
00069         return;
00070     cout << endl<<"     a   b   c   d   e   f   g   h";
00071     for (int t = 0; t <= 63; t++) {
00072         char x=' ';
00073         if (t % 8 == 0) {
00074             cout << endl << "   ---------------------------------"<<endl;
00075             cout << " " << 8-RANK_AT[t] << " | ";
00076         }
00077         x=(x=(x = FEN_PIECE[getPieceAt<WHITE>( POW2[63 - t])])!='-' ? x : FEN_PIECE[getPieceAt<BLACK>( POW2[63 - t])])=='-'?' ':x;
00078         x != ' ' ? cout << x:POW2[t] & WHITE_SQUARES?cout << " ":cout << ".";
00079         cout << " | ";
00080     };
00081     cout << endl <<"   ---------------------------------" <<endl;
00082     cout << "     a   b   c   d   e   f   g   h" <<endl <<endl;
00083     string fen;
00084     boardToFen(fen);
00085     cout << endl << fen << endl<<endl<<flush;
00086 }
00087 
00088 void ChessBoard::boardToFen(string& fen) {
00089     int x, y, l = 0, i = 0, sq;
00090     char row[8];
00091     int q;
00092     for (y = 0; y < 8; y++) {
00093         i = l = 0;
00094         strcpy(row, "");
00095         for (x = 0; x < 8; x++) {
00096             sq = (y * 8) + x;
00097             q = getPieceAt<BLACK>( POW2[63 - sq]);
00098             if (q == SQUARE_FREE)
00099                 q = getPieceAt<WHITE>( POW2[63 - sq]);
00100             if (q == SQUARE_FREE)
00101                 l++;
00102             else {
00103                 if (l > 0) {
00104                     row[i] = (char) (l + 48);
00105                     i++;
00106                 }
00107                 l = 0;
00108                 row[i] = FEN_PIECE[q];
00109                 i++;
00110             }
00111         }
00112         if (l > 0) {
00113             row[i] = (char) (l + 48);
00114             i++;
00115         }
00116         fen.append(row,i);
00117         if (y < 7)
00118             fen.append("/");
00119     }
00120     if (sideToMove==BLACK)
00121         fen.append(" b ");
00122     else
00123         fen.append(" w ");
00124     int cst = 0;
00125     if (RIGHT_CASTLE & RIGHT_KING_CASTLE_WHITE_MASK) {
00126         fen.append("K");
00127         cst++;
00128     }
00129     if (RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_WHITE_MASK) {
00130         fen.append("Q");
00131         cst++;
00132     }
00133     if (RIGHT_CASTLE & RIGHT_KING_CASTLE_BLACK_MASK) {
00134         fen.append("k");
00135         cst++;
00136     }
00137     if (RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_BLACK_MASK) {
00138         fen.append("q");
00139         cst++;
00140     }
00141     if (!cst)
00142         fen.append("-");
00143     if(enpassantPosition==-1)
00144         fen.append(" -");
00145     else {
00146         fen.append(" ");
00147         sideToMove?fen.append(BOARD[enpassantPosition+8]):fen.append(BOARD[enpassantPosition-8]);
00148     }
00149 }
00150 
00151 string ChessBoard::decodeBoardinv(const uchar type, const int a, const int side) {
00152     if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
00153         return "e1c1";
00154     }
00155     if (type & KING_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
00156         return "e1g1";
00157     }
00158     if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
00159         return "e8c8";
00160     }
00161     if (type & KING_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
00162         return "e8g8";
00163     }
00164     ASSERT(!(type& 0xC ));
00165     if (a >= 0 && a < 64)
00166         return BOARD[a];
00167     assert(0);
00168     return "";
00169 }
00170 
00171 char ChessBoard::decodeBoard(string a) {
00172     for (int i = 0; i < 64; i++) {
00173         if (!a.compare( BOARD[i]))
00174             return i;
00175     }
00176     cout << endl<<a<<endl;
00177     ASSERT(0);
00178     return -1;
00179 }
00180 
00181 int ChessBoard::loadFen() {
00182     return loadFen(START_FEN);
00183 }
00184 
00185 int ChessBoard::loadFen(string fen) {
00186     if(fen.length()==0)return loadFen() ;
00187     istringstream iss(fen);
00188     string pos,castle,enpassant,side;
00189     iss >> pos;
00190     iss >> side;
00191     iss >> castle;
00192     iss >> enpassant;
00193     int ix=0;
00194     int s[64];
00195     memset(chessboard, 0, sizeof(chessboard));
00196     for(unsigned ii=0; ii<pos.length(); ii++) {
00197         uchar ch = pos.at(ii);
00198         if(ch!='/') {
00199             if( INV_FEN[ch]!=0xFF)
00200                 s[ix++] = INV_FEN[ch];
00201             else if (ch > 47 && ch < 58) {
00202                 for (int t = 0; t < ch-48; t++)
00203                     s[ix++] = SQUARE_FREE;
00204             } else {
00205                 cout << "Bad FEN position format (" << (char) ch << ") " << fen<<endl;
00206                 exit(1);
00207             };
00208         }
00209     }
00210     if(ix!=64) {
00211         cout << "Bad FEN position format " << fen<<endl;
00212         exit(1);
00213     }
00214     for (int i = 0; i < 64; i++) {
00215         int p = s[63 - i];
00216         if (p != SQUARE_FREE) {
00217             chessboard[p] |= POW2[i];
00218         }
00219     };
00220     if(side=="b")
00221         sideToMove = BLACK;
00222     else if(side=="w")
00223         sideToMove = WHITE;
00224     else {
00225         cout << "Bad FEN position format " << fen<<endl;
00226         exit(1);
00227     }
00228     RIGHT_CASTLE = 0;
00229     for(unsigned e=0; e<castle.length(); e++) {
00230         switch (castle.at(e)) {
00231         case 'K':
00232             RIGHT_CASTLE |= RIGHT_KING_CASTLE_WHITE_MASK;
00233             break;
00234         case 'k':
00235             RIGHT_CASTLE |= RIGHT_KING_CASTLE_BLACK_MASK;
00236             break;
00237         case 'Q':
00238             RIGHT_CASTLE |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
00239             break;
00240         case 'q':
00241             RIGHT_CASTLE |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
00242             break;
00243         default:
00244             ;
00245         };
00246     };
00247     friendKing[WHITE] = BITScanForward(chessboard[KING_WHITE]);
00248     friendKing[BLACK] = BITScanForward(chessboard[KING_BLACK ]);
00249     enpassantPosition = -1;
00250     for (int i = 0; i < 64; i++) {
00251         if (enpassant==BOARD[i] ) {
00252             enpassantPosition =i;
00253             if (sideToMove)
00254                 enpassantPosition -= 8;
00255             else
00256                 enpassantPosition += 8;
00257             break;
00258         }
00259     }
00260     zobristKey=makeZobristKey();
00261     return sideToMove;
00262 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines