Пример #1
0
        private int FastestFirstSolve(ChessType[] board, int alpha, int beta, ChessType color, int depth, int empties, int discdiff, int prevmove)
        {
            lock (this)
            {
                int       i, j;
                int       score    = -Constants.HighestScore - 1;
                ChessType oppcolor = 2 - color;
                int       sqnum;
                int       eval;
                int       flipped;
                int       moves, mobility;
                int       best_value, best_index;
                Empties   em, old_em;
                Empties[] move_ptr = new Empties[Constants.MaxEmpties];
                int       holepar;
                int[]     goodness = new int[Constants.MaxEmpties];
                //
                bool fFoundPv = false;
                //
                //nodes++;
                if (depth == 0)
                {
                    nodes++;
                    //return evalation.MidEval2(board, color, oppcolor, empties,EmHead);
                    return(QuiescenceSolve(board, alpha, beta, color, 2, empties, discdiff, prevmove));
                }

                moves = 0;
                for (old_em = EmHead, em = old_em.Succ; em != null; old_em = em, em = em.Succ)
                {
                    sqnum   = em.Square;
                    flipped = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                    if (flipped > 0)
                    {
                        //
                        board[sqnum] = color;
                        old_em.Succ  = em.Succ;
                        //
                        mobility = count_mobility(board, oppcolor);
                        //
                        RuleUtils.UndoFlips(board, flipped, oppcolor);
                        old_em.Succ     = em;
                        board[sqnum]    = ChessType.EMPTY;
                        move_ptr[moves] = em;
                        goodness[moves] = -mobility;
                        moves++;
                    }
                }

                if (moves != 0)
                {
                    for (i = 0; i < moves; i++)
                    {
                        //
                        best_value = goodness[i];
                        best_index = i;
                        for (j = i + 1; j < moves; j++)
                        {
                            if (goodness[j] > best_value)
                            {
                                best_value = goodness[j];
                                best_index = j;
                            }
                        }
                        em = move_ptr[best_index];
                        move_ptr[best_index] = move_ptr[i];
                        goodness[best_index] = goodness[i];
                        //
                        sqnum        = em.Square;
                        holepar      = em.HoleId;
                        j            = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                        board[sqnum] = color;

                        em.Pred.Succ = em.Succ;
                        if (em.Succ != null)
                        {
                            em.Succ.Pred = em.Pred;
                        }

                        nodes++;
                        //
                        if (fFoundPv)
                        {
                            //
                            eval = -FastestFirstSolve(board, -alpha - 1, -alpha, oppcolor, depth - 1, empties - 1, -discdiff - 2 * j - 1, sqnum);
                            if ((eval > alpha) && (eval < beta))
                            {
                                eval = -FastestFirstSolve(board, -beta, -eval, oppcolor, depth - 1, empties - 1, -discdiff - 2 * j - 1, sqnum);
                                //eval = -FastestFirstMidSolve(board, -beta, -alpha, oppcolor, depth - 1, empties - 1, -discdiff - 2 * j - 1, sqnum);
                            }
                        }
                        else
                        {
                            eval = -FastestFirstSolve(board, -beta, -alpha, oppcolor, depth - 1, empties - 1, -discdiff - 2 * j - 1, sqnum);
                        }
                        //
                        RuleUtils.UndoFlips(board, j, oppcolor);
                        board[sqnum] = ChessType.EMPTY;
                        em.Pred.Succ = em;
                        if (em.Succ != null)
                        {
                            em.Succ.Pred = em;
                        }

                        if (eval > score)
                        {
                            score = eval;
                            if (eval > alpha)
                            {
                                if (eval >= beta)
                                {
                                    //
                                    return(score);
                                }
                                alpha    = eval;
                                fFoundPv = true;
                            }
                        }
                    }
                }
                else
                {
                    if (prevmove == 0)    //
                    {
                        if (discdiff > 0) //
                        {
                            return(Constants.HighestScore);
                        }
                        if (discdiff < 0)//
                        {
                            return(-Constants.HighestScore);
                        }
                        return(0);//
                    }
                    else  /* I pass: */
                    {
                        score = -FastestFirstSolve(board, -beta, -alpha, oppcolor, depth, empties, -discdiff, 0);
                    }
                }
                return(score);
            }
        }
