首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扑克牌手分类器第3部分:纸牌物品和7纸牌手

扑克牌手分类器第3部分:纸牌物品和7纸牌手
EN

Code Review用户
提问于 2017-01-23 15:34:00
回答 1查看 538关注 0票数 2

第1部分:扑克手分类器的起源第2部分:扑克手分类器的开始第二部分

我是一个初学者程序员,致力于学习c#和面向对象,并一直致力于扑克手分类器的实践。从上半部分开始,我就扩大了我的课程范围,并做出了一些我非常希望得到反馈的决定。

注:我可能没有完成所有建议我的想法,这要么是因为我必须改变类/方法,这些想法不再有效,或者是有点超出我的能力。

甲板对象类和2手类继承手

代码语言:javascript
复制
 public class Deck
{
    static Random rand = new Random();
    public List<Card> Cards { get; private set; }
    public Deck()
    {
        Cards = new List<Card>();
        FillDeck(this);
    }
    private static void FillDeck(Deck deck)
    {
        Face[] faceNames = { Face.Ace, Face.Two, Face.Three, Face.Four, Face.Five, Face.Six, Face.Seven, Face.Eight, Face.Nine, Face.Ten, Face.Jack, Face.Queen, Face.King };
        Suit[] allSuits = { Suit.Diamond, Suit.Club, Suit.Heart, Suit.Spade };

        foreach (Suit suit in allSuits)
        {
            foreach (Face face in faceNames)
            {
                deck.Cards.Add(new Card(suit, face));
            }
        }
        ShuffleDeck(deck);
    }
    public static void ShuffleDeck(Deck deck)
    {    
        for (int i = 1; i <= deck.Cards.Count; i++)
        {
            PerformCardSwap(deck);
        }
    }
    private static void PerformCardSwap(Deck deck)
    {
        int randomIndex = rand.Next(1, deck.Cards.Count);
        Card firstCard = deck.Cards[0];
        Card randomCard = deck.Cards[randomIndex];
        deck.Cards[0] = randomCard;
        deck.Cards[randomIndex] = firstCard;
    }
    public static List<Card> Deal5Cards(Deck deck)
    {
        List<Card> newHand = new List<Card>();
        for (int i = 0; i < 5; i++)
        {
            Card temp = deck.Cards[0];
            newHand.Add(temp);
            deck.Cards.RemoveAt(0);
        }
        return newHand;

    }
    public static List<Card> Deal2Cards(Deck deck)
    {
        List<Card> newHand = new List<Card>();
        for (int i = 0; i < 2; i++)
        {
            Card temp = deck.Cards[0];
            newHand.Add(temp);
            deck.Cards.RemoveAt(0);
        }
        return newHand;

    }
}
public class TwoCardHand : Hand
{
    public new List<Card> Cards { get; }
    public TwoCardHand(List<Card> cards)
    {
        if (cards.Count != 2)
        {
            throw new ArgumentOutOfRangeException("Invalid amount of Cards");
        }
        Cards = new List<Card>(cards);

    }
    public TwoCardHand()
    {
        Cards = Deck.Deal2Cards(deck);
    }
}

这是“洗牌”的最佳方式吗?在测试期间,我似乎有很多钻石西装是偶然的。继承手是必需的,以确保他们有相同的静态甲板对象属性,所以他们没有画相同的卡片。是这个糟糕的程序,我想不出另一种方法.

手的物体-很多变化,特别是在内部相比较。它现在正确地对配对值进行排序,并从21组手中提供最好的手。

