Beispiel #1
0
        public static int Heuristic(ulong board, bool max_for_white, List <ulong> possible_moves = null)
        {
            if (!Board.IsPlacementPhase(board))
            {
                if (Board.IsWhiteTurn(board) && Board.WhitePiecesOnBoard(board) < 3)
                {
                    if (max_for_white)
                    {
                        return(-1000);
                    }
                    else
                    {
                        return(1000);
                    }
                }
                else if (!Board.IsWhiteTurn(board) && Board.BlackPiecesOnBoard(board) < 3)
                {
                    if (max_for_white)
                    {
                        return(1000);
                    }
                    else
                    {
                        return(-1000);
                    }
                }
            }

            if (possible_moves == null)
            {
                possible_moves = Board.GetMoves(board);
            }

            if (possible_moves.Count == 0)
            {
                if (Board.IsWhiteTurn(board))
                {
                    if (max_for_white)
                    {
                        return(-1000);
                    }
                    else
                    {
                        return(1000);
                    }
                }
                else
                {
                    if (max_for_white)
                    {
                        return(1000);
                    }
                    else
                    {
                        return(-1000);
                    }
                }
            }

            /* We score +1 for a move, +2 if it forms a mill */
            int score    = 0;
            var old_runs = Board.GetRunPieces(board);

            foreach (var move in possible_moves)
            {
                var new_runs = Board.GetRunPieces(move);
                if (new_runs != old_runs && Board.CountBits(new_runs) >= Board.CountBits(old_runs))
                {
                    score += 5;
                }
                else
                {
                    score++;
                }
            }

            if (Board.IsWhiteTurn(board))
            {
                if (max_for_white)
                {
                    return(score);
                }
                else
                {
                    return(-score);
                }
            }
            else
            {
                if (max_for_white)
                {
                    return(-score);
                }
                else
                {
                    return(score);
                }
            }
        }
Beispiel #2
0
        int alphabeta(ulong board, int depth, int alpha, int beta, bool maximizingPlayer, out ulong move)
        {
            if (cache_v[depth].TryGetValue(board, out var cached))
            {
                move = cache_move[depth][board]; return(cached);
            }

            var children = Board.GetMoves(board);

            if (depth == 0 || Board.CurrentPlayerHasLessThanThree(board) || children.Count == 0)
            {
                move = 0UL;
                return(Heuristic(board, IsWhite, children));
            }

            if (maximizingPlayer)
            {
                var   bestValue = int.MinValue;
                ulong best_move = 0UL;
                foreach (var child in children)
                {
                    var v = alphabeta(child, depth - 1, alpha, beta, false, out var unused);
                    if (v > bestValue)
                    {
                        if (v > alpha)
                        {
                            alpha = v;
                        }
                        bestValue = v;
                        best_move = child;
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                move = best_move;
                cache_v[depth][board]    = bestValue;
                cache_move[depth][board] = move;
                return(bestValue);
            }
            else
            {
                // minimizing player
                var   bestValue = int.MaxValue;
                ulong best_move = 0UL;
                foreach (var child in children)
                {
                    var v = alphabeta(child, depth - 1, alpha, beta, true, out var unused);
                    if (v < bestValue)
                    {
                        if (v < beta)
                        {
                            beta = v;
                        }
                        bestValue = v;
                        best_move = child;
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                move = best_move;
                cache_v[depth][board]    = bestValue;
                cache_move[depth][board] = move;
                return(bestValue);
            }
        }