Exemplo n.º 1
0
        /// <summary>
        /// Removes castling possibility if needed.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        private void CalculateCastling(Bitboard bitboard)
        {
            switch (Piece)
            {
            case PieceType.King:
            {
                var shortCastlingIndex = FastArray.GetCastlingIndex(Color, CastlingType.Short);
                var longCastlingIndex  = FastArray.GetCastlingIndex(Color, CastlingType.Long);

                IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard);
                IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard);

                bitboard.CastlingPossibility[shortCastlingIndex] = false;
                bitboard.CastlingPossibility[longCastlingIndex]  = false;

                break;
            }

            case PieceType.Rook:
            {
                if (From == new Position(1, 1) || From == new Position(1, 8))
                {
                    IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard);
                    bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Long)] = false;
                }
                else if (From == new Position(8, 1) || From == new Position(8, 8))
                {
                    IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard);
                    bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Short)] = false;
                }

                break;
            }
            }
        }
Exemplo n.º 2
0
 //TODO: Make this API visibe only for array (currently is public for all classes in assembly)
 internal ElementMover(FastArray <T_ElementType> inArrayFrom, int inIndexToMove, bool inUseSwapRemove)
 {
     _arrayFrom                 = inArrayFrom;
     _indexToMove               = inIndexToMove;
     _useSwapRemove             = inUseSwapRemove;
     _validation_changesTracker = inArrayFrom._validation_changesTracker;
 }
Exemplo n.º 3
0
 private void collectConstructionSiteWorkers(ref FastArray <CrewMember> outWorkers)
 {
     outWorkers.clear();
     _carCity.collectCrewMembers(ref outWorkers, (CrewMember inCrewMember) => {
         return(_constructionSite == inCrewMember.getConstruction());
     });
 }
Exemplo n.º 4
0
 public void addAll(FastArray <T_ElementType> inOtherArray)
 {
     foreach (T_ElementType theElementToAdd in inOtherArray)
     {
         add(theElementToAdd);
     }
 }
