Belofte version 2.2.0
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 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 * @static Class static function
339 * Return true if position is attacked by opponent respecting move offsets
340 * @param b board
341 * @param cf from field
342 * @param fromcol field from
343 * @param fromrank field from
344 * @param ci col increment
345 * @param ri row increment
346 * @param cPiece first possible piece (rook/bishop)
347 * @param cPiece2 second possible piece (queen)
348 * @return true/false
349 */
351 case_t cf, column_t fromcol, rank_t fromrank,
352 int8_t const ci, int8_t const ri,
353 piece_t const cPiece, piece_t const cPiece2)
354{
355 int8_t offset = (8 * ri) + ci;
356
357 // slider move (queen, rook, bishop)
358 for (;;) {
359 // touch border?
360 fromcol += ci;
361 if (fromcol < 0 || fromcol > 7) break;
362 fromrank += ri;
363 if (fromrank < 0 || fromrank > 7) break;
364
365 cf += offset;
366 piece_t piece = b.getPiece(cf);
367
368 if (piece) {
369 if (piece == cPiece) return true;
370 if (piece == cPiece2) return true;
371 // not empty, not opponent piece, so protected
372 break;
373 }
374 }
375 return false;
376}
377
378/**
379 * Check if any could be added by just checking there
380 * @return true if move seems valid, false if in check after move
381 */
383 case_t const& cf, case_t const& ct) const
384{
385 bool canMove = false;
386
387 if (bPiece::isWhitePiece(b.getPiece(ct))) return false;
388
389 bMove m(cf, ct);
391
392 boardInfo_t oldBoardInfo = b.applyWhiteMove(m);
393 if (!belofte::cWhiteKingClass->isAttacked(b, b.getWhiteKingPos())) canMove = true;
394 b.unApplyMove(m, oldBoardInfo);
395
396 return canMove;
397}
398
399/**
400 * Check if any could be added by just checking there
401 * is not check, break on first
402 * @return true if move seems valid, false if in check after move
403 */
405 case_t const& cf, int8_t const ri, int8_t const ci) 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 for (;;) {
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 }
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) const
491{
492 column_t oldcol = bCase::column(cf);
493 column_t newcol = oldcol + ci;
494
495 rank_t oldrank = bCase::rank(cf);
496 rank_t newrank = oldrank + ri;
497
498 bool canMove = false;
499
500 for (;;) {
501 if (newcol < 0 || newcol > 7) return false;
502 if (newrank < 0 || newrank > 7) return false;
503
504 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
505
506 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
507 if (!belofte::cBlackKingClass->isAttacked(b, b.getBlackKingPos())) canMove = true;
508 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
509
510 if (canMove) break;
511
512 newcol += ci;
513 newrank += ri;
514 }
515
516 return canMove;
517}
518
519/**
520 * Check if pawn move could be added by just checking there
521 * is not check, case of possible promotion
522 * @return true if move seems valid, false if in check after move
523 */
525 case_t const& cf, int8_t const ri, int8_t const ci) const
526{
527 column_t oldcol = bCase::column(cf);
528
529 column_t newcol = oldcol + ci;
530 if (newcol < 0 || newcol > 7) return false;
531
532 rank_t oldrank = bCase::rank(cf);
533
534 rank_t newrank = oldrank + ri;
535 if (newrank < 0 || newrank > 7) return false;
536
537 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
538
539 bool canMove = true;
540
541 boardInfo_t oldBoardInfo = b.makeBoardMove(oldcol, oldrank, newcol, newrank);
542 if (belofte::cBlackKingClass->isAttacked(b, b.getBlackKingPos())) canMove = false;
543 b.unMakeBoardMove(cf, newcol, newrank, oldBoardInfo);
544
545 return canMove;
546}
547
548/**
549 * Check for in-check position, used for King and Knight
550 */
552 case_t const& cf, case_t const& ct,
553 bMoveList& ml) const
554{
555 if (b.isFieldEmpty(ct)) {
556 bMove m(cf, ct);
557 return ml.addWhiteMoveIfValid(b, m);
558 } else if (bPiece::isBlackPiece(b.getPiece(ct))) {
559 bMove m(cf, ct);
560 m.setCapture();
561 return ml.addWhiteMoveIfValid(b, m);
562 }
563 return 0;
564}
565
567 case_t const& cf, case_t const& ct,
568 bMoveList& ml) const
569{
570 if (b.isFieldEmpty(ct)) {
571 bMove m(cf, ct);
572 return ml.addBlackMoveIfValid(b, m);
573 } else if (bPiece::isWhitePiece(b.getPiece(ct))) {
574 bMove m(cf, ct);
575 m.setCapture();
576 return ml.addBlackMoveIfValid(b, m);
577 }
578 return 0;
579}
580
581/**
582 * Add moves for Queen, Rook and Bishop
583 * @return number of moves generated
584 */
586 case_t const& cf, int8_t const ri, int8_t const ci,
587 bMoveList& ml) const
588{
589 int_fast8_t nMax = 7;
590 movenum_t nMoves = 0;
591 column_t newcol = bCase::column(cf) + ci;
592 rank_t newrank = bCase::rank(cf) + ri;
593
594 while (--nMax >= 0) {
595 if (newcol < 0 || newcol > 7) return nMoves;
596 if (newrank < 0 || newrank > 7) return nMoves;
597
598 case_t to = bCase::coordToCase(newcol, newrank);
599 if (b.isFieldEmpty(to)) {
600 bMove m(cf, to);
601 nMoves += ml.addWhiteMoveIfValid(b, m);
602 } else if (bPiece::isBlackPiece(b.getPiece(to))) {
603 bMove m(cf, to);
604 m.setCapture();
605 nMoves += ml.addWhiteMoveIfValid(b, m);
606 break;
607 } else {
608 // own colour, cannot jump
609 break;
610 }
611 newcol += ci;
612 newrank += ri;
613 }
614 return nMoves;
615}
616
618 case_t const& cf, int8_t const ri, int8_t const ci,
619 bMoveList& ml) const
620{
621 int_fast8_t nMax = 7;
622 movenum_t nMoves = 0;
623 column_t newcol = bCase::column(cf) + ci;
624 rank_t newrank = bCase::rank(cf) + ri;
625
626 while (--nMax >= 0) {
627 if (newcol < 0 || newcol > 7) return nMoves;
628 if (newrank < 0 || newrank > 7) return nMoves;
629
630 case_t to = bCase::coordToCase(newcol, newrank);
631 if (b.isFieldEmpty(to)) {
632 bMove m(cf, to);
633 nMoves += ml.addBlackMoveIfValid(b, m);
634 } else if (bPiece::isWhitePiece(b.getPiece(to))) {
635 bMove m(cf, to);
636 m.setCapture();
637 nMoves += ml.addBlackMoveIfValid(b, m);
638 break;
639 } else {
640 // own colour, cannot jump
641 break;
642 }
643 newcol += ci;
644 newrank += ri;
645 }
646 return nMoves;
647}
648
649/**
650 * Test move is possible, single step non capture move
651 * could be promotion as well
652 */
653bool bWhitePawn::canPawnMove(bBasicBoard& b, case_t const& cf) const
654{
655 // no test on rank, as we remain on board
656 if (!b.isFieldEmpty(cf + 8)) return false;
657
658 return canMovePreflightCheck(b, cf, 1, 0);
659}
660
661/**
662 * Test move is possible, pawn capture move
663 * could be promotion as well
664 * @todo only look left and right when required
665 */
666bool bWhitePawn::canPawnCapture(bBasicBoard& b,
667 case_t const& cf, int8_t const ci) const
668{
669 column_t newcol = bCase::column(cf) + ci;
670 if (newcol < 0 || newcol > 7) return false;
671
672 rank_t newrank = bCase::rank(cf) + 1;
673 // no test on rank, as we remain on board
674
675 if (!bPiece::isBlackPiece(b.getPiece(newcol, newrank))) return false;
676
677 return canMovePreflightCheck(b, cf, 1, ci);
678}
679
680/**
681 * Test if e.p. move is possible
682 */
683bool bWhitePawn::canPawnEPMove(bBasicBoard& b,
684 case_t const& cf, int8_t const ci) const
685{
686 column_t newcol = bCase::column(cf) + ci;
687 if (newcol < 0 || newcol > 7) return false;
688
689 // no test on rank, as we remain on board
690
691 if (bCase::column(cf) != b.getEpColumn() + ci) return false;
692
693 return canMovePreflightCheck(b, cf, 1, ci);
694}
695
696/**
697 * @static Class static function
698 * Test move is possible, single step move
699 * non capture move
700 */
702 case_t const& cf, bMoveList& ml)
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 canMovePreflightCheck(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 canMovePreflightCheck(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 * @static Class static function
770 * Test move is possible, single step move
771 * non capture move
772 */
774 case_t const& cf, bMoveList& ml)
775{
776 // no test on rank, as we remain on board
777 case_t to = cf - 8;
778 if (b.isFieldEmpty(to)) {
779 bMove m(cf, to);
780 m.setPawnMove();
781 movenum_t nMoves = ml.addBlackMoveIfValid(b, m);
782 to = cf - 16;
783 if ((bCase::rank(cf) == 6) && b.isFieldEmpty(to)) {
784 bMove m2(cf, to);
785 m2.setEPPossible();
786 nMoves += ml.addBlackMoveIfValid(b, m2);
787 }
788 return nMoves;
789 }
790 return 0;
791}
792
794 case_t const& cf, int8_t const ci, bMoveList& ml)
795{
796 column_t newcol = bCase::column(cf) + ci;
797 if (newcol < 0 || newcol > 7) return 0;
798
799 rank_t newrank = bCase::rank(cf) + 1;
800 // no test on rank, as we remain on board
801
802 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) {
803 bMove m(cf, bCase::coordToCase(newcol, newrank));
804 m.setPawnMove();
805 m.setCapture();
806 return ml.addWhiteMoveIfValid(b, m);
807 }
808 return 0;
809}
810
812 case_t const& cf, int8_t const ci, bMoveList& ml)
813{
814 column_t newcol = bCase::column(cf) + ci;
815 if (newcol < 0 || newcol > 7) return 0;
816
817 rank_t newrank = bCase::rank(cf) - 1;
818 // no test on rank, as we remain on board
819
820 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) {
821 bMove m(cf, bCase::coordToCase(newcol, newrank));
822 m.setPawnMove();
823 m.setCapture();
824 return ml.addBlackMoveIfValid(b, m);
825 }
826 return 0;
827}
828
829/**
830 * Test move is possible, single step move
831 * non capture move
832 */
834 case_t const& cf, bMoveList& ml)
835{
836 // no test on new rank, as promotion is always in good rank
838 if (b.isFieldEmpty(to)) {
839 bMove m(cf, to);
840 return ml.addWhitePromotionIfValid(b, m);
841 }
842 return 0;
843}
844
846 case_t const& cf, bMoveList& ml)
847{
848 // no test on new rank, as promotion is always in good rank
850 if (b.isFieldEmpty(to)) {
851 bMove m(cf, to);
852 return ml.addBlackPromotionIfValid(b, m);
853 }
854 return 0;
855}
856
857/**
858 * Test move is possible, single step move
859 * capture only move
860 */
862 case_t const& cf, int8_t const ci, bMoveList& ml)
863{
864 column_t newcol = bCase::column(cf) + ci;
865
866 if (newcol < 0 || newcol > 7) return 0;
867 // no test on new rank, as capture promotion is always in good rank
868
869 rank_t newrank = 7;
870
871 if (bPiece::isBlackPiece(b.getPiece(newcol, newrank))) {
872 bMove m(cf, bCase::coordToCase(newcol, newrank));
873 m.setCapture();
874 return ml.addWhitePromotionIfValid(b, m);
875 }
876 return 0;
877}
878
880 case_t const& cf, int8_t const ci, bMoveList& ml)
881{
882 column_t newcol = bCase::column(cf) + ci;
883
884 if (newcol < 0 || newcol > 7) return 0;
885 // no test on new rank, as capture promotion is always in good rank
886
887 rank_t newrank = 0;
888
889 if (bPiece::isWhitePiece(b.getPiece(newcol, newrank))) {
890 bMove m(cf, bCase::coordToCase(newcol, newrank));
891 m.setCapture();
892 return ml.addBlackPromotionIfValid(b, m);
893 }
894 return 0;
895}
896
897/**
898 * Test move is possible, e.p. move
899 * capture only move, no test if pawn is present
900 * only board e.p. flag is used in calling function
901 */
903 case_t const& cf, int8_t const ci, bMoveList& ml)
904{
905 // no test on column, as e.p. move is pre-calculated
906 // no test on new rank, as e.p. is always in good rank
907 case_t to = bCase::coordToCase(bCase::column(cf) + ci, bCase::rank(cf) + 1);
908 bMove m(cf, to);
909 m.setCapture();
910 m.setEPMove();
911 return ml.addWhiteMoveIfValid(b, m);
912}
913
914/**
915 * Test move is possible, e.p. move
916 * capture only move, no test if pawn is present
917 * only board e.p. flag is used in calling function
918 */
920 case_t const& cf, int8_t const ci, bMoveList& ml)
921{
922 // no test on column, as e.p. move is pre-calculated
923 // no test on new rank, as e.p. is always in good rank
924 case_t to = bCase::coordToCase(bCase::column(cf) + ci, bCase::rank(cf) - 1);
925 bMove m(cf, to);
926 m.setCapture();
927 m.setEPMove();
928 return ml.addBlackMoveIfValid(b, m);
929}
930
931/**
932 * check if there is at least one move possible
933 * currently, relies on full move generation for pawn
934 */
936{
937 if (canPawnMove(b, cf)) return true;
938 if (canPawnCapture(b, cf, -1)) return true;
939 if (canPawnCapture(b, cf, 1)) return true;
940 if (bCase::rank(cf) == 4 && b.isEpSet()) {
941 if (canPawnEPMove(b, cf, -1)) return true;
942 if (canPawnEPMove(b, cf, 1)) return true;
943 }
944 return false;
945}
946
948 case_t const& cf, bMoveList& ml)
949{
950 movenum_t nMoves = 0;
951
952 rank_t oldrank = bCase::rank(cf);
953
954 if (oldrank == 6) {
955 nMoves += addNonCapturePromotionMove(b, cf, ml);
956 nMoves += addCapturePromotionMove(b, cf, -1, ml);
957 nMoves += addCapturePromotionMove(b, cf, 1, ml);
958 } else {
959 nMoves += addNonCapturePawnMove(b, cf, ml);
960 nMoves += addCapturePawnMove(b, cf, -1, ml);
961 nMoves += addCapturePawnMove(b, cf, 1, ml);
962 if (oldrank == 4 && b.isEpSet()) {
963 if (bCase::column(cf) == b.getEpColumn() + 1) {
964 nMoves += addEPMove(b, cf, -1, ml);
965 } else if (bCase::column(cf) == b.getEpColumn() - 1) {
966 nMoves += addEPMove(b, cf, 1, ml);
967 }
968 }
969 }
970 return nMoves;
971}
972
973/**
974 * check if there is at least one move possible
975 * currently, relies on full move generation for pawn
976 */
978{
979 if (canPawnMove(b, cf)) return true;
980 if (canPawnCapture(b, cf, -1)) return true;
981 if (canPawnCapture(b, cf, 1)) return true;
982 if (bCase::rank(cf) == 3 && b.isEpSet()) {
983 if (canPawnEPMove(b, cf, -1)) return true;
984 if (canPawnEPMove(b, cf, 1)) return true;
985 }
986 return false;
987}
988
990 case_t const& cf, bMoveList& ml)
991{
992 movenum_t nMoves = 0;
993
994 rank_t oldrank = bCase::rank(cf);
995
996 if (oldrank == 1) {
997 nMoves += addNonCapturePromotionMove(b, cf, ml);
998 nMoves += addCapturePromotionMove(b, cf, -1, ml);
999 nMoves += addCapturePromotionMove(b, cf, 1, ml);
1000 } else {
1001 nMoves += addNonCapturePawnMove(b, cf, ml);
1002 nMoves += addCapturePawnMove(b, cf, -1, ml);
1003 nMoves += addCapturePawnMove(b, cf, 1, ml);
1004 if (oldrank == 3 && b.isEpSet()) {
1005 if (bCase::column(cf) == b.getEpColumn() + 1) {
1006 nMoves += addEPMove(b, cf, -1, ml);
1007 } else if (bCase::column(cf) == b.getEpColumn() - 1) {
1008 nMoves += addEPMove(b, cf, 1, ml);
1009 }
1010 }
1011 }
1012 return nMoves;
1013}
1014
1016{
1017 if (canMovePreflightCheck(b, cf, -1, 0)
1018 || canMovePreflightCheck(b, cf, 1, 0)
1019 || canMovePreflightCheck(b, cf, 0, 1)
1020 || canMovePreflightCheck(b, cf, 0, -1)) return true;
1021 return false;
1022}
1023
1025{
1026 if (canMovePreflightCheck(b, cf, -1, 0)
1027 || canMovePreflightCheck(b, cf, 1, 0)
1028 || canMovePreflightCheck(b, cf, 0, -1)
1029 || canMovePreflightCheck(b, cf, 0, 1)) return true;
1030 return false;
1031}
1032
1034 case_t const& cf, bMoveList& ml)
1035{
1036 movenum_t nMoves = 0;
1037
1038 nMoves += addMoves(b, cf, -1, 0, ml);
1039 nMoves += addMoves(b, cf, 1, 0, ml);
1040 nMoves += addMoves(b, cf, 0, -1, ml);
1041 nMoves += addMoves(b, cf, 0, 1, ml);
1042
1043 return nMoves;
1044}
1045
1047 case_t const& cf, bMoveList& ml)
1048{
1049 movenum_t nMoves = 0;
1050
1051 nMoves += addMoves(b, cf, -1, 0, ml);
1052 nMoves += addMoves(b, cf, 1, 0, ml);
1053 nMoves += addMoves(b, cf, 0, -1, ml);
1054 nMoves += addMoves(b, cf, 0, 1, ml);
1055
1056 return nMoves;
1057}
1058
1060{
1061 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1062 if (canMovePreflightCheck(b, cf, belofte::knightarray[cf][iMove])) return true;
1063 }
1064
1065 return false;
1066}
1067
1069{
1070 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1071 if (canMovePreflightCheck(b, cf, belofte::knightarray[cf][iMove])) return true;
1072 }
1073
1074 return false;
1075}
1076
1078 case_t const& cf, bMoveList& ml)
1079{
1080 movenum_t nMoves = 0;
1081
1082 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1083 nMoves += addMove(b, cf, belofte::knightarray[cf][iMove], ml);
1084 }
1085
1086 return nMoves;
1087}
1088
1090 case_t const& cf, bMoveList& ml)
1091{
1092 movenum_t nMoves = 0;
1093
1094 for (int_fast8_t iMove = 1; iMove <= belofte::knightarray[cf][0]; ++iMove) {
1095 nMoves += addMove(b, cf, belofte::knightarray[cf][iMove], ml);
1096 }
1097
1098 return nMoves;
1099}
1100
1102{
1103 if (canMovePreflightCheck(b, cf, 1, -1)
1104 || canMovePreflightCheck(b, cf, 1, 1)
1105 || canMovePreflightCheck(b, cf, -1, 1)
1106 || canMovePreflightCheck(b, cf, -1, -1)) return true;
1107 return false;
1108}
1109
1111{
1112 if (canMovePreflightCheck(b, cf, -1, -1)
1113 || canMovePreflightCheck(b, cf, 1, -1)
1114 || canMovePreflightCheck(b, cf, -1, 1)
1115 || canMovePreflightCheck(b, cf, 1, 1)) return true;
1116 return false;
1117}
1118
1120 case_t const& cf, bMoveList& ml)
1121{
1122 movenum_t nMoves = 0;
1123
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 nMoves += addMoves(b, cf, 1, 1, ml);
1128
1129 return nMoves;
1130}
1131
1133 case_t const& cf, bMoveList& ml)
1134{
1135 movenum_t nMoves = 0;
1136
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 nMoves += addMoves(b, cf, 1, 1, ml);
1141
1142 return nMoves;
1143}
1144
1146{
1147 if (canMovePreflightCheck(b, cf, 0, -1)
1148 || canMovePreflightCheck(b, cf, 0, 1)
1149 || canMovePreflightCheck(b, cf, 1, -1)
1150 || canMovePreflightCheck(b, cf, 1, 0)
1151 || canMovePreflightCheck(b, cf, 1, 1)
1152 || canMovePreflightCheck(b, cf, -1, -1)
1153 || canMovePreflightCheck(b, cf, -1, 0)
1154 || canMovePreflightCheck(b, cf, -1, 1)) return true;
1155 return false;
1156}
1157
1159{
1160 if (canMovePreflightCheck(b, cf, 0, -1)
1161 || canMovePreflightCheck(b, cf, 0, 1)
1162 || canMovePreflightCheck(b, cf, 1, -1)
1163 || canMovePreflightCheck(b, cf, 1, 0)
1164 || canMovePreflightCheck(b, cf, 1, 1)
1165 || canMovePreflightCheck(b, cf, -1, -1)
1166 || canMovePreflightCheck(b, cf, -1, 0)
1167 || canMovePreflightCheck(b, cf, -1, 1)) return true;
1168 return false;
1169}
1170
1172 case_t const& cf, bMoveList& ml)
1173{
1174 movenum_t nMoves = 0;
1175
1176 nMoves += addMoves(b, cf, 0, -1, ml);
1177 nMoves += addMoves(b, cf, 0, 1, ml);
1178 nMoves += addMoves(b, cf, 1, -1, ml);
1179 nMoves += addMoves(b, cf, 1, 0, ml);
1180 nMoves += addMoves(b, cf, 1, 1, ml);
1181 nMoves += addMoves(b, cf, -1, -1, ml);
1182 nMoves += addMoves(b, cf, -1, 0, ml);
1183 nMoves += addMoves(b, cf, -1, 1, ml);
1184
1185 return nMoves;
1186}
1187
1189 case_t const& cf, bMoveList& ml)
1190{
1191 movenum_t nMoves = 0;
1192
1193 nMoves += addMoves(b, cf, 0, -1, ml);
1194 nMoves += addMoves(b, cf, 0, 1, ml);
1195 nMoves += addMoves(b, cf, 1, -1, ml);
1196 nMoves += addMoves(b, cf, 1, 0, ml);
1197 nMoves += addMoves(b, cf, 1, 1, ml);
1198 nMoves += addMoves(b, cf, -1, -1, ml);
1199 nMoves += addMoves(b, cf, -1, 0, ml);
1200 nMoves += addMoves(b, cf, -1, 1, ml);
1201
1202 return nMoves;
1203}
1204
1206{
1207 /// we do not check castle moves, castle is possible only when normal move
1208 /// is possible
1209 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1210 if (canMovePreflightCheck(b, cf, belofte::kingarray[cf][iMove])) return true;
1211 }
1212
1213 return false;
1214}
1215
1217{
1218 /// we do not check castle moves, castle is possible only when normal move
1219 /// is possible
1220 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1221 if (canMovePreflightCheck(b, cf, belofte::kingarray[cf][iMove])) return true;
1222 }
1223
1224 return false;
1225}
1226
1228 case_t const& cf, bMoveList& ml)
1229{
1230 movenum_t nMoves = 0;
1231
1232 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1233 nMoves += addMove(b, cf, belofte::kingarray[cf][iMove], ml);
1234 }
1235
1236 /// king not on original position, so not looking for castle
1237 if (cf != KingStartPosW) return nMoves;
1238
1239 // king in check on original position
1240 if (belofte::cWhiteKingClass->isAttacked(b, cf)) return nMoves;
1241
1243 // short castle, test if row is empty
1244 if (b.isFieldEmpty(5)
1245 && b.isFieldEmpty(6)
1246 && !belofte::cWhiteKingClass->isAttacked(b, 5)) {
1247 // king is not going over attacked field
1248 bMove m(KingStartPosW, 6);
1250 nMoves += ml.addWhiteMoveIfValid(b, m);
1251 }
1252 }
1253
1255 // long castle, test if row is empty
1256 if (b.isFieldEmpty(3)
1257 && b.isFieldEmpty(2)
1258 && b.isFieldEmpty(1)
1259 && !belofte::cWhiteKingClass->isAttacked(b, 3)) {
1260 // king is not going over attacked field
1261 bMove m(KingStartPosW, 2);
1263 nMoves += ml.addWhiteMoveIfValid(b, m);
1264 }
1265 }
1266
1267 return nMoves;
1268}
1269
1271 case_t const& cf, bMoveList& ml)
1272{
1273 movenum_t nMoves = 0;
1274
1275 for (int_fast8_t iMove = 1; iMove <= belofte::kingarray[cf][0]; ++iMove) {
1276 nMoves += addMove(b, cf, belofte::kingarray[cf][iMove], ml);
1277 }
1278
1279 /// king not on original position, so not looking for castle
1280 if (cf != KingStartPosB) return nMoves;
1281
1282 // king in check on original position
1283 if (belofte::cBlackKingClass->isAttacked(b, cf)) return nMoves;
1284
1286 // short castle, test if row is empty
1287 if (b.isFieldEmpty(61)
1288 && b.isFieldEmpty(62)
1289 && !belofte::cBlackKingClass->isAttacked(b, 61)) {
1290 // king is not going over attacked field
1291 bMove m(KingStartPosB, 62);
1293 nMoves += ml.addBlackMoveIfValid(b, m);
1294 }
1295 }
1296
1298 // long castle, test if row is empty
1299 if (b.isFieldEmpty(59)
1300 && b.isFieldEmpty(58)
1301 && b.isFieldEmpty(57)
1302 && !belofte::cBlackKingClass->isAttacked(b, 59)) {
1303 // king is not going over attacked field
1304 bMove m(KingStartPosB, 58);
1306 nMoves += ml.addBlackMoveIfValid(b, m);
1307 }
1308 }
1309
1310 return nMoves;
1311}
1312
1313//-----------------------------------------------------------------------
1314// 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:105
int8_t rank_t
Definition belofte.h:97
int8_t column_t
Definition belofte.h:98
uint_fast8_t movenum_t
Definition belofte.h:103
uint8_t case_t
Definition belofte.h:99
constexpr piece_t getPiece(case_t const cf) const
Definition basicboard.h:178
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:207
constexpr bool hasCastleRights(uint8_t const f) const
Definition basicboard.h:119
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:214
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:212
constexpr bool isEpSet() const
Definition basicboard.h:95
constexpr column_t getEpColumn() const
Definition basicboard.h:99
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:1110
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1132
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1270
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1216
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1089
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1068
static movenum_t addNonCapturePromotionMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml)
Definition piece.cpp:845
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:989
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:977
static movenum_t addNonCapturePawnMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml)
Class static function Test move is possible, single step move non capture move.
Definition piece.cpp:773
static movenum_t addCapturePawnMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Definition piece.cpp:811
bool canMovePreflightCheck(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:524
static movenum_t addEPMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Test move is possible, e.p.
Definition piece.cpp:919
static movenum_t addCapturePromotionMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Definition piece.cpp:879
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
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:617
movenum_t addMove(bBasicBoard const &b, case_t const &cf, case_t const &ct, bMoveList &ml) const override
Definition piece.cpp:566
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1188
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1158
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1046
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1024
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:267
movenum_t addBlackPromotionIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:324
movenum_t addWhiteMoveIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:251
movenum_t addWhitePromotionIfValid(bBasicBoard const &b, bMove &m)
Only add move to movelist if valid.
Definition movelist.cpp:283
static 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)
Class static function Return true if position is attacked by opponent respecting move offsets.
Definition piece.cpp:350
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 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:1119
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1101
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1227
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1205
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1077
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1059
bool canMovePreflightCheck(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 GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:947
static movenum_t addCapturePromotionMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Test move is possible, single step move capture only move.
Definition piece.cpp:861
static movenum_t addNonCapturePromotionMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml)
Test move is possible, single step move non capture move.
Definition piece.cpp:833
static movenum_t addCapturePawnMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Definition piece.cpp:793
static movenum_t addEPMove(bBasicBoard const &b, case_t const &cf, int8_t const ci, bMoveList &ml)
Test move is possible, e.p.
Definition piece.cpp:902
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:935
static movenum_t addNonCapturePawnMove(bBasicBoard const &b, case_t const &cf, bMoveList &ml)
Class static function Test move is possible, single step move non capture move.
Definition piece.cpp:701
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:551
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:382
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:585
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1145
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1171
bool hasValidMovePreflightCheck(bBasicBoard &b, case_t const &cf) override
Definition piece.cpp:1015
movenum_t GenerateMoves(bBasicBoard const &b, case_t const &cf, bMoveList &ml) override
Definition piece.cpp:1033
Allow index mapper for char values of piece into int in 1-12 range to reduce space and easy initialis...
Definition eval.cpp:10
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