C# i可比较且有序。尝试用C对扑克手进行排序#
我试图创建一个简单的程序来分析扑克牌。考虑到n手牌/玩家和社区卡(德克萨斯州持有),我想确定赢家。然而,当我有两个确切的结果时,我的测试失败了——它只返回一个获胜者。i、 e对于两位选手,手牌结果都包含J 9 K,但我的获奖名单包含一个 我在这里发帖有几个原因。显然,首先,这里有什么明显的错误吗?这是一种实现排序的好方法吗(我看不出将排序分开的原因),有更好的方法吗?为什么 我有一个DetermineWinners方法,它对玩家的HandResult执行命令:C# i可比较且有序。尝试用C对扑克手进行排序#,c#,poker,icomparer,C#,Poker,Icomparer,我试图创建一个简单的程序来分析扑克牌。考虑到n手牌/玩家和社区卡(德克萨斯州持有),我想确定赢家。然而,当我有两个确切的结果时,我的测试失败了——它只返回一个获胜者。i、 e对于两位选手,手牌结果都包含J 9 K,但我的获奖名单包含一个 我在这里发帖有几个原因。显然,首先,这里有什么明显的错误吗?这是一种实现排序的好方法吗(我看不出将排序分开的原因),有更好的方法吗?为什么 我有一个DetermineWinners方法,它对玩家的HandResult执行命令: var ordered = _pl
var ordered = _players.OrderByDescending(player => player.Result);
var bestHand = ordered.First();
var winners = ordered.Where(s => s.Result == bestHand.Result).ToList();
这是我的手工成绩课:
public class HandResult : IComparable<HandResult>
{
public Hand WholeCards { get; set; }
public HandRanking HandRank { get; set; }
public IEnumerable<Card> CommunityCards { get; set; }
public IEnumerable<Card> UsedCards { get; set; }
public static bool operator !=(HandResult a, HandResult b)
{
if (a == null)
return b != null;
if (b == null)
return true;
if (a.HandRank != b.HandRank)
return true;
//Compare Used Cards
var aCards = a.UsedCards.Select(s => s.GetCardValue()).ToList();
var bCards = b.UsedCards.Select(s => s.GetCardValue()).ToList();
var cardGroup = a.HandRank.GetGrouping();
for (int i = 0; i < 5; i += cardGroup[i])
{
if (aCards[i] != bCards[i])
return true;
}
return false;
}
public static bool operator ==(HandResult a, HandResult b)
{
if ((object)a == null)
return (object)b == null;
if ((object)b == null)
return false;
if (a.HandRank != b.HandRank)
return false;
var aCards = a.UsedCards.Select(s => s.GetCardValue()).ToList();
var bCards = b.UsedCards.Select(s => s.GetCardValue()).ToList();
var cardGroup = a.HandRank.GetGrouping();
for (int i = 0; i < 5; i += cardGroup[i])
{
if (aCards[i] != bCards[i])
{
return false;
}
}
return true;
}
public static bool operator >(HandResult a, HandResult b)
{
if ((object)a == null)
return (object)b != null;
if ((object)b == null)
return false;
if ((object)a == (object)b)
return false;
if (a.HandRank != b.HandRank)
return a.HandRank > b.HandRank;
if (a == b)
return false;
var aCards = a.UsedCards.Select(s => s.GetCardValue()).ToList();
var bCards = b.UsedCards.Select(s => s.GetCardValue()).ToList();
var cardGroup = a.HandRank.GetGrouping();
for (int i = 0; i < 5; i += cardGroup[i])
{
if (aCards[i] != bCards[i])
{
return aCards[i] > bCards[i];
}
}
return false;
}
public static bool operator <(HandResult a, HandResult b)
{
if ((object)a == null)
return (object)b == null;
if ((object)b == null)
return true;
if ((object)a == (object)b)
return false;
if (a.HandRank != b.HandRank)
return a.HandRank < b.HandRank;
var aCards = a.UsedCards.Select(s => s.GetCardValue()).ToList();
var bCards = b.UsedCards.Select(s => s.GetCardValue()).ToList();
var cardGroup = a.HandRank.GetGrouping();
for (int i = 0; i < 5; i += cardGroup[i])
{
if (aCards[i] != bCards[i])
return aCards[i] < bCards[i];
}
return false;
}
#region IComparable<HandResult> Members
public int CompareTo(HandResult other)
{
if (this == null)
return other == null ? 0 : -1;
if (other == null)
return 1;
if (this == other)
return 0;
if (this > other)
return 1;
return -1;
}
#endregion
public override bool Equals(object obj)
{
return this == (HandResult)obj;
}
public override int GetHashCode()
{
var result = 0;
result = (result * 397) ^ (int)this.HandRank;
foreach (var card in this.UsedCards)
{
result = (result * 397) ^ card.GetHashCode();
}
return result;
}
}
这是HandRanking枚举上的GetGrouping扩展。它用于在比较值时帮助迭代卡片:
internal static int[] GetGrouping(this HandRanking rank)
{
switch (rank)
{
case HandRanking.Pair:
return new int[] { 2, 0, 1, 1, 1 };
case HandRanking.TwoPair:
return new int[] { 2, 0, 2, 0, 1 };
case HandRanking.ThreeOfAKind:
return new int[] { 3, 0, 0, 1, 1 };
case HandRanking.FullHouse:
return new int[] { 3, 0, 0, 2, 0 };
case HandRanking.FourOfAKind:
return new int[] { 4, 0, 0, 0, 1 };
default:
return new int[] { 1, 1, 1, 1, 1 };
}
}
非常感谢你的帮助
编辑:我对CompareTo_Equal、CompareTo_LessThan和CompareTo_GreateThan(使用我的运算符重载)的测试成功,结果分别为0、-1和1。我相信这是我的Linq.OrderByDescending实现的问题。我认为这只是使用比较来实现,我错了吗?由
IComparable
提供的比较(无论如何,您应该使用通用版本IComparable
)仅通过接口方法int CompareTo(IComparable other)
表示,其结果是
-
如果当前对象大于
other
- <0如果当前对象小于
other
- =0表示相等
重载的比较运算符对于依赖于
IComparable
的任何代码都不重要。您正试图通过选择结果与最佳手的结果相同的代码来选择赢家,但只有当手完全相同时才是如此(我想,在不知道cardGroup[I]到底是什么的情况下,我很难看到整个画面
你确定你期望的完全相同的手实际上是完全相同的(甚至在同一套衣服里)
然后我还建议您根据其他运算符实现大多数运算符重载。例如!=可以实现为!(=)(反转调用==运算符的结果,而不是重新实现整个条件集-现在,如果更改确定等于的方式,则必须在中复制这些更改!)谢谢您的回复!我似乎没有正确粘贴代码。我编辑了我的帖子以反映完整的HandResult类,我还使用了IComparable的通用版本。也就是说,我的测试仍然失败。我在键入答案时看到您的原始代码被编辑,但我恐怕现在没有时间查看它和upda请依次回答我的问题。感谢您的回答。很抱歉,代码编辑之前没有全部内容。是的,赢家是由拥有最佳手牌的玩家决定的。我已覆盖.Equals和==运算符以检查牌的值,因此它不包括套件。cardGroup[I]只有当HandRank相同时,节才会命中,在这种情况下,它将遍历值,并在构成手牌的5张卡上进行比较。
internal static int[] GetGrouping(this HandRanking rank)
{
switch (rank)
{
case HandRanking.Pair:
return new int[] { 2, 0, 1, 1, 1 };
case HandRanking.TwoPair:
return new int[] { 2, 0, 2, 0, 1 };
case HandRanking.ThreeOfAKind:
return new int[] { 3, 0, 0, 1, 1 };
case HandRanking.FullHouse:
return new int[] { 3, 0, 0, 2, 0 };
case HandRanking.FourOfAKind:
return new int[] { 4, 0, 0, 0, 1 };
default:
return new int[] { 1, 1, 1, 1, 1 };
}
}