public void PartitionAndSortTest2()
        {
            var table = new ExtMove[]
            {
                new ExtMove(Move.Create(528), Value.Create(0)),
                new ExtMove(Move.Create(593), Value.Create(0)),
                new ExtMove(Move.Create(658), Value.Create(-32)),
                new ExtMove(Move.Create(723), Value.Create(0)),
                new ExtMove(Move.Create(788), Value.Create(0)),
                new ExtMove(Move.Create(853), Value.Create(-32)),
                new ExtMove(Move.Create(918), Value.Create(-32)),
                new ExtMove(Move.Create(983), Value.Create(-32)),
                new ExtMove(Move.Create(796), Value.Create(32)),
                new ExtMove(Move.Create(731), Value.Create(0))
            };

            var splitted = ExtMoveArrayWrapper.Partition(new ExtMoveArrayWrapper(table, 0),
                new ExtMoveArrayWrapper(table, 9));

            Assert.AreEqual(1, splitted.current);
            Assert.AreEqual(796, splitted[0].Move);
            Assert.AreEqual(593, splitted[1].Move);
            Assert.AreEqual(528, splitted[8].Move);

        }
Exemple #2
0
    // Our insertion sort, which is guaranteed (and also needed) to be stable
    public static void insertion_sort(ExtMove begin, ExtMove end)
    {
        ExtMove tmp = new ExtMove();
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
        ExtMove *p = new ExtMove();
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
        ExtMove *q = new ExtMove();

        for (p = begin + 1; p < end; ++p)
        {
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist:
//ORIGINAL LINE: tmp = *p;
            tmp.CopyFrom(p);
            for (q = p; q != begin && *(q - 1) < tmp; --q)
            {
                *q = (q - 1);
            }
            *q = tmp;
        }
    }
Exemple #3
0
    // Add underpromotion captures to list of captures.
    internal static ExtMove add_underprom_caps(Position pos, ExtMove stack, ExtMove end)
    {
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
        ExtMove *moves = new ExtMove();
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
//ORIGINAL LINE: ExtMove *extra = end;
        ExtMove *extra = new ExtMove(end);

        for (moves = stack; moves < end; moves++)
        {
            Move move = moves.move;
            if (GlobalMembersTypes.type_of(move) == MoveType.PROMOTION && !pos.empty(GlobalMembersTypes.to_sq(move)))
            {
                (*extra++).move = (Move)(move - (1 << 12));
                (*extra++).move = (Move)(move - (2 << 12));
                (*extra++).move = (Move)(move - (3 << 12));
            }
        }

        return(extra);
    }