Пример #2
0
        private int QuiescenceSolve(ChessType[] board, int alpha, int beta, ChessType color, int depth, int empties, int discdiff, int prevmove)
        {
            lock (this)
            {
                int i, j;
                int score1;
                int score2 = -Constants.HighestScore;

                ChessType oppcolor = 2 - color;
                int       sqnum;
                int       eval;
                int       flipped;
                int       moves, mobility;
                int       best_value, best_index;
                Empties   em, old_em;
                Empties[] move_ptr = new Empties[Constants.MaxEmpties];
                int       holepar;
                int[]     goodness = new int[Constants.MaxEmpties];

                //
                //nodes++;
                score1 = evalation.MidEval2(board, color, oppcolor, empties, EmHead);
                if (score1 >= beta || score1 >= 3000 || depth == 0)
                {
                    return(score1);
                }
                else if (score1 > alpha)
                {
                    alpha = score1;
                }
                moves = 0;
                for (old_em = EmHead, em = old_em.Succ; em != null; old_em = em, em = em.Succ)
                {
                    sqnum   = em.Square;
                    flipped = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                    if (flipped > 0)
                    {
                        //
                        board[sqnum] = color;
                        old_em.Succ  = em.Succ;
                        //
                        mobility = count_mobility(board, oppcolor);
                        //
                        RuleUtils.UndoFlips(board, flipped, oppcolor);
                        old_em.Succ     = em;
                        board[sqnum]    = ChessType.EMPTY;
                        move_ptr[moves] = em;
                        goodness[moves] = -mobility;
                        moves++;
                    }
                }

                if (moves != 0)
                {
                    for (i = 0; i < moves; i++)
                    {
                        best_value = goodness[i];
                        best_index = i;
                        for (j = i + 1; j < moves; j++)
                        {
                            if (goodness[j] > best_value)
                            {
                                best_value = goodness[j];
                                best_index = j;
                            }
                        }
                        em = move_ptr[best_index];
                        move_ptr[best_index] = move_ptr[i];
                        goodness[best_index] = goodness[i];

                        sqnum        = em.Square;
                        holepar      = em.HoleId;
                        j            = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                        board[sqnum] = color;

                        em.Pred.Succ = em.Succ;
                        if (em.Succ != null)
                        {
                            em.Succ.Pred = em.Pred;
                        }

                        //
                        nodes++;
                        //
                        eval = -evalation.MidEval2(board, oppcolor, color, empties - 1, EmHead);
                        // -QuiescenceSolve(board, -beta, -alpha, oppcolor, depth - 1, empties - 1, -discdiff - j - j - 1, sqnum);

                        RuleUtils.UndoFlips(board, j, oppcolor);
                        board[sqnum] = ChessType.EMPTY;
                        em.Pred.Succ = em;
                        if (em.Succ != null)
                        {
                            em.Succ.Pred = em;
                        }

                        if (eval > score2)
                        {
                            score2 = eval;
                            if (eval > alpha)
                            {
                                if (eval >= beta)
                                {
                                    //
                                    return(score2);
                                }
                                alpha = eval;
                            }
                        }
                    }
                }
                else
                {
                    if (prevmove == 0)//
                    {
                        if (discdiff > 0)
                        {
                            return(Constants.HighestScore);
                        }
                        if (discdiff < 0)
                        {
                            return(-Constants.HighestScore);
                        }
                        return(0);
                    }
                    else  /* I pass: */
                    {
                        nodes++;
                        score2 = -QuiescenceSolve(board, -beta, -alpha, oppcolor, depth, empties, -discdiff, 0);
                        return(score2);
                    }
                }
                return((2 * score1 + score2) / 3); // (5 * score1 + 3 * score2) / 8;
            }
        }
