【问题标题】:Understanding generation of 52 card ojects了解 52 个卡片对象的生成
【发布时间】:2019-08-13 09:09:40
【问题描述】:

我已经成功地向控制台输出了 52 个不同的“卡片”,但是我执行的检查以查看是否生成了单个对象似乎表明我在某个地方出错了。
例如,我的 num 构造函数不会随着卡片的创建而增加,而且当我使用 foreach 循环遍历列表时,卡片的值都为 13。我相信这是我将卡片添加到卡片组的地方,但我并不完全当然。

对不起,如果这是一个已经回答过的新手问题!


    {
        public int Suite 
        public int Value 
        public string cardString;
        public int num;
        public Card ()
        { num++; }

      public static void GenerateDeck()
        {
            List<Card> Deck = new List<Card>();
            for (int c = 1; c < 5; c++)
            {
                Card card = new Card();
                {
                    card.Suite = c;                   
                }
                for (int k = 1 ; k <=13; k++)
                {
                    card.Value = k;
                    {
                        switch (card.Suite)
                        {
                            case 1:
                                card.cardString = "Hearts";
                                break;
                            case 2:
                                card.cardString = "Diamonds";
                                break;
                            case 3:
                                card.cardString = "Spades";
                                break;
                            case 4:
                                card.cardString = "Clubs";
                                break;

                        }                   

                        if (card.Value == 1)
                        {
                            card.cardString = "Ace of " + card.cardString;                            
                        }
                        else if (card.Value > 0 && card.Value <= 10)
                        {
                            card.cardString = card.Value.ToString() + " of " + card.cardString;                                                      
                        }
                        else if (card.Value == 11)
                        {
                            card.cardString = "Jack of " + card.cardString;
                        }
                        else if (card.Value == 12)
                        {
                            card.cardString = "Queen of " + card.cardString;
                        }
                        else if (card.Value == 13)
                        { card.cardString = "King of " + card.cardString; }

                        Deck.Add(card);
                    }
                    Console.WriteLine(card.cardString);                  
                }
                Console.ReadLine();
            }

            foreach (var item in Deck)
            {
                Console.WriteLine("CARD SUITE {0} AND CARD VALUE {1}, num{2} ", item.Suite, item.Value, item.num                    
                    );
            }

            Console.WriteLine(Deck.Count);
            Console.ReadLine();
        }
    }
`````

【问题讨论】:

  • 您正在重用卡片对象。您为每个套件构建一次,然后为该套件中的所有 13 张卡重复使用它。您需要在最里面的循环内移动卡片对象的构造。
  • 换句话说,您正在构建 4 个不同的卡片对象,然后将值分配给每个 13 次,并将卡片对象每次添加 13 次到您的列表中。这意味着你最终会得到 13 个红桃 K,13 个黑桃 K,13 个 ... 等等。
  • 如果您不知道引用类型(类)和值类型(结构)之间的区别,那么您绝对应该搜索这些主题并阅读它们。
  • 非常感谢,Card 类是一种不好的方法吗?我已经成功编写了一个类似的程序,生成具有年龄、身高和唯一 ID 的“人”,但我没有使用嵌套循环来完成这项任务。
  • 不,Card 类很好。您只需要了解引用类型的工作原理(一个非常重要的概念)。

标签: c# list object


【解决方案1】:

就像 J.A.I.L 在他的回答中指出的那样,您只创建 4 个对象。

要解决您的问题,您需要为内部循环的每次迭代创建一个新的Card-object,例如:

for (int c = 1; ...)
{
    for (int k = 1; ...)
    {
        var card = new Card()
        card.Suite = c;
        card.Value = k;
        ...
     }
}

【讨论】:

  • 这似乎工作了! ` int 计数器 = 0;列表甲板=新列表(); for (int c = 1; c
  • @DavidGreen 如果你只在循环中使用它的值,你不需要将c 存储在一个额外的变量中。
【解决方案2】:

您只创建了 4 张新卡片:

           for (int c = 1; c < 5; c++)
            {
                Card card = new Card();
                {
                    card.Suite = c;

                }

然后,在创建这 4 辆汽车中的每一辆后,您将添加 相同的卡实例 13 次。您还将该实例的值更改 13 次,因此您最终会得到一个 Deck,其中包含 13 个相同卡片对象的实例(它们都是 Kings):

                Card card = new Card();
                { /*...*/ } 
                for (int k = 1 ; k <=13; k++)
                {
                    card.Value = k;
                    // ... 
                    Deck.Add(card);
                }

要解决您的问题,您必须在 for "values" 循环中创建每张卡片:

           for (int c = 1; c < 5; c++)
           {
                for (int k = 1 ; k <=13; k++)
                {
                     Card card = new Card();
                     // ... Set here the Value and Suite
                 }
            }

【讨论】:

    【解决方案3】:

    创建卡片一次,在最里面的循环中;像这样的

      // Possible Suits
      string[] suits = new string[] { "Hearts", "Diamonds", "Spades", "Clubs" };
    
      // Possible Values: 3 groups combined
      string[] values = new string[] { "Ace" }                     // Ace
        .Concat(Enumerable.Range(2, 9).Select(c => c.ToString()))  // 2..10
        .Concat(new string[] { "Jack", "Queen", "King" })          // Jack, Queen, King
        .ToArray();
    
      // For each combination of Suit and value ...
      for (int suitIndex = 0; suitIndex < suits.Length; ++suitIndex)
        for (int valueIndex = 0; valueIndex < values.Length; ++valueIndex) {
          // ... we creare a card and add it to deck
          Card card = new Card() {
            Suite = suitIndex + 1,  // + 1 - since arrays are zero based
            Value = valueIndex + 1,
            cardString = $"{values[valueIndex]} of {suits[suitIndex]}"
          };
    
          Deck.Add(card);
    
          // Debug purpose only
          Console.WriteLine(card.cardString);  
        } 
    

    【讨论】:

    • 我什至会使用Card 的构造函数来提供 Suite 和 Value 并使属性只读。这样可以防止此类错误(并且会在以后防止有人将他的牌变成所有 A ;-)
    • @PMF: 我也是 :) Card 应该是不可变的:一旦创建就不得更改
    猜你喜欢
    • 1970-01-01
    • 2017-12-26
    • 2017-04-27
    • 2012-07-25
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    相关资源
    最近更新 更多