LCOV - code coverage report
Current view: top level - src - fullmove.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 68 71 95.8 %
Date: 2019-01-29 11:06:41 Functions: 17 18 94.4 %

          Line data    Source code
       1             : /*
       2             : * Copyright (C) 2014  Fulvio Benini
       3             : 
       4             : * This file is part of Scid (Shane's Chess Information Database).
       5             : *
       6             : * Scid is free software: you can redistribute it and/or modify
       7             : * it under the terms of the GNU General Public License as published by
       8             : * the Free Software Foundation.
       9             : *
      10             : * Scid is distributed in the hope that it will be useful,
      11             : * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : * GNU General Public License for more details.
      14             : *
      15             : * You should have received a copy of the GNU General Public License
      16             : * along with Scid.  If not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : 
      19             : #ifndef FULLMOVE_H
      20             : #define FULLMOVE_H
      21             : 
      22             : #include "common.h"
      23             : #include <string>
      24             : 
      25             : class FullMove {
      26             :         // ** Lower 16 bits are compatible with Stockfish's Move **
      27             :         // bits  0- 5: destination square (from 0 to 63)
      28             :         // bits  6-11: origin square (from 0 to 63)
      29             :         // bits 12-13: promotion piece type -2 (from QUEEN-2 to KNIGHT-2)
      30             :         // bits 14-15: special move flag: promotion (1), en passant (2), castling (3)
      31             : 
      32             :         // ** Info for undoing the move **
      33             :         // bits 16-17: castling flags - TODO
      34             :         // bits 18-20: enpassant file - TODO
      35             :         // bits 21-23: captured pieceT
      36             : 
      37             :         // ** Info for direct SAN conversion **
      38             :         // bits 24-26: moving pieceT
      39             :         // bit     27: black to move
      40             :         // bit     28: ambiguous move, insert from fyle
      41             :         // bit     29: ambiguous move, insert from rank
      42             :         // bit     30: check
      43             : 
      44             :         // ** TODO: Use this flag to embed tags, variations, etc.. in a move stream
      45             :         // bit     31: special flag
      46             :         uint32_t m_;
      47             : 
      48             : public:
      49        6902 :         constexpr FullMove(uint32_t m = 0) : m_(m){};
      50             : 
      51           1 :         FullMove(colorT c, squareT kingSq, squareT rookSq)
      52             :             // Castle: encoding as king to rook allows the undoing of chess360 moves
      53           1 :             : FullMove(c, kingSq, rookSq, KING) {
      54           1 :                 m_ |= (3 << 14);
      55           1 :         }
      56             : 
      57          34 :         FullMove(colorT c, squareT from, squareT to, pieceT pt) {
      58          34 :                 m_ = to | (from << 6) | (pt << 24) | (c << 27);
      59          34 :         }
      60             : 
      61     2425730 :         operator bool() const { return m_ != 0; }
      62           0 :         bool operator!=(const FullMove& f) const { return m_ != f.m_; }
      63          39 :         bool    isPromo()     const { return (m_ & (3 << 14)) == (1 << 14); }
      64             :         bool    isEnpassant() const { return (m_ & (3 << 14)) == (2 << 14); }
      65          34 :         bool    isCastle()    const { return (m_ & (3 << 14)) == (3 << 14); }
      66      234375 :         squareT getTo()       const { return m_ & 0x3F; }
      67     2418832 :         squareT getFrom()     const { return (m_ >> 6) & 0x3F; }
      68          67 :         pieceT  getPiece()    const { return (m_ >> 24) & 0x07; }
      69          34 :         colorT  getColor()    const { return (m_ >> 27 & 1) ? BLACK : WHITE; }
      70          10 :         pieceT  getPromo()    const { return ((m_ >> 12) & 0x03) +2; }
      71          33 :         pieceT  getCaptured() const { return (m_ >> 21) & 0x07; }
      72          34 :         std::string getSAN(colorT* toMove = 0) const {
      73          68 :                 std::string res;
      74          34 :                 if (toMove) *toMove = getColor();
      75          34 :                 squareT to = getTo();
      76          34 :                 squareT from = getFrom();
      77          34 :                 if (to == 0 && from == 0) return "--";
      78          34 :                 if (isCastle()) {
      79           1 :                         res = (to > from) ? "O-O" : "O-O-O";
      80           1 :                         bool check = (m_ >> 30) & 1;
      81           1 :                         if (check)
      82           1 :                                 res += "+";
      83           1 :                         return res;
      84             :                 }
      85          33 :                 bool fromFyle = (m_ >> 28) & 1;
      86          33 :                 bool fromRank = (m_ >> 29) & 1;
      87          33 :                 bool check    = (m_ >> 30) & 1;
      88          33 :                 bool capture  = (getCaptured() != 0);
      89             : 
      90          33 :                 switch (getPiece()) {
      91           4 :                 case BISHOP: res += "B"; break;
      92           7 :                 case KNIGHT: res += "N"; break;
      93           7 :                 case ROOK:   res += "R"; break;
      94           9 :                 case QUEEN:  res += "Q"; break;
      95           0 :                 case KING:   res += "K"; break;
      96           6 :                 default: //PAWN
      97           6 :                         if (capture) res += 'a' + (from % 8);
      98             :                 }
      99          33 :                 if (fromFyle) res += 'a' + (from % 8);
     100          33 :                 if (fromRank) res += '1' + (from / 8);
     101          33 :                 if (capture)  res += "x";
     102          33 :                 res += 'a' + (to % 8);
     103          33 :                 res += '1' + (to / 8);
     104          33 :                 if (isPromo()) {
     105           5 :                         switch (getPromo()) {
     106           1 :                         case BISHOP: res += "=B"; break;
     107           0 :                         case KNIGHT: res += "=N"; break;
     108           1 :                         case ROOK:   res += "=R"; break;
     109           3 :                         case QUEEN:  res += "=Q"; break;
     110             :                         }
     111             :                 }
     112          33 :                 if (check) res += "+";
     113          33 :                 return res;
     114             :         }
     115             : 
     116           5 :         void setPromo(pieceT promo) {
     117           5 :                 ASSERT(promo == QUEEN || promo == ROOK || promo == BISHOP ||
     118             :                        promo == KNIGHT);
     119           5 :                 m_ |= ((promo - 2) << 12) | (1 << 14);
     120           5 :         }
     121           7 :         void setCapture(pieceT piece, bool enPassant) {
     122           7 :                 m_ |= ((piece & 0x07) << 21);
     123           7 :                 if (enPassant) m_ |= (2 << 14);
     124           7 :         }
     125          21 :         void setAmbiguity(bool fyle, bool rank) {
     126          21 :                 m_ &= ~(3 << 28);
     127          21 :                 if (fyle)
     128          18 :                         m_ |= (1 << 28);
     129          21 :                 if (rank)
     130           6 :                         m_ |= (1 << 29);
     131          21 :         }
     132          10 :         void setCheck() { m_ |= (1 << 30); }
     133             : };
     134             : 
     135             : #endif

Generated by: LCOV version 1.13