![]() |
Cinnamon
1.0
chess engine
|
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 }