Belofte version 2.1.9
A promising chess program using the UCI or Winboard interface
piece.cpp
Go to the documentation of this file.
1/*---------------------------------------------------------------------+
2 * File: piece.cpp
3 * Project: part of belofte - A Promising Chess Program
4 * Author: yves
5 * SPDX-License-Identifier: GPL-2.0-only
6 +---------------------------------------------------------------------*/
7
8#include "belofte.h"
9
10/**
11 * Allow index mapper for char values of piece into int in 1-12 range
12 * to reduce space and easy initialisation
13 */
14namespace belofte {
15 static piece_t bPieceIndex[128] = {};
18 static boardbitmap_t kingmoves[64] = {};
19 static boardbitmap_t knightmoves[64] = {};
20 static case_t kingarray[64][9] = {};
21 static case_t knightarray[64][9] = {};
22}
23
24/**
25 * we declare a separate namespace just for code purity
26 * below declarations are globals, not static
27 */
28namespace belofte {
29 extern bWhiteKing const* cWhiteKingClass;
30 extern bBlackKing const* cBlackKingClass;
31}
32
33namespace belofte {
34 bWhiteKing const* cWhiteKingClass = nullptr;
35 bBlackKing const* cBlackKingClass = nullptr;
36}
37
38//-----------------------------------------------------------------------
39
40boardbitmap_t static destinationbits(case_t const iCase, int8_t const ri, int8_t const ci);
41boardbitmap_t static destinationbits_king(case_t const iCase);
43
44//-----------------------------------------------------------------------
45
47{
61
75
78
92
93 for (case_t iCase = 0; iCase < 64; ++iCase) {
96 // initialise array with destination squares
97 belofte::kingarray[iCase][0] = 0;
98 for (case_t bit = 0; bit < 64; ++bit) {
99 if (belofte::kingmoves[iCase][bit]) {
100 belofte::kingarray[iCase][0] += 1;
101 belofte::kingarray[iCase][belofte::kingarray[iCase][0]] = bit;
102 }
103 }
104 belofte::knightarray[iCase][0] = 0;
105 for (case_t bit = 0; bit < 64; ++bit) {
106 if (belofte::knightmoves[iCase][bit]) {
107 belofte::knightarray[iCase][0] += 1;
108 belofte::knightarray[iCase][belofte::knightarray[iCase][0]] = bit;
109 }
110 }
111 }
112}
113
115 boardbitmap_t dbits = 0L;
116 dbits |= destinationbits(iCase, -1, -1);
117 dbits |= destinationbits(iCase, -1, 0);
118 dbits |= destinationbits(iCase, -1, 1);
119 dbits |= destinationbits(iCase, 0, -1);
120 dbits |= destinationbits(iCase, 0, 1);
121 dbits |= destinationbits(iCase, 1, -1);
122 dbits |= destinationbits(iCase, 1, 0);
123 dbits |= destinationbits(iCase, 1, 1);
124 return dbits;
125}
126
128 boardbitmap_t dbits = 0L;
129 dbits |= destinationbits(iCase, -2, -1);
130 dbits |= destinationbits(iCase, -2, 1);
131 dbits |= destinationbits(iCase, -1, -2);
132 dbits |= destinationbits(iCase, -1, 2);
133 dbits |= destinationbits(iCase, 1, -2);
134 dbits |= destinationbits(iCase, 1, 2);
135 dbits |= destinationbits(iCase, 2, -1);
136 dbits |= destinationbits(iCase, 2, 1);
137 return dbits;
138}
139
140boardbitmap_t static destinationbits(case_t const iCase, int8_t const ri, int8_t const ci) {
141 column_t newcol = bCase::column(iCase) + ci;
142 rank_t newrank = bCase::rank(iCase) + ri;
143
144 if (newcol < 0 || newcol > 7) return 0;
145 if (newrank < 0 || newrank > 7) return 0;
146
147 return bCase::caseToBit(bCase::coordToCase(newcol, newrank));
148}
149
151{
152 for (int i = 0; i < tPiece::P_SIZE; ++i) {
153 delete belofte::pieceinstances[i];
154 }
155}
156
157//-----------------------------------------------------------------------
158
159/** static class member function */
161{
162 return belofte::pieceinstances[piece];
163}
164
165#if defined(__GNUC__)
166#pragma GCC diagnostic push
167#pragma GCC diagnostic ignored "-Wswitch-enum"
168#endif
169
170/**
171 * static class member function
172 */
173std::string const bPiece::getPieceStrUpper(piece_t const piece)
174{
175 switch (piece) {
176 case tPiece::W_PAWN:
177 case tPiece::B_PAWN:
178 return S_P_PAWN;
179 case tPiece::W_ROOK:
180 case tPiece::B_ROOK:
181 return S_P_ROOK;
182 case tPiece::W_KNIGHT:
183 case tPiece::B_KNIGHT:
184 return S_P_KNIGHT;
185 case tPiece::W_BISHOP:
186 case tPiece::B_BISHOP:
187 return S_P_BISHOP;
188 case tPiece::W_KING:
189 case tPiece::B_KING:
190 return S_P_KING;
191 case tPiece::W_QUEEN:
192 case tPiece::B_QUEEN:
193 return S_P_QUEEN;
194 //case tPiece::P_EMPTY:
195 //case tPiece::P_SIZE:
196 // break;
197 default:
198 break;
199 }
200 return S_P_EMPTY;
201}
202
203#if defined(__GNUC__)
204#pragma GCC diagnostic pop
205#endif
206
207//-----------------------------------------------------------------------
208
210{
211 if (!m_piece) return tSide::SIDE_UNDEFINED;
212 if (m_piece <= tPiece::W_QUEEN) return tSide::SIDE_WHITE;
213 return tSide::SIDE_BLACK;
214}
215
216//-----------------------------------------------------------------------
217
218/** static class member function */
223
224/** static class member function */
226{
227 return belofte::bPieceIndex[p];
228}
229
230/** static class member function */
231bool bPiece::isOpponent(side_t const s, piece_t const p)
232{
233 if (!p) return false;
234 if (p <= tPiece::W_QUEEN) return s == tSide::SIDE_BLACK ;
235 return s == tSide::SIDE_WHITE;
236}
237
238/** static class member function */
239bool bPiece::isOwnColour(side_t const s, piece_t const p)
240{
241 if (!p) return false;
242 if (p <= tPiece::W_QUEEN) return s == tSide::SIDE_WHITE;
243 return s == tSide::SIDE_BLACK;
244}
245
246/** static class member function */
248{
249 if (!p) return false;
250 return (p <= tPiece::W_QUEEN);
251}
252
253/** static class member function */
255{
256 if (!p) return false;
257 return (p > tPiece::W_QUEEN);
258}
259
260//-----------------------------------------------------------------------
261
262/**
263 * Check if piece on position is attacked, start with piece always on board
264 * and then with pieces with greatest mobility, goal is to break out asap
265 * @param b board
266 * @param cf piece position
267 * @return true if attacked, false if not
268*/
269bool bWhitePiece::isAttacked(bBasicBoard const& b, case_t const& cf) const
270{
271 // see if from square can be reached by king
272 if (belofte::kingmoves[b.getBlackKingPos()][cf]) return true;
273
274 // knight
275 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
276 if (b.getPiece(belofte::knightarray[cf][iMove]) == tPiece::B_KNIGHT) return true;
277 }
278
279 column_t fromcol = bCase::column(cf);
280 rank_t fromrank = bCase::rank(cf);
281
282 // pawn
283 if (fromrank < 6) {
284 if (fromcol && (b.getPiece(cf + 7) == tPiece::B_PAWN)) return true;
285 if ((fromcol < 7) && (b.getPiece(cf + 9) == tPiece::B_PAWN)) return true;
286 }
287
288 // bishop, queen
289 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, -1, tPiece::B_BISHOP, tPiece::B_QUEEN)) return true;
290 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, 1, tPiece::B_BISHOP, tPiece::B_QUEEN)) return true;
291 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, -1, tPiece::B_BISHOP, tPiece::B_QUEEN)) return true;
292 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, 1, tPiece::B_BISHOP, tPiece::B_QUEEN)) return true;
293
294 // rook, queen
295 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, 0, tPiece::B_ROOK, tPiece::B_QUEEN)) return true;
296 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, 0, tPiece::B_ROOK, tPiece::B_QUEEN)) return true;
297 if (isAttackedBySlider(b, cf, fromcol, fromrank, 0, -1, tPiece::B_ROOK, tPiece::B_QUEEN)) return true;
298 if (isAttackedBySlider(b, cf, fromcol, fromrank, 0, 1, tPiece::B_ROOK, tPiece::B_QUEEN)) return true;
299
300 return false;
301}
302
303bool bBlackPiece::isAttacked(bBasicBoard const& b, case_t const& cf) const
304{
305 // see if from square can be reached by king
306 if (belofte::kingmoves[b.getWhiteKingPos()][cf]) return true;
307
308 // knight
309 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
310 if (b.getPiece(belofte::knightarray[cf][iMove]) == tPiece::W_KNIGHT) return true;
311 }
312
313 column_t fromcol = bCase::column(cf);
314 rank_t fromrank = bCase::rank(cf);
315
316 // pawn
317 if (fromrank > 1) {
318 if ((fromcol < 7) && (b.getPiece(cf - 7) == tPiece::W_PAWN)) return true;
319 if (fromcol && (b.getPiece(cf - 9) == tPiece::W_PAWN)) return true;
320 }
321
322 // bishop, queen
323 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, -1, tPiece::W_BISHOP, tPiece::W_QUEEN)) return true;
324 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, 1, tPiece::W_BISHOP, tPiece::W_QUEEN)) return true;
325 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, -1, tPiece::W_BISHOP, tPiece::W_QUEEN)) return true;
326 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, 1, tPiece::W_BISHOP, tPiece::W_QUEEN)) return true;
327
328 // rook, queen
329 if (isAttackedBySlider(b, cf, fromcol, fromrank, -1, 0, tPiece::W_ROOK, tPiece::W_QUEEN)) return true;
330 if (isAttackedBySlider(b, cf, fromcol, fromrank, 1, 0, tPiece::W_ROOK, tPiece::W_QUEEN)) return true;
331 if (isAttackedBySlider(b, cf, fromcol, fromrank, 0, -1, tPiece::W_ROOK, tPiece::W_QUEEN)) return true;
332 if (isAttackedBySlider(b, cf, fromcol, fromrank, 0, 1, tPiece::W_ROOK, tPiece::W_QUEEN)) return true;
333
334 return false;
335}
336
337/**
338 * Return true if position is attacked by opponent respecting move offsets
339 * @param b board
340 * @param cf from field
341 * @param fromcol field from
342 * @param fromrank field from
343 * @param ci col increment
344 * @param ri row increment
345 * @param cPiece first possible piece (rook/bishop)
346 * @param cPiece2 second possible piece (queen)
347 * @return true/false
348 */
350 case_t cf, column_t fromcol, rank_t fromrank,
351 int8_t const ci, int8_t const ri,
352 piece_t const cPiece, piece_t const cPiece2) const
353{
354 int8_t offset = 8 * ri + ci;
355
356 // slider move (queen, rook, bishop)
357 for (;;) {
358 // touch border?
359 fromcol += ci;
360 if (fromcol < 0 || fromcol > 7) break;
361 fromrank += ri;
362 if (fromrank < 0 || fromrank > 7) break;
363
364 cf += offset;
365 piece_t piece = b.getPiece(cf);
366
367 if (piece) {
368 if (piece == cPiece) return true;
369 if (piece == cPiece2) return true;
370 // not empty, not opponent piece, so protected
371 break;
372 }
373 }
374 return false;
375}
376
377/**
378 * Check if any could be added by just checking there
379 * @return true if move seems valid, false if in check after move
380 */
382 case_t const& cf, case_t const& ct) const
383{
384 bool canMove = false;
385
386 if (bPiece::isWhitePiece(b.getPiece(ct))) return false;
387
388 bMove m(cf, ct);
390
391 boardInfo_t oldBoardInfo = b.applyWhiteMove(m);
392 if (!belofte::cWhiteKingClass->isAttacked(b, b.getWhiteKingPos())) canMove = true;
393 b.unApplyMove(m, oldBoardInfo);
394
395 return canMove;
396}
397
398/**
399 * Check if any could be added by just checking there
400 * is not check, break on first
401 * @return true if move seems valid, false if in check after move
402 */
404 case_t const& cf, int8_t const ri, int8_t const ci,
405 uint_fast8_t nMax) const
406{
407 column_t oldcol = bCase::column(cf);
408 column_t newcol = oldcol + ci;
409
410 rank_t oldrank = bCase::rank(cf);
411 rank_t newrank = oldrank + ri;
412
413 bool canMove = false;
414
415 do {
416 if (newcol < 0 || newcol > 7) return false;
417 if (newrank < 0 || newrank > 7) return false;
418
419 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) return false;
420
421 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
422 if (!belofte::cWhiteKingClass->isAttacked(b, b.getWhiteKingPos())) canMove = true;
423 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
424
425 if (canMove) break;
426
427 newcol += ci;
428 newrank += ri;
429 } while (--nMax > 0);
430
431 return canMove;
432}
433
434/**
435 * Check if pawn move could be added by just checking there
436 * is not check, case of possible promotion
437 * @return true if move seems valid, false if in check after move
438 */
440 case_t const& cf, int8_t const ri, int8_t const ci) const
441{
442 column_t oldcol = bCase::column(cf);
443
444 column_t newcol = oldcol + ci;
445 if (newcol < 0 || newcol > 7) return false;
446
447 rank_t oldrank = bCase::rank(cf);
448
449 rank_t newrank = oldrank + ri;
450 if (newrank < 0 || newrank > 7) return false;
451
452 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) return false;
453
454 bool canMove = true;
455
456 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
457 if (belofte::cWhiteKingClass->isAttacked(b, b.getWhiteKingPos())) canMove = false;
458 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
459
460 return canMove;
461}
462
463/**
464 * Check if any could be added by just checking there
465 * @return true if move seems valid, false if in check after move
466 */
468 case_t const& cf, case_t const& ct) const
469{
470 bool canMove = false;
471
472 if (bPiece::isBlackPiece(b.getPiece(ct))) return false;
473
474 bMove m(cf, ct);
476
477 boardInfo_t oldBoardInfo = b.applyBlackMove(m);
478 if (!belofte::cBlackKingClass->isAttacked(b, b.getBlackKingPos())) canMove = true;
479 b.unApplyMove(m, oldBoardInfo);
480
481 return canMove;
482}
483
484/**
485 * Check if pawn move could be added by just checking there
486 * is not check, case of possible promotion
487 * @return true if move seems valid, false if in check after move
488 */
490 case_t const& cf, int8_t const ri, int8_t const ci,
491 uint_fast8_t nMax) const
492{
493 column_t oldcol = bCase::column(cf);
494 column_t newcol = oldcol + ci;
495
496 rank_t oldrank = bCase::rank(cf);
497 rank_t newrank = oldrank + ri;
498
499 bool canMove = false;
500
501 do {
502 if (newcol < 0 || newcol > 7) return false;
503 if (newrank < 0 || newrank > 7) return false;
504
505 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
506
507 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
508 if (!belofte::cBlackKingClass->isAttacked(b, b.getBlackKingPos())) canMove = true;
509 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
510
511 if (canMove) break;
512
513 newcol += ci;
514 newrank += ri;
515 } while (--nMax > 0);
516
517 return canMove;
518}
519
520/**
521 * Check if pawn move could be added by just checking there
522 * is not check, case of possible promotion
523 * @return true if move seems valid, false if in check after move
524 */
526 case_t const& cf, int8_t const ri, int8_t const ci) const
527{
528 column_t oldcol = bCase::column(cf);
529
530 column_t newcol = oldcol + ci;
531 if (newcol < 0 || newcol > 7) return false;
532
533 rank_t oldrank = bCase::rank(cf);
534
535 rank_t newrank = oldrank + ri;
536 if (newrank < 0 || newrank > 7) return false;
537
538 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
539
540 bool canMove = true;
541
542 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
543 if (belofte::cBlackKingClass->isAttacked(b, b.getBlackKingPos())) canMove = false;
544 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
545
546 return canMove;
547}
548
549/**
550 * Check for in-check position, used for King and Knight
551 */
553 case_t const& cf, case_t const& ct,
554 bMoveList& ml) const
555{
556 if (b.isFieldEmpty(ct)) {
557 bMove m(cf, ct);
558 return ml.addWhiteMoveIfValid(b, m);
559 } else if (bPiece::isBlackPiece(b.getPiece(ct))) {
560 bMove m(cf, ct);
561 m.setCapture();
562 return ml.addWhiteMoveIfValid(b, m);
563 }
564 return 0;
565}
566
568 case_t const& cf, case_t const& ct,
569 bMoveList& ml) const
570{
571 if (b.isFieldEmpty(ct)) {
572 bMove m(cf, ct);
573 return ml.addBlackMoveIfValid(b, m);
574 } else if (bPiece::isWhitePiece(b.getPiece(ct))) {
575 bMove m(cf, ct);
576 m.setCapture();
577 return ml.addBlackMoveIfValid(b, m);
578 }
579 return 0;
580}
581
582/**
583 * Add moves for Queen, Rook and Bishop
584 * @return number of moves generated
585 */
587 case_t const& cf, int8_t const ri, int8_t const ci,
588 bMoveList& ml) const
589{
590 int_fast8_t nMax = 7;
591 movenum_t nMoves = 0;
592 column_t newcol = bCase::column(cf) + ci;
593 rank_t newrank = bCase::rank(cf) + ri;
594
595 while (--nMax >= 0) {
596 if (newcol < 0 || newcol > 7) return nMoves;
597 if (newrank < 0 || newrank > 7) return nMoves;
598
599 case_t to = bCase::coordToCase(newcol, newrank);
600 if (b.isFieldEmpty(to)) {
601 bMove m(cf, to);
602 nMoves += ml.addWhiteMoveIfValid(b, m);
603 } else if (bPiece::isBlackPiece(b.getPiece(to))) {
604 bMove m(cf, to);
605 m.setCapture();
606 nMoves += ml.addWhiteMoveIfValid(b, m);
607 break;
608 } else {
609 // own colour, cannot jump
610 break;
611 }
612 newcol += ci;
613 newrank += ri;
614 }
615 return nMoves;
616}
617
619 case_t const& cf, int8_t const ri, int8_t const ci,
620 bMoveList& ml) const
621{
622 int_fast8_t nMax = 7;
623 movenum_t nMoves = 0;
624 column_t newcol = bCase::column(cf) + ci;
625 rank_t newrank = bCase::rank(cf) + ri;
626
627 while (--nMax >= 0) {
628 if (newcol < 0 || newcol > 7) return nMoves;
629 if (newrank < 0 || newrank > 7) return nMoves;
630
631 case_t to = bCase::coordToCase(newcol, newrank);
632 if (b.isFieldEmpty(to)) {
633 bMove m(cf, to);
634 nMoves += ml.addBlackMoveIfValid(b, m);
635 } else if (bPiece::isWhitePiece(b.getPiece(to))) {
636 bMove m(cf, to);
637 m.setCapture();
638 nMoves += ml.addBlackMoveIfValid(b, m);
639 break;
640 } else {
641 // own colour, cannot jump
642 break;
643 }
644 newcol += ci;
645 newrank += ri;
646 }
647 return nMoves;
648}
649
650/**
651 * Test move is possible, single step non capture move
652 * could be promotion as well
653 */
654bool bWhitePawn::canPawnMove(bBasicBoard& b, case_t const& cf) const
655{
656 // no test on rank, as we remain on board
657 if (!b.isFieldEmpty(cf + 8)) return false;
658
659 return canPawnMovePreflightCheck(b, cf, 1, 0);
660}
661
662/**
663 * Test move is possible, pawn capture move
664 * could be promotion as well
665 * @todo only look left and right when required
666 */
667bool bWhitePawn::canPawnCapture(bBasicBoard& b,
668 case_t const& cf, int8_t const ci) const
669{
670 column_t newcol = bCase::column(cf) + ci;
671 if (newcol < 0 || newcol > 7) return false;
672
673 rank_t newrank = bCase::rank(cf) + 1;
674 // no test on rank, as we remain on board
675
676 if (!bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
677
678 return canPawnMovePreflightCheck(b, cf, 1, ci);
679}
680
681/**
682 * Test if e.p. move is possible
683 */
684bool bWhitePawn::canPawnEPMove(bBasicBoard& b,
685 case_t const& cf, int8_t const ci) const
686{
687 column_t newcol = bCase::column(cf) + ci;
688 if (newcol < 0 || newcol > 7) return false;
689
690 // no test on rank, as we remain on board
691
692 if (bCase::column(cf) != b.getEpColumn() + ci) return false;
693
694 return canMovePreflightCheck(b, cf, 1, ci);
695}
696
697/**
698 * Test move is possible, single step move
699 * non capture move
700 */
702 case_t const& cf, bMoveList& ml) const
703{
704 // no test on rank, as we remain on board
705 case_t to = cf + 8;
706 if (b.isFieldEmpty(to)) {
707 bMove m(cf, to);
708 m.setPawnMove();
709 movenum_t nMoves = ml.addWhiteMoveIfValid(b, m);
710 to = cf + 16;
711 if ((bCase::rank(cf) == 1) && b.isFieldEmpty(to)) {
712 bMove m2(cf, to);
713 m2.setEPPossible();
714 nMoves += ml.addWhiteMoveIfValid(b, m2);
715 }
716 return nMoves;
717 }
718 return 0;
719}
720
721/**
722 * Test move is possible, single step non capture move
723 * could be promotion as well
724 */
725bool bBlackPawn::canPawnMove(bBasicBoard& b, case_t const& cf) const
726{
727 // no test on rank, as we remain on board
728 if (!b.isFieldEmpty(cf - 8)) return false;
729
730 return canPawnMovePreflightCheck(b, cf, -1, 0);
731}
732
733/**
734 * Test move is possible, pawn capture move
735 * could be promotion as well
736 * @todo only look left and right when required
737 */
738bool bBlackPawn::canPawnCapture(bBasicBoard& b,
739 case_t const& cf, int8_t const ci) const
740{
741 column_t newcol = bCase::column(cf) + ci;
742 if (newcol < 0 || newcol > 7) return false;
743
744 rank_t newrank = bCase::rank(cf) - 1;
745 // no test on rank, as we remain on board
746
747 if (!bPiece::isWhitePiece(b.getPiece(newcol, newrank))) return false;
748
749 return canPawnMovePreflightCheck(b, cf, -1, ci);
750}
751
752/**
753 * Test if e.p. move is possible
754 */
755bool bBlackPawn::canPawnEPMove(bBasicBoard& b,
756 case_t const& cf, int8_t const ci) const
757{
758 column_t newcol = bCase::column(cf) + ci;
759 if (newcol < 0 || newcol > 7) return false;
760
761 // no test on rank, as we remain on board
762
763 if (bCase::column(cf) != b.getEpColumn() + ci) return false;
764
765 return canMovePreflightCheck(b, cf, -1, ci);
766}
767
768/**
769 * Test move is possible, single step move
770 * non capture move
771 */
773 case_t const& cf, bMoveList& ml) const
774{
775 // no test on rank, as we remain on board
776 case_t to = cf - 8;
777 if (b.isFieldEmpty(to)) {
778 bMove m(cf, to);
779 m.setPawnMove();
780 movenum_t nMoves = ml.addBlackMoveIfValid(b, m);
781 to = cf - 16;
782 if ((bCase::rank(cf) == 6) && b.isFieldEmpty(to)) {
783 bMove m2(cf, to);
784 m2.setEPPossible();
785 nMoves += ml.addBlackMoveIfValid(b, m2);
786 }
787 return nMoves;
788 }
789 return 0;
790}
791
793 case_t const& cf, int8_t const ci, bMoveList& ml) const
794{
795 column_t newcol = bCase::column(cf) + ci;
796 if (newcol < 0 || newcol > 7) return 0;
797
798 rank_t newrank = bCase::rank(cf) + 1;
799 // no test on rank, as we remain on board
800
801 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) {
802 bMove m(cf, bCase::coordToCase(newcol, newrank));
803 m.setPawnMove();
804 m.setCapture();
805 return ml.addWhiteMoveIfValid(b, m);
806 }
807 return 0;
808}
809
811 case_t const& cf, int8_t const ci, bMoveList& ml) const
812{
813 column_t newcol = bCase::column(cf) + ci;
814 if (newcol < 0 || newcol > 7) return 0;
815
816 rank_t newrank = bCase::rank(cf) - 1;
817 // no test on rank, as we remain on board
818
819 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) {
820 bMove m(cf, bCase::coordToCase(newcol, newrank));
821 m.setPawnMove();
822 m.setCapture();
823 return ml.addBlackMoveIfValid(b, m);
824 }
825 return 0;
826}
827
828/**
829 * Test move is possible, single step move
830 * non capture move
831 */
833 case_t const& cf, bMoveList& ml) const
834{
835 // no test on new rank, as promotion is always in good rank
837 if (b.isFieldEmpty(to)) {
838 bMove m(cf, to);
839 return ml.addWhitePromotionIfValid(b, m);
840 }
841 return 0;
842}
843
845 case_t const& cf, bMoveList& ml) const
846{
847 // no test on new rank, as promotion is always in good rank
849 if (b.isFieldEmpty(to)) {
850 bMove m(cf, to);
851 return ml.addBlackPromotionIfValid(b, m);
852 }
853 return 0;
854}
855
856/**
857 * Test move is possible, single step move
858 * capture only move
859 */
861 case_t const& cf, int8_t const ci, bMoveList& ml) const
862{
863 column_t newcol = bCase::column(cf) + ci;
864
865 if (newcol < 0 || newcol > 7) return 0;
866 // no test on new rank, as capture promotion is always in good rank
867
868 rank_t newrank = 7;
869
870 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) {
871 bMove m(cf, bCase::coordToCase(newcol, newrank));
872 m.setCapture();
873 return ml.addWhitePromotionIfValid(b, m);
874 }
875 return 0;
876}
877
879 case_t const& cf, int8_t const ci, bMoveList& ml) const
880{
881 column_t newcol = bCase::column(cf) + ci;
882
883 if (newcol < 0 || newcol > 7) return 0;
884 // no test on new rank, as capture promotion is always in good rank
885
886 rank_t newrank = 0;
887
888 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) {
889 bMove m(cf, bCase::coordToCase(newcol, newrank));
890 m.setCapture();
891 return ml.addBlackPromotionIfValid(b, m);
892 }
893 return 0;
894}
895
896/**
897 * Test move is possible, e.p. move
898 * capture only move, no test if pawn is present
899 * only board e.p. flag is used in calling function
900 */
902 case_t const& cf, int8_t const ci, bMoveList& ml) const
903{
904 // no test on column, as e.p. move is pre-calculated
905 // no test on new rank, as e.p. is always in good rank
906 case_t to = bCase::coordToCase(bCase::column(cf) + ci, bCase::rank(cf) + 1);
907 bMove m(cf, to);
908 m.setCapture();
909 m.setEPMove();
910 return ml.addWhiteMoveIfValid(b, m);
911}
912
913/**
914 * Test move is possible, e.p. move
915 * capture only move, no test if pawn is present
916 * only board e.p. flag is used in calling function
917 */
919 case_t const& cf, int8_t const ci, bMoveList& ml) const
920{
921 // no test on column, as e.p. move is pre-calculated
922 // no test on new rank, as e.p. is always in good rank
923 case_t to = bCase::coordToCase(bCase::column(cf) + ci, bCase::rank(cf) - 1);
924 bMove m(cf, to);
925 m.setCapture();
926 m.setEPMove();
927 return ml.addBlackMoveIfValid(b, m);
928}
929
930/**
931 * check if there is at least one move possible
932 * currently, relies on full move generation for pawn
933 */
935{
936 if (canPawnMove(b, cf)) return true;
937 if (canPawnCapture(b, cf, -1)) return true;
938 if (canPawnCapture(b, cf, 1)) return true;
939 if (bCase::rank(cf) == 4 && b.isEpSet()) {
940 if (canPawnEPMove(b, cf, -1)) return true;
941 if (canPawnEPMove(b, cf, 1)) return true;
942 }
943 return false;
944}
945
947 case_t const& cf, bMoveList& ml)
948{
949 movenum_t nMoves = 0;
950
951 rank_t oldrank = bCase::rank(cf);
952
953 if (oldrank == 6) {
954 nMoves += addNonCapturePromotionMove(b, cf, ml);
955 nMoves += addCapturePromotionMove(b, cf, -1, ml);
956 nMoves += addCapturePromotionMove(b, cf, 1, ml);
957 } else {
958 nMoves += addNonCapturePawnMove(b, cf, ml);
959 nMoves += addCapturePawnMove(b, cf, -1, ml);
960 nMoves += addCapturePawnMove(b, cf, 1, ml);
961 if (oldrank == 4 && b.isEpSet()) {
962 if (bCase::column(cf) == b.getEpColumn() + 1) {
963 nMoves += addEPMove(b, cf, -1, ml);
964 } else if (bCase::column(cf) == b.getEpColumn() - 1) {
965 nMoves += addEPMove(b, cf, 1, ml);
966 }
967 }
968 }
969 return nMoves;
970}
971
972/**
973 * check if there is at least one move possible
974 * currently, relies on full move generation for pawn
975 */
977{
978 if (canPawnMove(b, cf)) return true;
979 if (canPawnCapture(b, cf, -1)) return true;
980 if (canPawnCapture(b, cf, 1)) return true;
981 if (bCase::rank(cf) == 3 && b.isEpSet()) {
982 if (canPawnEPMove(b, cf, -1)) return true;
983 if (canPawnEPMove(b, cf, 1)) return true;
984 }
985 return false;
986}
987
989 case_t const& cf, bMoveList& ml)
990{
991 movenum_t nMoves = 0;
992
993 rank_t oldrank = bCase::rank(cf);
994
995 if (oldrank == 1) {
996 nMoves += addNonCapturePromotionMove(b, cf, ml);
997 nMoves += addCapturePromotionMove(b, cf, -1, ml);
998 nMoves += addCapturePromotionMove(b, cf, 1, ml);
999 } else {
1000 nMoves += addNonCapturePawnMove(b, cf, ml);
1001 nMoves += addCapturePawnMove(b, cf, -1, ml);
1002 nMoves += addCapturePawnMove(b, cf, 1, ml);
1003 if (oldrank == 3 && b.isEpSet()) {
1004 if (bCase::column(cf) == b.getEpColumn() + 1) {
1005 nMoves += addEPMove(b, cf, -1, ml);
1006 } else if (bCase::column(cf) == b.getEpColumn() - 1) {
1007 nMoves += addEPMove(b, cf, 1, ml);
1008 }
1009 }
1010 }
1011 return nMoves;
1012}
1013
1015{
1016 if (canMovePreflightCheck(b, cf, -1, 0, 7)
1017 || canMovePreflightCheck(b, cf, 1, 0, 7)
1018 || canMovePreflightCheck(b, cf, 0, 1, 7)
1019 || canMovePreflightCheck(b, cf, 0, -1, 7)) return true;
1020 return false;
1021}
1022
1024{
1025 if (canMovePreflightCheck(b, cf, -1, 0, 7)
1026 || canMovePreflightCheck(b, cf, 1, 0, 7)
1027 || canMovePreflightCheck(b, cf, 0, -1, 7)
1028 || canMovePreflightCheck(b, cf, 0, 1, 7)) return true;
1029 return false;
1030}
1031
1033 case_t const& cf, bMoveList& ml)
1034{
1035 movenum_t nMoves = 0;
1036
1037 nMoves += addMoves(b, cf, -1, 0, ml);
1038 nMoves += addMoves(b, cf, 1, 0, ml);
1039 nMoves += addMoves(b, cf, 0, -1, ml);
1040 nMoves += addMoves(b, cf, 0, 1, ml);
1041
1042 return nMoves;
1043}
1044
1046 case_t const& cf, bMoveList& ml)
1047{
1048 movenum_t nMoves = 0;
1049
1050 nMoves += addMoves(b, cf, -1, 0, ml);
1051 nMoves += addMoves(b, cf, 1, 0, ml);
1052 nMoves += addMoves(b, cf, 0, -1, ml);
1053 nMoves += addMoves(b, cf, 0, 1, ml);
1054
1055 return nMoves;
1056}
1057
1059{
1060 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1061 if (canMovePreflightCheck(b, cf, belofte::knightarray[cf][iMove])) return true;
1062 }
1063
1064 return false;
1065}
1066
1068{
1069 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1070 if (canMovePreflightCheck(b, cf, belofte::knightarray[cf][iMove])) return true;
1071 }
1072
1073 return false;
1074}
1075
1077 case_t const& cf, bMoveList& ml)
1078{
1079 movenum_t nMoves = 0;
1080
1081 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1082 nMoves += addMove(b, cf, belofte::knightarray[cf][iMove], ml);
1083 }
1084
1085 return nMoves;
1086}
1087
1089 case_t const& cf, bMoveList& ml)
1090{
1091 movenum_t nMoves = 0;
1092
1093 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1094 nMoves += addMove(b, cf, belofte::knightarray[cf][iMove], ml);
1095 }
1096
1097 return nMoves;
1098}
1099
1101{
1102 if (canMovePreflightCheck(b, cf, 1, -1, 7)
1103 || canMovePreflightCheck(b, cf, 1, 1, 7)
1104 || canMovePreflightCheck(b, cf, -1, 1, 7)
1105 || canMovePreflightCheck(b, cf, -1, -1, 7)) return true;
1106 return false;
1107}
1108
1110{
1111 if (canMovePreflightCheck(b, cf, -1, -1, 7)
1112 || canMovePreflightCheck(b, cf, 1, -1, 7)
1113 || canMovePreflightCheck(b, cf, -1, 1, 7)
1114 || canMovePreflightCheck(b, cf, 1, 1, 7)) return true;
1115 return false;
1116}
1117
1119 case_t const& cf, bMoveList& ml)
1120{
1121 movenum_t nMoves = 0;
1122
1123 nMoves += addMoves(b, cf, -1, -1, ml);
1124 nMoves += addMoves(b, cf, 1, -1, ml);
1125 nMoves += addMoves(b, cf, -1, 1, ml);
1126 nMoves += addMoves(b, cf, 1, 1, ml);
1127
1128 return nMoves;
1129}
1130
1132 case_t const& cf, bMoveList& ml)
1133{
1134 movenum_t nMoves = 0;
1135
1136 nMoves += addMoves(b, cf, -1, -1, ml);
1137 nMoves += addMoves(b, cf, 1, -1, ml);
1138 nMoves += addMoves(b, cf, -1, 1, ml);
1139 nMoves += addMoves(b, cf, 1, 1, ml);
1140
1141 return nMoves;
1142}
1143
1145{
1146 if (canMovePreflightCheck(b, cf, 0, -1, 7)
1147 || canMovePreflightCheck(b, cf, 0, 1, 7)
1148 || canMovePreflightCheck(b, cf, 1, -1, 7)
1149 || canMovePreflightCheck(b, cf, 1, 0, 7)
1150 || canMovePreflightCheck(b, cf, 1, 1, 7)
1151 || canMovePreflightCheck(b, cf, -1, -1, 7)
1152 || canMovePreflightCheck(b, cf, -1, 0, 7)
1153 || canMovePreflightCheck(b, cf, -1, 1, 7)) return true;
1154 return false;
1155}
1156
1158{
1159 if (canMovePreflightCheck(b, cf, 0, -1, 7)
1160 || canMovePreflightCheck(b, cf, 0, 1, 7)
1161 || canMovePreflightCheck(b, cf, 1, -1, 7)
1162 || canMovePreflightCheck(b, cf, 1, 0, 7)
1163 || canMovePreflightCheck(b, cf, 1, 1, 7)
1164 || canMovePreflightCheck(b, cf, -1, -1, 7)
1165 || canMovePreflightCheck(b, cf, -1, 0, 7)
1166 || canMovePreflightCheck(b, cf, -1, 1, 7)) return true;
1167 return false;
1168}
1169
1171 case_t const& cf, bMoveList& ml)
1172{
1173 movenum_t nMoves = 0;
1174
1175 nMoves += addMoves(b, cf, 0, -1, ml);
1176 nMoves += addMoves(b, cf, 0, 1, ml);
1177 nMoves += addMoves(b, cf, 1, -1, ml);
1178 nMoves += addMoves(b, cf, 1, 0, ml);
1179 nMoves += addMoves(b, cf, 1, 1, ml);
1180 nMoves += addMoves(b, cf, -1, -1, ml);
1181 nMoves += addMoves(b, cf, -1, 0, ml);
1182 nMoves += addMoves(b, cf, -1, 1, ml);
1183
1184 return nMoves;
1185}
1186
1188 case_t const& cf, bMoveList& ml)
1189{
1190 movenum_t nMoves = 0;
1191
1192 nMoves += addMoves(b, cf, 0, -1, ml);
1193 nMoves += addMoves(b, cf, 0, 1, ml);
1194 nMoves += addMoves(b, cf, 1, -1, ml);
1195 nMoves += addMoves(b, cf, 1, 0, ml);
1196 nMoves += addMoves(b, cf, 1, 1, ml);
1197 nMoves += addMoves(b, cf, -1, -1, ml);
1198 nMoves += addMoves(b, cf, -1, 0, ml);
1199 nMoves += addMoves(b, cf, -1, 1, ml);
1200
1201 return nMoves;
1202}
1203
1205{
1206 /// we do not check castle moves, castle is possible only when normal move
1207 /// is possible
1208 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1209 if (canMovePreflightCheck(b, cf, belofte::kingarray[cf][iMove])) return true;
1210 }
1211
1212 return false;
1213}
1214
1216{
1217 /// we do not check castle moves, castle is possible only when normal move
1218 /// is possible
1219 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1220 if (canMovePreflightCheck(b, cf, belofte::kingarray[cf][iMove])) return true;
1221 }
1222
1223 return false;
1224}
1225
1227 case_t const& cf, bMoveList& ml)
1228{
1229 movenum_t nMoves = 0;
1230
1231 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1232 nMoves += addMove(b, cf, belofte::kingarray[cf][iMove], ml);
1233 }
1234
1235 /// king not on original position, so not looking for castle
1236 if (cf != KingStartPosW) return nMoves;
1237
1238 // king in check on original position
1239 if (belofte::cWhiteKingClass->isAttacked(b, cf)) return nMoves;
1240
1242 // short castle, test if row is empty
1243 if (b.isFieldEmpty(5)
1244 && b.isFieldEmpty(6)
1245 && !belofte::cWhiteKingClass->isAttacked(b, 5)) {
1246 // king is not going over attacked field
1247 bMove m(KingStartPosW, 6);
1249 nMoves += ml.addWhiteMoveIfValid(b, m);
1250 }
1251 }
1252
1254 // long castle, test if row is empty
1255 if (b.isFieldEmpty(3)
1256 && b.isFieldEmpty(2)
1257 && b.isFieldEmpty(1)
1258 && !belofte::cWhiteKingClass->isAttacked(b, 3)) {
1259 // king is not going over attacked field
1260 bMove m(KingStartPosW, 2);
1262 nMoves += ml.addWhiteMoveIfValid(b, m);
1263 }
1264 }
1265
1266 return nMoves;
1267}
1268
1270 case_t const& cf, bMoveList& ml)
1271{
1272 movenum_t nMoves = 0;
1273
1274 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1275 nMoves += addMove(b, cf, belofte::kingarray[cf][iMove], ml);
1276 }
1277
1278 /// king not on original position, so not looking for castle
1279 if (cf != KingStartPosB) return nMoves;
1280
1281 // king in check on original position
1282 if (belofte::cBlackKingClass->isAttacked(b, cf)) return nMoves;
1283
1285 // short castle, test if row is empty
1286 if (b.isFieldEmpty(61)
1287 && b.isFieldEmpty(62)
1288 && !belofte::cBlackKingClass->isAttacked(b, 61)) {
1289 // king is not going over attacked field
1290 bMove m(KingStartPosB, 62);
1292 nMoves += ml.addBlackMoveIfValid(b, m);
1293 }
1294 }
1295
1297 // long castle, test if row is empty
1298 if (b.isFieldEmpty(59)
1299 && b.isFieldEmpty(58)
1300 && b.isFieldEmpty(57)
1301 && !belofte::cBlackKingClass->isAttacked(b, 59)) {
1302 // king is not going over attacked field
1303 bMove m(KingStartPosB, 58);
1305 nMoves += ml.addBlackMoveIfValid(b, m);
1306 }
1307 }
1308
1309 return nMoves;
1310}
1311
1312//-----------------------------------------------------------------------
1313// eof
union boardInfo boardInfo_t
#define KingStartPosW
Definition basicboard.h:11
#define KingStartPosB
Definition basicboard.h:12
@ BCASTLE_L
Definition basicboard.h:14
@ BCASTLE_S
Definition basicboard.h:14
@ WCASTLE_S
Definition basicboard.h:14
@ WCASTLE_L
Definition basicboard.h:14
This is the main include file, needs to be included before any other include.
std::bitset< 64 > boardbitmap_t
Definition belofte.h:102
int8_t rank_t
Definition belofte.h:94
int8_t column_t
Definition belofte.h:95
uint_fast8_t movenum_t
Definition belofte.h:100
uint8_t case_t
Definition belofte.h:96
constexpr piece_t getPiece(case_t const cf) const
Definition basicboard.h:172
boardInfo_t makeBoardMove(column_t const oldcol, rank_t const oldrank, column_t const newcol, rank_t const newrank)
apply move to check if in check only, board to be discarded as it will be in incomplete state,...
boardInfo_t applyBlackMove(bMove const &m)
constexpr bool isFieldEmpty(case_t const cf) const
Definition basicboard.h:201
constexpr bool hasCastleRights(uint8_t const f) const
Definition basicboard.h:113
boardInfo_t applyWhiteMove(bMove const &m)
void unApplyMove(bMove const &m, boardInfo_t const oldBoardInfo)
exact restoration of basic board using move details
constexpr case_t getBlackKingPos() const
Definition basicboard.h:208
void unMakeBoardMove(case_t const &cf, column_t const newcol, rank_t const newrank, boardInfo_t const oldBoardInfo)
undo makeBoardMove, restoring previous situation
constexpr case_t getWhiteKingPos() const
Definition basicboard.h:206
constexpr bool isEpSet() const
Definition basicboard.h:89
constexpr column_t getEpColumn() const
Definition basicboard.h:93
void setEPPossible()
Definition basicmove.h:122
void setPawnMove()
Definition basicmove.h:99
void setLongCastleMove()
Definition basicmove.h:105
void setShortCastleMove()
Definition basicmove.h:103
void setCapture()
Definition basicmove.h:95
void setEPMove()
Definition basicmove.h:128
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1109
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1131
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1269
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1215
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1088
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1067
movenum_t addEPMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Test move is possible, e.p.
Definition piece.cpp:918
movenum_t addNonCapturePawnMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml) const
Test move is possible, single step move non capture move.
Definition piece.cpp:772
movenum_t addCapturePawnMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Definition piece.cpp:810
movenum_t addCapturePromotionMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Definition piece.cpp:878
movenum_t addNonCapturePromotionMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml) const
Definition piece.cpp:844
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:988
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
check if there is at least one move possible currently, relies on full move generation for pawn
Definition piece.cpp:976
bool canMovePreflightCheck(bBasicBoard &b, case_t const &cf, case_t const &ct) const override
Check if any could be added by just checking there.
Definition piece.cpp:467
bool isAttacked(bBasicBoard const &b, case_t const &cf) const override
Definition piece.cpp:303
bool canPawnMovePreflightCheck(bBasicBoard &b, case_t const &cf, int8_t const ri, int8_t const ci) const override
Check if pawn move could be added by just checking there is not check, case of possible promotion.
Definition piece.cpp:525
movenum_t addMoves(bBasicBoard const &b, case_t const &cf, int8_t const ri, int8_t const ci, bMoveList &ml) const override
Definition piece.cpp:618
movenum_t addMove(bBasicBoard const &b, case_t const &cf, case_t const &ct, bMoveList &ml) const override
Definition piece.cpp:567
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1187
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1157
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1045
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1023
constexpr rank_t rank() const
Definition case.h:43
static constexpr boardbitmap_t caseToBit(case_t const cf)
Definition case.h:66
constexpr column_t column() const
Definition case.h:41
static constexpr case_t coordToCase(column_t const c, rank_t const r)
Definition case.h:51
Definition move.h:13
movenum_t addBlackMoveIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:193
movenum_t addBlackPromotionIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:250
movenum_t addWhiteMoveIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:177
movenum_t addWhitePromotionIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:209
bool isAttackedBySlider(bBasicBoard const &b, case_t cf, column_t fromcol, rank_t fromrank, int8_t const ci, int8_t const ri, piece_t const cPiece, piece_t const cPiece2) const
Return true if position is attacked by opponent respecting move offsets.
Definition piece.cpp:349
piece representation
Definition piece.h:82
static cpiece_t getPieceChar(piece_t const piece)
static class member function
Definition piece.cpp:219
side_t toMove() const
Definition piece.cpp:209
static bPiece * getPieceClass(piece_t const piece)
static class member function
Definition piece.cpp:160
constexpr piece_t getPiece() const
Definition piece.h:101
static bool isOpponent(side_t const s, piece_t const piece)
static class member function
Definition piece.cpp:231
static bool isOwnColour(side_t const s, piece_t const piece)
static class member function
Definition piece.cpp:239
static bool isBlackPiece(piece_t const p)
static class member function
Definition piece.cpp:254
static bool isWhitePiece(piece_t const p)
static class member function
Definition piece.cpp:247
bPiece()
Definition piece.h:84
static const std::string getPieceStrUpper(piece_t const piece)
static class member function
Definition piece.cpp:173
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1118
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1100
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1226
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1204
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1076
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1058
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:946
movenum_t addNonCapturePawnMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml) const
Test move is possible, single step move non capture move.
Definition piece.cpp:701
movenum_t addCapturePromotionMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Test move is possible, single step move capture only move.
Definition piece.cpp:860
movenum_t addCapturePawnMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Definition piece.cpp:792
movenum_t addEPMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml) const
Test move is possible, e.p.
Definition piece.cpp:901
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
check if there is at least one move possible currently, relies on full move generation for pawn
Definition piece.cpp:934
movenum_t addNonCapturePromotionMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml) const
Test move is possible, single step move non capture move.
Definition piece.cpp:832
bool canPawnMovePreflightCheck(bBasicBoard &b, case_t const &cf, int8_t const ri, int8_t const ci) const override
Check if pawn move could be added by just checking there is not check, case of possible promotion.
Definition piece.cpp:439
movenum_t addMove(bBasicBoard const &b, case_t const &cf, case_t const &ct, bMoveList &ml) const override
Check for in-check position, used for King and Knight.
Definition piece.cpp:552
bool canMovePreflightCheck(bBasicBoard &b, case_t const &cf, case_t const &ct) const override
Check if any could be added by just checking there.
Definition piece.cpp:381
bool isAttacked(bBasicBoard const &b, case_t const &cf) const override
Check if piece on position is attacked, start with piece always on board and then with pieces with gr...
Definition piece.cpp:269
movenum_t addMoves(bBasicBoard const &b, case_t const &cf, int8_t const ri, int8_t const ci, bMoveList &ml) const override
Add moves for Queen, Rook and Bishop.
Definition piece.cpp:586
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1144
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1170
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1014
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1032
Allow index mapper for char values of piece into int in 1-12 range to reduce space and easy initialis...
Definition eval.cpp:22
static boardbitmap_t kingmoves[64]
Definition piece.cpp:18
static bPiece * pieceinstances[tPiece::P_SIZE]
Definition piece.cpp:17
static case_t knightarray[64][9]
Definition piece.cpp:21
static boardbitmap_t knightmoves[64]
Definition piece.cpp:19
bBlackKing const * cBlackKingClass
Definition movelist.cpp:16
static piece_t bPieceIndex[128]
Definition piece.cpp:15
static case_t kingarray[64][9]
Definition piece.cpp:20
bWhiteKing const * cWhiteKingClass
Definition movelist.cpp:15
static cpiece_t bPieceMapper[tPiece::P_SIZE]
Definition piece.cpp:16
void bPiece_dtor()
Definition piece.cpp:150
void bPiece_ctor()
Definition piece.cpp:46
static boardbitmap_t destinationbits_knight(case_t const iCase)
Definition piece.cpp:127
static boardbitmap_t destinationbits_king(case_t const iCase)
Definition piece.cpp:114
static boardbitmap_t destinationbits(case_t const iCase, int8_t const ri, int8_t const ci)
Definition piece.cpp:140
#define S_P_EMPTY
Definition piece.h:17
#define S_P_ROOK
Definition piece.h:16
enum tSide side_t
Definition piece.h:65
@ C_W_KNIGHT
Definition piece.h:23
@ C_W_PAWN
Definition piece.h:24
@ C_B_QUEEN
Definition piece.h:31
@ C_W_ROOK
Definition piece.h:26
@ C_EMPTY
Definition piece.h:20
@ C_B_BISHOP
Definition piece.h:27
@ C_W_QUEEN
Definition piece.h:25
@ C_B_KNIGHT
Definition piece.h:29
@ C_B_PAWN
Definition piece.h:30
@ C_W_BISHOP
Definition piece.h:21
@ C_B_ROOK
Definition piece.h:32
@ C_B_KING
Definition piece.h:28
@ C_W_KING
Definition piece.h:22
@ W_PAWN
Definition piece.h:39
@ W_KNIGHT
Definition piece.h:39
@ P_SIZE
Definition piece.h:41
@ B_BISHOP
Definition piece.h:40
@ W_ROOK
Definition piece.h:39
@ B_ROOK
Definition piece.h:40
@ W_QUEEN
Definition piece.h:39
@ B_KING
Definition piece.h:40
@ P_EMPTY
Definition piece.h:38
@ B_KNIGHT
Definition piece.h:40
@ W_KING
Definition piece.h:39
@ B_PAWN
Definition piece.h:40
@ B_QUEEN
Definition piece.h:40
@ W_BISHOP
Definition piece.h:39
enum tPiece piece_t
Definition piece.h:44
#define S_P_PAWN
Definition piece.h:14
#define S_P_QUEEN
Definition piece.h:15
enum tCPiece cpiece_t
Definition piece.h:35
#define S_P_BISHOP
Definition piece.h:11
#define S_P_KNIGHT
Definition piece.h:13
#define S_P_KING
Definition piece.h:12
@ SIDE_BLACK
Definition piece.h:62
@ SIDE_WHITE
Definition piece.h:61
@ SIDE_UNDEFINED
Definition piece.h:60