Ejemplo n.º 1
0
    /// <summary>
    /// Executes random actions with the next pieces over the state of node
    /// </summary>
    /// <param name="node"></param>
    /// <returns></returns>
    protected virtual float Rollout(MCTSNode node)
    {
        TetrisState newState = node.state.CloneState();

        int nPieces = 0;

        float totalScore  = node.state.GetScore();
        float weight      = 1f;
        float totalWeight = weight;

        //node.height identifies the height of the node in the MCTreeSearch, but also identifies the index of the piece inside the history of all the pieces played
        //So, if that node.height plus the number of pieces played in the rollout are bigger than the number of known pieces, then the rollout must stop.
        //Also it stops if an action has caused a game over
        while ((node.height + nPieces) < pieces.Count && !newState.IsTerminal())
        {
            weight      *= rolloutScoreWeightReduction;
            totalWeight += weight;

            PieceModel piece;
            piece = new PieceModel(pieces[node.height + nPieces]);

            newState.DoAction(piece, newState.GetRandomAction(piece));
            nPieces++;

            totalScore += newState.GetScore() * weight;
        }

        float score = totalScore / totalWeight;

        rollouts++;

        return(score);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Main bot method that searches for the best action to do with the current piece in the current state.
    /// It has a budget of time which is the max time it has to find that best action
    /// </summary>
    /// <param name="nextPieceType"></param>
    /// <param name="budget"></param>
    /// <returns></returns>
    public virtual IEnumerator ActCoroutine(PieceType nextPieceType, float budget)
    {
        float t0 = 0.0f;

        PieceModel nextPiece = new PieceModel(nextPieceType);

        List <PieceAction> possibleActions; //First of all, it gets the possible actions with the current piece in the current state

        if (!pieceActionDictionary.ContainsKey(nextPieceType))
        {
            possibleActions = emptyTetrisState.GetActions(nextPiece);
            pieceActionDictionary.Add(nextPieceType, possibleActions);
        }
        else
        {
            possibleActions = pieceActionDictionary[nextPieceType];
        }

        float       bestScore = -float.MaxValue;
        PieceAction bestAction;

        int i            = Random.Range(0, possibleActions.Count); //The first possible action to test is chosen randomly
        int initialIndex = i;

        bestAction = possibleActions[i];

        yield return(null);

        t0 += Time.deltaTime;

        //In a while loop that goes until the time ends
        while (t0 < budget && i < possibleActions.Count)
        {
            if (!TBController.pausedGame)
            {
                t0 += Time.deltaTime;

                TetrisState newState = currentTetrisState.CloneState(); //The TetrisState is cloned

                newState.DoAction(nextPiece, possibleActions[i]);       //One of the possible actions is played in the cloned state
                nextPiece.ResetCoordinates();

                float score = newState.GetScore(); //And its score is got

                if (score > bestScore)
                {
                    bestScore  = score;
                    bestAction = possibleActions[i];
                }

                i++;

                if (i == possibleActions.Count)
                {
                    i = 0;
                }
                if (i == initialIndex)
                {
                    break;                    //If all the possible actions have been tested, the while loop ends
                }
            }

            yield return(null);
        }

        currentTetrisState.DoAction(nextPiece, bestAction); //The bestAction is played in the real state

        TBController.DoActionByBot(bestAction);             //And also, it is said to the TetrisBoardController to play that action in the real board
    }