Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.     Texel - A UCI chess engine.
  3.     Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. /*
  20.  * position.hpp
  21.  *
  22.  *  Created on: Feb 25, 2012
  23.  *      Author: petero
  24.  */
  25.  
  26. #ifndef POSITION_HPP_
  27. #define POSITION_HPP_
  28.  
  29. #include <iosfwd>
  30.  
  31. #include "move.hpp"
  32. #include "undoInfo.hpp"
  33. #include "bitBoard.hpp"
  34. #include "piece.hpp"
  35. #include "material.hpp"
  36. #include <algorithm>
  37. #include <iostream>
  38.  
  39. /**
  40.  * Stores the state of a chess position.
  41.  * All required state is stored, except for all previous positions
  42.  * since the last capture or pawn move. That state is only needed
  43.  * for three-fold repetition draw detection, and is better stored
  44.  * in a separate hash table.
  45.  */
  46. class Position {
  47. public:
  48.     /** Bit definitions for the castleMask bit mask. */
  49.     static const int A1_CASTLE = 0; /** White long castle. */
  50.     static const int H1_CASTLE = 1; /** White short castle. */
  51.     static const int A8_CASTLE = 2; /** Black long castle. */
  52.     static const int H8_CASTLE = 3; /** Black short castle. */
  53.  
  54.     /** Initialize board to empty position. */
  55.     Position();
  56.  
  57.     bool equals(const Position& other) const;
  58.  
  59.     /**
  60.      * Return Zobrist hash value for the current position.
  61.      * Everything except the move counters are included in the hash value.
  62.      */
  63.     U64 zobristHash() const;
  64.     U64 pawnZobristHash() const;
  65.     U64 kingZobristHash() const;
  66.  
  67.     /** Zobrist hash including the halfMove clock.
  68.      *  Only large halfMove clock values affect the hash. */
  69.     U64 historyHash() const;
  70.     /** Hash including halfMoveClock, to avoid opening book cycles. */
  71.     U64 bookHash() const;
  72.  
  73.     /** Compute zobrist hash for position after "move" has been made.
  74.      * May be incorrect in some cases, intended for prefetch. */
  75.     U64 hashAfterMove(const Move& move) const;
  76.  
  77.     /** Return the material identifier. */
  78.     int materialId() const;
  79.  
  80.     /**
  81.      * Decide if two positions are equal in the sense of the draw by repetition rule.
  82.      * @return True if positions are equal, false otherwise.
  83.      */
  84.     bool drawRuleEquals(Position other) const;
  85.  
  86.     bool isWhiteMove() const;
  87.  
  88.     void setWhiteMove(bool whiteMove);
  89.  
  90.     /** Return piece occupying a square. */
  91.     int getPiece(int square) const;
  92.  
  93.     /** Set a square to a piece value. */
  94.     void setPiece(int square, int piece);
  95.  
  96.     /**
  97.      * Set a square to a piece value.
  98.      * Special version that only updates enough of the state for the SEE function to be happy.
  99.      */
  100.     void setSEEPiece(int square, int piece);
  101.  
  102.     /** Return true if white long castling right has not been lost. */
  103.     bool a1Castle() const;
  104.  
  105.     /** Return true if white short castling right has not been lost. */
  106.     bool h1Castle() const;
  107.  
  108.     /** Return true if black long castling right has not been lost. */
  109.     bool a8Castle() const;
  110.  
  111.     /** Return true if black short castling right has not been lost. */
  112.     bool h8Castle() const;
  113.  
  114.     /** Bitmask describing castling rights. */
  115.     int getCastleMask() const;
  116.     void setCastleMask(int castleMask);
  117.  
  118.     /** En passant square, or -1 if no en passant possible. */
  119.     int getEpSquare() const;
  120.  
  121.     void setEpSquare(int epSquare);
  122.  
  123.     int getKingSq(bool white) const;
  124.  
  125.     /** Apply a move to the current position. */
  126.     void makeMove(const Move& move, UndoInfo& ui);
  127.  
  128.     void unMakeMove(const Move& move, const UndoInfo& ui);
  129.  
  130.     /** Special make move functions used by MoveGen::isLegal(). Does not update all data members. */
  131.     void makeMoveB(const Move& move, UndoInfo& ui);
  132.     void unMakeMoveB(const Move& move, const UndoInfo& ui);
  133.     void setPieceB(int square, int piece);
  134.  
  135.     /**
  136.      * Apply a move to the current position.
  137.      * Special version that only updates enough of the state for the SEE function to be happy.
  138.      */
  139.     void makeSEEMove(const Move& move, UndoInfo& ui);
  140.  
  141.     void unMakeSEEMove(const Move& move, const UndoInfo& ui);
  142.  
  143.     int getFullMoveCounter() const;
  144.     void setFullMoveCounter(int fm);
  145.     int getHalfMoveClock() const;
  146.     void setHalfMoveClock(int hm);
  147.  
  148.     /** Return incrementally updated piece square table score for middle game and endgame. */
  149.     int psScore1(int piece) const;
  150.     int psScore2(int piece) const;
  151.  
  152.     /** BitBoard for all squares occupied by a piece type. */
  153.     U64 pieceTypeBB(Piece::Type piece) const;
  154.     /** BitBoard for all squares occupied by several piece types. */
  155.     template <typename Piece0, typename... Pieces> U64 pieceTypeBB(Piece0 piece0, Pieces... pieces) const;
  156.  
  157.     /** BitBoard for all squares occupied by white pieces. */
  158.     U64 whiteBB() const;
  159.     /** BitBoard for all squares occupied by black pieces. */
  160.     U64 blackBB() const;
  161.     /** BitBoard for all squares occupied by white or black pieces. */
  162.     U64 colorBB(int wtm) const;
  163.  
  164.     /** BitBoard for all squares occupied by white and black pieces. */
  165.     U64 occupiedBB() const;
  166.  
  167.     int wKingSq() const;
  168.     int bKingSq() const;
  169.  
  170.     /** Total white/black material value. */
  171.     int wMtrl() const;
  172.     int bMtrl() const;
  173.     /** White/black material value for all pawns. */
  174.     int wMtrlPawns() const;
  175.     int bMtrlPawns() const;
  176.  
  177.  
  178.     /** Return index in squares[] vector corresponding to (x,y). */
  179.     static int getSquare(int x, int y);
  180.  
  181.     /** Return x position (file) corresponding to a square. */
  182.     static int getX(int square);
  183.  
  184.     /** Return y position (rank) corresponding to a square. */
  185.     static int getY(int square);
  186.  
  187.     /** Return getSquare(getX(square),7-getY(square)). */
  188.     static int mirrorY(int square);
  189.  
  190.     /** Return true if (x,y) is a dark square. */
  191.     static bool darkSquare(int x, int y);
  192.  
  193.     /** Compute the Zobrist hash value non-incrementally. Only useful for testing. */
  194.     U64 computeZobristHash();
  195.  
  196.     /** Initialize static data. */
  197.     static void staticInitialize();
  198.  
  199.     /** Get hash key for a piece at a square. */
  200.     static U64 getHashKey(int piece, int square);
  201.  
  202.  
  203.     /** Serialization. Used by tree logging code. */
  204.     struct SerializeData {
  205.         U64 v[5];
  206.     };
  207.     void serialize(SerializeData& data) const;
  208.     void deSerialize(const SerializeData& data);
  209.  
  210. private:
  211.     /** Move a non-pawn piece to an empty square. */
  212.     void movePieceNotPawn(int from, int to);
  213.     void movePieceNotPawnB(int from, int to);
  214.  
  215.     void removeCastleRights(int square);
  216.  
  217.     static U64 getRandomHashVal(int rndNo);
  218.  
  219.  
  220.     int wKingSq_, bKingSq_;  // Cached king positions
  221.     int wMtrl_;              // Total value of all white pieces and pawns
  222.     int bMtrl_;              // Total value of all black pieces and pawns
  223.     int wMtrlPawns_;         // Total value of all white pawns
  224.     int bMtrlPawns_;         // Total value of all black pawns
  225.  
  226.     int squares[64];
  227.  
  228.     // Piece square table scores
  229.     short psScore1_[Piece::nPieceTypes];
  230.     short psScore2_[Piece::nPieceTypes];
  231.  
  232.     // Bitboards
  233.     U64 pieceTypeBB_[Piece::nPieceTypes];
  234.     U64 whiteBB_, blackBB_;
  235.  
  236.     bool whiteMove;
  237.  
  238.     /** Number of half-moves since last 50-move reset. */
  239.     int halfMoveClock;
  240.  
  241.     /** Game move number, starting from 1. */
  242.     int fullMoveCounter;
  243.  
  244.     int castleMask;
  245.     int epSquare;
  246.  
  247.     U64 hashKey;           // Cached Zobrist hash key
  248.     U64 pHashKey;          // Cached Zobrist pawn hash key
  249.     MatId matId;           // Cached material identifier
  250.  
  251.     static U64 psHashKeys[Piece::nPieceTypes][64];    // [piece][square]
  252.  
  253.     static U64 whiteHashKey;
  254.     static U64 castleHashKeys[16];   // [castleMask]
  255.     static U64 epHashKeys[9];        // [epFile + 1] (epFile==-1 for no ep)
  256.     static U64 moveCntKeys[101];     // [min(halfMoveClock, 100)]
  257.  
  258.     static const U64 zobristRndKeys[];
  259. };
  260.  
  261. /** For debugging. */
  262. std::ostream& operator<<(std::ostream& os, const Position& pos);
  263.  
  264. inline bool
  265. Position::equals(const Position& other) const {
  266.     if (!drawRuleEquals(other))
  267.         return false;
  268.     if (halfMoveClock != other.halfMoveClock)
  269.         return false;
  270.     if (fullMoveCounter != other.fullMoveCounter)
  271.         return false;
  272.     if (hashKey != other.hashKey)
  273.         return false;
  274.     if (pHashKey != other.pHashKey)
  275.         return false;
  276.     if (matId() != other.matId())
  277.         return false;
  278.     return true;
  279. }
  280.  
  281. inline U64
  282. Position::zobristHash() const {
  283.     return hashKey;
  284. }
  285.  
  286. inline U64
  287. Position::pawnZobristHash() const {
  288.     return pHashKey;
  289. }
  290.  
  291. inline U64
  292. Position::kingZobristHash() const {
  293.     return psHashKeys[Piece::WKING][wKingSq()] ^
  294.            psHashKeys[Piece::BKING][bKingSq()];
  295. }
  296.  
  297. inline U64
  298. Position::historyHash() const {
  299.     U64 ret = hashKey;
  300.     if (halfMoveClock >= 40) {
  301.         if (halfMoveClock < 80)
  302.             ret ^= moveCntKeys[halfMoveClock / 10];
  303.         else
  304.             ret ^= moveCntKeys[std::min(halfMoveClock, 100)];
  305.     }
  306.     return ret;
  307. }
  308.  
  309. inline U64
  310. Position::bookHash() const {
  311.     U64 ret = hashKey;
  312.     ret ^= moveCntKeys[std::min(halfMoveClock, 100)];
  313.     return ret;
  314. }
  315.  
  316. inline int
  317. Position::materialId() const {
  318.     return matId();
  319. }
  320.  
  321. inline bool
  322. Position::drawRuleEquals(Position other) const {
  323.     for (int i = 0; i < 64; i++)
  324.         if (squares[i] != other.squares[i])
  325.             return false;
  326.     if (whiteMove != other.whiteMove)
  327.         return false;
  328.     if (castleMask != other.castleMask)
  329.         return false;
  330.     if (epSquare != other.epSquare)
  331.         return false;
  332.     return true;
  333. }
  334.  
  335. inline bool
  336. Position::isWhiteMove() const {
  337.     return whiteMove;
  338. }
  339.  
  340. inline void
  341. Position::setWhiteMove(bool whiteMove) {
  342.     if (whiteMove != this->whiteMove) {
  343.         hashKey ^= whiteHashKey;
  344.         this->whiteMove = whiteMove;
  345.     }
  346. }
  347.  
  348. inline int
  349. Position::getPiece(int square) const {
  350.     return squares[square];
  351. }
  352.  
  353. inline void
  354. Position::setSEEPiece(int square, int piece) {
  355.     int removedPiece = squares[square];
  356.  
  357.     // Update board
  358.     squares[square] = piece;
  359.  
  360.     // Update bitboards
  361.     U64 sqMask = 1ULL << square;
  362.     pieceTypeBB_[removedPiece] &= ~sqMask;
  363.     pieceTypeBB_[piece] |= sqMask;
  364.     if (removedPiece != Piece::EMPTY) {
  365.         if (Piece::isWhite(removedPiece))
  366.             whiteBB_ &= ~sqMask;
  367.         else
  368.             blackBB_ &= ~sqMask;
  369.     }
  370.     if (piece != Piece::EMPTY) {
  371.         if (Piece::isWhite(piece))
  372.             whiteBB_ |= sqMask;
  373.         else
  374.             blackBB_ |= sqMask;
  375.     }
  376. }
  377.  
  378. inline bool
  379. Position::a1Castle() const {
  380.     return (castleMask & (1 << A1_CASTLE)) != 0;
  381. }
  382.  
  383. inline bool
  384. Position::h1Castle() const {
  385.     return (castleMask & (1 << H1_CASTLE)) != 0;
  386. }
  387.  
  388. inline bool
  389. Position::a8Castle() const {
  390.     return (castleMask & (1 << A8_CASTLE)) != 0;
  391. }
  392.  
  393. inline bool
  394. Position::h8Castle() const {
  395.     return (castleMask & (1 << H8_CASTLE)) != 0;
  396. }
  397.  
  398. inline int
  399. Position::getCastleMask() const {
  400.     return castleMask;
  401. }
  402.  
  403. inline void
  404. Position::setCastleMask(int castleMask) {
  405.     hashKey ^= castleHashKeys[this->castleMask];
  406.     hashKey ^= castleHashKeys[castleMask];
  407.     this->castleMask = castleMask;
  408. }
  409.  
  410. inline int
  411. Position::getEpSquare() const {
  412.     return epSquare;
  413. }
  414.  
  415. inline void
  416. Position::setEpSquare(int epSquare) {
  417.     if (this->epSquare != epSquare) {
  418.         hashKey ^= epHashKeys[(this->epSquare >= 0) ? getX(this->epSquare) + 1 : 0];
  419.         hashKey ^= epHashKeys[(epSquare >= 0) ? getX(epSquare) + 1 : 0];
  420.         this->epSquare = epSquare;
  421.     }
  422. }
  423.  
  424. inline int
  425. Position::getKingSq(bool white) const {
  426.     return white ? wKingSq() : bKingSq();
  427. }
  428.  
  429. inline void
  430. Position::unMakeMove(const Move& move, const UndoInfo& ui) {
  431.     hashKey ^= whiteHashKey;
  432.     whiteMove = !whiteMove;
  433.     int p = squares[move.to()];
  434.     setPiece(move.from(), p);
  435.     setPiece(move.to(), ui.capturedPiece);
  436.     setCastleMask(ui.castleMask);
  437.     setEpSquare(ui.epSquare);
  438.     halfMoveClock = ui.halfMoveClock;
  439.     bool wtm = whiteMove;
  440.     if (move.promoteTo() != Piece::EMPTY) {
  441.         p = wtm ? Piece::WPAWN : Piece::BPAWN;
  442.         setPiece(move.from(), p);
  443.     }
  444.     if (!wtm)
  445.         fullMoveCounter--;
  446.  
  447.     // Handle castling
  448.     int king = wtm ? Piece::WKING : Piece::BKING;
  449.     if (p == king) {
  450.         int k0 = move.from();
  451.         if (move.to() == k0 + 2) { // O-O
  452.             movePieceNotPawn(k0 + 1, k0 + 3);
  453.         } else if (move.to() == k0 - 2) { // O-O-O
  454.             movePieceNotPawn(k0 - 1, k0 - 4);
  455.         }
  456.     }
  457.  
  458.     // Handle en passant
  459.     if (move.to() == epSquare) {
  460.         if (p == Piece::WPAWN) {
  461.             setPiece(move.to() - 8, Piece::BPAWN);
  462.         } else if (p == Piece::BPAWN) {
  463.             setPiece(move.to() + 8, Piece::WPAWN);
  464.         }
  465.     }
  466. }
  467.  
  468. inline void
  469. Position::unMakeMoveB(const Move& move, const UndoInfo& ui) {
  470.     int p = squares[move.to()];
  471.     setPieceB(move.from(), p);
  472.     setPieceB(move.to(), ui.capturedPiece);
  473.     bool wtm = whiteMove;
  474.     if (move.promoteTo() != Piece::EMPTY) {
  475.         p = wtm ? Piece::WPAWN : Piece::BPAWN;
  476.         setPieceB(move.from(), p);
  477.     }
  478.  
  479.     // Handle castling
  480.     int king = wtm ? Piece::WKING : Piece::BKING;
  481.     if (p == king) {
  482.         int k0 = move.from();
  483.         if (move.to() == k0 + 2) { // O-O
  484.             movePieceNotPawnB(k0 + 1, k0 + 3);
  485.         } else if (move.to() == k0 - 2) { // O-O-O
  486.             movePieceNotPawnB(k0 - 1, k0 - 4);
  487.         }
  488.     }
  489.  
  490.     // Handle en passant
  491.     if (move.to() == epSquare) {
  492.         if (p == Piece::WPAWN) {
  493.             setPieceB(move.to() - 8, Piece::BPAWN);
  494.         } else if (p == Piece::BPAWN) {
  495.             setPieceB(move.to() + 8, Piece::WPAWN);
  496.         }
  497.     }
  498. }
  499.  
  500. inline void
  501. Position::setPieceB(int square, int piece) {
  502.     int removedPiece = squares[square];
  503.     squares[square] = piece;
  504.  
  505.     // Update bitboards
  506.     const U64 sqMask = 1ULL << square;
  507.     pieceTypeBB_[removedPiece] &= ~sqMask;
  508.     pieceTypeBB_[piece] |= sqMask;
  509.  
  510.     if (removedPiece != Piece::EMPTY) {
  511.         if (Piece::isWhite(removedPiece))
  512.             whiteBB_ &= ~sqMask;
  513.         else
  514.             blackBB_ &= ~sqMask;
  515.     }
  516.  
  517.     if (piece != Piece::EMPTY) {
  518.         if (Piece::isWhite(piece)) {
  519.             whiteBB_ |= sqMask;
  520.             if (piece == Piece::WKING)
  521.                 wKingSq_ = square;
  522.         } else {
  523.             blackBB_ |= sqMask;
  524.             if (piece == Piece::BKING)
  525.                 bKingSq_ = square;
  526.         }
  527.     }
  528. }
  529.  
  530. inline void
  531. Position::movePieceNotPawnB(int from, int to) {
  532.     const int piece = squares[from];
  533.  
  534.     squares[from] = Piece::EMPTY;
  535.     squares[to] = piece;
  536.  
  537.     const U64 sqMaskF = 1ULL << from;
  538.     const U64 sqMaskT = 1ULL << to;
  539.     pieceTypeBB_[piece] &= ~sqMaskF;
  540.     pieceTypeBB_[piece] |= sqMaskT;
  541.     if (Piece::isWhite(piece)) {
  542.         whiteBB_ &= ~sqMaskF;
  543.         whiteBB_ |= sqMaskT;
  544.         if (piece == Piece::WKING)
  545.             wKingSq_ = to;
  546.     } else {
  547.         blackBB_ &= ~sqMaskF;
  548.         blackBB_ |= sqMaskT;
  549.         if (piece == Piece::BKING)
  550.             bKingSq_ = to;
  551.     }
  552. }
  553.  
  554. inline void
  555. Position::makeSEEMove(const Move& move, UndoInfo& ui) {
  556.     ui.capturedPiece = squares[move.to()];
  557.     int p = squares[move.from()];
  558.  
  559.     // Handle en passant
  560.     if (move.to() == epSquare) {
  561.         if (p == Piece::WPAWN) {
  562.             setSEEPiece(move.to() - 8, Piece::EMPTY);
  563.         } else if (p == Piece::BPAWN) {
  564.             setSEEPiece(move.to() + 8, Piece::EMPTY);
  565.         }
  566.     }
  567.  
  568.     // Perform move
  569.     setSEEPiece(move.from(), Piece::EMPTY);
  570.     setSEEPiece(move.to(), p);
  571.     whiteMove = !whiteMove;
  572. }
  573.  
  574. inline void
  575. Position::unMakeSEEMove(const Move& move, const UndoInfo& ui) {
  576.     whiteMove = !whiteMove;
  577.     int p = squares[move.to()];
  578.     setSEEPiece(move.from(), p);
  579.     setSEEPiece(move.to(), ui.capturedPiece);
  580.  
  581.     // Handle en passant
  582.     if (move.to() == epSquare) {
  583.         if (p == Piece::WPAWN) {
  584.             setSEEPiece(move.to() - 8, Piece::BPAWN);
  585.         } else if (p == Piece::BPAWN) {
  586.             setSEEPiece(move.to() + 8, Piece::WPAWN);
  587.         }
  588.     }
  589. }
  590.  
  591. inline int
  592. Position::getSquare(int x, int y) {
  593.     return y * 8 + x;
  594. }
  595.  
  596. /** Return x position (file) corresponding to a square. */
  597. inline int
  598. Position::getX(int square) {
  599.     return square & 7;
  600. }
  601.  
  602. /** Return y position (rank) corresponding to a square. */
  603. inline int
  604. Position::getY(int square) {
  605.     return square >> 3;
  606. }
  607.  
  608. inline int
  609. Position::mirrorY(int square) {
  610.     return square ^ 56;
  611. }
  612.  
  613. /** Return true if (x,y) is a dark square. */
  614. inline bool
  615. Position::darkSquare(int x, int y) {
  616.     return (x & 1) == (y & 1);
  617. }
  618.  
  619. inline void
  620. Position::removeCastleRights(int square) {
  621.     if (square == getSquare(0, 0)) {
  622.         setCastleMask(castleMask & ~(1 << A1_CASTLE));
  623.     } else if (square == getSquare(7, 0)) {
  624.         setCastleMask(castleMask & ~(1 << H1_CASTLE));
  625.     } else if (square == getSquare(0, 7)) {
  626.         setCastleMask(castleMask & ~(1 << A8_CASTLE));
  627.     } else if (square == getSquare(7, 7)) {
  628.         setCastleMask(castleMask & ~(1 << H8_CASTLE));
  629.     }
  630. }
  631.  
  632. inline int Position::getFullMoveCounter() const {
  633.     return fullMoveCounter;
  634. }
  635.  
  636. inline void Position::setFullMoveCounter(int fm) {
  637.     fullMoveCounter = fm;
  638. }
  639.  
  640. inline int Position::getHalfMoveClock() const {
  641.     return halfMoveClock;
  642. }
  643.  
  644. inline void Position::setHalfMoveClock(int hm) {
  645.     halfMoveClock = hm;
  646. }
  647.  
  648. inline int Position::psScore1(int piece) const {
  649.     return psScore1_[piece];
  650. }
  651.  
  652. inline int Position::psScore2(int piece) const {
  653.     return psScore2_[piece];
  654. }
  655.  
  656. inline U64 Position::pieceTypeBB(Piece::Type piece) const {
  657.     return pieceTypeBB_[piece];
  658. }
  659.  
  660. template <typename Piece0, typename... Pieces>
  661. inline U64 Position::pieceTypeBB(Piece0 piece0, Pieces... pieces) const {
  662.     return pieceTypeBB(piece0) | pieceTypeBB(pieces...);
  663. }
  664.  
  665. inline U64 Position::whiteBB() const {
  666.     return whiteBB_;
  667. }
  668.  
  669. inline U64 Position::blackBB() const {
  670.     return blackBB_;
  671. };
  672.  
  673. inline U64 Position::colorBB(int wtm) const {
  674.     return wtm ? whiteBB_ : blackBB_;
  675. }
  676.  
  677. inline U64 Position::occupiedBB() const {
  678.     return whiteBB() | blackBB();
  679. }
  680.  
  681. inline int Position::wKingSq() const {
  682.     return wKingSq_;
  683. }
  684.  
  685. inline int Position::bKingSq() const {
  686.     return bKingSq_;
  687. }
  688.  
  689. inline int Position::wMtrl() const {
  690.     return wMtrl_;
  691. }
  692.  
  693. inline int Position::bMtrl() const {
  694.     return bMtrl_;
  695. }
  696.  
  697. inline int Position::wMtrlPawns() const {
  698.     return wMtrlPawns_;
  699. }
  700.  
  701. inline int Position::bMtrlPawns() const {
  702.     return bMtrlPawns_;
  703. }
  704.  
  705. inline U64 Position::getHashKey(int piece, int square) {
  706.     return psHashKeys[piece][square];
  707. }
  708.  
  709. #endif /* POSITION_HPP_ */
  710.