Exemple #4
0
    /// generate_next_stage() generates, scores and sorts the next bunch of moves,
    /// when there are no more moves to try for the current stage.
    private void generate_next_stage()
    {
        Debug.Assert(stage != Stages.STOP);

        cur.set(moves);

        switch (++stage)
        {
            case Stages.GOOD_CAPTURES:
            case Stages.QCAPTURES_1:
            case Stages.QCAPTURES_2:
            case Stages.PROBCUT_CAPTURES:
            case Stages.RECAPTURES:
            {
                endMoves = Movegen.generate(GenType.CAPTURES, pos, new ExtMoveArrayWrapper(moves));
                score(GenType.CAPTURES);
            }
                break;

            case Stages.KILLERS:
                killers[0] = new ExtMove(ss[ss.current].killers0, killers[0].Value);
                killers[1] = new ExtMove(ss[ss.current].killers1, killers[1].Value);
                killers[2] = new ExtMove(countermove, killers[2].Value);
                cur.set(killers);
                endMoves = new ExtMoveArrayWrapper(cur.table, cur.current + 2
                                                              +
                                                              ((countermove != killers[0] && countermove != killers[1])
                                                                  ? 1
                                                                  : 0));
                break;

            case Stages.GOOD_QUIETS:
            {
                endQuiets = Movegen.generate(GenType.QUIETS, pos, new ExtMoveArrayWrapper(moves));
                endMoves = endQuiets;
                score(GenType.QUIETS);

                endMoves = ExtMoveArrayWrapper.Partition(cur, endMoves);
                ExtMoveArrayWrapper.insertion_sort(cur, endMoves);
            }
                break;

            case Stages.BAD_QUIETS:
                cur = new ExtMoveArrayWrapper(endMoves);
                endMoves = endQuiets;
                if (depth >= 3*Depth.ONE_PLY_C)
                {
                    ExtMoveArrayWrapper.insertion_sort(cur, endMoves);
                }
                break;

            case Stages.BAD_CAPTURES:
                // Just pick them in reverse order to get correct ordering
                cur = new ExtMoveArrayWrapper(moves) + (_.MAX_MOVES - 1);
                endMoves = endBadCaptures;
                break;

            case Stages.ALL_EVASIONS:
            {
                endMoves = Movegen.generate(GenType.EVASIONS, pos, new ExtMoveArrayWrapper(moves));

                if (endMoves.current > 1)
                {
                    score(GenType.EVASIONS);
                }
            }
                break;

            case Stages.CHECKS:
            {
                endMoves = Movegen.generate(
                    GenType.QUIET_CHECKS,
                    pos,
                    new ExtMoveArrayWrapper(moves));
            }
                break;

            case Stages.EVASION:
            case Stages.QSEARCH_WITH_CHECKS:
            case Stages.QSEARCH_WITHOUT_CHECKS:
            case Stages.PROBCUT:
            case Stages.RECAPTURE:
            case Stages.STOP:
                stage = Stages.STOP;
                break;

            default:
                Debug.Assert(false);
                break;
        }
    }
Exemple #5
0
    private void score_EVASIONS()
    {
        // Try winning and equal captures captures ordered by MVV/LVA, then non-captures
        // ordered by history value, then bad-captures and quiet moves with a negative
        // SEE ordered by SEE value.

        for (var i = 0; i < endMoves.current; i++)
        {
            var m = moves[i];
            ValueT see;
            if ((see = pos.see_sign(m)) < Value.VALUE_ZERO)
            {
                moves[i] = new ExtMove(m, see - HistoryStats.Max); // At the bottom
            }

            else if (pos.capture(m))
            {
                moves[i] = new ExtMove(
                    m,
                    Value.PieceValue[(int) Phase.MG][pos.piece_on(Move.to_sq(m))]
                    - Value.Create(Piece.type_of(pos.moved_piece(m))) + HistoryStats.Max);
            }
            else
            {
                moves[i] = new ExtMove(m, history.value(pos.moved_piece(m), Move.to_sq(m)));
            }
        }
    }
Exemple #6
0
    private void score_QUIETS()
    {
        var prevSq = Move.to_sq(ss[ss.current - 1].currentMove);
        var cmh = counterMovesHistory.value(pos.piece_on(prevSq), prevSq);

        for (var i = 0; i < endMoves.current; i++)
        {
            var m = moves[i];
            moves[i] = new ExtMove(
                m,
                history.value(pos.moved_piece(m), Move.to_sq(m))
                + cmh.value(pos.moved_piece(m), Move.to_sq(m)));
        }
    }
Exemple #7
0
    /// score() assigns a numerical value to each move in a move list. The moves with
    /// highest values will be picked first.
    private void score_CAPTURES()
    {
        // Winning and equal captures in the main search are ordered by MVV, preferring
        // captures near our home rank. Suprisingly, this appears to perform slightly
        // better than SEE based move ordering: exchanging big pieces before capturing
        // a hanging piece probably helps to reduce the subtree size.
        // In main search we want to push captures with negative SEE values to the
        // badCaptures[] array, but instead of doing it now we delay until the move
        // has been picked up, saving some SEE calls in case we get a cutoff.

        for (var i = 0; i < endMoves.current; i++)
        {
            var m = moves[i];
            moves[i] = new ExtMove(
                m,
                Value.PieceValue[(int) Phase.MG][pos.piece_on(Move.to_sq(m))]
                - Value.Create(200 * Rank.relative_rank_CtSt(pos.side_to_move(), Move.to_sq(m))));
        }
    }
 internal void setCurrentMove(MoveT m)
 {
     table[current] = new ExtMove(m, table[current].Value);
 }
 internal void Add(MoveT m)
 {
     table[current] = new ExtMove(m, table[current].Value);
     current++;
 }
 internal void set(ExtMove[] table)
 {
     this.table = table;
     current = 0;
 }
 internal ExtMoveArrayWrapper(ExtMove[] table, int current)
 {
     this.table = table;
     this.current = current;
 }
 internal ExtMoveArrayWrapper(ExtMove[] table)
     : this(table, 0)
 {
 }
