第1部分:扑克手分类器的起源第2部分:扑克手分类器的开始第二部分
我是一个初学者程序员,致力于学习c#和面向对象,并一直致力于扑克手分类器的实践。从上半部分开始,我就扩大了我的课程范围,并做出了一些我非常希望得到反馈的决定。
注:我可能没有完成所有建议我的想法,这要么是因为我必须改变类/方法,这些想法不再有效,或者是有点超出我的能力。
甲板对象类和2手类继承手
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组手中提供最好的手。
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部分,如果您希望查看它们的逻辑,以找到所有可能的手,那么最好使用它。
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();
}
}
}主程序代码来运行控制台。
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);我在这里说的例子太多了吗?这能做得更好吗?
这很可能是我在这个项目上的最后一篇文章,因为我认为我已经达到了我进一步扩展它的能力的极限。我真诚地感谢人们对我的代码提出的所有建议。
如果你想自己运行的话。请查看第一部分和第二部分中的卡片类、枚举和检查手的等级,我认为它们应该仍然有效。
发布于 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 }
可以成为:
Array faceNames = Enum.GetValues(typeof(Face));
Array allSuits = Enum.GetValues(typeof(Suit));或者使用T[]:
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;}
可以变成一个单一的方法:
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(卡片我);}}
如下所示:
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};
如下所示:
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;
如下所示:
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是出现最多的值对。
如下所示:
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(此);}
如下所示:
public PokerHandsRank HandRank => CheckHandRank(this);https://codereview.stackexchange.com/questions/153401
复制相似问题