Skip to content

Commit 1abff49

Browse files
committed
version 2.3.1
1 parent 4af8162 commit 1abff49

20 files changed

+556
-434
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Cinnamon is a chess program for Windows, Linux, Mac OS, Android and Raspberry Pi
66

77
Version
88
----------
9-
2.3
9+
2.3.1
1010

1111
News
1212
----------

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,5 @@ set(SOURCE_FILES
7070

7171
set(CMAKE_CXX_COMPILER "clang++")
7272
add_executable(cinnamon_debug ${SOURCE_FILES})
73+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
7374
target_link_libraries(cinnamon_debug ${CMAKE_SOURCE_DIR}/lib/Linux/64/libgtb.a /usr/lib/libgtest.a)

src/ChessBoard.cpp

Lines changed: 215 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ void ChessBoard::makeZobristKey() {
4141
}
4242
}
4343

44-
4544
for (u64 x2 = chessboard[RIGHT_CASTLE_IDX]; x2; RESET_LSB(x2)) {
4645
const int position = BITScanForward(x2);
4746
updateZobristKey(RIGHT_CASTLE_IDX, position);//12
@@ -63,18 +62,168 @@ int ChessBoard::loadFen() {
6362
return loadFen(fenString);
6463
}
6564

66-
int ChessBoard::loadFen(const string& fen) {
65+
string ChessBoard::boardToFen() const {
66+
string fen;
67+
for (int y = 0; y < 8; y++) {
68+
int l = 0;
69+
string row;
70+
for (int x = 0; x < 8; x++) {
71+
int q = board::getPieceAt<BLACK>(POW2[63 - ((y * 8) + x)], chessboard);
72+
if (q == SQUARE_EMPTY) {
73+
q = board::getPieceAt<WHITE>(POW2[63 - ((y * 8) + x)], chessboard);
74+
}
75+
if (q == SQUARE_EMPTY) {
76+
l++;
77+
} else {
78+
if (l > 0) {
79+
row.append(1, (char) (l + 48));
80+
}
81+
l = 0;
82+
row.append(1, FEN_PIECE[q]);
83+
}
84+
}
85+
if (l > 0) {
86+
row.append(1, (char) (l + 48));
87+
}
88+
fen.append(row.c_str());
89+
if (y < 7) {
90+
fen.append("/");
91+
}
92+
}
93+
if (chessboard[SIDETOMOVE_IDX] == BLACK) {
94+
fen.append(" b ");
95+
} else {
96+
fen.append(" w ");
97+
}
98+
int cst = 0;
99+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) {
100+
fen += whiteRookKingSideCastle;
101+
cst++;
102+
}
103+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) {
104+
fen += whiteRookQueenSideCastle;
105+
cst++;
106+
}
107+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) {
108+
fen += blackRookKingSideCastle;
109+
cst++;
110+
}
111+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) {
112+
fen += whiteRookKingSideCastle;
113+
cst++;
114+
}
115+
if (!cst) {
116+
fen.append("-");
117+
}
118+
if (chessboard[ENPASSANT_IDX] == NO_ENPASSANT) {
119+
fen.append(" -");
120+
} else {
121+
fen.append(" ");
122+
chessboard[SIDETOMOVE_IDX] ? fen.append(BOARD[chessboard[ENPASSANT_IDX] + 8]) : fen.append(
123+
BOARD[chessboard[ENPASSANT_IDX] - 8]);
124+
}
125+
fen.append(" 0 ");
126+
fen.append(to_string(movesCount));
127+
return fen;
128+
}
129+
130+
void ChessBoard::display() const {
131+
cout << endl << " a b c d e f g h";
132+
for (int t = 0; t <= 63; t++) {
133+
char x = ' ';
134+
if (t % 8 == 0) {
135+
cout << endl << " ----+---+---+---+---+---+---+----" << endl;
136+
cout << " " << 8 - RANK_AT[t] << " | ";
137+
}
138+
x = (x = (x = FEN_PIECE[board::getPieceAt<WHITE>(POW2[63 - t], chessboard)]) != '-' ? x
139+
: FEN_PIECE[board::getPieceAt<BLACK>(
140+
POW2[63 - t], chessboard)]) == '-' ? ' ' : x;
141+
x != ' ' ? cout << x : POW2[t] & WHITE_SQUARES ? cout << " " : cout << ".";
142+
cout << " | ";
143+
};
144+
cout << endl << " ----+---+---+---+---+---+---+----" << endl;
145+
cout << " a b c d e f g h" << endl << endl << "fen:\t\t" << boardToFen() << endl;
146+
147+
cout << "side:\t\t" << (chessboard[SIDETOMOVE_IDX] ? "White" : "Black") << endl;
148+
cout << "castle:\t\t";
149+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_WHITE_MASK) cout << whiteRookKingSideCastle;
150+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_WHITE_MASK) cout << whiteRookQueenSideCastle;
151+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_KING_CASTLE_BLACK_MASK) cout << blackRookKingSideCastle;
152+
if (chessboard[RIGHT_CASTLE_IDX] & RIGHT_QUEEN_CASTLE_BLACK_MASK) cout << blackRookQueenSideCastle;
153+
cout << endl;
154+
155+
cout << "ep:\t\t\t"
156+
<< (chessboard[ENPASSANT_IDX] == 100 ? "" : (chessboard[SIDETOMOVE_IDX] ? BOARD[chessboard[ENPASSANT_IDX] + 8]
157+
: BOARD[chessboard[ENPASSANT_IDX] -
158+
8])) << endl;
159+
cout << "Chess960:\t" << (chess960 ? "true" : "false") << endl;
160+
#ifdef DEBUG_MODE
161+
cout << "zobristKey:\t0x" << hex << chessboard[ZOBRISTKEY_IDX] << "ull" << dec << endl;
162+
#endif
163+
cout << endl;
164+
}
165+
166+
string ChessBoard::moveToString(const _Tmove *move) {
167+
string a = decodeBoardinv(move->s.type, move->s.from, move->s.side);
168+
if (move->s.type & 0xc) return a;
169+
string b = decodeBoardinv(move->s.type, move->s.to, move->s.side);
170+
if (move->s.promotionPiece != -1) (a + b) += (char) tolower(FEN_PIECE[move->s.promotionPiece]);
171+
return a + b;
172+
}
173+
174+
void ChessBoard::print(const _Tmove *move, const _Tchessboard &chessboard) {
175+
cout << moveToString(move) << " " << flush;
176+
}
177+
178+
string ChessBoard::decodeBoardinv(const uchar type, const int a, const int side) {
179+
if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
180+
return isChess960() ? BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide] : "e1c1";
181+
}
182+
if (type & KING_SIDE_CASTLE_MOVE_MASK && side == WHITE) {
183+
return isChess960() ? BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookKingSide] : "e1g1";
184+
}
185+
if (type & QUEEN_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
186+
return isChess960() ? BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide] : "e8c8";
187+
}
188+
if (type & KING_SIDE_CASTLE_MOVE_MASK && side == BLACK) {
189+
return isChess960() ? BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide] : "e8g8";
190+
}
191+
ASSERT(!(type & 0xC));
192+
if (a >= 0 && a < 64) {
193+
return BOARD[a];
194+
}
195+
_assert(0);
196+
}
197+
198+
int ChessBoard::loadFen(const string &fen) {
67199
if (fen.empty()) {
68200
return loadFen();
69201
}
202+
startPosWhiteKing = -1;
203+
startPosWhiteRookKingSide = -1;
204+
startPosWhiteRookQueenSide = -1;
205+
206+
startPosBlackKing = -1;
207+
startPosBlackRookKingSide = -1;
208+
startPosBlackRookQueenSide = -1;
209+
MATCH_QUEENSIDE = "";
210+
MATCH_QUEENSIDE_WHITE = "O-O-O ";
211+
MATCH_KINGSIDE_WHITE = "O-O ";
212+
MATCH_QUEENSIDE_BLACK = "O-O-O ";
213+
MATCH_KINGSIDE_BLACK = "O-O ";
70214
fenString = fen;
71215
memset(chessboard, 0, sizeof(_Tchessboard));
72216
istringstream iss(fen);
73-
string pos, castle, enpassant, side;
217+
string pos, castle, enpassant, side, a1, a2;
74218
iss >> pos;
75219
iss >> side;
76220
iss >> castle;
77221
iss >> enpassant;
222+
iss >> a1;
223+
iss >> a2;
224+
a2 += " 1";
225+
movesCount = stoi(a2);
226+
78227
int ix = 0;
79228
array<int, 64> s;
80229
for (unsigned ii = 0; ii < pos.length(); ii++) {
@@ -110,74 +259,75 @@ int ChessBoard::loadFen(const string& fen) {
110259
} else {
111260
chessboard[p] &= NOTPOW2[i];
112261
}
262+
}
263+
startPosWhiteKing = BITScanForward(chessboard[KING_WHITE]);
264+
startPosBlackKing = BITScanForward(chessboard[KING_BLACK]);
265+
auto whiteRookKingSide = [&](const char c) {
266+
startPosWhiteRookKingSide = BITScanForward(chessboard[ROOK_WHITE] & 0xffULL);
267+
updateZobristKey(RIGHT_CASTLE_IDX, 4);
268+
ASSERT(4 == BITScanForward(RIGHT_KING_CASTLE_WHITE_MASK));
269+
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
270+
whiteRookKingSideCastle = c;
271+
};
272+
auto blackRookKingSide = [&](const char c) {
273+
startPosBlackRookKingSide = BITScanForward(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
274+
updateZobristKey(RIGHT_CASTLE_IDX, 6);
275+
ASSERT(6 == BITScanForward(RIGHT_KING_CASTLE_BLACK_MASK));
276+
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
277+
blackRookKingSideCastle = c;
278+
};
279+
auto whiteRookQueenSide = [&](const char c) {
280+
startPosWhiteRookQueenSide = BITScanReverse(chessboard[ROOK_WHITE] & 0xffULL);
281+
updateZobristKey(RIGHT_CASTLE_IDX, 5);
282+
ASSERT(5 == BITScanForward(RIGHT_QUEEN_CASTLE_WHITE_MASK));
283+
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
284+
whiteRookQueenSideCastle = c;
285+
};
286+
auto blackRookQueenSide = [&](const char c) {
287+
startPosBlackRookQueenSide = BITScanReverse(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
288+
updateZobristKey(RIGHT_CASTLE_IDX, 7);
289+
ASSERT(7 == BITScanForward(RIGHT_QUEEN_CASTLE_BLACK_MASK));
290+
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
291+
blackRookQueenSideCastle = c;
113292
};
114-
115293
for (unsigned e = 0; e < castle.length(); e++) {
116294
const char c = castle.at(e);
117295
switch (c) {
118296
case 'K':
119-
startPosWhiteKing = BITScanForward(chessboard[KING_WHITE]);
120-
startPosWhiteRookKingSide = BITScanForward(chessboard[ROOK_WHITE] & 0xffULL);
121-
updateZobristKey(RIGHT_CASTLE_IDX, 4);
122-
ASSERT(4 == BITScanForward(RIGHT_KING_CASTLE_WHITE_MASK));
123-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
297+
whiteRookKingSide(c);
124298
break;
125299
case 'k':
126-
startPosBlackKing = BITScanForward(chessboard[KING_BLACK]);
127-
startPosBlackRookKingSide = BITScanForward(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
128-
updateZobristKey(RIGHT_CASTLE_IDX, 6);
129-
ASSERT(6 == BITScanForward(RIGHT_KING_CASTLE_BLACK_MASK));
130-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
300+
blackRookKingSide(c);
131301
break;
132302
case 'Q':
133-
startPosWhiteKing = BITScanForward(chessboard[KING_WHITE]);
134-
startPosWhiteRookQueenSide = BITScanReverse(chessboard[ROOK_WHITE] & 0xffULL);
135-
updateZobristKey(RIGHT_CASTLE_IDX, 5);
136-
ASSERT(5 == BITScanForward(RIGHT_QUEEN_CASTLE_WHITE_MASK));
137-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
303+
whiteRookQueenSide(c);
138304
break;
139305
case 'q':
140-
startPosBlackKing = BITScanForward(chessboard[KING_BLACK]);
141-
startPosBlackRookQueenSide = BITScanReverse(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
142-
updateZobristKey(RIGHT_CASTLE_IDX, 7);
143-
ASSERT(7 == BITScanForward(RIGHT_QUEEN_CASTLE_BLACK_MASK));
144-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
306+
blackRookQueenSide(c);
145307
break;
146308
case '-':
147309
break;
148310
default:
149311
//x-fen
312+
setChess960(true);
150313
const int wKing = FILE_AT[BITScanForward(chessboard[KING_WHITE])];
151314
const int bKing = FILE_AT[BITScanForward(chessboard[KING_BLACK])];
152315

153316
if (isupper(c)) {
154-
startPosWhiteKing = BITScanForward(chessboard[KING_WHITE]);
155317
if (board::getFile(c) < wKing) {
156-
startPosWhiteRookKingSide = BITScanForward(chessboard[ROOK_WHITE] & 0xffULL);
157-
updateZobristKey(RIGHT_CASTLE_IDX, 4);
158-
ASSERT(4 == BITScanForward(RIGHT_KING_CASTLE_WHITE_MASK));
159-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_WHITE_MASK;
318+
whiteRookKingSide(c);
160319
break;
161320
} else {
162-
startPosWhiteRookQueenSide = BITScanReverse(chessboard[ROOK_WHITE] & 0xffULL);
163-
updateZobristKey(RIGHT_CASTLE_IDX, 5);
164-
ASSERT(5 == BITScanForward(RIGHT_QUEEN_CASTLE_WHITE_MASK));
165-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_WHITE_MASK;
321+
whiteRookQueenSide(c);
166322
break;
167323
}
168324
} else {
169-
startPosBlackKing = BITScanForward(chessboard[KING_BLACK]);
325+
170326
if (board::getFile(c) < bKing) {
171-
startPosBlackRookKingSide = BITScanForward(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
172-
updateZobristKey(RIGHT_CASTLE_IDX, 6);
173-
ASSERT(6 == BITScanForward(RIGHT_KING_CASTLE_BLACK_MASK));
174-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_KING_CASTLE_BLACK_MASK;
327+
blackRookKingSide(c);
175328
break;
176329
} else {
177-
startPosBlackRookQueenSide = BITScanReverse(chessboard[ROOK_BLACK] & 0xff00000000000000ULL);
178-
updateZobristKey(RIGHT_CASTLE_IDX, 7);
179-
ASSERT(7 == BITScanForward(RIGHT_QUEEN_CASTLE_BLACK_MASK));
180-
chessboard[RIGHT_CASTLE_IDX] |= RIGHT_QUEEN_CASTLE_BLACK_MASK;
330+
blackRookQueenSide(c);
181331
break;
182332
}
183333
}
@@ -198,5 +348,28 @@ int ChessBoard::loadFen(const string& fen) {
198348
}
199349
}
200350

351+
if (isChess960()) {
352+
if (startPosWhiteRookKingSide != -1)
353+
MATCH_KINGSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookKingSide];
354+
if (startPosBlackRookQueenSide != -1)
355+
MATCH_QUEENSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide];
356+
if (startPosWhiteRookQueenSide != -1)
357+
MATCH_QUEENSIDE_WHITE += BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide];
358+
if (startPosBlackRookKingSide != -1)
359+
MATCH_KINGSIDE_BLACK += BOARD[startPosBlackKing] + BOARD[startPosBlackRookKingSide];
360+
if (startPosBlackRookQueenSide != -1)
361+
MATCH_QUEENSIDE +=
362+
MATCH_QUEENSIDE_BLACK + " " + BOARD[startPosBlackKing] + BOARD[startPosBlackRookQueenSide];
363+
if (startPosWhiteRookQueenSide != -1)
364+
MATCH_QUEENSIDE +=
365+
MATCH_QUEENSIDE_WHITE + " " + BOARD[startPosWhiteKing] + BOARD[startPosWhiteRookQueenSide];
366+
} else {
367+
MATCH_QUEENSIDE_WHITE += "e1c1";
368+
MATCH_KINGSIDE_WHITE += "e1g1";
369+
MATCH_QUEENSIDE_BLACK += "e8c8";
370+
MATCH_KINGSIDE_BLACK += "e8g8";
371+
MATCH_QUEENSIDE = MATCH_QUEENSIDE_WHITE + " e8c8";
372+
}
373+
201374
return chessboard[SIDETOMOVE_IDX];
202375
}

0 commit comments

Comments
 (0)