循环通过Enum创建BlackJack卡座

时间:2017-09-09 13:52:04

标签: c# enums

我一直在搜索,但找不到符合我问题的答案。

我有2个Enums,一个有cardvalues,另一个有西装。由于我正在尝试创建BlackJack游戏,我希望JackQueenKing等于10。 现在,JacksQueensKings在我的游戏中使用时指向10。 我还尝试了Jack=10Queen=10King=10,但在执行此操作时JQK显示为10,创建了多个10。我已经检查了,无论哪种方式,套牌都包含52张牌。

有人可以告诉我最新消息吗? 提前谢谢!

public enum Value
{
    Ace=1,
    Two=2,
    Three=3,
    Four=4,
    Five=5,
    Six=6,
    Seven=7,
    Eight=8,
    Nine=9,    
    Ten=10,
    Jack=Ten,
    Queen=Ten,
    King=Ten
}

public enum Suits
{
    Hearts,
    Clubs,
    Spades,
    Diamonds
}

    public Deck()
     {
        rand = new Random();
        cardlist = new List<Card>();
        foreach (Suits s in Enum.GetValues(typeof(Suits)))
        {
            foreach (Value v in Enum.GetValues(typeof(Value)))
            {                    
                cardlist.Add(new Card(s, v));
            }
        }
       ShuffleCards();            
    }

做过这样的事情,但仍然没有效果......

 public class Card
 {
    /// <summary>
    /// Variables
    /// Card has one value and one suit
    /// </summary>
     Value v;
     Suits s;

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="siu"></param>
    /// <param name="val"></param>
    public Card ( Suits siu, string val )
    {
        Value = (Value)Enum.Parse(typeof(Value), val);
        Suits = siu;
    }

    /// <summary>
    /// Property value
    /// </summary>
    public Value Value
    {
        get { return v;}
        set { v = value; }
    }

    /// <summary>
    /// Property Suit
    /// </summary>
    public Suits Suits
    {
        get { return s; }
        set { s = value; }
    }

    /// <summary>
    /// To string method. Adding value and suit.
    /// </summary>
    /// <returns></returns>
    public override String ToString()
    {
        return Value.ToString() + " " +  Suits.ToString();
    }
}

4 个答案:

答案 0 :(得分:2)

将点存储在字典中,不要在枚举中指定它们:

public enum Value
{
    Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}

private Dictionary<Value, int> _pointDict = new Dictionary<Value, int>() {
    [Value.Ace] = 1,
    [Value.Two] = 2,
    ...
    [Value.Ten] = 10,
    [Value.Jack] = 10,
    [Value.Queen] = 10,
    [Value.King] = 10,
};

然后你可以用

获得积分
int points = _pointDict[v];  // With v typed as Value

注意:我使用了C# 6.0 New Feature Dictionary Initializers

答案 1 :(得分:0)

您希望为同一个数字(10)设置多个枚举值,然后获取名称并将其添加到List,您需要使用Enum.GetNames而不是Enum.GetValues

foreach (var v in Enum.GetNames(typeof(Value)))
{
    cardlist.Add(new Card(s, v));
}

您还应该将v类中Card的类型更改为字符串。

答案 2 :(得分:0)

在C#中,枚举是一种值类型。值类型的实例按值进行比较。因此,具有相同数值的枚举值被认为是相同的。

将枚举值转换为字符串将产生具有该数值的第一个枚举值的名称。这就是为什么杰克,女王和国王表现为&#34; Ten&#34;。枚举的枚举值通常应该是唯一的。

