user12304080
user12304080

Reputation:

How to reset a TicTacToe game

I am making a TicTacToe game in Unity, but now I need to restart it when a button is clicked.

public class GlobalCtrl : MonoBehaviour
{
    #region variables
    /// <summary>
    /// the prefab of playerMarkA
    /// </summary>
    public GameObject playerMarkA;
    /// <summary>
    /// the prefab of playerMarkB
    /// </summary>
    public GameObject playerMarkB;
    public Camera mainCamera;
    public List<GameObject> list = new List<GameObject>();
    private int[,] boardStatus = new int[3, 3];
    private Vector3[,] boardPos = new Vector3[3, 3];
    private Vector3 a;
    private Vector3 b;
    private Vector3 c;
    private Vector3 d;
    bool playerChange = true;
    bool playerA = false;
    bool playerB = false;
    bool gameOver = false;
    bool tie = false;
    public Button m_button;
    public Text m_text;
    #endregion

    /// <summary>
    /// Start is called before the first 
    /// </summary>
    void Start()
    {
        boardPos[0, 0] = new Vector3(-10 / 3, -10 / 3, 0);
        boardPos[0, 1] = new Vector3(0, -10 / 3, 0);
        boardPos[0, 2] = new Vector3(10 / 3, -10 / 3, 0);
        boardPos[1, 0] = new Vector3(-10 / 3, 0, 0);
        boardPos[1, 1] = new Vector3(0, 0, 0);
        boardPos[1, 2] = new Vector3(10 / 3, 0, 0);
        boardPos[2, 0] = new Vector3(-10 / 3, 10 / 3, 0);
        boardPos[2, 1] = new Vector3(0, 10 / 3, 0);
        boardPos[2, 2] = new Vector3(10 / 3, 10 / 3, 0);
        a = new Vector3(-10 / 6, 10 / 6, 0);
        b = new Vector3(10 / 6, 10 / 6, 0);
        c = new Vector3(-10 / 6, -10 / 6, 0);
        d = new Vector3(10 / 6, -10 / 6, 0);

        boardStatus[0, 0] = boardStatus[0, 1] = boardStatus[0, 2] =
            boardStatus[1, 0] = boardStatus[1, 1] = boardStatus[1, 2] =
            boardStatus[2, 0] = boardStatus[1, 0] = boardStatus[0, 0] = 0;
    }

    // Update is called once per frame
    void Update()
    {
        if(gameOver == false) {

            if (Input.GetMouseButtonDown(0))
            {

                Debug.Log(Input.mousePosition);

                Ray _ray = mainCamera.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit1;
                if (Physics.Raycast(_ray, out hit1))
                {

                    int m = 0;
                    int n = 0;
                    if (hit1.point.x < a.x)//left
                    {
                        m = 0;
                    }
                    else if (hit1.point.x > b.x)//right
                    {
                        m = 2;
                    }
                    else//middle
                    {
                        m = 1;
                    }
                    if (hit1.point.y > a.y)//top
                    {
                        n = 2;
                    }
                    else if (hit1.point.y < c.y)//bottom
                    {
                        n = 0;
                    }
                    else//middle
                    {
                        n = 1;
                    }
                    if (playerChange)
                    {
                        if (boardStatus[n, m] == 0)
                        {
                            list.Add(Instantiate(playerMarkA, transform.position = boardPos[n, m], Quaternion.identity));
                            boardStatus[n, m] = -1;
                            playerChange = false;
                            Debug.Log(boardStatus[n, m]);
                            winner();
                        }
                    }
                    else
                    {
                        if (boardStatus[n, m] == 0)
                        {
                            list.Add(Instantiate(playerMarkB, transform.position = boardPos[n, m], Quaternion.identity));
                            boardStatus[n, m] = 1;
                            playerChange = true;
                            Debug.Log(boardStatus[n, m]);
                            winner();
                        }

                    }

                }

            }
        }

    }

    void winner()
    {
        if(gameOver)
        {

        }
        if ((boardStatus[0, 0] == -1 && boardStatus[0, 1] == -1 && boardStatus[0, 2] == -1) ||
           (boardStatus[1, 0] == -1 && boardStatus[1, 1] == -1 && boardStatus[1, 2] == -1) ||
           (boardStatus[2, 0] == -1 && boardStatus[2, 1] == -1 && boardStatus[2, 2] == -1) ||
           (boardStatus[2, 0] == -1 && boardStatus[1, 0] == -1 && boardStatus[0, 0] == -1) ||
           (boardStatus[2, 1] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 1] == -1) ||
           (boardStatus[2, 2] == -1 && boardStatus[1, 2] == -1 && boardStatus[0, 2] == -1) ||
           (boardStatus[2, 0] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 2] == -1) ||
           (boardStatus[2, 2] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 0] == -1))
        {
            playerA = true;
        }
        else if ((boardStatus[0, 0] == 1 && boardStatus[0, 1] == 1 && boardStatus[0, 2] == 1) ||
             (boardStatus[1, 0] == 1 && boardStatus[1, 1] == 1 && boardStatus[1, 2] == 1) ||
             (boardStatus[2, 0] == 1 && boardStatus[2, 1] == 1 && boardStatus[2, 2] == 1) ||
             (boardStatus[2, 0] == 1 && boardStatus[1, 0] == 1 && boardStatus[0, 0] == 1) ||
             (boardStatus[2, 1] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 1] == 1) ||
             (boardStatus[2, 2] == 1 && boardStatus[1, 2] == 1 && boardStatus[0, 2] == 1) ||
             (boardStatus[2, 0] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 2] == 1) ||
             (boardStatus[2, 2] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 0] == 1))
        {
            playerB = true;
        }
        else
        {
            tie = true;
        }

        if (playerA)
        {
            m_text.text = "Player A wins!";
            gameOver = true;

        }
        else if (playerB)
        {
            m_text.text = "Player B wins!";
            gameOver = true;
        }
        else if (tie)
        {
            m_text.text = "Nobody won :(";
            //gameOver = true;
        }

    }

}

Then I just need to add the function to delete the game objects. I mean when I restart the game, ontly the game objects should be deleted, but the board should stay there as it is:

click to see the photo

So I tried this

public void button()
    {
        for(int i = 0; i < list.Count - 1; i++)
        {
            var last = list[list.Count - 1];
            list.Remove(last);
            Destroy(last);
        }
}

But it doesn't seem to work properly, because when I click to add an object into the board, the board ceases to exist, but there is still the added objects in the hierarchy window (it's nowhere to be seen in the game/scene).

I'd be really happy to read some of your answers, thanks in advance!

Upvotes: 1

Views: 342

Answers (1)

derHugo
derHugo

Reputation: 90659

Doing this in a for loop is bad since you change the Count of objects from within the loop which sooner or later makes your iteration index i invalid.

You should rather do simply

// destroy all items
foreach(var item in list)
{
    Destroy(item);
}

// then in one call remove all elements from the list
list.Clear();

Note: Your list is public. So in order to be sure there is nothing referenced by accident from the Inspector which would get deleted on the first reset you should clear the list once in

private void Awake()
{
    list.Clear();
}

However as already mentioned it is often also a good solution to simply reload the entire scene. This way you don't have to take care of any resetting yourself

SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);

btw your instantion lines should probably simply look like

Instantiate(playerMarkA, boardPos[n, m], Quaternion.identity);

Instantiate(playerMarkB, boardPos[n, m], Quaternion.identity);

Upvotes: 2

Related Questions