コード例 #1
0
    /// <summary>
    /// Uses also the budget in order to make a fair calculation: if the budget is consumed checking the Tetris, then it stops
    /// </summary>
    /// <param name="nextPiece"></param>
    /// <param name="currentTetrisState"></param>
    /// <param name="possibleActions"></param>
    /// <param name="budget"></param>
    /// <returns></returns>
    protected IEnumerator CheckTetris(PieceModel nextPiece, TetrisState currentTetrisState, List <PieceAction> possibleActions, float budget)
    {
        int i = 0;

        while (t0 < budget && i < possibleActions.Count)
        {
            if (!TBController.pausedGame)
            {
                t0 += Time.deltaTime;

                PieceAction action = possibleActions[i];
                if (action.rotationIndex == 0) //The I piece is horizontal, not vertical, so it can't be a Tetris
                {
                    i++;
                    continue;
                }

                TetrisState newState = currentTetrisState.CloneState();

                newState.DoAction(nextPiece, action);
                nextPiece.ResetCoordinates();

                if (newState.IsTetris())
                {
                    bestAction = action;
                }

                i++;
            }

            yield return(null);
        }
    }
コード例 #2
0
ファイル: MCTSNode.cs プロジェクト: Halvaren/AITetris
    public int height; //Identifies in which height of the tree search is

    public MCTSNode(int id, MCTSNode parent, TetrisState state, PieceAction action, PieceModel currentPiece)
    {
        this.id           = id;
        this.parent       = parent;
        this.state        = state;
        this.action       = action;
        this.currentPiece = currentPiece;

        children = new List <MCTSNode>();

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

        MCTreeSearch.nNodes++;
        if (height > MCTreeSearch.currentHeight)
        {
            MCTreeSearch.currentHeight = height;
        }
    }
コード例 #3
0
 private void Awake()
 {
     // init all pieces
     allBeforeAttack = new PieceAction(() => { });
     allAttack       = new PieceAction(() => { });
     allReset        = new PieceAction(() => { });
 }
コード例 #4
0
    /// <summary>
    /// Giving a TetrisState and a PieceAction, the piece model reproduces this action
    /// </summary>
    /// <param name="action"></param>
    /// <param name="tetrisState"></param>
    public void DoAction(PieceAction action, TetrisState tetrisState)
    {
        for (int i = 0; i < action.rotationIndex; i++)
        {
            Rotate();
        }

        Move(new Vector2Int(action.xCoord - tileCoordinates[0].x, 0), tetrisState);
    }
コード例 #5
0
 public void PermanantRemovePiece(Piece p)
 {
     if (piecesGrid.ContainsKey(p.boardIdx))
     {
         piecesGrid.Remove(p.boardIdx);
     }
     allAttack       -= p.AutoAttack;
     allReset        -= p.ResetAfterTurnEnd;
     allBeforeAttack -= p.BeforeAttack;
     pieceList.Remove(p);
     p.PieceDestroy();
     Destroy(p.gameObject);
 }
コード例 #6
0
    /// <summary>
    /// It executes the action chosen by the bot
    /// </summary>
    /// <param name="action"></param>
    public void DoActionByBot(PieceAction action, bool debug = false)
    {
        /*if (debugMode && !debug) nextPieceAction = action;
         * else
         * {*/
        for (int i = 0; i < action.rotationIndex; i++)
        {
            currentPiece.RotatePiece(true, true);
        }
        currentPiece.MovePiece(new Vector2Int(action.xCoord - currentPiece.tiles[0].Coordinates.x, 0));

        currentPiece.DropPiece(true);
        //}
    }
コード例 #7
0
    public IEnumerator ShowPossibleActionCoroutine(PieceAction action)
    {
        for (int i = 0; i < action.rotationIndex; i++)
        {
            currentPiece.RotatePiece(true, true);
        }
        Vector2Int direction = new Vector2Int(action.xCoord - currentPiece.tiles[0].Coordinates.x, 0);

        currentPiece.MovePiece(direction);

        yield return(new WaitForSeconds(0.1f));

        currentPiece.DropPiece(true, true);

        yield return(new WaitForSeconds(0.3f));
    }
コード例 #8
0
    public void AddPiece(Piece p)
    {
        var idx = PosToNearIndex(p.transform.position.x, p.transform.position.z);

        if (CheckPiece(idx))
        {
            Debug.LogError("[ERR-AddPiece] already piece on " + idx);
        }
        else
        {
            piecesGrid.Add(idx, p);
            p.boardIdx = idx;
            pieceList.Add(p);

            allAttack       += p.AutoAttack;
            allReset        += p.ResetAfterTurnEnd;
            allBeforeAttack += p.BeforeAttack;
        }
    }
コード例 #9
0
    public void FullyLoad()
    {
        PieceActions = new List <PieceAction>();
        //Debug.Log("actions "+Actions);
        string[] s = Regex.Split(Actions, ", ");

        for (int j = 0; j < s.Length; j++)
        {
            for (int i = 0; i < ResourcesMaster.PieceActions.Count; i++)
            {
                PieceAction pa = ResourcesMaster.PieceActions[i];
                if (pa != null && pa.Name.Equals(s[j]))
                {
                    PieceActions.Add(pa);
                }
                else
                {
                    //Debug.Log("Null Action");
                }
            }
        }
    }
コード例 #10
0
 public PieceCommand(Piece piece, PieceAction pieceAction)
 {
     _piece       = piece;
     _pieceAction = pieceAction;
 }
コード例 #11
0
    /// <summary>
    /// Main loop of the bot. It's based on the same method of TetrisBot, but with the add-on that checks if a Tetris can be played
    /// </summary>
    /// <param name="nextPieceType"></param>
    /// <param name="budget"></param>
    /// <returns></returns>
    public override IEnumerator ActCoroutine(PieceType nextPieceType, float budget)
    {
        t0 = 0.0f;

        PieceModel nextPiece = new PieceModel(nextPieceType);

        List <PieceAction> possibleActions = currentTetrisState.GetActions(nextPiece);

        bestAction = null;

        yield return(null);

        t0 += Time.deltaTime;

        //If the currentPiece is a I piece, the Tetris is checked since there is no possibility to make a Tetris with another type of piece
        if (nextPieceType == PieceType.I)
        {
            CheckTetris(nextPiece, currentTetrisState, possibleActions, budget);
        }

        //If there is no possibility of Tetris, the same algorithm than TetrisBot is played
        if (bestAction == null)
        {
            float bestScore = -float.MaxValue;

            int i            = Random.Range(0, possibleActions.Count);
            int initialIndex = i;
            while (t0 < budget)
            {
                if (!TBController.pausedGame)
                {
                    t0 += Time.deltaTime;

                    TetrisState newState = currentTetrisState.CloneState();

                    newState.DoAction(nextPiece, possibleActions[i]);
                    nextPiece.ResetCoordinates();

                    float score = newState.GetHumanizedScore();

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

                    i++;

                    if (i == possibleActions.Count)
                    {
                        i = 0;
                    }
                    if (i == initialIndex)
                    {
                        break;
                    }
                }

                yield return(null);
            }
        }
        else
        {
            Debug.Log("BOOM! Tetris for bot");
        }

        //If there is no bestAction at this point, a random action is going to be played
        if (bestAction == null)
        {
            bestAction = currentTetrisState.GetRandomAction(nextPiece);
        }
        currentTetrisState.DoAction(nextPiece, bestAction);

        TBController.DoActionByBot(bestAction);
    }