- Home /
List of different classes
I am creating a card game and I am running into difficulties, or rather I am uncertain as to how to do it, building a deck of cards. It is not a deck of standard playing cards, think more so along the lines of Magic or other trading card type games.
I have a class which defines what a card is and the attributes it can have. Then I have a new class for each card, which uses the CardAttribute class. As shown below.
public class CardAttributes
{
private string name;
private int hp;
private int dmg;
private int cost;
public CardAttributes()
{
name = "";
hp = 0;
dmg = 0;
cost = 0;
}
#region setters and getters
#endregion
}
public class ExampleCard : CardAttributes {
public Example()
{
Name = "I'm an example";
HP = 2;
DMG = 3;
COST = 2;
}
}
Now the part I am unsure on is how would I go and create a deck that contains many different types of cards?
I have created a text file for each deck, which is literally a list of every card in the deck. So I would like to read in the text file, use the different values to get the appropriate card and then add that card to a deck. Basically below is an outline of what I need to do. I am ok for reading in text files and taking that data, but I am confused as to how to create a list, using the input from the text files to add the related card class.
public class Deck
{
public Player currentDeck;
function to read in deck text files based on currentDeck
Loop that goes through parsed data from files
add to deck list current card getting the class.
}
Answer by Nanobrain · Mar 05, 2014 at 06:15 PM
In your text file, for each card, you will need to have a bit of info that you can use to determine what type of class each particular card is. Say, a number from 0 to the number of different classes available.
In your CardAttributes class you could create a series of constants as ints, and name them after the various card classes. By doing this, you can then compare the card class number from the text file to the constants using a switch statement. If the class number matches any card class, then you create a card for that particular class, and add it to a list.
Example: place integers for reference in your CardAttributes class;
public class CardAttributes
{
protected string name;
protected int hp;
protected int dmg;
protected int cost;
// create ints that we can compare to
public static int EXAMPLE_CARD_1 = 0;
public static int EXAMPLE_CARD_2 = 1;
public static int EXAMPLE_CARD_3 = 2;
// so forth and so on
...
In the script in which you read in data, do something like this:
// within the data loop
string classType = // <- retreive card type data string and convert to integer
switch(classType) {
case CardAttributes.EXAMPLE_CARD_1: {
ExampleCard1 card = new ExampleCard1();
break;
}
case CardAttributes.EXAMPLE_CARD_2: {
ExampleCard2 card = new ExampleCard2();
break;
}
case CardAttributes.EXAMPLE_CARD_3: {
ExampleCard3 card = new ExampleCard3();
break;
}
}
Ok that sounds easier than what I was planing to do for reading in the cards.
How would I use the above to add the cards to a deck.
Would it be something along the lines of this:
public class Deck{
...
//Could be a string either or
List<int> deck = new List<int>();
switch(classType){
case CardAttributes.Example_Card_1:{
ExampleCard1 card = new ExampleCard1();
deck.Add(ExampleCard1);
break;
}
...
}
}
Yes, that's how I would do it. However, I would change the list type to CardAttributes, ins$$anonymous$$d of integer, that way you can easily access the base card class attributes without type casting.
List<CardAttributes> deck = new List<CardAttributes>();
Place this next line at the top of the script that contains this list, so you can use your custom class as a list type, otherwise you'll get errors when trying to create a list of any type other than built in types:
using System.Collections.Generic;
Then, if needed, add another member to CardAttributes class, say 'cardType', that is an integer and contains the integer representing the the card's class type. Afterwards, to access the card's derived class, you would simply check the 'cardType' value and compare it against CardAttributes' card type int in a switch statement, just like before.
public int cardType;
Set this attribute within the constructor of the derived class:
public class ExampleCard1 : CardAttributes {
public Example()
{
Name = "I'm an example";
HP = 2;
D$$anonymous$$G = 3;
COST = 2;
cardType = CardAttributes.EXA$$anonymous$$PLE_CARD_1; // set here
}
Now, when you access the deck list, you can use a switch statement to gain access to each card's derived class. Of course, accessing the derived class is only necessary if you need to access methods or members that are derived from it. Otherwise, you may not need this switch statement, if you only need to access members from CardAttributes:
foreach(CardAttributes card in deck) {
switch(card.cardType) {
case CardAttributes.EXA$$anonymous$$PLE_CARD_1: {
ExampleCard1 derivedCard = (ExampleCard1) card;
break;
}
case CardAttributes.EXA$$anonymous$$PLE_CARD_2: {
ExampleCard2 derivedCard = (ExampleCard2) card;
break;
}
case CardAttributes.EXA$$anonymous$$PLE_CARD_3: {
ExampleCard3 derivedCard = (ExampleCard3) card;
break;
}
}
}
You have been a great help. I'll try get this implemented and running now. Hopefully you won't hear from me again if I can get it all up and running without any hitches.
$$anonymous$$uch appreciated Nanobrain!
No problem. Best of luck to ya! Just let me know if you have any trouble.
Ok so I'm having a little bit of trouble getting this to work. Now I have added the following to both CardAttributes and each individual card:
//CardAttribute.cs
public int cardType;
public static int CARD1 = 0;
public static int CARD2 = 1;
public static int CARD3 = 2;
public static int CARD4 = 3;
//ExampleCard.cs
public BattleChariot()
{
Name = "Battle Chariot";
HP = 1;
D$$anonymous$$G = 2;
COST = 1;
cardType = CardAttributes.CARD1;
}
I don't think I need a getter and setter for the cardType, but just want to double check if I'm correct in this assumption?
Anyway within my deck class I'm getting a few errors:
error CS1502: The best overloaded method match for
System.Collections.Generic.List.Add(CardAttributes)' has some invalid arguments - error CS1503: Argument
#1' cannot convertstring' expression to type
CardAttributes'error CS0150: A constant value is expected
I understand my problem with the first two, but not sure how to fix it. Do I need to type cast the string or what? The 3rd error comes from the switch statement but again I am unsure why I am getting this error?
Also if you notice I added a new list into my deck class which acts as a temp storage for what is read in from the file. I think it may be the source of my problem, but regardless is it needed? Or have I just added extra stuff for no real reason?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
public class Deck : $$anonymous$$onoBehaviour {
public List<CardAttributes> deck = new List<CardAttributes>();
public List<CardAttributes> readFile = new List<CardAttributes>();
public string filename;
public Deck()
{
//This will be changed to take value from player + enemy current deck.
filename = "celtic.txt";
Load(filename);
AddToDeck(readFile);
}
public void Load(string file)
{
readFile.Clear(); //Clears the list that will store what is read in from the file.
//Creates StreamReader pointing to where application data is store + '/' or '\' + filename
StreamReader sw = new StreamReader(Application.dataPath + System.IO.Path.DirectorySeparatorChar + file);
while(!sw.EndOfStream)
{
string line = sw.ReadLine();
if(line.Length != null)
{
readFile.Add (line);
}
}
}
public void AddToDeck(List<CardAttributes> myDeck)
{
deck.Clear();
foreach(CardAttributes card in readFile)
{
switch(card.cardType)
{
case CardAttributes.CARD1:
BattleChariot derivedCard = (BattleChariot) card;
deck.Add(BattleChariot);
break;
}
}
}
}