Пример #1
0
        // connected_threat() tests whether it is safe to forward prune a move or if
        // is somehow connected to the threat move returned by null search.
        static bool connected_threat(Position pos, Move m, Move threat)
        {
            Debug.Assert(Utils.is_ok_M(m));
            Debug.Assert(Utils.is_ok_M(threat));
            Debug.Assert(!pos.is_capture_or_promotion(m));
            Debug.Assert(!pos.is_passed_pawn_push(m));

            Square mfrom, mto, tfrom, tto;

            mfrom = Utils.from_sq(m);
            mto = Utils.to_sq(m);
            tfrom = Utils.from_sq(threat);
            tto = Utils.to_sq(threat);

            // Case 1: Don't prune moves which move the threatened piece
            if (mfrom == tto)
                return true;

            // Case 2: If the threatened piece has value less than or equal to the
            // value of the threatening piece, don't prune moves which defend it.
            if (pos.is_capture(threat)
                && (Position.PieceValueMidgame[pos.piece_on(tfrom)] >= Position.PieceValueMidgame[pos.piece_on(tto)]
                    || Utils.type_of(pos.piece_on(tfrom)) == PieceTypeC.KING)
                && pos.move_attacks_square(m, tto))
                return true;

            // Case 3: If the moving piece in the threatened move is a slider, don't
            // prune safe moves which block its ray.
            if (piece_is_slider(pos.piece_on(tfrom))
                && (Utils.bit_is_set(Utils.between_bb(tfrom, tto), mto) != 0)
                && pos.see(m, true) >= 0)
                return true;

            return false;
        }