Exemple #13
0
    // This routine treats a position with en passant captures as one without.
    internal static int probe_dtz_no_ep(Position pos, ref int success)
    {
        int wdl;
        int dtz;

        wdl = GlobalMembersTbprobe.probe_ab(pos, -2, 2, ref success);
        if (success == 0)
        {
            return(0);
        }

        if (wdl == 0)
        {
            return(0);
        }

        if (success == 2)
        {
            return(wdl == 2 ? 1 : 101);
        }

        ExtMove[] stack = Arrays.InitializeWithDefaultInstances <ExtMove>(192);
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
        ExtMove * moves = new ExtMove();
        ExtMove   end   = null;
        StateInfo st    = new StateInfo();
        CheckInfo ci    = new CheckInfo(pos);

        if (wdl > 0)
        {
            // Generate at least all legal non-capturing pawn moves
            // including non-capturing promotions.
            if (pos.checkers() == 0)
            {
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
//ORIGINAL LINE: end = generate<NON_EVASIONS>(pos, stack);
                end = GlobalMembersMovegen.generate <GenType.NON_EVASIONS>(pos, new ExtMove(stack));
            }
            else
            {
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
//ORIGINAL LINE: end = generate<EVASIONS>(pos, stack);
                end = GlobalMembersMovegen.generate <GenType.EVASIONS>(pos, new ExtMove(stack));
            }

            for (moves = stack; moves < end; moves++)
            {
                Move move = moves.move;
                if (GlobalMembersTypes.type_of(pos.moved_piece(move)) != PieceType.PAWN || pos.capture(move) || !pos.legal(move, ci.pinned))
                {
                    continue;
                }
                pos.do_move(move, st, ci, pos.gives_check(move, ci));
                int v = -GlobalMembersTbprobe.probe_ab(pos, -2, -wdl + 1, ref success);
                pos.undo_move(move);
                if (success == 0)
                {
                    return(0);
                }
                if (v == wdl)
                {
                    return(v == 2 ? 1 : 101);
                }
            }
        }

        dtz = 1 + GlobalMembersTbprobe.probe_dtz_table(pos, wdl, ref success);
        if (success >= 0)
        {
            if ((wdl & 1) != 0)
            {
                dtz += 100;
            }
            return(wdl >= 0 ? dtz : -dtz);
        }

        if (wdl > 0)
        {
            int best = 0xffff;
            for (moves = stack; moves < end; moves++)
            {
                Move move = moves.move;
                if (pos.capture(move) || GlobalMembersTypes.type_of(pos.moved_piece(move)) == PieceType.PAWN || !pos.legal(move, ci.pinned))
                {
                    continue;
                }
                pos.do_move(move, st, ci, pos.gives_check(move, ci));
                int v = -GlobalMembersTbprobe.probe_dtz(pos, ref success);
                pos.undo_move(move);
                if (success == 0)
                {
                    return(0);
                }
                if (v > 0 && v + 1 < best)
                {
                    best = v + 1;
                }
            }
            return(best);
        }
        else
        {
            int best = -1;
            if (pos.checkers() == 0)
            {
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
//ORIGINAL LINE: end = generate<NON_EVASIONS>(pos, stack);
                end = GlobalMembersMovegen.generate <GenType.NON_EVASIONS>(pos, new ExtMove(stack));
            }
            else
            {
//C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
//ORIGINAL LINE: end = generate<EVASIONS>(pos, stack);
                end = GlobalMembersMovegen.generate <GenType.EVASIONS>(pos, new ExtMove(stack));
            }
            for (moves = stack; moves < end; moves++)
            {
                int  v;
                Move move = moves.move;
                if (!pos.legal(move, ci.pinned))
                {
                    continue;
                }
                pos.do_move(move, st, ci, pos.gives_check(move, ci));
                if (st.rule50 == 0)
                {
                    if (wdl == -2)
                    {
                        v = -1;
                    }
                    else
                    {
                        v = GlobalMembersTbprobe.probe_ab(pos, 1, 2, ref success);
                        v = (v == 2) ? 0 : -101;
                    }
                }
                else
                {
                    v = -GlobalMembersTbprobe.probe_dtz(pos, ref success) - 1;
                }
                pos.undo_move(move);
                if (success == 0)
                {
                    return(0);
                }
                if (v < best)
                {
                    best = v;
                }
            }
            return(best);
        }
    }
