Needing a hint about tossing dices and using their value

Hello everyone.
I just started learning coding and now I would love to get a hint from you pros about the following problem.

Maybe some of you know the dice game Yatzee. I’m trying to recreate that, but I’m logically stuck at the moment.

So far I can toss the dices, determine which side is up and ad then a corresponding value to a list.

Here the code so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Dice : MonoBehaviour
{
    [SerializeField] float force = 500f;
    [SerializeField] Vector3 startPosition = new Vector3();

    bool isRollable = true;

    Rigidbody _rigidbody;
    //BoxCollider _boxCollider;

    void Start()
    {
        transform.position = startPosition;
        //_boxCollider = GetComponent<BoxCollider>();
        _rigidbody = GetComponent<Rigidbody>();
        _rigidbody.useGravity = false;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && isRollable)
        {
            if (!_rigidbody.useGravity)
            {
                _rigidbody.useGravity = true;
            }

            float dirX = Random.Range(0f, 500f);
            float dirY = Random.Range(0f, 500f);
            float dirZ = Random.Range(0f, 500f);
            transform.position = startPosition;
            transform.rotation = Quaternion.identity;
            _rigidbody.AddForce(transform.up * force);
            _rigidbody.AddTorque(dirX, dirY, dirZ);

            isRollable = false;
        }

        float _OneUp = Vector3.Angle(transform.up, Vector3.up);
        float _TwoUp = Vector3.Angle(-transform.right, Vector3.up);
        float _ThreeUp = Vector3.Angle(transform.forward, Vector3.up);
        float _FourUp = Vector3.Angle(-transform.forward, Vector3.up);
        float _FiveUp = Vector3.Angle(transform.right, Vector3.up);
        float _SixUp = Vector3.Angle(-transform.up, Vector3.up);


        if (_rigidbody.velocity.x <= Mathf.Epsilon && _rigidbody.velocity.y <= Mathf.Epsilon && _rigidbody.velocity.z <= Mathf.Epsilon && !isRollable)
        {
            if (_OneUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(1);
                isRollable = true;
            }
            else if (_TwoUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(2);
                isRollable = true;
            }
            else if (_ThreeUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(3);
                isRollable = true;
            }
            else if (_FourUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(4);
                isRollable = true;
            }
            else if (_FiveUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(5);
                isRollable = true;
            }
            else if (_SixUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.numbersList.Add(6);
                isRollable = true;
            }

        }
    }
}

I’m not sure if the logic is correct, because I wanted to print the values in the list on the console, but that didn’t work well:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class DiceNumberTextScript : MonoBehaviour
{
    //public static int[] diceNumbers = new int[5];
    public static List<int> numbersList = new List<int>();
    string myNumbers;

    public static TMP_Text text;

    void Start()
    {
        text = GetComponent<TMP_Text>();
    }


    void Update()
    {
        //text.text = $"{diceNumbers[0]} , {diceNumbers[1]} , {diceNumbers[2]} , {diceNumbers[3]} , {diceNumbers[4]}";
        if (Input.GetKeyDown(KeyCode.P))
        {
            DisplayNumbers();
        }
        
    }

    void DisplayNumbers()
    {
        foreach (var number in numbersList)
        {
            myNumbers += number.ToString() + ", ";
        }
        Debug.Log(myNumbers);
    }
}

So what is my intention?
In the end, I will need five values from the dices in a list or somewhere, where I can interpret them. So I need to check if certain conditions are true. E.g. two pairs in the list, or just one pair. Did the player toss a street (1,2,3,4,5 or 2,3,4,5,6) or did he toss (5,5,5,5,5) So you see I need to find a way to interpret the numbers in the list.

Maybe you guys could help me out? I don’t wan’t a written solution. Instead I would be very happy to some hints about the right direction. So I then can try and search more concrete stuff.

I hope this was understandable and I’m very happy to hear from you.

If I’m wrong here with my question, then I’m sorry.

Thank you all

Hi, I think the way how you decide which number is up is a simple and smart solution. I think thought that you can put it into the if statement where you check whether the dice is still moving so it is not computing each frame since its not necessary but only once when the dice stop moviing. Btw you can shorten the if statement to rigidbody.velocity.magnitude <= Mathf.Epsilon && !isRollable and maybe put the isRollable = true to the end of the statement so you dont have to repeat it in each if but that are details. What exactly dosent work well? Does it not print your numbers? My suggestion would be to make a AddNumber(int number) method in the DiceNumberTextScript which the Dice script will be using to add numbers to the numbersList. To make a method for storing the numbers to the numbersList instead storing them directly enables you to easily put Debug.Log(number) to see what is actually being put into the numbersList after each throw. This is a one of concepts of “encapsulation” - you can check it out if you want. Finally if you want to check whether the player tossed a street or five same numbers you probably need to have some kind of counter which will be incremented each time player throws the dice. When the counter reaches 5 you reset it back to 0 and check the numberList. I would do a separate method for checking each combination you want. For example checking if the player tossed a street each subsequent number should be exactly one bigger then the previous. You can check that using for or while loop. I hope I understood your problem. If you have another questions you can ask.

