【问题标题】:Array for Blackjack cards, strings or integers?二十一点卡、字符串或整数的数组?
【发布时间】:2013-06-07 18:34:32
【问题描述】:

查看相关的 BlackJack 问题后,人们对于卡片更好地使用什么感到困惑,要么制作字符串/项目数组,要么制作整数数组。

在我的二十一点游戏中,A 只有 11 和 10,J、Q 和 K 的值都是 10,这与花色无关。什么能让我用字符串或整数对卡片进行编码更容易?

Visual Studio C# 2010,Windows 窗体应用程序

【问题讨论】:

  • 技巧问题:两者都不是。我会创建一个专用的 Card 类,并可能为 13 个可能的值创建一个支持 enum
  • 听起来容易多了
  • 没有“最佳”或“轻松”的方式来做到这一点。有人会说 52 个值的枚举。其他人会说一个带有值的“卡片”对象,也许是花色的枚举。有些人可能会找到在同一个应用程序中同时执行这两项操作的理由。您是否与从未做过 OOP 的人一起工作?那么也许你不应该使用一个对象。像这样的问题对 StackOverflow 来说不是好问题。使用一种方法,并了解它为什么不起作用。但要意识到,在编程​​中几乎没有这种“最好”的方式来做任何事情,因为每个人的经历和项目都不同。
  • 我写了一篇关于here的文章。虽然同意不同的表示对于不同的应用程序更好,但字符串从来没有是最好的。

标签: c# visual-studio blackjack


【解决方案1】:

卡片是一个对象,所以让它成为自己的类。

应使用 Suit 枚举(Heart、Diamond、Club、Spade)和Rank 枚举(Ace、Jack、10 等,为了便于比较,按相应顺序排列)。您可以从套装中获取颜色,因此我不建议将颜色作为构造函数的参数,因为它是多余的。您实际上只需要构造函数中的这两个字段,除非您计划复制卡片,例如您在游戏中使用多个套牌。使用这些卡片时,强烈建议使用 List 或类似类型,因为很多排序操作是内置的。当您需要洗牌时,请使用 Knuth 洗牌!您可以通过 Google 轻松找到它,它易于实施,并且工作快速高效。

这种方法来自我的 CS 教授,我也很欣赏它。您的代码对现实生活的建模越多,就越容易理解和扩展。你可以使用 int 或 string 常量,但它们是你不需要做的额外工作,也不优雅。

public class Card
{
    public Suit Suit { get; private set; }
    public Rank Rank { get; private set; }

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

【讨论】:

    【解决方案2】:

    字符串几乎从来都不是实际文本的最佳内部表示。弦乐是给人的;计算机使用数字。尤其是对于卡片来说,这是不费吹灰之力的,因为卡片通常需要按等级比较并按价值添加。告诉程序 12 > 11 或将 10 添加到总数中所需的代码比告诉程序“K” > “Q”或将“J”添加到总数中要少得多。对于懒得学习数据表示的新手程序员来说,在内部使用字符串很常见。

    当然,在像 C++ 这样面向对象的语言中,您可以使用对象,但那些持有牌位和花色的对象的成员变量应该是整数,以便您可以索引查找表、比较范围等。

    我写了一篇关于卡片表示的文章here

    对于二十一点,如果您不需要通用的卡片表示,那么只使用整数 1 到 10 是理想的。将 1 用于 ace,而不是 11,这将使您的总计算速度更快:您只需将一个 ace 从 1 提升到 11,但您需要将几个从 11 降级到 1。

    例如,如果您有一个代表手牌的整数数组,则将手牌总数相加是这样的(当然,充实):

    int total = 0, acefound = 0, soft = 0;
    
    for (int i = 0; i < cardsinhand; ++i) {
        total += hand[i];
        if (1 == hand[i]) acefound = 1;
    }
    if (acefound && total < 12) {
        soft = 1;
        total += 10;
    }
    

    简单,速度惊人。如果您代表的是实际卡片,那么您将拥有等级为 11、12、13 的面卡,那么只需在其中添加类似 if (r &gt; 10) r = 10; 的内容(制作 ace 1 的另一个原因)。我可以像这样在几分钟内模拟 十亿 手牌。

    【讨论】:

    • 比我的答案要好得多,我应该花时间正确布置课程而不是寻找快速答案,尤其是作为优化的粉丝,我应该知道比发布这样的答案更好马虎的回答,很高兴成员们在这个网站上互相保持关注!
    【解决方案3】:

    二十一点控制台应用程序示例项目 (C#) GitHub:

    https://github.com/koistya/Blackjack

    public class Card
    {
        public Card(Rank rank, Suite suite)
        {
            this.Rank = rank;
            this.Suite = suite;
            this.IsFaceUp = true;
        }
    
        public Rank Rank { get; private set; }
    
        public Suite Suite { get; private set; }
    
        public bool IsFaceUp { get; private set; }
    
        public void Flip()
        {
            this.IsFaceUp = !this.IsFaceUp;
        }
    }
    
    public enum Rank : byte
    {
        Ace   = 1,
        Two   = 2,
        Three = 3,
        Four  = 4,
        Five  = 5,
        Six   = 6,
        Seven = 7,
        Eight = 8,
        Nine  = 9,
        Ten   = 10,
        Jack  = 11,
        Queen = 12,
        King  = 13,
    }
    
    public enum Suite : byte
    {
        Club    = 1,
        Diamond = 2,
        Heart   = 3,
        Spades  = 4
    }
    

    【讨论】:

      【解决方案4】:

      enum 13 个可能的值会更好

      【讨论】:

        猜你喜欢
        • 2016-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        相关资源
        最近更新 更多