Exemplo n.º 5
0
        /// <summary>
        /// Calculates attacks for the specified piece.
        /// </summary>
        /// <param name="pieceBitboard">The bitboard with set bit at piece position.</param>
        /// <param name="excludedFields">The bitboard with excluded fields from attacks calculating.</param>
        /// <param name="opt">The generator parameters.</param>
        private static void CalculateAttacks(ulong pieceBitboard, ulong excludedFields, GeneratorParameters opt)
        {
            if ((opt.Mode & GeneratorMode.CalculateAttacks) == 0)
            {
                return;
            }

            var pieceIndex       = BitOperations.GetBitIndex(pieceBitboard);
            var blockersToRemove = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Bishop)] |
                                   opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Queen)];

            var allPiecesOccupancy = opt.OccupancySummary & ~blockersToRemove;

            var pattern = MagicContainer.GetBishopAttacks(pieceIndex, allPiecesOccupancy);

            pattern  = CalculatePawnBlockers(pieceIndex, pattern, opt);
            pattern ^= excludedFields;

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);

                opt.Bitboard.Attacks[patternIndex] |= pieceBitboard;
                opt.Bitboard.AttacksSummary[(int)opt.FriendlyColor] |= patternLSB;
            }
        }
        /// <summary>
        /// Checks if there is a G4/G5 sacrifice pattern (enemy sacrifice light piece to open file near to the king and
        /// attack him with the Queen/Rook).
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="move">The move.</param>
        /// <returns>True if patterns is detected and move should be pruned, otherwise false.</returns>
        private bool IsG4G5Sacrifice(Bitboard bitboard, Move move)
        {
            const ulong whiteTrapField = 0x0000000200000000;
            const ulong blackTrapField = 0x0000000002000000;

            var castlingDone       = bitboard.CastlingDone[(int)move.Color];
            var regularGamePhase   = bitboard.GamePhase == GamePhase.Regular;
            var moveDetected       = false;
            var lightPieceDetected = false;

            var whitePiecesTrap = bitboard.Pieces[FastArray.GetPieceIndex(Color.White, PieceType.Knight)] |
                                  bitboard.Pieces[FastArray.GetPieceIndex(Color.White, PieceType.Bishop)];

            var blackPiecesTrap = bitboard.Pieces[FastArray.GetPieceIndex(Color.Black, PieceType.Knight)] |
                                  bitboard.Pieces[FastArray.GetPieceIndex(Color.Black, PieceType.Bishop)];

            switch (move.Color)
            {
            case Color.White:
            {
                moveDetected       = move.From == new Position(8, 3) && move.To == new Position(7, 4);
                lightPieceDetected = (blackPiecesTrap & blackTrapField) != 0;
                break;
            }

            case Color.Black:
            {
                moveDetected       = move.From == new Position(8, 6) && move.To == new Position(7, 5);
                lightPieceDetected = (whitePiecesTrap & whiteTrapField) != 0;
                break;
            }
            }

            return(castlingDone && regularGamePhase && moveDetected && lightPieceDetected);
        }
        /// <summary>
        /// Adds or removes piece from Zobrist hash.
        /// </summary>
        /// <param name="color">The piece color.</param>
        /// <param name="pieceType">The piece type.</param>
        /// <param name="field">The field bitboard.</param>
        /// <param name="bitboard">The bitboard.</param>
        public static void AddOrRemovePiece(Color color, PieceType pieceType, ulong field, Bitboard bitboard)
        {
            var fieldIndex = BitOperations.GetBitIndex(field);
            var index      = FastArray.GetZobristPieceIndex(color, pieceType, fieldIndex);

            bitboard.Hash ^= ZobristContainer.Pieces[index];
        }
        /// <summary>
        /// Removes castling possibility Zobrist hash.
        /// </summary>
        /// <param name="color">The piece color.</param>
        /// <param name="castlingType">The castling type.</param>
        /// <param name="bitboard">The bitboard.</param>
        public static void RemoveCastlingPossibility(Color color, CastlingType castlingType, Bitboard bitboard)
        {
            var castlingIndex = FastArray.GetCastlingIndex(color, castlingType);

            if (bitboard.CastlingPossibility[castlingIndex])
            {
                bitboard.Hash ^= ZobristContainer.Castling[castlingIndex];
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Removes castling possibility from the specified bitboard.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        private void RemoveCastlingPossibility(Bitboard bitboard)
        {
            IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard);
            IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard);

            bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Short)] = false;
            bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Long)]  = false;
            IncrementalCastling.SetCastlingDone(bitboard, Color);

            bitboard.CastlingDone[(int)Color] = true;
        }