我假设您希望能够获得排名(&#34; King&#34;)以及指定的数值(10)。试试这个:

public enum Rank
{
    Ace = 1,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King
}

请注意,Jack,Queen和King的值是唯一的(11,12,13)。

这是一个扩展方法,它将返回一个等级的数值:

public static class RankExtensions
{
    public static int GetNumericValue(this Rank rank)
    {
        return (rank < Rank.Ten) ? (int)rank : 10;
    }
}

以下是一些演示结果的代码:

public static class Program
{
    static void Main(string[] args)
    {
        var ranks = Enum.GetValues(typeof(Rank)).Cast<Rank>();

        Console.WriteLine("Test rank with unique values:");
        foreach (Rank rank in ranks)
        {
            Console.WriteLine($"  ToString()={rank,-5}, (int)={(int)rank, 2}, GetNumericValue()={rank.GetNumericValue(), 2}");
        }
    }

以下是结果:

Test rank with unique values:
  ToString()=Ace  , (int)= 1, GetNumericValue()= 1
  ToString()=Two  , (int)= 2, GetNumericValue()= 2
  ToString()=Three, (int)= 3, GetNumericValue()= 3
  ToString()=Four , (int)= 4, GetNumericValue()= 4
  ToString()=Five , (int)= 5, GetNumericValue()= 5
  ToString()=Six  , (int)= 6, GetNumericValue()= 6
  ToString()=Seven, (int)= 7, GetNumericValue()= 7
  ToString()=Eight, (int)= 8, GetNumericValue()= 8
  ToString()=Nine , (int)= 9, GetNumericValue()= 9
  ToString()=Ten  , (int)=10, GetNumericValue()=10
  ToString()=Jack , (int)=11, GetNumericValue()=10
  ToString()=Queen, (int)=12, GetNumericValue()=10
  ToString()=King , (int)=13, GetNumericValue()=10

答案 3 :(得分:0)

您应该使用enum Value来表示卡片的正面,而不是卡片的价值。

有两个原因。 (1)如您所发现,它最终会映射JackQueen&amp;当您尝试将映射从King转换为int时,Value全部为10。 (2)在二十一点游戏中,Ace可以有两个值111。您不能让一张卡代表enum中的两个值,因此您需要其他方法。

首先,像这样定义你的enum Value

public enum Value
{
    Ace = 1,
    Two, Three, Four, Five,
    Six, Seven, Eight, Nine,
    Ten, Jack, Queen, King
}

不,您可以定义Card类,以便每张卡可以返回多个值,使Ace同时返回111,皇家卡片返回{{1 },以及所有其他卡片返回其面值:

10

现在,你希望能够得到一个&#34; Hand&#34;所以制作一个可以容纳0张或更多张卡片的public class Card { public Card(Suits suit, Value value) { this.Value = value; this.Suit = suit; } public Value Value { get; private set; } public Suits Suit { get; private set; } public IEnumerable<int> Values() { yield return (int)this.Value < 10 ? (int)this.Value : 10; if (this.Value == Value.Ace) { yield return 11; } } public override String ToString() { return String.Format("{0} {1}", this.Value, this.Suit); } } 课程。通过继承Hand来保持简单。

List<Card>

现在public class Hand : List<Card> { public Hand(IEnumerable<Card> cards) { this.AddRange(cards); } public IEnumerable<int> Values() { return ComputeValues(this.ToArray()); } private IEnumerable<int> ComputeValues(Card[] cards) { if (cards.Length == 0) { return Enumerable.Empty<int>(); } else if (cards.Length == 1) { return cards[0].Values(); } else { return cards[0] .Values() .SelectMany( v => ComputeValues(cards.Skip(1).ToArray()), (v, n) => v + n) .Distinct(); } } } 可以解决计算手牌可能值的繁重问题。我会在答案结尾处显示一些结果。

最后,您需要一个ComputeValues课程来代表整套卡片。这只是Deck类的扩展。

Hand

请注意,甲板的创建和混洗是内置于构造函数中的。

现在将所有这些放在一起很容易。因此,如果我想从牌组中拿两张牌,我可以这样做:

public class Deck : Hand
{
    private static Random rand = new Random();

    public Deck() : base(
        from Suits s in Enum.GetValues(typeof(Suits))
        from Value v in Enum.GetValues(typeof(Value))
        orderby rand.Next()
        select new Card(s, v))
    { }
}

运行时,我得到这样的结果:

Six Spades + Jack Hearts
16

或:

Ace Hearts + Jack Clubs
11 OR 21

如果我将其改为使用var deck = new Deck(); var hand = new Hand(deck.Take(2)); Console.WriteLine(String.Join(" + ", hand.Select(c => c.ToString()))); Console.WriteLine(String.Join(" OR ", hand.Values())); 获得3张牌,并且我有足够的时间,我最终得到了这个:

Ace Diamonds + Ace Hearts + Four Spades
6 OR 16 OR 26