public static ulong GenerateMovesForPieceBitboard(int piece, int[] board) { PieceType pt = Util.GetPieceType(piece); switch (pt) { case PieceType.Pawn: return(PawnMoveGenerator.PossiblePositionsBitboard(piece, board)); case PieceType.Night: return(KnightMoveGenerator.PossiblePositionsBitboard(piece, board)); case PieceType.Bishop: return(BishopMoveGenerator.PossiblePositionsBitboard(piece, board)); case PieceType.Rook: return(RookMoveGenerator.PossiblePositionsBitboard(piece, board)); case PieceType.Queen: return(QueenMoveGenerator.PossiblePositionsBitboard(piece, board)); case PieceType.King: return(KingMoveGenerator.PossiblePositionsBitboard(piece, board)); default: break; } return(0); }
public static List <Move> GenerateMovesForPiece(int piece, int[] board) { PieceType pt = Util.GetPieceType(piece); List <int> temp = new List <int>(); List <Move> result = new List <Move>(); switch (pt) { case PieceType.Pawn: temp = PawnMoveGenerator.PossiblePositions(piece, board); break; case PieceType.Night: temp = KnightMoveGenerator.PossiblePositions(piece, board); break; case PieceType.Bishop: temp = BishopMoveGenerator.PossiblePositions(piece, board); break; case PieceType.Rook: temp = RookMoveGenerator.PossiblePositions(piece, board); break; case PieceType.Queen: temp = QueenMoveGenerator.PossiblePositions(piece, board); break; case PieceType.King: temp = KingMoveGenerator.PossiblePositions(piece, board); break; default: break; } foreach (int m in temp) { result.Add(new Move(piece, m)); } return(result); }
public MoveGenerationResult GetMoves() { MoveGenerationResult result = new MoveGenerationResult(); List <Move> myGeneratedMoves = new List <Move>(); List <Move> nonCheckingMoves = new List <Move>(); List <ulong> enemyPseudoMoves = new List <ulong>(); List <int> threateningPieces = new List <int>(); List <int> threateningPiecesNonKingMove = new List <int>(); IEnumerable <int> positions = _theBoard.Where(e => e > 0); List <int> myPieces = positions.Where(e => _whiteToMove == Util.IsWhite(e)).ToList(); List <int> enemyPieces = positions.Where(e => _whiteToMove == !Util.IsWhite(e)).ToList(); bool kingChecked = false; int currentKingPosition; int opponentKingPiece; double materialScore = Material(); if (_whiteToMove) { currentKingPiece = whiteKing; } else { currentKingPiece = blackKing; } if (!_whiteToMove) { opponentKingPiece = whiteKing; } else { opponentKingPiece = blackKing; } currentKingPosition = Util.GetPieceOffset(currentKingPiece); Dictionary <int, List <Move> > enemyMovements = new Dictionary <int, List <Models.Move> >(); List <Move> pieceMoves; //see if king is currently in check. If yes and no moves are generated it is checkmate. If no and no moves generated it is stalemate bool allowOOOCastle = true, allowOOCastle = true; foreach (int piece in enemyPieces) { pieceMoves = MoveGenerator.GenerateMovesForPiece(piece, _theBoard); if (Util.IsSquareAttacked(currentKingPosition, pieceMoves)) { kingChecked = true; } else { if (_whiteToMove) { if (Util.AreSquaresAttacked(whiteOOCastleAttackedSquares, pieceMoves)) { allowOOCastle = false; } if (Util.AreSquaresAttacked(whiteOOOCastleAttackedSquares, pieceMoves)) { allowOOOCastle = false; } } else { if (Util.AreSquaresAttacked(blackOOCastleAttackedSquares, pieceMoves)) { allowOOCastle = false; } if (Util.AreSquaresAttacked(blackOOOCastleAttackedSquares, pieceMoves)) { allowOOOCastle = false; } } } //get all targeted enemy squares without regard for blocking squares. Used to trim check verification step enemyPseudoMoves.Add(MoveGenerator.PseudomoveBitboard(piece, _theBoard)); } if (!kingChecked) { if (_whiteToMove) { if (_whiteOOCastle && allowOOCastle && Util.AreSquaresEmpty(whiteOOCastleAttackedSquares, _theBoard)) { nonCheckingMoves.Add(new Move() { From = whiteKing, To = whiteKing + 2, CastleRookFrom = _theBoard[7], CastleRookTo = _theBoard[7] - 2, removesOO = true }); } if (_whiteOOOCastle && allowOOOCastle && Util.AreSquaresEmpty(whiteOOOCastleOccupiedSquares, _theBoard)) { nonCheckingMoves.Add(new Move() { From = whiteKing, To = whiteKing - 2, CastleRookFrom = _theBoard[0], CastleRookTo = _theBoard[0] + 3, removesOOO = true }); } } else { if (_blackOOCastle && allowOOOCastle && Util.AreSquaresEmpty(blackOOCastleAttackedSquares, _theBoard)) { nonCheckingMoves.Add(new Move() { From = blackKing, To = blackKing + 2, CastleRookFrom = _theBoard[63], CastleRookTo = _theBoard[63] - 2, removesOO = true }); } if (_blackOOOCastle && allowOOOCastle && Util.AreSquaresEmpty(blackOOOCastleOccupiedSquares, _theBoard)) { nonCheckingMoves.Add(new Move() { From = blackKing, To = blackKing - 2, CastleRookFrom = _theBoard[56], CastleRookTo = _theBoard[56] + 3, removesOOO = true }); } } } //generate legal moves for each of my pieces foreach (int piece in myPieces) { myGeneratedMoves.AddRange(MoveGenerator.GenerateMovesForPiece(piece, _theBoard)); } ulong movedKingPositions = KingMoveGenerator.PseudomoveBitboard(currentKingPiece); ulong unmovedKingPosition = (one << (currentKingPosition)); foreach (int piece in _theBoard.Where(e => e > 0 && _whiteToMove != Util.IsWhite(e))) { //find out if the move caused the king to be in check if ((movedKingPositions & MoveGenerator.PseudomoveBitboard(piece, _theBoard)) > 0) { threateningPieces.Add(piece); } if ((unmovedKingPosition & MoveGenerator.PseudomoveBitboard(piece, _theBoard)) > 0) { threateningPiecesNonKingMove.Add(piece); } } foreach (Move m in myGeneratedMoves) { bool kingFutureChecked = false; Move maybeCapturedEnemy = Move(m, true); m.MaterialScore = materialScore + (maybeCapturedEnemy.Captured.HasValue ? Util.GetPieceValue(maybeCapturedEnemy.Captured.Value) : 0); if (!_whiteToMove) { currentKingPiece = whiteKing; } else { currentKingPiece = blackKing; } currentKingPosition = Util.GetPieceOffset(currentKingPiece); if (Util.IsKing(m.From)) { foreach (int piece in threateningPieces.Where(e => _theBoard.Contains(e))) { //find out if the move caused the king to be in check if (((one << (currentKingPosition)) & MoveGenerator.GenerateMovesForPieceBitboard(piece, _theBoard)) > 0) { kingFutureChecked = true; } } } else { foreach (int piece in threateningPiecesNonKingMove.Where(e => _theBoard.Contains(e))) { //find out if the move caused the king to be in check if (((one << (currentKingPosition)) & MoveGenerator.GenerateMovesForPieceBitboard(piece, _theBoard)) > 0) { kingFutureChecked = true; } } } Undo(); if (!kingFutureChecked) { nonCheckingMoves.Add(m); } } result.Moves = nonCheckingMoves; if (nonCheckingMoves.Count == 0) { if (kingChecked) { result.Endgame = EndgameType.Checkmate; } else { result.Endgame = EndgameType.Stalemate; } } return(result); }