Пример #3
0
        public int FastestFirstEndSolve(ChessType[] board, int alpha, int beta, ChessType color, int empties, int discdiff, int prevmove)
        {
            int       i, j;
            int       score    = -highestScore;
            ChessType oppcolor = 2 - color;
            int       sqnum    = -1;
            int       ev;
            int       flipped;
            int       moves, mobility;
            int       best_value, best_index;
            Empties   em, old_em;

            Empties[] move_ptr = new Empties[64];
            int       holepar;

            int[] goodness = new int[64];
            moves = 0;
            nodes++;
            for (old_em = EmHead, em = old_em.Succ; em != null; old_em = em, em = em.Succ)
            {
                sqnum   = em.Square;
                flipped = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                if (flipped > 0)
                {
                    board[sqnum] = color;
                    old_em.Succ  = em.Succ;
                    mobility     = count_mobility(board, oppcolor);
                    RuleUtils.UndoFlips(board, flipped, oppcolor);
                    old_em.Succ     = em;
                    board[sqnum]    = ChessType.EMPTY;
                    move_ptr[moves] = em;
                    goodness[moves] = -mobility;
                    moves++;
                }
            }

            if (moves != 0)
            {
                for (i = 0; i < moves; i++)
                {
                    best_value = goodness[i];
                    best_index = i;
                    for (j = i + 1; j < moves; j++)
                    {
                        if (goodness[j] > best_value)
                        {
                            best_value = goodness[j];
                            best_index = j;
                        }
                    }
                    em = move_ptr[best_index];
                    move_ptr[best_index] = move_ptr[i];
                    goodness[best_index] = goodness[i];

                    sqnum         = em.Square;
                    holepar       = em.HoleId;
                    j             = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                    board[sqnum]  = color;
                    RegionParity ^= (uint)holepar;
                    em.Pred.Succ  = em.Succ;
                    if (em.Succ != null)
                    {
                        em.Succ.Pred = em.Pred;
                    }
                    if (empties <= Constants.Fastest_First + 1)
                    {
                        ev = -ParEndSolve(board, -beta, -alpha, oppcolor, empties - 1,
                                          -discdiff - 2 * j - 1, sqnum);
                    }
                    else
                    {
                        ev = -FastestFirstEndSolve(board, -beta, -alpha, oppcolor,
                                                   empties - 1, -discdiff - 2 * j - 1, sqnum);
                    }
                    RuleUtils.UndoFlips(board, j, oppcolor);
                    RegionParity ^= (uint)holepar;
                    board[sqnum]  = ChessType.EMPTY;
                    em.Pred.Succ  = em;
                    if (em.Succ != null)
                    {
                        em.Succ.Pred = em;
                    }

                    if (ev > score)
                    {
                        score = ev;
                        if (empties == searchDepth)
                        {
                            bestMove = sqnum;
                        }
                        if (ev > alpha)
                        {
                            if (ev >= beta)
                            {
                                return(score);
                            }
                            alpha = ev;
                        }
                    }
                }
            }
            else
            {
                if (prevmove == 0)
                {
                    if (discdiff > 0)
                    {
                        return(discdiff + empties);
                    }
                    if (discdiff < 0)
                    {
                        return(discdiff - empties);
                    }
                    return(0);
                }
                else  /* I pass: */
                {
                    score = -FastestFirstEndSolve(board, -beta, -alpha, oppcolor, empties, -discdiff, 0);
                }

                if (empties == searchDepth)
                {
                    bestMove = MVPASS;
                }
            }
            return(score);
        }
