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++;
}
}
}
}
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)
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.
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++;
}
}
}
}