Exemplo n.º 10
0
        /// <summary>
        /// Removes en passant piece from the specified bitboard.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="enemyColor">The enemy color.</param>
        /// <param name="fieldLSB">The bitboard with set field.</param>
        private void RemoveEnPassantPiece(Bitboard bitboard, Color enemyColor, ulong fieldLSB)
        {
            var enPassantPiece = Color == Color.White ? fieldLSB >> 8 : fieldLSB << 8;

            bitboard.Pieces[FastArray.GetPieceIndex(enemyColor, PieceType.Pawn)] &= ~enPassantPiece;
            bitboard.Occupancy[(int)enemyColor] ^= enPassantPiece;

            IncrementalMaterial.RemovePiece(bitboard, enemyColor, PieceType.Pawn);
            IncrementalPosition.RemovePiece(bitboard, enemyColor, PieceType.Pawn, enPassantPiece);
            IncrementalZobrist.AddOrRemovePiece(enemyColor, PieceType.Pawn, enPassantPiece, bitboard);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets a piece type on the specified field.
        /// </summary>
        /// <param name="field">The field with piece.</param>
        /// <param name="pieceColor">The piece color.</param>
        /// <param name="bitboard">The bitboard.</param>
        /// <exception cref="PieceTypeNotFoundException">Thrown when there is no piece on the specified field.</exception>
        /// <returns>The piece type on the specified field.</returns>
        private PieceType GetPieceType(ulong field, Color pieceColor, Bitboard bitboard)
        {
            for (var piece = 0; piece < 6; piece++)
            {
                if ((field & bitboard.Pieces[FastArray.GetPieceIndex(pieceColor, (PieceType)piece)]) != 0)
                {
                    return((PieceType)piece);
                }
            }

            throw new PieceTypeNotFoundException();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Calculates a position evaluation result for the specified parameters.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="color">The player color.</param>
        /// <returns>The position evaluation result.</returns>
        private int GetPosition(Bitboard bitboard, Color color)
        {
            var position = 0;

            for (var piece = 0; piece < 6; piece++)
            {
                var piecesToParse = bitboard.Pieces[FastArray.GetPieceIndex(color, (PieceType)piece)];
                position += GetPositionValue(bitboard, color, (PieceType)piece, piecesToParse);
            }

            return(position);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Gets a pieces array (for bitboards).
        /// </summary>
        /// <returns>The pieces array.</returns>
        public ulong[] GetPiecesArray()
        {
            var pieces = new ulong[12];

            foreach (var piece in Pieces)
            {
                var bitPosition = BitPositionConverter.ToULong(piece.Position);
                pieces[FastArray.GetPieceIndex(piece.Color, piece.Type)] |= bitPosition;
            }

            return(pieces);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Calculates occupancy for all players.
        /// </summary>
        /// <returns>The occupancy array.</returns>
        private ulong[] CalculateOccupancy()
        {
            var occupancy = new ulong[2];

            for (var piece = 0; piece < 6; piece++)
            {
                occupancy[(int)Color.White] |= Pieces[FastArray.GetPieceIndex(Color.White, (PieceType)piece)];
                occupancy[(int)Color.Black] |= Pieces[FastArray.GetPieceIndex(Color.Black, (PieceType)piece)];
            }

            return(occupancy);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Checks if king with the specified color is checked.
        /// </summary>
        /// <param name="color">The king color.</param>
        /// <returns>True if king with specified color is checked, otherwise false.</returns>
        public bool IsCheck(Color color)
        {
            if (!_calculated)
            {
                throw new BitboardNotCalculatedException();
            }

            var enemyColor = ColorOperations.Invert(color);
            var king       = Pieces[FastArray.GetPieceIndex(color, PieceType.King)];

            return((AttacksSummary[(int)enemyColor] & king) != 0);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Calculates diagonal attacks (and moves if possible).
        /// </summary>
        /// <param name="leftAttackShift">The left attack shift.</param>
        /// <param name="rightAttackShift">The right attacks shift.</param>
        /// <param name="ignoreFields">The bitboard with fields to ignore (white and black pieces will have different ones).</param>
        /// <param name="opt">The generator parameters.</param>
        private static void CalculateDiagonalAttacks(int leftAttackShift, int rightAttackShift, ulong ignoreFields, GeneratorParameters opt)
        {
            var piecesToParse = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Pawn)];
            var validPieces   = piecesToParse & ~ignoreFields;

            var pattern       = opt.FriendlyColor == Color.White ? validPieces << leftAttackShift : validPieces >> rightAttackShift;
            var promotionLine = GetPromotionLine(opt.FriendlyColor);

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);

                var pieceLSB   = opt.FriendlyColor == Color.White ? patternLSB >> leftAttackShift : patternLSB << rightAttackShift;
                var pieceIndex = BitOperations.GetBitIndex(pieceLSB);

                if ((opt.Mode & GeneratorMode.CalculateMoves) != 0)
                {
                    var piecePosition  = BitPositionConverter.ToPosition(pieceIndex);
                    var enPassantField = opt.Bitboard.EnPassant[(int)opt.EnemyColor] & patternLSB;

                    if ((patternLSB & opt.EnemyOccupancy) != 0 || enPassantField != 0)
                    {
                        var to = BitPositionConverter.ToPosition(patternIndex);

                        if (enPassantField != 0)
                        {
                            opt.Bitboard.Moves.AddLast(new EnPassantMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor));
                        }
                        else if ((patternLSB & promotionLine) != 0)
                        {
                            opt.Bitboard.Moves.AddLast(new PromotionMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Queen, true));
                            opt.Bitboard.Moves.AddLast(new PromotionMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Rook, true));
                            opt.Bitboard.Moves.AddLast(new PromotionMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Bishop, true));
                            opt.Bitboard.Moves.AddLast(new PromotionMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Knight, true));
                        }
                        else
                        {
                            opt.Bitboard.Moves.AddLast(new KillMove(piecePosition, to, PieceType.Pawn, opt.FriendlyColor));
                        }
                    }
                }

                if ((opt.Mode & GeneratorMode.CalculateAttacks) != 0)
                {
                    opt.Bitboard.Attacks[patternIndex] |= pieceLSB;
                    opt.Bitboard.AttacksSummary[(int)opt.FriendlyColor] |= patternLSB;
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Generates available moves.
        /// </summary>
        /// <param name="pieceType">The piece type.</param>
        /// <param name="opt">The generator parameters.</param>
        public static void Generate(PieceType pieceType, GeneratorParameters opt)
        {
            var piecesToParse = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, pieceType)];

            while (piecesToParse != 0)
            {
                var pieceLSB = BitOperations.GetLSB(piecesToParse);
                piecesToParse = BitOperations.PopLSB(piecesToParse);

                var excludeFromAttacks = CalculateMoves(pieceType, pieceLSB, opt);
                CalculateAttacks(pieceLSB, excludeFromAttacks, opt);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Calculates a material evaluation result for the specified player by adding all piece values and
        /// multiplying them by the specified ratio.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="color">The player color.</param>
        /// <returns>The material evaluation result for the specified player.</returns>
        private int GetMaterialValue(Bitboard bitboard, Color color)
        {
            var material = 0;

            for (var piece = 0; piece < 6; piece++)
            {
                var piecesToParse = bitboard.Pieces[FastArray.GetPieceIndex(color, (PieceType)piece)];
                var piecesCount   = BitOperations.Count(piecesToParse);

                material += piecesCount * MaterialValues.PieceValues[piece];
            }

            return(material);
        }
Exemplo n.º 19
0
        public static byte[] ReadStream(Stream s)
        {
            var buffer = new byte[2048];

            using (var output = FastArray.New(2024))
                do
                {
                    var i = s.Read(buffer, 0, buffer.Length);
                    if (i == 0)
                    {
                        return(output.ToArray());
                    }
                    output.AddRange(buffer, i);
                } while (true);
        }
Exemplo n.º 20
0
 public void collectAll(ref FastArray <T_ElementType> outElements, ElementPredicate inPredicate)
 {
     if (null == inPredicate)
     {
         return;
     }
     foreach (T_ElementType theElement in this)
     {
         if (!inPredicate(theElement))
         {
             continue;
         }
         outElements.add(theElement);
     }
 }
Exemplo n.º 21
0
        /// <summary>
        /// Gets a least valuable piece for the specified bitboard with field attackers.
        /// </summary>
        /// <param name="attackers">The bitboard with field attackers.</param>
        /// <param name="color">The color of a least valuable piece.</param>
        /// <param name="bitboard">The bitboard.</param>
        /// <returns>The least valuable piece (null if there is no more available pieces).</returns>
        private PieceType?GetAndPopLeastValuablePiece(ref ulong attackers, Color color, Bitboard bitboard)
        {
            for (var piece = 0; piece < 6; piece++)
            {
                var attackersWithType = attackers & bitboard.Pieces[FastArray.GetPieceIndex(color, (PieceType)piece)];

                if (attackersWithType != 0)
                {
                    var attackerLSB = BitOperations.GetLSB(attackersWithType);
                    attackers &= ~attackerLSB;

                    return((PieceType)piece);
                }
            }

            return(null);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Helper method for derived classes, calculates move with the specified parameters.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="pieceFrom">The source piece type.</param>
        /// <param name="from">The piece source position.</param>
        /// <param name="pieceTo">The destination piece type.</param>
        /// <param name="to">The piece destination position.</param>
        protected void CalculatePieceMove(Bitboard bitboard, PieceType pieceFrom, ulong from, PieceType pieceTo, ulong to)
        {
            bitboard.Pieces[FastArray.GetPieceIndex(Color, pieceFrom)] &= ~from;
            bitboard.Pieces[FastArray.GetPieceIndex(Color, pieceTo)]   |= to;
            bitboard.Occupancy[(int)Color] ^= from | to;

            IncrementalPosition.RemovePiece(bitboard, Color, pieceFrom, from);
            IncrementalPosition.AddPiece(bitboard, Color, pieceTo, to);

            IncrementalZobrist.AddOrRemovePiece(Color, pieceFrom, from, bitboard);
            IncrementalZobrist.AddOrRemovePiece(Color, pieceTo, to, bitboard);

            if (pieceFrom == PieceType.Pawn)
            {
                bitboard.ReversibleMoves = 0;
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Calculates X-Ray attacks when friendly pawn is on bishop way.
        /// </summary>
        /// <param name="pieceIndex">The field index with the specified bishop.</param>
        /// <param name="pattern">The bishop moves pattern.</param>
        /// <param name="opt">The generator parameters.</param>
        /// <returns>The attacks bitboard with pawn X-Ray attacks.</returns>
        private static ulong CalculatePawnBlockers(int pieceIndex, ulong pattern, GeneratorParameters opt)
        {
            var patternWithFriendlyBlockers = pattern;
            var allowedBlockers             = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Pawn)];

            var piecePosition    = BitPositionConverter.ToPosition(pieceIndex);
            var friendlyBlockers = pattern & opt.FriendlyOccupancy & allowedBlockers;

            while (friendlyBlockers != 0)
            {
                var friendlyBlockerLSB = BitOperations.GetLSB(friendlyBlockers);
                friendlyBlockers = BitOperations.PopLSB(friendlyBlockers);

                var friendlyBlockerIndex    = BitOperations.GetBitIndex(friendlyBlockerLSB);
                var friendlyBlockerPosition = BitPositionConverter.ToPosition(friendlyBlockerIndex);

                switch (opt.FriendlyColor)
                {
                case Color.White when friendlyBlockerPosition.X > piecePosition.X && friendlyBlockerPosition.Y > piecePosition.Y && (friendlyBlockerLSB & (BitConstants.HFile | BitConstants.HRank)) == 0:
                {
                    patternWithFriendlyBlockers |= friendlyBlockerLSB << 7;
                    break;
                }

                case Color.White when friendlyBlockerPosition.X <piecePosition.X && friendlyBlockerPosition.Y> piecePosition.Y && (friendlyBlockerLSB & (BitConstants.AFile | BitConstants.HRank)) == 0:
                {
                    patternWithFriendlyBlockers |= friendlyBlockerLSB << 9;
                    break;
                }

                case Color.Black when friendlyBlockerPosition.X > piecePosition.X && friendlyBlockerPosition.Y < piecePosition.Y && (friendlyBlockerLSB & (BitConstants.HFile | BitConstants.ARank)) == 0:
                {
                    patternWithFriendlyBlockers |= friendlyBlockerLSB >> 9;
                    break;
                }

                case Color.Black when friendlyBlockerPosition.X < piecePosition.X && friendlyBlockerPosition.Y < piecePosition.Y && (friendlyBlockerLSB & (BitConstants.AFile | BitConstants.ARank)) == 0:
                {
                    patternWithFriendlyBlockers |= friendlyBlockerLSB >> 7;
                    break;
                }
                }
            }

            return(patternWithFriendlyBlockers);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Calculates a chain evaluation result for the specified player by adding number of pawns
        /// in chains multiplied by the specified ratio.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="color">The player color.</param>
        /// <returns>The chain evaluation result for the specified player.</returns>
        public int GetChainValue(Bitboard bitboard, Color color)
        {
            var chain = 0;

            var pawns        = bitboard.Pieces[FastArray.GetPieceIndex(color, PieceType.Pawn)];
            var pawnsToParse = pawns;

            while (pawnsToParse != 0)
            {
                var pawnLSB = BitOperations.GetLSB(pawnsToParse);
                pawnsToParse = BitOperations.PopLSB(pawnsToParse);

                var chainMask = GetChainMask(color, pawnLSB);

                chain += BitOperations.Count(pawns & chainMask);
            }

            return(chain * PawnStructureValues.PawnChainRatio[(int)bitboard.GamePhase]);
        }
Exemplo n.º 25
0
        /// <summary>
        /// Generates available moves.
        /// </summary>
        /// <param name="opt">The generator parameters.</param>
        public static void Generate(GeneratorParameters opt)
        {
            var piecesToParse = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Knight)];

            while (piecesToParse != 0)
            {
                var pieceLSB = BitOperations.GetLSB(piecesToParse);
                piecesToParse = BitOperations.PopLSB(piecesToParse);

                var pieceIndex    = BitOperations.GetBitIndex(pieceLSB);
                var piecePosition = BitPositionConverter.ToPosition(pieceIndex);

                var pattern = PatternsContainer.KnightPattern[pieceIndex];

                while (pattern != 0)
                {
                    var patternLSB = BitOperations.GetLSB(pattern);
                    pattern = BitOperations.PopLSB(pattern);

                    var patternIndex = BitOperations.GetBitIndex(patternLSB);

                    if ((opt.Mode & GeneratorMode.CalculateMoves) != 0 && (patternLSB & opt.FriendlyOccupancy) == 0)
                    {
                        var to = BitPositionConverter.ToPosition(patternIndex);

                        if ((patternLSB & opt.EnemyOccupancy) == 0 && !opt.QuiescenceSearch)
                        {
                            opt.Bitboard.Moves.AddLast(new QuietMove(piecePosition, to, PieceType.Knight, opt.FriendlyColor));
                        }
                        else if ((patternLSB & opt.EnemyOccupancy) != 0)
                        {
                            opt.Bitboard.Moves.AddLast(new KillMove(piecePosition, to, PieceType.Knight, opt.FriendlyColor));
                        }
                    }

                    if ((opt.Mode & GeneratorMode.CalculateAttacks) != 0)
                    {
                        opt.Bitboard.Attacks[patternIndex] |= pieceLSB;
                        opt.Bitboard.AttacksSummary[(int)opt.FriendlyColor] |= patternLSB;
                    }
                }
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Removes killed piece from the specified bitboard.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="enemyColor">The enemy color.</param>
        /// <param name="fieldLSB">The bitboard with set field.</param>
        protected void CalculateKill(Bitboard bitboard, Color enemyColor, ulong fieldLSB)
        {
            for (var piece = 0; piece < 6; piece++)
            {
                var index = FastArray.GetPieceIndex(enemyColor, (PieceType)piece);
                if ((bitboard.Pieces[index] & fieldLSB) != 0)
                {
                    bitboard.Pieces[index] &= ~fieldLSB;
                    bitboard.Occupancy[(int)enemyColor] &= ~fieldLSB;

                    IncrementalMaterial.RemovePiece(bitboard, enemyColor, (PieceType)piece);
                    IncrementalPosition.RemovePiece(bitboard, enemyColor, (PieceType)piece, fieldLSB);
                    IncrementalZobrist.AddOrRemovePiece(enemyColor, (PieceType)piece, fieldLSB, bitboard);

                    bitboard.ReversibleMoves = 0;
                    break;
                }
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Calculates double push moves.
        /// </summary>
        /// <param name="opt">The generator parameters.</param>
        private static void CalculateMovesForDoublePush(GeneratorParameters opt)
        {
            if ((opt.Mode & GeneratorMode.CalculateMoves) == 0 || opt.QuiescenceSearch)
            {
                return;
            }

            var   piecesToParse = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Pawn)];
            ulong validPieces;
            ulong pattern;

            if (opt.FriendlyColor == Color.White)
            {
                validPieces  = piecesToParse & BitConstants.BRank;
                validPieces &= ~opt.OccupancySummary >> 8;
                pattern      = validPieces << 16;
            }
            else
            {
                validPieces  = piecesToParse & BitConstants.GRank;
                validPieces &= ~opt.OccupancySummary << 8;
                pattern      = validPieces >> 16;
            }

            pattern &= ~opt.OccupancySummary;

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);

                var pieceLSB   = opt.FriendlyColor == Color.White ? patternLSB >> 16 : patternLSB << 16;
                var pieceIndex = BitOperations.GetBitIndex(pieceLSB);

                var from = BitPositionConverter.ToPosition(pieceIndex);
                var to   = BitPositionConverter.ToPosition(patternIndex);

                opt.Bitboard.Moves.AddLast(new QuietMove(from, to, PieceType.Pawn, opt.FriendlyColor));
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Calculates a doubled pawns evaluation result for the specified player by adding number of pawns
        /// on the same files.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="color">The player color.</param>
        /// <returns>The doubled pawns evaluation result for the specified player.</returns>
        public int GetDoubledPawnsValue(Bitboard bitboard, Color color)
        {
            var doubledPawns = 0;
            var pawns        = bitboard.Pieces[FastArray.GetPieceIndex(color, PieceType.Pawn)];

            for (var i = 0; i < 8; i++)
            {
                var file = BitConstants.HFile << i;

                var pawnsInFile = pawns & file;
                pawnsInFile = BitOperations.PopLSB(pawnsInFile);

                if (pawnsInFile != 0)
                {
                    doubledPawns += BitOperations.Count(pawnsInFile);
                }
            }

            return(doubledPawns * PawnStructureValues.DoubledPawnsRatio[(int)bitboard.GamePhase]);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Calculates single push moves.
        /// </summary>
        /// <param name="opt">The generator parameters.</param>
        private static void CalculateMovesForSinglePush(GeneratorParameters opt)
        {
            if ((opt.Mode & GeneratorMode.CalculateMoves) == 0)
            {
                return;
            }

            var piecesToParse = opt.Bitboard.Pieces[FastArray.GetPieceIndex(opt.FriendlyColor, PieceType.Pawn)];

            var promotionLine = GetPromotionLine(opt.FriendlyColor);

            var pattern = opt.FriendlyColor == Color.White ? piecesToParse << 8 : piecesToParse >> 8;

            pattern &= ~opt.OccupancySummary;

            while (pattern != 0)
            {
                var patternLSB = BitOperations.GetLSB(pattern);
                pattern = BitOperations.PopLSB(pattern);

                var patternIndex = BitOperations.GetBitIndex(patternLSB);

                var pieceLSB   = opt.FriendlyColor == Color.White ? patternLSB >> 8 : patternLSB << 8;
                var pieceIndex = BitOperations.GetBitIndex(pieceLSB);

                var from = BitPositionConverter.ToPosition(pieceIndex);
                var to   = BitPositionConverter.ToPosition(patternIndex);

                if ((patternLSB & promotionLine) == 0 && !opt.QuiescenceSearch)
                {
                    opt.Bitboard.Moves.AddLast(new QuietMove(from, to, PieceType.Pawn, opt.FriendlyColor));
                }
                else if ((patternLSB & promotionLine) != 0)
                {
                    opt.Bitboard.Moves.AddLast(new PromotionMove(from, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Queen, false));
                    opt.Bitboard.Moves.AddLast(new PromotionMove(from, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Rook, false));
                    opt.Bitboard.Moves.AddLast(new PromotionMove(from, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Bishop, false));
                    opt.Bitboard.Moves.AddLast(new PromotionMove(from, to, PieceType.Pawn, opt.FriendlyColor, PieceType.Knight, false));
                }
            }
        }
Exemplo n.º 30
0
        /// <summary>
        /// Calculates a value of pieces that are attacking the neighbour fields of specified king.
        /// </summary>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="color">The king color.</param>
        /// <returns>The value of the pieces that are attacking king neighbour fields multiplied by the specified ratio.</returns>
        private int GetAttackedNeighboursValue(Bitboard bitboard, Color color)
        {
            var attackedNeighbours = 0;

            var king      = bitboard.Pieces[FastArray.GetPieceIndex(color, PieceType.King)];
            var kingIndex = BitOperations.GetBitIndex(king);
            var kingMoves = PatternsContainer.KingExpandedPattern[kingIndex];

            while (kingMoves != 0)
            {
                var fieldLSB = BitOperations.GetLSB(kingMoves);
                kingMoves = BitOperations.PopLSB(kingMoves);

                var fieldIndex = BitOperations.GetBitIndex(fieldLSB);
                var attacks    = bitboard.Attacks[fieldIndex] & ~bitboard.Occupancy[(int)color];

                attackedNeighbours += BitOperations.Count(attacks);
            }

            return(attackedNeighbours * KingSafetyValues.AttackedNeighboursRatio[(int)bitboard.GamePhase]);
        }