123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- #include "Board.h"
- #include <string>
- #include <map>
- #include <ctype.h>
- #include <stdexcept>
- #include <sstream>
- #include "MoveGeneration.h"
- using namespace chessy;
- using namespace std;
- void Board::resetBoard(void)
- {
- whites[PieceType::PAWN] = 0x000000000000FF00;
- whites[PieceType::ROOK] = 0x0000000000000081;
- whites[PieceType::KNIGHT] = 0x0000000000000042;
- whites[PieceType::BISHOP] = 0x0000000000000024;
- whites[PieceType::QUEEN] = 0x0000000000000008;
- whites[PieceType::KING] = 0x0000000000000010;
- blacks[PieceType::PAWN] = 0x00FF000000000000;
- blacks[PieceType::ROOK] = 0x8100000000000000;
- blacks[PieceType::KNIGHT] = 0x4200000000000000;
- blacks[PieceType::BISHOP] = 0x2400000000000000;
- blacks[PieceType::QUEEN] = 0x0800000000000000;
- blacks[PieceType::KING] = 0x1000000000000000;
- }
- void Board::setEmpty(void)
- {
- whites[PieceType::PAWN] = 0;
- whites[PieceType::KNIGHT] = 0;
- whites[PieceType::BISHOP] = 0;
- whites[PieceType::ROOK] = 0;
- whites[PieceType::QUEEN] = 0;
- whites[PieceType::KING] = 0;
- blacks[PieceType::PAWN] = 0;
- blacks[PieceType::KNIGHT] = 0;
- blacks[PieceType::BISHOP] = 0;
- blacks[PieceType::ROOK] = 0;
- blacks[PieceType::QUEEN] = 0;
- blacks[PieceType::KING] = 0;
- }
- bool Board::tryToMove(Bitboard start, Bitboard end, Bitboard& b)
- {
- if (start & b)
- b = b ^ start ^ end;
- return false;
- }
- void Board::setBoard(const std::string& fenPosition)
- {
- int row = 7, column = 0;
- map<char, Bitboard*> boards {
- { 'p', &blacks[PieceType::PAWN] },
- { 'n', &blacks[PieceType::KNIGHT] },
- { 'b', &blacks[PieceType::BISHOP] },
- { 'r', &blacks[PieceType::ROOK] },
- { 'q', &blacks[PieceType::QUEEN] },
- { 'k', &blacks[PieceType::KING] },
- { 'P', &whites[PieceType::PAWN] },
- { 'N', &whites[PieceType::KNIGHT] },
- { 'B', &whites[PieceType::BISHOP] },
- { 'R', &whites[PieceType::ROOK] },
- { 'Q', &whites[PieceType::QUEEN] },
- { 'K', &whites[PieceType::KING] }
- };
- setEmpty();
- for (auto character : fenPosition) {
- if (character >= '0' && character <= '9') {
- column += character - '0';
- }
- else if (character == '/') {
- -- row;
- column = 0;
- }
- else {
- auto board = boards.find(character);
- if (board != boards.end()) {
- *(board->second) |= Bitboard::fromIndex({row, column});
- }
- else {
- throw runtime_error("invalid piece type "s + character);
- }
- ++ column;
- }
- if (row < -1 || column > 8)
- throw runtime_error("invalid board string "s + fenPosition);
- }
- }
- // a bit hacky, sry
- std::string Board::getFenBoard(void) const
- {
- using namespace std;
- stringstream str;
- for (int row = 7; row >= 0; row--) {
- int counter = 0;
- for (int column = 0; column < 8; column++) {
- PieceType black = getBlackAtPosition({ row, column });
- PieceType white = getWhiteAtPosition({ row, column });
- //str << " " << Bitboard::fromIndex({row, column}) << " " << " ";;
- //str << "row,column,index: " << row << "," << column << "," <<
- // int(Index(row, column).index) << " ";
- if (black == PieceType::EMPTY && white == PieceType::EMPTY)
- ++ counter;
- else if (counter > 0) {
- str << counter;
- counter = 0;
- }
- switch (black) {
- case PieceType::PAWN: str << 'p'; break;
- case PieceType::KNIGHT: str << 'n'; break;
- case PieceType::BISHOP: str << 'b'; break;
- case PieceType::ROOK: str << 'r'; break;
- case PieceType::QUEEN: str << 'q'; break;
- case PieceType::KING: str << 'k'; break;
- default:
- switch (white) {
- case PieceType::PAWN: str << 'P'; break;
- case PieceType::KNIGHT: str << 'N'; break;
- case PieceType::BISHOP: str << 'B'; break;
- case PieceType::ROOK: str << 'R'; break;
- case PieceType::QUEEN: str << 'Q'; break;
- case PieceType::KING: str << 'K'; break;
- default:;
- }
- }
- }
- if (counter > 0)
- str << counter;
- if (row != 0)
- str << "/";
- }
- return str.str();
- }
- PieceType Board::getWhiteAtPosition(Index i) const
- {
- Bitboard mask = Bitboard::fromIndex(i);
- for (int i = 0; i < 6; i++)
- if (whites[i] & mask)
- return (PieceType) i;
- return PieceType::EMPTY;
- }
- PieceType Board::getBlackAtPosition(Index i) const
- {
- Bitboard mask = Bitboard::fromIndex(i);
- for (int i = 0; i < 6; i++)
- if (blacks[i] & mask)
- return (PieceType) i;
- return PieceType::EMPTY;
- }
- PieceType Board::getAtPosition(Index i) const
- {
- PieceType b = getWhiteAtPosition(i);
- if (b != PieceType::EMPTY)
- return b;
- return getBlackAtPosition(i);;
- }
- void Board::move(const Move& move)
- {
- Bitboard start = Bitboard::fromIndex(move.origin);
- Bitboard end = Bitboard::fromIndex(move.destination);
- for (Bitboard& b : whites)
- if (b & end) {
- b ^= end;
- goto move;
- }
- for (Bitboard& b : blacks)
- if (b & end) {
- b ^= end;
- goto move;
- }
- move:
- for (Bitboard& b : whites) {
- if (b & end)
- b ^= end;
- if (b & start) {
- b &= ~start;
- b |= end;
- return;
- }
- }
- for (Bitboard& b : blacks) {
- if (b & start) {
- b &= ~start;
- b |= end;
- return;
- }
- }
- }
- void Board::removeAt(Index i)
- {
- Bitboard mask = ~Bitboard::fromIndex(i);
- for (Bitboard& b : whites)
- b &= mask;
- for (Bitboard& b : blacks)
- b &= mask;
- }
- Bitboard Board::getWhites(void) const
- {
- return whites[0] | whites[1] | whites[2] | whites[3] | whites[4] | whites[5];
- }
- Bitboard Board::getBlacks(void) const
- {
- return blacks[0] | blacks[1] | blacks[2] | blacks[3] | blacks[4] | blacks[5];
- }
- Bitboard Board::getOccupied(void) const
- {
- return getBlacks() | getWhites();
- }
- Bitboard Board::getFree(void) const
- {
- return ~getOccupied();
- }
- #include <iostream>
- template<Side side>
- bool Board::isCheck(void) const
- {
- constexpr Side enemy = otherSide(side);
- Index kingIndex = getKing<side>().getLeastSignificantBit();
- KnightMoveGenerator nmg{ kingIndex, 0 };
- if (nmg.getBitboard() & getKnights<enemy>())
- return true;
- PrimitiveBishopMoveGenerator pbmg{ kingIndex, get<enemy>(), get<side>() };
- if (pbmg.getBitboard() & (getBishops<enemy>() | getQueens<enemy>()))
- return true;
- PrimitiveRookMoveGenerator prmg{ kingIndex, get<enemy>(), get<side>() };
- if (prmg.getBitboard() & (getRooks<enemy>() | getQueens<enemy>()))
- return true;
- if (side == WHITE_SIDE) {
- if (kingIndex.getRow() < 6) {
- if (kingIndex.getColumn() > 0)
- if (getKing<side>().neOne() & getPawns<enemy>())
- return true;
- if (kingIndex.getColumn() < 7)
- if (getKing<side>().nwOne() & getPawns<enemy>())
- return true;
- }
- }
- else {
- if (kingIndex.getRow() > 1) {
- if (kingIndex.getColumn() > 0)
- if (getKing<side>().seOne() & getPawns<enemy>())
- return true;
- if (kingIndex.getColumn() < 7)
- if (getKing<side>().swOne() & getPawns<enemy>())
- return true;
- }
- }
- KingMoveGenerator kmg{ getKing<side>(), 0 };
- if (kmg.getBitboard() & getKing<enemy>())
- return true;
- return false;
- }
- template bool Board::isCheck<WHITE_SIDE>(void) const;
- template bool Board::isCheck<BLACK_SIDE>(void) const;
|