代码语言:javascript
复制
 public class Hand : IComparable<Hand>
{
    public static Deck deck = new Deck();
    public List<Card> Cards { get; private set; }
    public PokerHandsRank HandRank
    {
        get { return CheckHandRank(this);  }
    }
    public Hand(List<Card> cards)
    {
        if (cards.Count != 5)
        {
            throw new ArgumentOutOfRangeException("Invalid amount of Cards");
        }
        Cards = new List<Card>(cards);
    }
    public Hand()
    {
        this.Cards = Deck.Deal5Cards(deck);
    }
    public override string ToString()
    {
        sortHandbyFaceDesc(this);
        return string.Join(" ", Cards.Select(c => $"({c.Face} of {c.Suit}'s)"));     
    }
    private static int SortandCompareFaceValues(Hand hand, Hand secondhand)
    {
        sortHandbyFaceDesc(hand);
        sortHandbyFaceDesc(secondhand);
        for (int i = 4; 0 <= i; i--)
        {
            if (hand.Cards[i].Face == secondhand.Cards[i].Face)
            {
                if (i == 0) return 0;
                continue;
            }
            return hand.Cards[i].Face > secondhand.Cards[i].Face ? 1 : -1;
        }
        return 0; // should never get here but how to handle
    }
    public int CompareTo(Hand other)
    {
        if (HandRank == other.HandRank) //if the hand rank is equal, sort the cards by face value and compare the two biggest
        {
            if (HandRank.Equals(PokerHandsRank.Pair) || HandRank.Equals(PokerHandsRank.TwoPair) || HandRank.Equals(PokerHandsRank.ThreeOfKind) || HandRank.Equals(PokerHandsRank.FullHouse) || HandRank.Equals(PokerHandsRank.FourOfKind))
            {                    
                int pairValue = (ComparePairValue(this, other)); //check the values of the pairs and judge which is highest value
                return pairValue == 0  ? SortandCompareFaceValues(this, other) :  pairValue; //if pair is equal rank and highest value is equal check for highcards
            }
            return SortandCompareFaceValues(this, other);
        }
        return HandRank > other.HandRank ? 1 : -1;
    }
    private static int ComparePairValue(Hand hand, Hand secondHand)
    {
        Face face1 = FindHighestPairValuesFace(hand);
        Face face2 = FindHighestPairValuesFace(secondHand);

        return face1 == face2 ? 0 : face1 > face2 ? 1 : -1;
    }
    private static Face FindHighestPairValuesFace(Hand hand)
    {
        return (from card in hand.Cards
                orderby card.Face descending //sort by face value first
                group card by new { card.Face } into g
                let count = g.Count()
                orderby count descending // sort by what cards appear the most
                select new { g.Key.Face }.Face).First(); //first is highest value pair that appears the most
    }
    public static void sortHandbyFaceDesc(Hand hand)
    {
        var sortCards = (from cards in hand.Cards
                         orderby cards.Face descending
                         select cards).ToList();
        hand.Cards = sortCards;
    }
    public static void sortHandbyFace(Hand hand)
    {
        var sortCards = (from cards in hand.Cards
                         orderby cards.Face
                         select cards).ToList();
        hand.Cards = sortCards;
    }    

不包括Pokerhandchecker以节省空间,请参阅第2部分,如果您希望查看它们的逻辑,以找到所有可能的手,那么最好使用它。

代码语言:javascript
复制
      private static Hand findBestHandInList(List<Hand> possibleHands)
    {
        // return  possibleHands.OrderByDescending(h => h.HandRank).First().Cards;
        Hand returnList = new Hand(possibleHands[0].Cards);
        for (int i = 0; i < possibleHands.Count - 1; i++)
        {
            if (returnList.CompareTo(possibleHands[i + 1]) == -1)
            {
                returnList = possibleHands[i + 1];
            }
        }
        return returnList;
    }
    private static void addPossibleHandFromSevenCards(List<Card> cards, List<Hand> possibleHands)
    {
        List<Card> tempCardList = new List<Card>();  // select first card not to be in the hand
        for (int firstCard = 0; firstCard < cards.Count; firstCard++)
        {
            for (int secondCard = firstCard + 1; secondCard < cards.Count; secondCard++) // select first card not to be in the hand
            {
                for (int i = 0; i < cards.Count; i++)
                {
                    if (i != firstCard && i != secondCard) // every card that is not the first or second will added to the hand
                    {
                        tempCardList.Add(cards[i]);
                    }
                }
                possibleHands.Add(new Hand(tempCardList));
                tempCardList.Clear();
            }
        }
    }

主程序代码来运行控制台。

代码语言:javascript
复制
        Console.BackgroundColor = ConsoleColor.DarkGreen;
        Console.ForegroundColor = ConsoleColor.White;
        Console.Clear();
        Hand tableHand = new Hand();
        Console.WriteLine("Cards on the table are:");
        PrintCards(tableHand);


        TwoCardHand your2Cards = new TwoCardHand();
        TwoCardHand their2Cards = new TwoCardHand();
        Console.WriteLine();
        Console.WriteLine("Your two cards are:");
        PrintCards(your2Cards.Cards);
        Console.WriteLine("Their two cards are:");
        PrintCards(their2Cards.Cards);
        Console.WriteLine();
        Console.Read();
        List<Card> YourSevenHand = new List<Card>(your2Cards.Cards.Concat(tableHand.Cards));
        List<Card> TheirSevenHand = new List<Card>(their2Cards.Cards.Concat(tableHand.Cards));

        List<Hand> yourPossibleHands = new List<Hand>();
        List<Hand> theirPossibleHands = new List<Hand>();

        addPossibleHandFromSevenCards(YourSevenHand, yourPossibleHands);
        addPossibleHandFromSevenCards(TheirSevenHand, theirPossibleHands);

        Hand yourFinalHand = findBestHandInList(yourPossibleHands);               
        Hand theirFinalHand = findBestHandInList(theirPossibleHands);

        Console.WriteLine(yourFinalHand.CompareTo(theirFinalHand) == 1 ? "You win" : yourFinalHand.CompareTo(theirFinalHand) == 0 ? "Draw" : "They win");

