static char * check_test() { assert(gs.initialized); printf("Running check_test\n"); char fen[] = "rnbqk1nr/pppp1Bpp/8/2b1p3/4P3/8/PPPP1PPP/RNBQK1NR w KQkq - 0 1"; //black king is in check from white bishop parseFen(fen); assert( isInCheck(BLACK)); assert( !isInCheck(WHITE)); return 0; }
int main() { int n = 1; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) board[i][j] = 'z'; while (!feof(stdin)) { int reiPX = -1, reiPY = -1, reiWX = -1, reiWY = -1; bool bcheck = false, wcheck = false; bool vazio = true; char lixo; for (int i = 3; i < 11; i++) { for (int j = 3; j < 11; j++) { scanf("%c", &board[i][j]); if (board[i][j] == 'k') { reiPX = i; reiPY = j; } if (board[i][j] == 'K') { reiWX = i; reiWY = j; } if (board[i][j] != '.') vazio = false; } scanf("%c", &lixo); } scanf("%c", &lixo); if (vazio) break; bcheck = isInCheck(reiPX, reiPY, 0); wcheck = isInCheck(reiWX, reiWY, 1); if (wcheck) printf("Game #%d: white king is in check.\n", n); else if (bcheck) printf("Game #%d: black king is in check.\n", n); else printf("Game #%d: no king is in check.\n", n); n++; } //system("pause"); return 0; }
/** * Function to check if a final stage has been reached */ bool Board::finalReached() { if (!isInCheck() && isInCheckmate()) { Stats *s = s->getInstance(); #pragma omp atomic s->draw++; winner = 2; decision = calculateHeuristic(turn); bestBoard = nullptr; return true; } whiteKing = nullptr; whiteKing = getWhiteKing(); if (isInCheckmateWithPieces(whiteKing, blackPieces)) { winner = BLACK; decision = calculateHeuristic(BLACK) * 2; Stats *s = s->getInstance(); #pragma omp atomic s->blackWins++; bestBoard = nullptr; return true; } blackKing = nullptr; blackKing = getBlackKing(); if (isInCheckmateWithPieces(blackKing, whitePieces)) { winner = WHITE; decision = calculateHeuristic(WHITE) * 2; Stats *s = s->getInstance(); #pragma omp atomic s->whiteWins++; bestBoard = nullptr; return true; } if (turnsLeft == 0) { winner = 2; decision = calculateHeuristic(turn); Stats *s = s->getInstance(); #pragma omp atomic s->draw++; bestBoard = nullptr; return true; } return false; }
/** * A function to execute all the posible movements for a piece, and creating all the new posible boards */ void Board::execute() { matrix = getMatrix(); if (finalReached()) { return; } bool incheck = isInCheck(); std::vector<Piece *> pieces; if (turn == WHITE) { pieces = whitePieces; } else { pieces = blackPieces; } for (std::vector<Piece *>::iterator pieceIt = pieces.begin(); pieceIt != pieces.end(); ++pieceIt) { std::vector<Move *> *moves = (*pieceIt)->makeMove(matrix); removeInvalidMoves(*pieceIt, moves); std::vector<Board *> child_boards; #pragma omp task untied { for (std::vector<Move *>::iterator moveIt = moves->begin(); moveIt != moves->end(); ++moveIt) { Board *board = createBoard(*pieceIt, *moveIt, incheck, turnsLeft - 1); if (board != nullptr) { board->execute(); board->updateFather(); child_boards.push_back(board); } delete (*moveIt); } for (std::vector<Board *>::iterator child = child_boards.begin(); child != child_boards.end(); ++child) { if ((*child) != bestBoard) delete (*child); } } delete moves; } #pragma omp taskwait }
/* * Pseudo-legal move generator */ extern int generateMoves(Board_t self, int moveList[maxMoves]) { int side = sideToMove(self); updateSideInfo(self); self->movePtr = moveList; for (int from=0; from<boardSize; from++) { int piece = self->squares[from]; if (piece == empty || pieceColor(piece) != sideToMove(self)) continue; /* * Generate moves for this piece */ int to; switch (piece) { int dir, dirs; case whiteKing: case blackKing: dirs = kingDirections[from]; dir = 0; do { dir = (dir - dirs) & dirs; // pick next to = from + kingStep[dir]; if (self->squares[to] == empty || pieceColor(self->squares[to]) != sideToMove(self)) if (self->sides[other(side)].attacks[to] == 0) pushMove(self, from, to); } while (dirs -= dir); // remove and go to next break; case whiteQueen: case blackQueen: generateSlides(self, from, dirsQueen); break; case whiteRook: case blackRook: generateSlides(self, from, dirsRook); break; case whiteBishop: case blackBishop: generateSlides(self, from, dirsBishop); break; case whiteKnight: case blackKnight: dirs = knightDirections[from]; dir = 0; do { dir = (dir - dirs) & dirs; // pick next to = from + knightJump[dir]; if (self->squares[to] == empty || pieceColor(self->squares[to]) != sideToMove(self)) pushMove(self, from, to); } while (dirs -= dir); // remove and go to next break; case whitePawn: if (file(from) != fileH) { to = from + stepNE; if (self->squares[to] != empty && pieceColor(self->squares[to]) == black) pushPawnMove(self, from, to); } if (file(from) != fileA) { to = from + stepNW; if (self->squares[to] != empty && pieceColor(self->squares[to]) == black) pushPawnMove(self, from, to); } to = from + stepN; if (self->squares[to] != empty) break; pushPawnMove(self, from, to); if (rank(from) == rank2) { to += stepN; if (self->squares[to] == empty) { pushMove(self, from, to); if (self->sides[black].attacks[to+stepS]) self->movePtr[-1] |= specialMoveFlag; } } break; case blackPawn: if (file(from) != fileH) { to = from + stepSE; if (self->squares[to] != empty && pieceColor(self->squares[to]) == white) pushPawnMove(self, from, to); } if (file(from) != fileA) { to = from + stepSW; if (self->squares[to] != empty && pieceColor(self->squares[to]) == white) pushPawnMove(self, from, to); } to = from + stepS; if (self->squares[to] != empty) break; pushPawnMove(self, from, to); if (rank(from) == rank7) { to += stepS; if (self->squares[to] == empty) { pushMove(self, from, to); if (self->sides[white].attacks[to+stepN]) self->movePtr[-1] |= specialMoveFlag; } } break; } } /* * Generate castling moves */ if (self->castleFlags && !isInCheck(self)) { static const int flags[2][2] = { { castleFlagWhiteKside, castleFlagWhiteQside }, { castleFlagBlackKside, castleFlagBlackQside } }; int side = sideToMove(self); int sq = self->sides[side].king; if ((self->castleFlags & flags[side][0]) && self->squares[sq+stepE] == empty && self->squares[sq+2*stepE] == empty && self->sides[other(side)].attacks[sq+stepE] == 0 && self->sides[other(side)].attacks[sq+2*stepE] == 0) pushSpecialMove(self, sq, sq + 2*stepE); if ((self->castleFlags & flags[side][1]) && self->squares[sq+stepW] == empty && self->squares[sq+2*stepW] == empty && self->squares[sq+3*stepW] == empty && self->sides[other(side)].attacks[sq+stepW] == 0 && self->sides[other(side)].attacks[sq+2*stepW] == 0) pushSpecialMove(self, sq, sq + 2*stepW); } /* * Generate en passant captures */ if (self->enPassantPawn) { static const int steps[] = { stepN, stepS }; static const int pawns[] = { whitePawn, blackPawn }; int step = steps[sideToMove(self)]; int pawn = pawns[sideToMove(self)]; int ep = self->enPassantPawn; if (file(ep) != fileA && self->squares[ep+stepW] == pawn) pushSpecialMove(self, ep + stepW, ep + step); if (file(ep) != fileH && self->squares[ep+stepE] == pawn) pushSpecialMove(self, ep + stepE, ep + step); } return self->movePtr - moveList; // nrMoves }