Beispiel #1
0
    /// <summary>
    /// Acts similarly to normal alpha beta search but instead of generating new board nodes, traverses existing board node list.
    /// </summary>
    /// <param name="_node"></param>
    /// <param name="_depth"></param>
    /// <param name="_alpha"></param>
    /// <param name="_beta"></param>
    /// <param name="_searchingPlayer"></param>
    /// <param name="_maximizingPlayer"></param>
    /// <param name="_player"></param>
    /// <param name="_accuracyMod"></param>
    /// <returns></returns>
    static public float TraverseNodeList(BoardNode _node, int _depth, float _alpha, float _beta, int _searchingPlayer, bool _maximizingPlayer, AI _player, float _accuracyMod)
    {
        float v;

        if (_depth == 0 || _node.MoveCount() == 0)
        {
            if (_maximizingPlayer)
            {
                v = (float)_node.GetValue(_player);
                if (_accuracyMod != 0)
                {
                    System.Random random = new MathNet.Numerics.Random.SystemRandomSource();
                    v = v + (float)random.NextDouble() * (2 * _accuracyMod) - _accuracyMod;
                }
                return(v);
            }
            else
            {
                return(AlphaBeta(_node, _depth, _alpha, _beta, _searchingPlayer, _maximizingPlayer, _player, _accuracyMod));
            }
        }

        if (!_node.IsEndNode())
        {
            if (_maximizingPlayer)
            {
                v = -Mathf.Infinity;
                foreach (BoardNode b in _node.GetChildren())
                {
                    v      = Mathf.Max(v, TraverseNodeList(b, _depth - 1, _alpha, _beta, _searchingPlayer, false, _player, _accuracyMod));
                    _alpha = Mathf.Max(_alpha, v);
                    if (_beta <= _alpha)
                    {
                        break;
                    }
                }
                return(v);
            }
            else
            {
                v = 1;
                foreach (BoardNode b in _node.GetChildren())
                {
                    v     = Mathf.Min(v, TraverseNodeList(b, _depth - 1, _alpha, _beta, _searchingPlayer, true, _player, _accuracyMod));
                    _beta = Mathf.Min(_beta, v);
                    if (_beta <= _alpha)
                    {
                        break;
                    }
                }
                return(v);
            }
        }
        else
        {
            return(AlphaBeta(_node, _depth, _alpha, _beta, _searchingPlayer, _maximizingPlayer, _player, _accuracyMod));
        }
    }
Beispiel #2
0
    static public float AlphaBeta(BoardNode _node, int _depth, float _alpha, float _beta, int _searchingPlayer, bool _maximizingPlayer, AI _player, float _accuracyMod)
    {
        float v;

        //If we have reach the end of the search
        if (_depth == 0 || _node.MoveCount() == 0)
        {
            //If we are currently on the maximising player then find the board rating and return
            if (_maximizingPlayer)
            {
                v = (float)_node.GetValue(_player);
                if (_accuracyMod != 0)
                {
                    System.Random random = new MathNet.Numerics.Random.SystemRandomSource();
                    v = v + (float)random.NextDouble() * (2 * _accuracyMod) - _accuracyMod;
                }
                return(v);
            }
            //If we are not currently on the maximising player then jump one extra layer.
            else
            {
                v = 1;

                foreach (StoneMove m in _node.GetMoveList())
                {
                    Board testBoard = _node.boardState.Clone();
                    testBoard.ResolveMove(m);
                    _node.AddChild(new BoardNode(testBoard, _searchingPlayer, m));
                }

                foreach (BoardNode b in _node.GetChildren())
                {
                    v     = Mathf.Min(v, AlphaBeta(b, _depth - 1, _alpha, _beta, _searchingPlayer, true, _player, _accuracyMod));
                    _beta = Mathf.Min(_beta, v);
                    if (_beta <= _alpha)
                    {
                        break;
                    }
                }
                return(v);
            }
        }

        if (_maximizingPlayer)
        {
            v = -Mathf.Infinity;

            foreach (StoneMove m in _node.GetMoveList())
            {
                Board testBoard = _node.boardState.Clone();
                testBoard.ResolveMove(m);
                _node.AddChild(new BoardNode(testBoard, 3 - _searchingPlayer, m));
            }

            foreach (BoardNode b in _node.GetChildren())
            {
                v      = Mathf.Max(v, AlphaBeta(b, _depth - 1, _alpha, _beta, _searchingPlayer, false, _player, _accuracyMod));
                _alpha = Mathf.Max(_alpha, v);
                if (_beta <= _alpha)
                {
                    break;
                }
            }
            return(v);
        }
        else
        {
            v = +Mathf.Infinity;

            foreach (StoneMove m in _node.GetMoveList())
            {
                Board testBoard = _node.boardState.Clone();
                testBoard.ResolveMove(m);
                _node.AddChild(new BoardNode(testBoard, _searchingPlayer, m));
            }

            foreach (BoardNode b in _node.GetChildren())
            {
                v     = Mathf.Min(v, AlphaBeta(b, _depth - 1, _alpha, _beta, _searchingPlayer, true, _player, _accuracyMod));
                _beta = Mathf.Min(_beta, v);
                if (_beta <= _alpha)
                {
                    break;
                }
            }
            return(v);
        }
    }