Пример #4
0
        public int NoParEndSolve(ChessType[] board, int alpha, int beta, ChessType color, int empties, int discdiff, int prevmove)
        {
            int       score = -highestScore;
            ChessType oppcolor = 2 - color;
            int       sqnum = -1, j, j1;
            int       eval;
            Empties   em, old_em;

            nodes++;
            for (old_em = EmHead, em = old_em.Succ; em != null; old_em = em, em = em.Succ)
            {
                sqnum = em.Square;
                j     = RuleUtils.DoFlips(board, sqnum, color, oppcolor);
                if (j > 0)
                {
                    board[sqnum] = color;
                    old_em.Succ  = em.Succ;
                    if (empties == 2)
                    {
                        j1 = RuleUtils.CountFlips(board, EmHead.Succ.Square, oppcolor, color);
                        if (j1 > 0)//
                        {
                            eval = discdiff + 2 * (j - j1);
                        }
                        else //pass
                        {
                            j1   = RuleUtils.CountFlips(board, EmHead.Succ.Square, color, oppcolor);
                            eval = discdiff + 2 * j;
                            if (j1 > 0)//
                            {
                                eval += 2 * (j1 + 1);
                            }
                            else
                            {//both pass
                                if (eval >= 0)
                                {
                                    eval += 2;
                                }
                            }
                        }
                    }
                    else
                    {
                        eval = -NoParEndSolve(board, -beta, -alpha,
                                              oppcolor, empties - 1, -discdiff - 2 * j - 1, sqnum);
                    }
                    RuleUtils.UndoFlips(board, j, oppcolor);
                    board[sqnum] = ChessType.EMPTY;
                    old_em.Succ  = em;
                    //purning
                    if (eval > score)
                    {
                        score = eval;

                        if (empties == searchDepth)
                        {
                            bestMove = sqnum;
                        }
                        if (eval > alpha)
                        {
                            if (eval >= beta)
                            { // purning
                                return(score);
                            }
                            alpha = eval;
                        }
                    }
                }
            }

            if (score == -highestScore)
            {
                if (empties == searchDepth)
                {
                    bestMove = MVPASS;
                }
                if (prevmove == 0)
                {
                    if (discdiff > 0)
                    {
                        return(discdiff + empties);
                    }
                    if (discdiff < 0)
                    {
                        return(discdiff - empties);
                    }
                    return(0);
                }
                else
                {
                    return(-NoParEndSolve(board, -beta, -alpha, oppcolor, empties, -discdiff, 0));
                }
            }
            return(score);
        }
Пример #5
0
        public int ParEndSolve(ChessType[] board, int alpha, int beta, ChessType color, int empties, int discdiff, int prevmove)
        {
            int       score    = -highestScore;
            ChessType oppcolor = 2 - color;
            int       sqnum    = -1;
            int       j;
            int       eval;
            Empties   em, old_em;
            int       holepar;

            //
            nodes++;

            for (old_em = EmHead, em = old_em.Succ; em != null; old_em = em, em = em.Succ)
            {
                holepar = em.HoleId;
                holepar = em.Square;
                holepar = em.HoleId;
                sqnum   = em.Square;
                j       = RuleUtils.DoFlips(board, sqnum, color, oppcolor);

                if (j > 0)
                {
                    //
                    board[sqnum] = color;
                    //
                    RegionParity ^= (uint)holepar;
                    //
                    old_em.Succ = em.Succ;
                    if (empties <= 1 + Constants.Use_Parity)
                    {
                        eval = -NoParEndSolve(board, -beta, -alpha, oppcolor, empties - 1, -discdiff - 2 * j - 1, sqnum);
                    }
                    else
                    {
                        eval = -ParEndSolve(board, -beta, -alpha, oppcolor, empties - 1, -discdiff - 2 * j - 1, sqnum);
                    }
                    //
                    RuleUtils.UndoFlips(board, j, oppcolor);
                    RegionParity ^= (uint)holepar;
                    board[sqnum]  = ChessType.EMPTY;
                    old_em.Succ   = em;

                    if (eval > score)
                    {
                        score = eval;
                        //=========================================
                        if (empties == searchDepth)
                        {
                            bestMove = sqnum;
                            //StaticMethod.UpdateMessage(score, nodes,sqnum);
                            // StaticMethod.UpdateThinkingMove(sqnum);
                        }
                        if (eval > alpha)
                        {
                            if (eval >= beta)
                            {
                                return(score);
                            }
                            alpha = eval;
                        }
                    }
                }
            }

            if (score == -highestScore)
            {
                if (empties == searchDepth)
                {
                    bestMove = MVPASS;
                }

                if (prevmove == 0)
                {
                    if (discdiff > 0)
                    {
                        return(discdiff + empties);
                    }
                    if (discdiff < 0)
                    {
                        return(discdiff - empties);
                    }
                    return(0);
                }
                else
                {
                    return(-ParEndSolve(board, -beta, -alpha, oppcolor, empties, -discdiff, 0));
                }
            }
            return(score);
        }