Beispiel #1
0
    private MctsNode createNode(BoardState state, MctsNode parent, int incomingMove)
    {
        GameObject gob  = Instantiate(m_nodePrefab.gameObject);
        MctsNode   node = gob.GetComponent <MctsNode>();

        node.m_unexpandedMoves = new List <int>();
        for (int i = 0; i < 9; i++)
        {
            if (state.m_cellState[i] == 0)
            {
                node.m_unexpandedMoves.Add(i);
            }
        }
        node.m_incomingMove       = incomingMove;
        node.m_incomingMovePlayer = 3 - state.m_currentPlayer;
        node.m_parent             = parent;
        if (parent != null)
        {
            parent.m_children.Add(node);
        }

        if (parent != null)
        {
            node.m_depth = parent.m_depth + 1;
        }
        else
        {
            node.m_depth = 0;
        }

        Vector3 position;

        if (parent == null)
        {
            position = transform.position + Vector3.back * transform.localScale.z;
        }
        else
        {
            position = parent.transform.position + Vector3.forward * transform.localScale.z;
            int cx = (incomingMove % 3) - 1;
            int cy = (incomingMove / 3) - 1;
            position.x += cx * transform.localScale.x * Mathf.Pow(0.25f, node.m_depth - 1);
            position.y += cy * transform.localScale.y * Mathf.Pow(0.25f, node.m_depth - 1);
            //const float expansion = 1.1f;
            //position.x *= Mathf.Pow(expansion, node.m_depth - 1);
            //position.y *= Mathf.Pow(expansion, node.m_depth - 1);
        }

        node.setPosition(position);

        m_nodes.Add(node);

        return(node);
    }
Beispiel #2
0
    private IEnumerator doMCTS()
    {
        clearNodes();

        MctsNode rootNode = createNode(m_state, null, -1);

        for (int t = 0; t < m_iterations; t++)
        {
            MctsNode   currentNode  = rootNode;
            BoardState currentState = new BoardState(m_state);

            // Selection
            while (!currentState.IsTerminal && currentNode.m_unexpandedMoves.Count == 0)
            {
                currentNode = currentNode.selectChild();
                currentState.playMove(currentNode.m_incomingMove);
            }

            // Expansion
            if (!currentState.IsTerminal)
            {
                int index = Random.Range(0, currentNode.m_unexpandedMoves.Count);
                int move  = currentNode.m_unexpandedMoves[index];
                currentNode.m_unexpandedMoves.RemoveAt(index);

                currentState.playMove(move);
                currentNode = createNode(currentState, currentNode, move);
            }

            // Simulation
            while (!currentState.IsTerminal)
            {
                int index = Random.Range(0, 9);
                currentState.playMove(index);
            }

            // Backpropagation
            for (; currentNode != null; currentNode = currentNode.m_parent)
            {
                currentNode.updateStatistics(currentState.m_terminalReward);
            }

            if (t % m_iterationsPerFrame == 0)
            {
                yield return(null);
            }
        }

        int chosenMove = rootNode.getMostVisitedChild().m_incomingMove;

        m_state.playMove(chosenMove);
        updateBoard();
        m_waitingForPlayerMove = true;
    }
Beispiel #3
0
    public MctsNode selectChild()
    {
        float    bestScore = 0;
        MctsNode bestChild = null;

        foreach (MctsNode child in m_children)
        {
            float score = child.calculateUcb() + Random.Range(0, 1.0e-5f);
            if (bestChild == null || score > bestScore)
            {
                bestChild = child;
                bestScore = score;
            }
        }

        return(bestChild);
    }
Beispiel #4
0
    public MctsNode getMostVisitedChild()
    {
        float    bestScore = 0;
        MctsNode bestChild = null;

        foreach (MctsNode child in m_children)
        {
            float score = child.m_visits + Random.Range(0, 1.0e-5f);
            if (bestChild == null || score > bestScore)
            {
                bestChild = child;
                bestScore = score;
            }
        }

        return(bestChild);
    }