        Console.WriteLine(yourFinalHand);
        Console.WriteLine("You have a {0}", yourFinalHand.HandRank);
        Console.WriteLine(theirFinalHand);
        Console.WriteLine("They have a {0}", theirFinalHand.HandRank);

我在这里说的例子太多了吗?这能做得更好吗?

这很可能是我在这个项目上的最后一篇文章,因为我认为我已经达到了我进一步扩展它的能力的极限。我真诚地感谢人们对我的代码提出的所有建议。

如果你想自己运行的话。请查看第一部分和第二部分中的卡片类、枚举和检查手的等级,我认为它们应该仍然有效。

EN

回答 1

Code Review用户

回答已采纳

发布于 2017-01-23 16:10:09

可以使用Enum类获取枚举中的所有值:

Face[] faceNames ={ Face.Ace,Face.Two,Face.Three,Face.Four,Face.Five,Face.Six,Face.Seven,Face.Eight,Face.Nine,Face.Ten,Face.Jack,Face.Queen,Face.King }

可以成为:

代码语言:javascript
复制
Array faceNames = Enum.GetValues(typeof(Face));
Array allSuits = Enum.GetValues(typeof(Suit));

或者使用T[]

代码语言:javascript
复制
Face[] faceNames = Enum.GetValues(typeof(Face)).Cast<Face>().ToArray();
Suit[] allSuits = Enum.GetValues(typeof(Suit)).Cast<Suit>().ToArray();

你的两种处理卡的方法:

公共静态List Deal5Cards(甲板){ List newHand =新List();for (int i= 0;i< 5;i++) { Card temp = deck.Cards0;newHand.Add(temp);deck.Cards.RemoveAt(0);}返回newHand;}公共静态List Deal2Cards(甲板甲板){ List newHand = new List();for (int i= 0;i<2);( i++) { Card temp = deck.Cards0;newHand.Add(temp);deck.Cards.RemoveAt(0);}返回newHand;}

可以变成一个单一的方法:

代码语言:javascript
复制
public static List<Card> DealNCards(Deck deck, int count)
{
    List<Card> newHand = new List<Card>();
    for (int i = 0; i < count; i++)
    {
        Card temp = deck.Cards[0];
        newHand.Add(temp);
        deck.Cards.RemoveAt(0);
    }
    return newHand;
}

使用LINQ可以缩短addPossibleHandFromSevenCards中的第三个循环

对于(int i= 0;i< cards.Count;i++) { if (i = firstCard && if;i= secondCard) //每一张非第一或第二张卡都将添加到手{tempCardList.Add(卡片我);}}

如下所示:

代码语言:javascript
复制
tempCardList.AddRange(cards.Where((t, i) => i != firstCard && i != secondCard));

使用lambda语法可以缩短两种排序方法:

公共静态空sortHandbyFaceDesc(手手){ var sortCards =(从hand.Cards orderby cards.Face降序选择卡中的卡片).ToList();hand.Cards = sortCards;}公共静态空( hand) { var sortCards =(源于hand.Cards orderby cards.Face选择卡中的卡片).ToList();hand.Cards =sortCards};

如下所示:

代码语言:javascript
复制
public static void sortHandbyFaceDesc(Hand hand)
{
    hand.Cards = hand.Cards.OrderByDescending(cards => cards.Face).ToList();
}

public static void sortHandbyFace(Hand hand)
{
    hand.Cards = hand.Cards.OrderBy(cards => cards.Face).ToList();
}

使用ComparePairValue可以使CompareTo变得更短、更干净

返回face1 == face2 ?0: face1 > face2 ?1:-1;

如下所示:

代码语言:javascript
复制
return face1.CompareTo(face2);

使用lambda语法可以使FindHighestPairValuesFace缩短:

私有静态FindHighestPairValuesFace(手手){返回(从hand.Cards orderby card.Face中的卡片降/排序按面值第一组卡由新的{card.Face} }到g,让count = g.Count() orderby count降//按什么卡出现最多选择的新的{g.Key.Face}.Face).First();//first是出现最多的值对。

如下所示:

代码语言:javascript
复制
private static Face FindHighestPairValuesFace(Hand hand)
{
    return hand.Cards.OrderByDescending(card => card.Face)
        .GroupBy(card => new {card.Face})
        .Select(g => new {g, count = g.Count()})
        .OrderByDescending(t => t.count)
        .Select(t => new {t.g.Key.Face}.Face).First(); //first is highest value pair that appears the most
}

您可以在这里为您的属性使用表达式正文:

公共PokerHandsRank HandRank { get {返回CheckHandRank(此);}

如下所示:

代码语言:javascript
复制
public PokerHandsRank HandRank => CheckHandRank(this);
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/153401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档