Hi Marek, thank you very much for your answer.
Your tips are great and make sense, about putting stuff in different positions in the code.
The actual code is printing some weird stuff, like lot of 1s, even though I didn‘t toss a 1. But I think I will find a solution for this. I‘ll try your mentioned method.

The biggest issue I have is this:
The concept of the game will be, that the player can toss the dices 3 times. On each toss he then can select which dice he wants to keep and toss with the other dices. At the end of these 3 tosses there are 5 dices which are counting.
The player should then have the option to put the combinations he tossed in available spots on a scoresheet

Just an example for this: The player tosses 1,1, 5, 5, 5. This toss is meeting several conditions. He has a pair of 1, he has also a pair of 5s, also three times 5, and last he also has a full house.

I understand, that I put different conditions to check in a method. But I mainly have a hard time setting these conditions. Because in the example above he is fullfilling different conditions from which he can choose where he wants to put his dices in.

Your street example with checking if each number is greater than the previous. Needs this method a sorting of the list first?

I really wanna say thank you for your help and I hope I could transport my issue as good as possible.

Thanks again

Hello again

Thank you for your detailed answer. Appreciate it very much.

I think with your input I could solve the part of Detection and throw.

Maybe you want to have a look at the actual scripts.

Script for the Dice:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Dice : MonoBehaviour
{
    [SerializeField] float force = 500f;
    [SerializeField] Vector3 startPosition = new Vector3();

    float _OneUp, _TwoUp, _ThreeUp, _FourUp, _FiveUp, _SixUp;

    bool isRollable = true;

    Rigidbody _rigidbody;
    BoxCollider _boxCollider;

    void Start()
    {
        transform.position = startPosition;
        _boxCollider = GetComponent<BoxCollider>();
        _rigidbody = GetComponent<Rigidbody>();
        _rigidbody.useGravity = false;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && isRollable && DiceNumberTextScript.turns <3)
        {
            if (!_rigidbody.useGravity)
            {
                _rigidbody.useGravity = true;
            }

            float dirX = Random.Range(0f, 500f);
            float dirY = Random.Range(0f, 500f);
            float dirZ = Random.Range(0f, 500f);
            transform.position = startPosition;
            transform.rotation = Quaternion.identity;
            _rigidbody.AddForce(transform.up * force);
            _rigidbody.AddTorque(dirX, dirY, dirZ);

        }

        if (_rigidbody.velocity.magnitude <= Mathf.Epsilon)
        {
            _OneUp = Vector3.Angle(transform.up, Vector3.up);
            _TwoUp = Vector3.Angle(-transform.right, Vector3.up);
            _ThreeUp = Vector3.Angle(transform.forward, Vector3.up);
            _FourUp = Vector3.Angle(-transform.forward, Vector3.up);
            _FiveUp = Vector3.Angle(transform.right, Vector3.up);
            _SixUp = Vector3.Angle(-transform.up, Vector3.up);

        }

        if (DiceNumberTextScript.turns == 3 && _rigidbody.velocity.magnitude <= Mathf.Epsilon && isRollable)
        {
            if (_OneUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(1);
            }
            else if (_TwoUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(2);
            }
            else if (_ThreeUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(3);
            }
            else if (_FourUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(4);
            }
            else if (_FiveUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(5);
            }
            else if (_SixUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(6);
            }

            isRollable = false;
        }
    }

    private void OnMouseDown()
    {

        if (_rigidbody.velocity.magnitude <= Mathf.Epsilon)
        {
            if (_OneUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(1);
            }
            else if (_TwoUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(2);
            }
            else if (_ThreeUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(3);
            }
            else if (_FourUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(4);
            }
            else if (_FiveUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(5);
            }
            else if (_SixUp <= Mathf.Epsilon)
            {
                DiceNumberTextScript.AddNumberToList(6);
            }


            _rigidbody.useGravity = false;
            _boxCollider.enabled = false;
            isRollable = false;
        }
        
    }
}

And the script for the Storing in a list

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class DiceNumberTextScript : MonoBehaviour
{

    static List<int> numbersList = new List<int>();
    public static int turns = 0;

    public static TMP_Text text;

    void Start()
    {
        text = GetComponent<TMP_Text>();
    }


    void Update()
    {
       if (Input.GetKeyDown(KeyCode.Space))
        {
            Invoke("IncreaseTurns", 1f);
        }
    }

    public static void AddNumberToList(int diceNumber)
    {
        numbersList.Add(diceNumber);
        Debug.Log(diceNumber);
        Debug.Log(numbersList.Count);
    }

    void IncreaseTurns()
    {
        turns++;
    }
}

So actually I can toss the dices, click on the dice I want to keep (for the moment I had to disable gravity and box collider on click to prevent strange movements) and the respectable numbers are sent to the list. On the last turn the rest of the dices are automatically assigned to the list. There was a problem where in special occasions while pressing space directly a int assigned to the list. I solved it through Invoking the turn increase. So now everything should work in regards to tossing and storing in a list.

So now at the end of three turns I have a list with 5 ints in it.

And now I see the hard part, interpreting them. Is it better to use an array as you suggest or is the same interpretation possible with a list?

Yeah I thought it would be a simple thing to try stuff out, but it is harder than it looked :smiley: But I love challenges, so I will continue until I solve all the problems :slight_smile:

Thank you very much for your input and help