Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int inf = 1e9;
- const int maxv = 100;
- struct Cell {
- int x, y;
- Cell() {
- x = y = -1;
- }
- Cell(int _x, int _y) {
- x = _x;
- y = _y;
- }
- Cell operator+ (const Cell& other) const {
- return {x + other.x, y + other.y};
- }
- bool operator ==(const Cell& other) const {
- return x == other.x && y == other.y;
- }
- [[nodiscard]] bool inRange() const {
- if (1 <= x && x <= 8
- && 1 <= y && y <= 8)
- return true;
- return false;
- }
- };
- struct Piece {
- enum PieceType {
- Pawn,
- Knight,
- Bishop,
- Rook,
- Queen,
- King
- };
- PieceType type;
- Cell cell;
- char color;
- Piece () = default;
- Piece(PieceType _type, Cell _cell, char _color) {
- type = _type;
- cell = _cell;
- color = _color;
- }
- Piece(char c, int x, int y) {
- if (isupper(c)) {
- color = 'w';
- c = tolower(c);
- } else {
- color = 'b';
- }
- if (c == 'p')
- type = Pawn;
- else if (c == 'n')
- type = Knight;
- else if (c == 'b')
- type = Bishop;
- else if (c == 'r')
- type = Rook;
- else if (c == 'q')
- type = Queen;
- else if (c == 'k')
- type = King;
- cell = Cell(x, y);
- }
- struct Directions {
- vector<int> dx;
- vector<int> dy;
- int steps;
- };
- [[nodiscard]] static Directions generateDirections(PieceType pieceType) {
- if (pieceType == Knight) {
- return {vector<int>({2, 2, 1, 1, -1, -1, -2, -2}),
- vector<int>({1, -1, 2, -2, 2, -2, 1, -1}),
- 1};
- } else if (pieceType == Bishop) {
- return {vector<int>({-1, -1, 1, 1}),
- vector<int>({-1, 1, -1, 1}),
- 7
- };
- } else if (pieceType == Rook) {
- return {vector<int>({1, -1, 0, 0}),
- vector<int>({0, 0, 1, -1}),
- 7
- };
- } else if (pieceType == Queen) {
- return {vector<int>({-1, -1, 1, 1, 1, -1, 0, 0}),
- vector<int>({-1, 1, -1, 1, 0, 0, 1, -1}),
- 7
- };
- } else if (pieceType == King) {
- return {vector<int>({-1, -1, -1, 0, 1, 1, 1, 0}),
- vector<int>({-1, 0, 1, 1, 1, 0, -1, -1}),
- 1
- };
- }
- }
- [[nodiscard]] vector<vector<Cell> > generateMoves() const {
- vector<vector<Cell> > allMoves;
- if (type == Pawn) {
- for (int step = 1; step <= 2; ++step) {
- int sgn = (color == 'w' ? 1 : -1);
- if (step == 2 &&
- ((color == 'w' && cell.x != 2) || (color == 'b' && cell.x != 7)))
- continue;
- vector<Cell> currMove;
- bool illegal = false;
- for (int currStep = 1; currStep <= step; ++currStep) {
- Cell newCell = cell + Cell(currStep * sgn, 0);
- if (!newCell.inRange()) {
- illegal = true;
- break;
- }
- currMove.push_back(newCell);
- }
- if (!illegal) {
- allMoves.push_back(currMove);
- }
- }
- } else {
- Directions directions = generateDirections(type);
- for (int dir = 0; dir < directions.dx.size(); ++dir) {
- int dirX = directions.dx[dir];
- int dirY = directions.dy[dir];
- for (int step = 1; step <= directions.steps; ++step) {
- vector<Cell> currMove;
- bool illegal = false;
- for (int currStep = 1; currStep <= step; ++currStep) {
- Cell newCell = cell + Cell(currStep * dirX, currStep * dirY);
- if (!newCell.inRange()) {
- illegal = true;
- break;
- }
- currMove.push_back(newCell);
- }
- if (!illegal) {
- allMoves.push_back(currMove);
- }
- }
- }
- }
- return allMoves;
- }
- };
- struct BoardState;
- string generateFEN(BoardState board, bool includeMoves);
- struct BoardState {
- vector<Piece> pieces;
- char activeColor;
- char whiteCastling;
- char blackCastling;
- Cell enPassant;
- int halfMoves;
- int fullMoves;
- [[nodiscard]] bool isInCheck(char color) const {
- Cell kingPosition;
- for (const Piece& piece : pieces) {
- if (piece.color == color && piece.type == Piece::King) {
- kingPosition = piece.cell;
- break;
- }
- }
- vector<vector<bool> > attacked = attackedCells(color ^ 'w' ^ 'b');
- return attacked[kingPosition.x][kingPosition.y];
- }
- [[nodiscard]] bool isDraw() const {
- if (halfMoves >= 50 || pieces.size() == 2)
- return true;
- vector<BoardState> boardStates = generateAllMoves();
- if (boardStates.empty() && !isInCheck(activeColor))
- return true;
- return false;
- }
- [[nodiscard]] bool isCheckMate() const {
- if (!isInCheck(activeColor))
- return false;
- vector<BoardState> boardStates = generateAllMoves();
- return boardStates.empty();
- }
- [[nodiscard]] vector<vector<bool> > attackedCells(char color) const {
- char b[10][10];
- memset(b, 0, sizeof(b));
- for (const Piece& piece : pieces) {
- b[piece.cell.x][piece.cell.y] = (piece.color == 'w' ? 1 : -1);
- }
- vector<vector<bool> > isAttacked(9, vector<bool>(9, false));
- for (const Piece& piece : pieces) {
- if (piece.color != color)
- continue;
- if (piece.type != Piece::Pawn) {
- vector<vector<Cell>> movesPiece = piece.generateMoves();
- for (vector<Cell> movesList : movesPiece) {
- bool invalid = false;
- for (int i = 0; i < movesList.size(); ++i) {
- Cell cell = movesList[i];
- if (b[cell.x][cell.y] != 0) {
- if (i != movesList.size() - 1) {
- invalid = true;
- break;
- } else {
- if ((color == 'w' && b[cell.x][cell.y] == 1)
- || (color == 'b' && b[cell.x][cell.y] == -1)) {
- invalid = true;
- break;
- }
- }
- }
- }
- if (invalid)
- continue;
- Cell endPosition = movesList.back();
- isAttacked[endPosition.x][endPosition.y] = true;
- }
- } else {
- if (piece.color == 'w') {
- Cell newCell = piece.cell + Cell(1, -1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 1)
- isAttacked[newCell.x][newCell.y] = true;
- newCell = piece.cell + Cell(1, 1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 1)
- isAttacked[newCell.x][newCell.y] = true;
- } else if (piece.color == 'b') {
- Cell newCell = piece.cell + Cell(-1, -1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != -1)
- isAttacked[newCell.x][newCell.y] = true;
- newCell = piece.cell + Cell(-1, 1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != -1)
- isAttacked[newCell.x][newCell.y] = true;
- }
- }
- }
- return isAttacked;
- }
- [[nodiscard]] vector<BoardState> generateAllMoves() const {
- vector<BoardState> newBoards;
- char newColor = activeColor ^ 'w' ^ 'b';
- char b[10][10];
- memset(b, 0, sizeof(b));
- for (const Piece& piece : pieces) {
- char p;
- if (piece.type == Piece::Pawn) {
- p = 'p';
- } else if (piece.type == Piece::Knight) {
- p = 'n';
- } else if (piece.type == Piece::Bishop) {
- p = 'b';
- } else if (piece.type == Piece::Rook) {
- p = 'r';
- } else if (piece.type == Piece::Queen) {
- p = 'q';
- } else if (piece.type == Piece::King) {
- p = 'k';
- }
- if (piece.color == 'w')
- p = toupper(p);
- b[piece.cell.x][piece.cell.y] = p;
- }
- for (int pieceIdx = 0; pieceIdx < pieces.size(); ++pieceIdx) {
- Piece piece = pieces[pieceIdx];
- if (piece.color != activeColor)
- continue;
- vector<vector<Cell>> movesPiece = piece.generateMoves();
- if (piece.type == Piece::Pawn) {
- if (piece.color == 'w') {
- Cell newCell = piece.cell + Cell(1, -1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 0 && islower(b[newCell.x][newCell.y]) && b[newCell.x][newCell.y] != 'k')
- movesPiece.push_back(vector<Cell>({newCell}));
- newCell = piece.cell + Cell(1, 1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 0 && islower(b[newCell.x][newCell.y]) && b[newCell.x][newCell.y] != 'k')
- movesPiece.push_back(vector<Cell>({newCell}));
- } else if (piece.color == 'b') {
- Cell newCell = piece.cell + Cell(-1, -1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 0 && isupper(b[newCell.x][newCell.y]) && b[newCell.x][newCell.y] != 'K')
- movesPiece.push_back(vector<Cell>({newCell}));
- newCell = piece.cell + Cell(-1, 1);
- if (newCell.inRange() && b[newCell.x][newCell.y] != 0 && isupper(b[newCell.x][newCell.y]) && b[newCell.x][newCell.y] != 'K')
- movesPiece.push_back(vector<Cell>({newCell}));
- }
- }
- for (vector<Cell> movesList : movesPiece) {
- BoardState newBoard;
- bool invalid = false;
- for (int i = 0; i < movesList.size(); ++i) {
- Cell cell = movesList[i];
- if (b[cell.x][cell.y] != 0) {
- if (i != movesList.size() - 1) {
- invalid = true;
- break;
- } else {
- if ((islower(b[cell.x][cell.y]) && activeColor == 'b')
- || (isupper(b[cell.x][cell.y]) && activeColor == 'w') || tolower(b[cell.x][cell.y]) == 'k') {
- invalid = true;
- break;
- }
- if (piece.type == Piece::Pawn && cell.y == piece.cell.y) {
- invalid = true;
- break;
- }
- }
- }
- }
- if (invalid)
- continue;
- Cell endPosition = movesList.back();
- char oldPiece = b[endPosition.x][endPosition.y];
- b[endPosition.x][endPosition.y] = 0;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.fullMoves = fullMoves + 1;
- // compute newBoard.enPassant
- if (piece.type == Piece::Pawn && abs(endPosition.x - piece.cell.x) == 2) {
- newBoard.enPassant = piece.cell + Cell((endPosition.x - piece.cell.x) / 2, 0);
- } else {
- newBoard.enPassant = Cell(-1, -1);
- }
- // compute newBoard.castling
- newBoard.whiteCastling = newBoard.blackCastling = 0;
- if (whiteCastling & 1) {
- // K
- if (b[1][5] == 'K' && b[1][8] == 'R')
- newBoard.whiteCastling += 1;
- }
- if (whiteCastling & 2) {
- // Q
- if (b[1][5] == 'K' && b[1][1] == 'R')
- newBoard.whiteCastling += 2;
- }
- if (blackCastling & 1) {
- // k
- if (b[8][5] == 'k' && b[8][8] == 'r')
- newBoard.blackCastling += 1;
- }
- if (blackCastling & 2) {
- // q
- if (b[8][5] == 'k' && b[8][1] == 'r')
- newBoard.blackCastling += 2;
- }
- b[endPosition.x][endPosition.y] = oldPiece;
- if (piece.type == Piece::Pawn || b[endPosition.x][endPosition.y] != 0)
- newBoard.halfMoves = 0;
- else
- newBoard.halfMoves = halfMoves + 1;
- newBoard.pieces[pieceIdx].cell = endPosition;
- if (b[endPosition.x][endPosition.y] != 0) {
- for (int removeIdx = 0; removeIdx < newBoard.pieces.size(); ++removeIdx) {
- if (newBoard.pieces[removeIdx].cell == endPosition && newBoard.pieces[removeIdx].color != activeColor) {
- std::swap(newBoard.pieces[removeIdx], newBoard.pieces.back());
- newBoard.pieces.pop_back();
- break;
- }
- }
- }
- if (piece.type == Piece::Pawn && (endPosition.x == 1 || endPosition.x == 8)) {
- for (auto newPieceType : {Piece::Queen, Piece::Knight, Piece::Bishop, Piece::Rook}) {
- newBoard.pieces[pieceIdx].type = newPieceType;
- if (!newBoard.isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- } else if (!newBoard.isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- // implement en passant
- if (enPassant.x != -1) {
- int upDir = (activeColor == 'w' ? 1 : -1);
- for (int dir : {-1, 1}) {
- Cell capturePawn = enPassant + Cell(-upDir, dir);
- Cell toCapturePawn = enPassant + Cell(-upDir, 0);
- if (capturePawn.inRange() &&
- ((activeColor == 'w' && b[capturePawn.x][capturePawn.y] == 'P') ||
- (activeColor == 'b' && b[capturePawn.x][capturePawn.y] == 'p'))) {
- BoardState newBoard;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.whiteCastling = whiteCastling;
- newBoard.blackCastling = blackCastling;
- newBoard.fullMoves = fullMoves + 1;
- newBoard.halfMoves = 0;
- newBoard.enPassant = Cell(-1, -1);
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == capturePawn) {
- newBoard.pieces[pieceIdx].cell = enPassant;
- break;
- }
- }
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == toCapturePawn) {
- std::swap(newBoard.pieces[pieceIdx], newBoard.pieces.back());
- newBoard.pieces.pop_back();
- break;
- }
- }
- if (!isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- }
- // implement castling
- if (activeColor == 'w') {
- vector<vector<bool>> attacked = attackedCells(newColor);
- if (whiteCastling & 1) {
- bool invalid = false;
- for (int col = 6; col <= 7; ++col) {
- if (b[1][col] != 0) {
- invalid = true;
- break;
- }
- }
- for (int col = 5; col <= 6; ++col) {
- if (attacked[1][col]) {
- invalid = true;
- break;
- }
- }
- if (!invalid) {
- BoardState newBoard;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.whiteCastling = 0;
- newBoard.blackCastling = blackCastling;
- newBoard.fullMoves = fullMoves + 1;
- newBoard.halfMoves = halfMoves + 1;
- newBoard.enPassant = Cell(-1, -1);
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(1, 5)) {
- newBoard.pieces[pieceIdx].cell = Cell(1, 7);
- break;
- }
- }
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(1, 8)) {
- newBoard.pieces[pieceIdx].cell = Cell(1, 6);
- break;
- }
- }
- if (!isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- if (whiteCastling & 2) {
- bool invalid = false;
- for (int col = 2; col <= 4; ++col) {
- if (b[1][col] != 0) {
- invalid = true;
- break;
- }
- }
- for (int col = 3; col <= 5; ++col) {
- if (attacked[1][col]) {
- invalid = true;
- break;
- }
- }
- if (!invalid) {
- BoardState newBoard;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.whiteCastling = 0;
- newBoard.blackCastling = blackCastling;
- newBoard.fullMoves = fullMoves + 1;
- newBoard.halfMoves = halfMoves + 1;
- newBoard.enPassant = Cell(-1, -1);
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(1, 5)) {
- newBoard.pieces[pieceIdx].cell = Cell(1, 3);
- break;
- }
- }
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(1, 1)) {
- newBoard.pieces[pieceIdx].cell = Cell(1, 4);
- break;
- }
- }
- if (!isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- } else {
- vector<vector<bool>> attacked = attackedCells(newColor);
- if (blackCastling & 1) {
- bool invalid = false;
- for (int col = 6; col <= 7; ++col) {
- if (b[8][col] != 0) {
- invalid = true;
- break;
- }
- }
- for (int col = 5; col <= 6; ++col) {
- if (attacked[8][col]) {
- invalid = true;
- break;
- }
- }
- if (!invalid) {
- BoardState newBoard;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.whiteCastling = 0;
- newBoard.blackCastling = blackCastling;
- newBoard.fullMoves = fullMoves + 1;
- newBoard.halfMoves = halfMoves + 1;
- newBoard.enPassant = Cell(-1, -1);
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(8, 5)) {
- newBoard.pieces[pieceIdx].cell = Cell(8, 7);
- break;
- }
- }
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(8, 8)) {
- newBoard.pieces[pieceIdx].cell = Cell(8, 6);
- break;
- }
- }
- if (!isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- if (blackCastling & 2) {
- bool invalid = false;
- for (int col = 2; col <= 4; ++col) {
- if (b[8][col] != 0) {
- invalid = true;
- break;
- }
- }
- for (int col = 3; col <= 5; ++col) {
- if (attacked[8][col]) {
- invalid = true;
- break;
- }
- }
- if (!invalid) {
- BoardState newBoard;
- newBoard.pieces = pieces;
- newBoard.activeColor = newColor;
- newBoard.whiteCastling = 0;
- newBoard.blackCastling = blackCastling;
- newBoard.fullMoves = fullMoves + 1;
- newBoard.halfMoves = halfMoves + 1;
- newBoard.enPassant = Cell(-1, -1);
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(8, 5)) {
- newBoard.pieces[pieceIdx].cell = Cell(8, 3);
- break;
- }
- }
- for (int pieceIdx = 0; pieceIdx < newBoard.pieces.size(); ++pieceIdx) {
- if (newBoard.pieces[pieceIdx].cell == Cell(8, 1)) {
- newBoard.pieces[pieceIdx].cell = Cell(8, 4);
- break;
- }
- }
- if (!isInCheck(activeColor)) {
- newBoards.push_back(newBoard);
- }
- }
- }
- }
- return newBoards;
- }
- };
- BoardState parseFEN(string fen) {
- int currIndex = 0;
- BoardState board;
- for (int i = 8; i >= 1; --i) {
- int pos = 0;
- while (pos < 8) {
- if (isdigit(fen[currIndex])) {
- pos += fen[currIndex] - '0';
- } else {
- pos++;
- board.pieces.emplace_back(fen[currIndex], i, pos);
- }
- currIndex++;
- }
- currIndex++;
- }
- board.activeColor = fen[currIndex];
- currIndex += 2;
- board.whiteCastling = board.blackCastling = 0;
- while (fen[currIndex] != ' ') {
- if (fen[currIndex] == 'K')
- board.whiteCastling += 1;
- else if (fen[currIndex] == 'Q')
- board.whiteCastling += 2;
- else if (fen[currIndex] == 'k')
- board.blackCastling += 1;
- else if (fen[currIndex] == 'q')
- board.blackCastling += 2;
- currIndex++;
- }
- currIndex++;
- if (fen[currIndex] == '-') {
- board.enPassant = Cell(-1, -1);
- currIndex += 2;
- } else {
- board.enPassant = Cell(fen[currIndex + 1] - '0', fen[currIndex] - 'a' + 1);
- currIndex += 3;
- }
- board.halfMoves = 0;
- while (fen[currIndex] != ' ') {
- board.halfMoves = board.halfMoves * 10 + fen[currIndex] - '0';
- currIndex++;
- }
- currIndex++;
- board.fullMoves = 0;
- while (currIndex < fen.size()) {
- board.fullMoves = board.fullMoves * 10 + fen[currIndex] - '0';
- currIndex++;
- }
- return board;
- }
- //string generateFEN(const BoardState& board, bool includeMoves) {
- // string fen = "";
- // char b[10][10];
- // memset(b, 0, sizeof(b));
- // for (const Piece& piece : board.pieces) {
- // char p;
- // if (piece.type == Piece::Pawn) {
- // p = 'p';
- // } else if (piece.type == Piece::Knight) {
- // p = 'n';
- // } else if (piece.type == Piece::Bishop) {
- // p = 'b';
- // } else if (piece.type == Piece::Rook) {
- // p = 'r';
- // } else if (piece.type == Piece::Queen) {
- // p = 'q';
- // } else if (piece.type == Piece::King) {
- // p = 'k';
- // }
- // if (piece.color == 'w')
- // p = toupper(p);
- // b[piece.cell.x][piece.cell.y] = p;
- // }
- //
- // for (int i = 8; i >= 1; --i) {
- // int pos = 0;
- // for (int j = 1; j <= 8; ++j) {
- // if (b[i][j] == 0) {
- // pos++;
- // } else {
- // if (pos > 0) {
- // fen += to_string(pos);
- // pos = 0;
- // }
- // fen += b[i][j];
- // }
- // }
- // if (pos != 0)
- // fen += to_string(pos);
- // if (i == 1) {
- // fen += " ";
- // } else {
- // fen += "/";
- // }
- // }
- //
- // fen += board.activeColor;
- // fen += " ";
- //
- // if (board.whiteCastling == 0 && board.blackCastling == 0)
- // fen += "-";
- // else {
- // if (board.whiteCastling & 1) {
- // fen += "K";
- // }
- // if (board.whiteCastling & 2) {
- // fen += "Q";
- // }
- // if (board.blackCastling & 1) {
- // fen += "k";
- // }
- // if (board.blackCastling & 2) {
- // fen += "q";
- // }
- // }
- // fen += " ";
- //
- // if (board.enPassant.x == -1) {
- // fen += "-";
- // } else {
- // fen += ('a' + board.enPassant.y - 1);
- // fen += ('0' + board.enPassant.x);
- // }
- //
- // if (includeMoves) {
- // fen += " ";
- // fen += to_string(board.halfMoves);
- // fen += " ";
- // fen += to_string(board.fullMoves);
- // }
- //
- // return fen;
- //}
- struct SortedBoards {
- BoardState board;
- int value;
- };
- int computeBoardScore(const BoardState& board) {
- int score = 0;
- for (const Piece& piece : board.pieces) {
- int value = 0;
- if (piece.type == Piece::Pawn) {
- value = 1;
- } else if (piece.type == Piece::Bishop) {
- value = 3;
- } else if (piece.type == Piece::Knight) {
- value = 3;
- } else if (piece.type == Piece::Rook) {
- value = 5;
- } else if (piece.type == Piece::Queen) {
- value = 9;
- }
- if (piece.color == 'w')
- score += value;
- else
- score -= value;
- }
- return score;
- }
- int alphaBetaMiniMax(const BoardState& board, int depth, int alpha, int beta) {
- if (depth >= 4)
- return 0;
- if (board.isDraw())
- return 0;
- if (board.isCheckMate()) {
- if (board.activeColor == 'w') {
- return -maxv + depth;
- } else {
- return maxv - depth;
- }
- }
- vector<BoardState> generatedBoards = board.generateAllMoves();
- vector<SortedBoards> sortedBoards(generatedBoards.size());
- for (int i = 0; i < generatedBoards.size(); ++i) {
- swap(sortedBoards[i].board, generatedBoards[i]);
- sortedBoards[i].value = computeBoardScore(sortedBoards[i].board);
- }
- if (board.activeColor == 'w') {
- int maxEval = -inf;
- sort(sortedBoards.begin(), sortedBoards.end(), [](const auto& b1, const auto& b2) {return b1.value > b2.value; });
- for (const auto& newBoard : sortedBoards) {
- int eval = alphaBetaMiniMax(newBoard.board, depth + 1, alpha, beta);
- maxEval = max(maxEval, eval);
- alpha = max(alpha, eval);
- if (beta <= alpha)
- break;
- }
- return maxEval;
- } else {
- int minEval = inf;
- sort(sortedBoards.begin(), sortedBoards.end(), [](const auto& b1, const auto& b2) {return b1.value < b2.value; });
- for (const auto& newBoard : sortedBoards) {
- int eval = alphaBetaMiniMax(newBoard.board, depth + 1, alpha, beta);
- minEval = min(minEval, eval);
- beta = min(beta, eval);
- if (beta <= alpha)
- break;
- }
- return minEval;
- }
- }
- int main() {
- freopen("instances/easy/3.in", "r", stdin);
- string fen;
- getline(cin, fen);
- BoardState board = parseFEN(fen);
- int answer = alphaBetaMiniMax(board, 0, -inf, inf);
- if (answer == 0) {
- cout << "Draw" << endl;
- } else if (answer > 0) {
- cout << "W M" << (-answer + maxv + 1) / 2 << endl;
- } else {
- cout << "B M" << (answer + maxv + 1) / 2 << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement