Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

C# Assignment issue

So im working on a C# Card Game, i have a piece of code that is sapose to assign a deck id to each card as it is added to the deck, but for some reason it gives all cards with the same id(database id) the deck id of the last card assigned. Example: i add 10 of the same card, instead of getting 1,2,3,4,5,6,7,8,9,10 i get: 10, 10, 10, 10, 10, 10, 10, 10, 10

Here is the add card code: (deckId is a public int in the Card class)
Code:
public void AddCard(int id)

        {

            // finds the next null in the deck[] and assigns the number to nextBlankSpot

            NextBlank();

            deck[nextBlankSpot] = cardDataBase.GetCard(id - 1);

            deck[nextBlankSpot].deckId = nextBlankSpot;

        }

here is the get card method:
Code:
public Card GetCard(int id)

        {

            return cards[id];

        }

let me know if you need anymore information
 
I don't understand what you mean by deck id, are there multiple decks or do you mean suits or do you split up a root deck into multiple piles?
 
its just meant for me to be able to keep track of different copies of the same card.

example: say i have two creatures they would both have id 27, but different deck id's


edit: you only have one deck

if this helps here is the output from my test deck:
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Jelly_Fish, id: 8 ,deck id: 21 , ATK: 1
Jelly_Fish, id: 8 ,deck id: 21 , ATK: 1
Deep_Sea_Horror, id: 10 ,deck id: 22 , ATK: 6
Water_Spirt, id: 16 ,deck id: 23 , ATK: 3
Blow_Fish, id: 6 ,deck id: 25 , ATK: 3
Blow_Fish, id: 6 ,deck id: 25 , ATK: 3

it should look like:
Calming_Pools, id: 1 ,deck id: 0 , ATK: 0
Calming_Pools, id: 1 ,deck id: 1 , ATK: 0
Calming_Pools, id: 1 ,deck id: 2 , ATK: 0
Calming_Pools, id: 1 ,deck id: 3 , ATK: 0
Calming_Pools, id: 1 ,deck id: 4 , ATK: 0
Calming_Pools, id: 1 ,deck id: 5 , ATK: 0
Calming_Pools, id: 1 ,deck id: 6 , ATK: 0
Calming_Pools, id: 1 ,deck id: 7 , ATK: 0
Calming_Pools, id: 1 ,deck id: 8 , ATK: 0
Calming_Pools, id: 1 ,deck id: 9 , ATK: 0
Calming_Pools, id: 1 ,deck id: 10 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 12 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 13 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 14 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Pirate, id: 4 ,deck id: 16 , ATK: 2
Pirate, id: 4 ,deck id: 17 , ATK: 2
Pirate, id: 4 ,deck id: 18 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Jelly_Fish, id: 8 ,deck id: 20 , ATK: 1
Jelly_Fish, id: 8 ,deck id: 21 , ATK: 1
Deep_Sea_Horror, id: 10 ,deck id: 22 , ATK: 6
Water_Spirt, id: 16 ,deck id: 23 , ATK: 3
Blow_Fish, id: 6 ,deck id: 24 , ATK: 3
Blow_Fish, id: 6 ,deck id: 25 , ATK: 3
 
Oh do you mean instance ids? If you're using C# and you're making direct object references you shouldn't need an I'd for the card at all as it's object orientated.

So it's a monster card game rather than playing cards? I understand now.

Can you show me your complete card and deck classes?
 
i hope my code doesnt make me look too dumb lol

Code:
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

 

 

namespace Card_Game

{

    class Deck

    {

        Card[] deck;

        const int minCards = 30;

        StreamReader reader;

        StreamWriter writer;

        CardDataBase cardDataBase;

        int nextBlankSpot = 0;

        Random rand = new Random();

        ContentManager Content;

        public Card[] hand = new Card[8];

        public Texture2D[] handTexture = new Texture2D[7];

        StreamWriter writer2 = new StreamWriter("C:\\Users\\plague180\\Desktop\\debug.txt");

        public bool errorHasBeenReported = false;

 

        public Deck(CardDataBase cardDataBase, ContentManager Content)

        {

            this.cardDataBase = cardDataBase;

            this.Content = Content;

        }

        public void LoadDeck(string fileName)

        {

            reader = new StreamReader(fileName);

            string[] working = reader.ReadLine().Split(' ');

            //make sure the deck is the right size so there will be no null objects

            deck = new Card[working.Length];

            for (int i = 0; i < working.Length; i++)

            {

                AddCard(Int32.Parse(working[i]));

            }

        }

        public void InitHand()

        {

            for (int i = 0; i < 7; i++)

            {

                // fill first hand

                hand[i] = deck[i];

                // create textures

                handTexture[i] = Content.Load<Texture2D>("Cards\\" + hand[i].fileName);

                //remove cards from top of deck

                

            }

            

        }

        public void AddCard(int id)

        {

            NextBlank();

            deck[nextBlankSpot] = cardDataBase.GetCard(id - 1);

            deck[nextBlankSpot].deckId = nextBlankSpot;

        }

        public void RemoveCard(int id)

        {

 

        }

        public void NextBlank()

        {      

            for (int i = 0; i < deck.Length; i++)

            {

                if (deck[i] == null)

                {

                    nextBlankSpot = i;

                    break;

                }

            }

        }

        public void Shuffle()

        {

            for (int i = deck.Length - 1; i > 0; i--)

            {

                int n = rand.Next(i + 1);

                Swap(i, n);

            }

        }

        public void Swap(int i, int n)

        {

            Card temp = deck[i];

            deck[i] = deck[n];

            deck[n] = temp; 

        }

}

 

Code:
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Card_Game

{

    public enum Element { None, Water, Fire };

    public enum Passive { None, Temp1 };

    public enum Active  { None, Temp2 };

    public enum Status  { None };

    public enum Rarity  { Common, Uncommon, Rare, SuperRare, BeyondRare };

 

    public class Card

    {

        public string fileName = "None";

        public bool foil = false;

        public bool energy = false;

        public bool shrine = false;

        public int playCost = 0;

        public int id = -1;

        public int attack = 0;

        public int hp = 0;

        public int maxHp = 0;

        public int abilityCost = 0;

        public int deckId = -1;

        Element element;

        Passive passive;

        Active active;

        Status status;

        Rarity rarity;

 

 

        public Card(int id, string fileName, bool foil, int attack, int maxHp, int playCost, int abilityCost, string element, string passive, string active, string status, string rarity)

        {

            this.id = id;

            this.fileName = fileName;

            this.foil = foil;

            this.attack = attack;

            this.maxHp = maxHp;

            this.playCost = playCost;

            this.abilityCost = abilityCost;

            this.element = (Element)Enum.Parse(typeof(Element), element);

            this.passive = (Passive)Enum.Parse(typeof(Passive), passive);

            this.active = (Active)Enum.Parse(typeof(Active), active);

            this.status = (Status)Enum.Parse(typeof(Status), status);

            this.rarity = (Rarity)Enum.Parse(typeof(Rarity), rarity);

        }

        public Card(int id, bool foil, bool energy, bool shrine, string element, string fileName, string rarity)

        {

            this.id = id;

            this.foil = foil;

            this.energy = energy;

            this.shrine = shrine;

            this.element = (Element)Enum.Parse(typeof(Element), element);

            this.fileName = fileName;

            this.rarity = (Rarity)Enum.Parse(typeof(Rarity), rarity);

        }

        public Card()

        {

           

        }

        public string report()

        {

            return fileName + ", id: " + id + " ,deck id: " + deckId + " , ATK: " + attack;

        }

    }

}

 
 
You are recording some bizarre stuff, why is next blank a member variable when it is only changed in the function get next blank? You can easily throw in a return statement and assign a new variable in stead. I'm guessing you're very new to C#?

It looks to me like you've made deck[] a varying sized array and it's always looping to the end of it with nextblank which is index 10, however your code is so messy that it's pretty difficult to follow, try break pointing inside getnextblank's function and stepping through checking how it finds the next null slot in deck.
Also, I'm guessing you loop through the array as you have cards removed from the middle of the deck sometimes? Otherwise you can just use deck.Length as the next null slot.

It looks totally weird because I'd understand if it never sets next blank as you haven't looped into the null space of the array, but it is always looping to the end of it for some reason.

When I have time I'll write up a clean design for you so it's easier to trace the code, it's that unneeded data that's getting me completely lost as it's not clear at all where the array is being built around it (to me the array should always be ending up with 1 card)

Edit: I just noticed the working.Length line, what is the contents of your data file? You are definitely mistreating your poor array there with it's data reliance
 
the code makes perfect sense to me, im by no means a master, but i dont think its as bad as you make it out to be. i really appreciate your help, just not acting like im a complete idiot. the contents of the file are "1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 4 4 4 4 8 8 10 16 6 6" which is all the card ids (used for getting the card from the database) in plaintext (for now, so i can read it easy)

the flow is nothing like you explained, or at least how i understood how you explained. (maybe because i didnt say im using XNA, idk) i have a manager class the performs the following:

Code:
// create database

            cardDataBase.LoadCards();

            // Create Deck

            deck = new Deck(cardDataBase, Content);

            // Load deck

            deck.LoadDeck(Content.RootDirectory + "\\Decks\\SaveGame\\Save1.txt");

            // Draw 7 cards

            deck.InitHand();

it creates my database of cards from a text file, which works perfectly, the it create the blank deck (i dont instantly load a deck because i plan on putting a deck selection screen there) i load a deck for debug purposes. then draw my hand. this all works perfectly including when i use shuffle, the part im having issues with is changing the deck. i understand if my add card method is all wrong, im open to suggestions.

edit: after rereading your post i see that you mean about the nextBlank int, i guess that could be simpler, i just wanted to be able to reuse the number latter. the end of nextBlank is 25 since there are 26 cards in my deck, not 10 as you stated.

also i would like to add, that i have debugged the hell out of NextBlank() it always returns the right number.

as for working.length its worked perfect for me, it makes sure the size of the array is the same size of the deck
 
Vergessen":1x6ko4qo said:
the end of nextBlank is 25 since there are 26 cards in my deck
If there are 26 cards in the deck, that's ID's 0-25, so the next blank should be 26 shouldn't it?
Is the ID - 1 part of the code to correct the card table as it starts from 1 in human readable format and 0 in the array?

I have a bit of time to take a look at the classes together now, I have them set up and I think I can see a misalignment, I'll test and rewrite a small solution for you now

EDIT:
Could you try this quickly and see if nextBlankSpot has changed it's behaviour at all?
Code:
public void AddCard(int id)

        {

            nextBlankSpot = NextBlank();

            deck[nextBlankSpot] = cardDataBase.GetCard(id - 1);

            deck[nextBlankSpot].deckId = nextBlankSpot;

        }

        

        public int NextBlank()

        {      

            for (int i = 0; i < deck.Length; i++)

            {

                if (deck[i] == null)

                {

                    return i;

                }

            }

        }


Also you may want to use List<T> in stead of an array, the reason is because you can simply do:
Code:
 

List<Card> deck;

deck.Add(cardDataBase.GetCard(id - 1));

deck[deck.Length - 1].deckId = deck.Length - 1; // You can probably now see why deckId is never needed.

 

You can then use this to remove a card from the deck at Pos:
Code:
 

deck.Remove(Pos);

 
 
Xilef":2bmfygxb said:
Vergessen":2bmfygxb said:
the end of nextBlank is 25 since there are 26 cards in my deck
If there are 26 cards in the deck, that's ID's 0-25, so the next blank should be 26 shouldn't it?
Is the ID - 1 part of the code to correct the card table as it starts from 1 in human readable format and 0 in the array?

I have a bit of time to take a look at the classes together now, I have them set up and I think I can see a misalignment, I'll test and rewrite a small solution for you now

EDIT:
Could you try this quickly and see if nextBlankSpot has changed it's behaviour at all?
Code:
public void AddCard(int id)

        {

            nextBlankSpot = NextBlank();

            deck[nextBlankSpot] = cardDataBase.GetCard(id - 1);

            deck[nextBlankSpot].deckId = nextBlankSpot;

        }

        

        public int NextBlank()

        {      

            for (int i = 0; i < deck.Length; i++)

            {

                if (deck[i] == null)

                {

                    return i;

                }

            }

        }


Also you may want to use List<T> in stead of an array, the reason is because you can simply do:
Code:
 

List<Card> deck;

deck.Add(cardDataBase.GetCard(id - 1));

deck[deck.Length - 1].deckId = deck.Length - 1; // You can probably now see why deckId is never needed.

 

You can then use this to remove a card from the deck at Pos:
Code:
 

deck.Remove(Pos);

 


the next one would be 26 if the code continued, it loops from 0-25 in the loadDeck method since working.length is 26

yes the -1 is to change it from human 1-26 to computer 0-25

i tried your solution, i get the same output as my code:
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Calming_Pools, id: 1 ,deck id: 11 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Sunken_Shrine, id: 2 ,deck id: 15 , ATK: 0
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Pirate, id: 4 ,deck id: 19 , ATK: 2
Jelly_Fish, id: 8 ,deck id: 21 , ATK: 1
Jelly_Fish, id: 8 ,deck id: 21 , ATK: 1
Deep_Sea_Horror, id: 10 ,deck id: 22 , ATK: 6
Water_Spirt, id: 16 ,deck id: 23 , ATK: 3
Blow_Fish, id: 6 ,deck id: 25 , ATK: 3
Blow_Fish, id: 6 ,deck id: 25 , ATK: 3

note the calming pools are all id 1 and deckid 11, it should be id 1 for all of them, but different deckid

i can see what you wanted with the list, but wouldn't that cause problems if i shuffle?
 
Vergessen":1ogdazic said:
i can see what you wanted with the list, but wouldn't that cause problems if i shuffle?
As long as the length never changes it should be fine.

Code:
 

for (int i = 0; i < deck.Length; i++)

{

    int randSlot = rand(0, deck.Length); // Replace rand() with your random number function

    Card temp = deck[i]; // Store deck[i] in a temporary slot for swapping with random other card.

    deck[i] = deck[randSlot]; // Swap them around;

    deck[randSlot] = temp;

}

 

EDIT:
Can even use foreach with a list if you like those (Performance improvements when your for loop comparitor is a function return that is constantly used).
 
ive read alot into shuffle algorithms, id like to use this one(fisher-yates if i recall):

Code:
public void Shuffle()

        {

            for (int i = deck.Length - 1; i > 0; i--)

            {

                int n = rand.Next(i + 1);

                Swap(i, n);

            }

        }

the algorithm is sapose to be completely balanced. i ran 5 million simulations, no repeat in order, i know that's only a fraction of the possibility's, but its still better then the others i tried.


just thought id ask your opinion, ill work on changing it all to a list and see what happens (after work tmw, i need to go to bed now) thanks for your help thus far
 
Yeah the algorithm I posted there is Fisher-Yates, just without the Swap method (I store the temporary value and then swap, which is actually what most swap functions do, there's a lower level version with some neat bitwise tricks that I use but the performance difference is tiny).
 
i made your suggested changes, and i still get the wrong output, but ill play around with the list idea more, it makes alot of sense

edit: so i started playing with my database code to see if it was causing the problem, when i run the output after all the deck code has been ran i get:
1, Calming_Pools, 11
2, Sunken_Shrine, 15
3, Sunken_Shrine_Foil, -1
4, Pirate, 19
5, Pirate_Foil, -1
6, Blow_Fish, 25
7, Blow_Fish_Foil, -1
8, Jelly_Fish, 21
9, Jelly_Fish_Foil, -1
10, Deep_Sea_Horror, 22
11, Deep_Sea_Horror_Foil, -1
12, Dazed_Survivor, -1
13, Dazed_Survivor_Foil, -1
14, Kraken, -1
15, Kraken_Foil, -1
16, Water_Spirt, 23
17, Water_Spirt_Foil, -1
18, Glacier_Dragon, -1
19, Glacier_Dragon_Foil, -1
20, Dread_Capitan, -1
21, Dread_Capitan_Foil, -1

which means im modifying the database directly somehow. the only thing that i could see is if: cardDataBase.GetCard(id - 1) is returning a pointer to the original object. what do you think?

p.s. ignore the -1 that just means there isnt one in my deck

edit 2: i now see why i dont need deckid, thanks
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top