Exemple #14
0
 // Picks the best move in the range (begin, end) and moves it to the front.
 // It's faster than sorting all the moves in advance when there are few
 // moves e.g. possible captures.
 public static ExtMove pick_best(ExtMove begin, ExtMove end)
 {
     std.swap(begin, *std.max_element(begin, end));
     return(begin);
 }
Exemple #15
0
 // Unary predicate used by std::partition to split positive values from remaining
 // ones so as to sort the two sets separately, with the second sort delayed.
 public static bool has_positive_value(ExtMove move)
 {
     return(move.value > Value.VALUE_ZERO);
 }
        public void PartitionAndSortTest1()
        {
            var table = new ExtMove[]
            {
                new ExtMove(Move.Create(528), Value.Create(-1008)),
                new ExtMove(Move.Create(593), Value.Create(-1008)),
                new ExtMove(Move.Create(658), Value.Create(-1069)),
                new ExtMove(Move.Create(788), Value.Create(-413)),
                new ExtMove(Move.Create(853), Value.Create(-944)),
                new ExtMove(Move.Create(918), Value.Create(-944)),
                new ExtMove(Move.Create(983), Value.Create(-944)),
                new ExtMove(Move.Create(1243), Value.Create(-413)),
                new ExtMove(Move.Create(536), Value.Create(-444)),
                new ExtMove(Move.Create(601), Value.Create(-444)),
                new ExtMove(Move.Create(666), Value.Create(-444)),
                new ExtMove(Move.Create(796), Value.Create(475)),
                new ExtMove(Move.Create(861), Value.Create(-444)),
                new ExtMove(Move.Create(926), Value.Create(-444)),
                new ExtMove(Move.Create(991), Value.Create(-444)),
                new ExtMove(Move.Create(75), Value.Create(-32)),
                new ExtMove(Move.Create(88), Value.Create(-444)),
                new ExtMove(Move.Create(82), Value.Create(-444)),
                new ExtMove(Move.Create(405), Value.Create(-444)),
                new ExtMove(Move.Create(407), Value.Create(-444)),
                new ExtMove(Move.Create(139), Value.Create(32)),
                new ExtMove(Move.Create(148), Value.Create(0)),
                new ExtMove(Move.Create(157), Value.Create(0)),
                new ExtMove(Move.Create(166), Value.Create(0)),
                new ExtMove(Move.Create(175), Value.Create(0)),
                new ExtMove(Move.Create(203), Value.Create(0)),
                new ExtMove(Move.Create(267), Value.Create(0)),
            };

            var splitted = ExtMoveArrayWrapper.Partition(new ExtMoveArrayWrapper(table, 0),
                new ExtMoveArrayWrapper(table, 26));

            Assert.AreEqual(2, splitted.current);
            Assert.AreEqual(139, table[0].Move);
            Assert.AreEqual(796, table[1].Move);
            Assert.AreEqual(593, table[11].Move);

            ExtMoveArrayWrapper.insertion_sort(new ExtMoveArrayWrapper(table, 0),
                splitted);

            Assert.AreEqual(796, table[0].Move);
            Assert.AreEqual(139, table[1].Move);
            Assert.AreEqual(593, table[11].Move);
        }