Why?: UNITY freezes when I run this code.

Hi, I started to enjoy UNITY & C# last week.
I have in trouble. Please help me or advice.

I would like to make Shaffling trumps script.
I make this code.
But, UNITY freezes when I run this code.

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

//Trunps Shaffe code

public class Card : MonoBehaviour {

    string[] mark = new string[]{ "H" ,"D" ,"S" ,"C"};
    string[] number = new string[]{"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    string[] cardSfl = new string[52];

    void Start () {
        int i = 0;
        while (i <= 51) {
            int r = Random.Range (1, 52);
            int markNo = r % 4;
            int numberNo = r / 4;
            cardSfl [I] = mark [markNo] + "-" + number [numberNo];
            int cardEq = 1;

//same card check
            for (int j = 0; j < i; j++) {
                if (cardSfl [j] == cardSfl [I]) {
                    cardEq = 0;       //***** I think this line is bad.. *****
                    break;
                }
            }
            if (cardEq != 0) {
                Debug.Log ("No:" + i + " " + cardSfl [I] );
                i++;
            }
        }
    }  
}

Use code tags!

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

//Trunps Shaffe code

public class Card : MonoBehaviour {

    string[] mark = new string[]{ "H" ,"D" ,"S" ,"C"};
    string[] number = new string[]{"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    string[] cardSfl = new string[52];

    void Start () {
        int i = 0;
        while (i <= 51) {
            int r = Random.Range (1, 52);
            int markNo = r % 4;
            int numberNo = r / 4;
            cardSfl = mark [markNo] + "-" + number [numberNo];
            int cardEq = 1;

            //same card check
            for (int j = 0; j < i; j++) {
                if (cardSfl [j] == cardSfl ) {
                    cardEq = 0; //***** I think this line is bad.. *****
                    break;
                }
            }
            if (cardEq != 0) {
                Debug.Log ("No:" + i + " " + cardSfl );
                i++;
            }
        }
    }
}

Also, have you tried putting in breakpoints and stepping through the code and seeing what’s happening?

If Unity is freezing, and you have loops, that often means you have an infinite loop somewhere… so step through it and logically find it. (make sure you attach the VisualStudio or MonoDevelop IDE to unity with the “attach to unity” option)

I mean… technically WE could do it for you… but these are the sorts of things you should get practice in.

and just to give you an idea where to look based on a cursory read through. Since you loop doesnt end until i reaches 51, and you don’t increment i if you for loop finds what its looking for and set cardEq to 0; maybe take a peak at how often that’s happening (i’m betting every loop)

// Hint to the problem
i <= 51 always true
j < i always false
cardEq  != 0 always false

Here is some code I have had laying around for a deck. You just add both of these scripts to your project. They don’t have to be attached to a GameObject:
Card script

using System;

public class Card : IComparable
{
    static string[] SuitName = new string[4] { "Clubs", "Diamonds", "Hearts", "Spades" };
    static string[] ShortSuitName = new string[4] { "C", "D", "H", "S" };
    static string[] RankName = new string[13] { "2", "3", "4", "5", "6", "7", "8", "9", "Ten", "Jack", "Queen", "King", "Ace" };
    static string[] ShortRankName = new string[13] { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" };
    int rank;
    int suit;

    public int Rank
    {
        get { return rank; }
        set { rank = value; }
    }
    public int Suit
    {
        get { return suit; }
        set { suit = value; }
    }

    public Card(int rank, int suit)
    {
        this.rank = rank;
        this.suit = suit;
    }

    public override string ToString()
    {
        return RankName[rank] + " of " + SuitName[suit];
    }

    public string GetShortName()
    {
        return ShortRankName[rank] + ShortSuitName[suit];
    }

    // Sorts them by suit then rank
    // 2c is the lowest card   Ace spaces is the highest
    int IComparable.CompareTo(object obj)
    {
        if (obj == null)
            throw new ArgumentException("Object is null in Card Compare");
        Card other = (Card)obj;
        if (other == null)
            throw new ArgumentException("Object isn't a card in Card Compare");
        if (this.suit > other.suit)
            return 1;
        else if (this.suit < other.suit)
            return -1;
        else
        {
            if (this.rank > other.rank)
                return 1;
            else if (this.rank < other.rank)
                return -1;
            else
                return 0;
        }
    }
}

Deck script

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;

public class Deck {
    List<Card> cards;
    List<Card> outOfDeck;

    public Deck()
    {
        cards = new List<Card>();
        outOfDeck = new List<Card>();
        for (int suit = 0;suit<4;++suit)
        {
            for (int rank =0;rank<13;++rank)
            {
                cards.Add(new Card(rank, suit));
            }
        }
    }

    public Card DrawOne()
    {
        if (cards.Count == 0)
            return null;
        Card topCard = cards[0];
        outOfDeck.Add(cards[0]);
        cards.RemoveAt(0);
        return topCard;
    }

    public List<Card> DrawX(int numCards)
    {
        List<Card> drawnCards = new List<Card>();
        for (int i=0;i<numCards;++i)
        {
            Card nextCard = DrawOne();
            if (nextCard != null)
                drawnCards.Add(nextCard);
        }
        return drawnCards;
    }

    public void ReturnCard(Card card, bool onTop = true)
    {
        outOfDeck.Remove(card);
        if (onTop)
            cards.Insert(0, card);
        else
            cards.Add(card);
    }

    //Fisher-Yates shuffle
    public void Shuffle()
    {
        for (int i=0;i<cards.Count-2;++i)
        {
            int j = Random.Range(i, cards.Count);
            Card temp = cards[i];
            cards[i] = cards[j];
            cards[j] = temp;
        }
    }

    public void ResetAndShuffle()
    {
        cards.AddRange(outOfDeck);
        outOfDeck.Clear();
        Shuffle();
    }

}

Here is a quickie example script I made to show how to use them. Attach this to a GameObject and press play
Example script

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

public class Example : MonoBehaviour {
    Deck myDeck;

    private void Awake()
    {
        myDeck = new Deck();
        Card card = myDeck.DrawOne();
        // this should be 2 of clubs
        Debug.Log("Drawn Card was " + card);
        myDeck.ResetAndShuffle();
        List<Card> hand = myDeck.DrawX(3);
        Debug.Log("I Drew these 3 cards into my hand:");
        for (int i = 0; i < hand.Count; ++i)
            Debug.Log(hand[i]);
        Debug.Log("The shortnames would be this");
        for (int i=0;i<hand.Count;++i)
            Debug.Log(hand[i].GetShortName());
    }
}

Even if you don’t end up using any of it. Take a look in the Deck script at the shuffle algorithm. Its a Fisher-Yates shuffle. Its very common and easy to implement. It seemed like your original code was trying to shuffle some cards.

Thank you for your advises.
So, I had loops.

I checked my code again.
When i= 51, it becomes a loop.
A corrected code is below.

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

public class Card : MonoBehaviour {

    string[] mark = new string[]{ "H" ,"D" ,"S" ,"C"};
    string[] number = new string[]{"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    string[] cardSfl = new string[52];

    void Start () {
        int i = 0;
        while (i <= 51) {
            int r = Random.Range (0, 52);  // ***********
            int markNo = r % 4;
            int numberNo = r / 4;
            cardSfl [i] = mark [markNo] + "-" + number [numberNo];
            int cardEq = 1;

            for (int j = 0; j < i; j++) {
                if (cardSfl [j] == cardSfl [i]) {
                    cardEq = 0;
                    break;
                }
            }
            if (cardEq != 0) {
                Debug.Log ("No:" + i + " " + cardSfl [i] +" r="+ r);
                i++;
            }
        }
    }   
}