接上一篇:
https://blog.csdn.net/ylq1045/article/details/157128226
新建玩家类Player
Player.cs源程序如下:
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FiveCardStud
{
/// <summary>
/// 玩家:德州扑克玩家,最多拥有 5张牌.有五张牌时进行结算
/// </summary>
public class Player
{
public Player(string playerName, bool isDealer = false)
{
this.PlayerName = playerName;
this.IsDealer = isDealer;
this.ListCard = new List<string>();
}
/// <summary>
/// 玩家名称
/// </summary>
public string PlayerName { get; set; }
/// <summary>
/// 是否庄家,True为庄家,False为玩家
/// </summary>
public bool IsDealer { get; set; }
/// <summary>
/// 手上持有的牌
/// </summary>
public List<string> ListCard { get; set; }
public string IpAndPort { get; set; }
/// <summary>
/// 玩家手上的五张牌组成的牌型,比如是【顺子Straight】
/// </summary>
public CardCategory CurrentCardCategory
{
get
{
return CommonUtil.GetCurrentCategory(this.ListCard.ToArray());
}
}
/// <summary>
/// 按照点数,对五张扑克牌进行排序【倒序Descending】,如果点数一致,就按照黑桃♠>红心♥>梅花♣>方块♦ 排序
/// </summary>
public void Sort()
{
//按照点数,对五张扑克牌进行排序【倒序Descending】,如果点数一致,就按照黑桃♠>红心♥>梅花♣>方块♦ 排序
ListCard.Sort((x, y) =>
{
int offset = CommonUtil.Dict[y] - CommonUtil.Dict[x];
if (offset == 0)
{
//如果点数一致,就按照 黑桃♠>红心♥>梅花♣>方块♦
SuitCategory suitX = CommonUtil.GetSuitCategory(x);
SuitCategory suitY = CommonUtil.GetSuitCategory(y);
return (int)suitX - (int)suitY;
}
return offset;
});
}
/// <summary>
/// 展示玩家牌型等基本信息
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("{0}【{1}】--手上的牌:【{2}】,当前牌型:【{3}】-【{4}】", new object[]
{
this.IsDealer ? "庄家" : "玩家",
this.PlayerName,
string.Join(",", this.ListCard),
this.CurrentCardCategory,
CurrentCardCategory.GetEnumDescription()
});
}
}
}
新建部分类CommonUtil.Partial.cs
字典Dict:Key为扑克牌名称,Value为点数【为了方便进行点数比较,设定J的点数认为是11,Q的点数是12,K的点数为13,A的点数是14】
图片字典DictImage:Key为扑克牌名称,Value为图片文件名,全路径在 应用程序根目录下的pokerImg目录下。比如 ♠A黑桃 所对应的文件路径为 :pokerImg\ace_of_spades.png
CommonUtil.Partial.cs源程序如下:
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FiveCardStud
{
public partial class CommonUtil
{
/// <summary>
/// 字典:Key为扑克牌名称,Value为点数【为了方便进行点数比较,设定J的点数认为是11,Q的点数是12,K的点数为13,A的点数是14】
/// </summary>
public static Dictionary<string, int> Dict = new Dictionary<string, int>
{
{
"♠2黑桃",
2
},
{
"♠3黑桃",
3
},
{
"♠4黑桃",
4
},
{
"♠5黑桃",
5
},
{
"♠6黑桃",
6
},
{
"♠7黑桃",
7
},
{
"♠8黑桃",
8
},
{
"♠9黑桃",
9
},
{
"♠10黑桃",
10
},
{
"♠J黑桃",
11
},
{
"♠Q黑桃",
12
},
{
"♠K黑桃",
13
},
{
"♠A黑桃",
14
},
{
"♥2红心",
2
},
{
"♥3红心",
3
},
{
"♥4红心",
4
},
{
"♥5红心",
5
},
{
"♥6红心",
6
},
{
"♥7红心",
7
},
{
"♥8红心",
8
},
{
"♥9红心",
9
},
{
"♥10红心",
10
},
{
"♥J红心",
11
},
{
"♥Q红心",
12
},
{
"♥K红心",
13
},
{
"♥A红心",
14
},
{
"♣2梅花",
2
},
{
"♣3梅花",
3
},
{
"♣4梅花",
4
},
{
"♣5梅花",
5
},
{
"♣6梅花",
6
},
{
"♣7梅花",
7
},
{
"♣8梅花",
8
},
{
"♣9梅花",
9
},
{
"♣10梅花",
10
},
{
"♣J梅花",
11
},
{
"♣Q梅花",
12
},
{
"♣K梅花",
13
},
{
"♣A梅花",
14
},
{
"♦2方块",
2
},
{
"♦3方块",
3
},
{
"♦4方块",
4
},
{
"♦5方块",
5
},
{
"♦6方块",
6
},
{
"♦7方块",
7
},
{
"♦8方块",
8
},
{
"♦9方块",
9
},
{
"♦10方块",
10
},
{
"♦J方块",
11
},
{
"♦Q方块",
12
},
{
"♦K方块",
13
},
{
"♦A方块",
14
}
};
/// <summary>
/// 图片字典:Key为扑克牌名称,Value为图片文件名,全路径在 应用程序根目录下的pokerImg目录下
/// 比如 ♠A黑桃 所对应的文件路径为 :pokerImg\ace_of_spades.png
/// </summary>
public static Dictionary<string, string> DictImage = new Dictionary<string, string>
{
{
"♠A黑桃",
"ace_of_spades.png"
},
{
"♠2黑桃",
"2_of_spades.png"
},
{
"♠3黑桃",
"3_of_spades.png"
},
{
"♠4黑桃",
"4_of_spades.png"
},
{
"♠5黑桃",
"5_of_spades.png"
},
{
"♠6黑桃",
"6_of_spades.png"
},
{
"♠7黑桃",
"7_of_spades.png"
},
{
"♠8黑桃",
"8_of_spades.png"
},
{
"♠9黑桃",
"9_of_spades.png"
},
{
"♠10黑桃",
"10_of_spades.png"
},
{
"♠J黑桃",
"jack_of_spades.png"
},
{
"♠Q黑桃",
"queen_of_spades.png"
},
{
"♠K黑桃",
"king_of_spades.png"
},
{
"♥A红心",
"ace_of_hearts.png"
},
{
"♥2红心",
"2_of_hearts.png"
},
{
"♥3红心",
"3_of_hearts.png"
},
{
"♥4红心",
"4_of_hearts.png"
},
{
"♥5红心",
"5_of_hearts.png"
},
{
"♥6红心",
"6_of_hearts.png"
},
{
"♥7红心",
"7_of_hearts.png"
},
{
"♥8红心",
"8_of_hearts.png"
},
{
"♥9红心",
"9_of_hearts.png"
},
{
"♥10红心",
"10_of_hearts.png"
},
{
"♥J红心",
"jack_of_hearts.png"
},
{
"♥Q红心",
"queen_of_hearts.png"
},
{
"♥K红心",
"king_of_hearts.png"
},
{
"♣A梅花",
"ace_of_clubs.png"
},
{
"♣2梅花",
"2_of_clubs.png"
},
{
"♣3梅花",
"3_of_clubs.png"
},
{
"♣4梅花",
"4_of_clubs.png"
},
{
"♣5梅花",
"5_of_clubs.png"
},
{
"♣6梅花",
"6_of_clubs.png"
},
{
"♣7梅花",
"7_of_clubs.png"
},
{
"♣8梅花",
"8_of_clubs.png"
},
{
"♣9梅花",
"9_of_clubs.png"
},
{
"♣10梅花",
"10_of_clubs.png"
},
{
"♣J梅花",
"jack_of_clubs.png"
},
{
"♣Q梅花",
"queen_of_clubs.png"
},
{
"♣K梅花",
"king_of_clubs.png"
},
{
"♦A方块",
"ace_of_diamonds.png"
},
{
"♦2方块",
"2_of_diamonds.png"
},
{
"♦3方块",
"3_of_diamonds.png"
},
{
"♦4方块",
"4_of_diamonds.png"
},
{
"♦5方块",
"5_of_diamonds.png"
},
{
"♦6方块",
"6_of_diamonds.png"
},
{
"♦7方块",
"7_of_diamonds.png"
},
{
"♦8方块",
"8_of_diamonds.png"
},
{
"♦9方块",
"9_of_diamonds.png"
},
{
"♦10方块",
"10_of_diamonds.png"
},
{
"♦J方块",
"jack_of_diamonds.png"
},
{
"♦Q方块",
"queen_of_diamonds.png"
},
{
"♦K方块",
"king_of_diamonds.png"
}
};
}
}
新建关键部分类CommonUtil.cs
关键方法:
public static Tuple<int, string> CompareCard(Player player1, Player player2):
两个玩家进行扑克牌大小比较【先进行牌型比较】。元组的第一个元素为1代表玩家一赢,为2代表玩家二赢
public static CardCategory GetCurrentCategory(string[] pokers):
获取玩家手中的五张牌组合而成的牌型 按照点数,对五张扑克牌进行排序【倒序Descending】,如果点数一致,就按照黑桃♠>红心♥>梅花♣>方块♦ 排序。 排序后,如果是相同点数的牌一定是相邻的
CommonUtil.cs源程序如下:
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FiveCardStud
{
public partial class CommonUtil
{
/// <summary>
/// 获取玩家手中的五张牌组合而成的牌型
/// 按照点数,对五张扑克牌进行排序【倒序Descending】,如果点数一致,就按照黑桃♠>红心♥>梅花♣>方块♦ 排序
/// 排序后,如果是相同点数的牌一定是相邻的
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static CardCategory GetCurrentCategory(string[] pokers)
{
if (pokers == null || pokers.Length != 5)
{
Console.WriteLine("德州扑克需要五张牌...");
return CardCategory.Unknown;
}
//按照点数,对五张扑克牌进行排序【倒序Descending】,如果点数一致,就按照黑桃♠>红心♥>梅花♣>方块♦ 排序
Array.Sort(pokers, (x, y) =>
{
int offset = Dict[y] - Dict[x];
if (offset == 0)
{
//如果点数一致,就按照 黑桃♠>红心♥>梅花♣>方块♦
SuitCategory suitX = GetSuitCategory(x);
SuitCategory suitY = GetSuitCategory(y);
return (int)suitX - (int)suitY;
}
return offset;
});
//对已排序的五张牌进行处理,相同点数的牌一定是相邻的
bool isFlush = IsFlush(pokers);
bool isStraight = IsStraight(pokers);
bool isFourKind = IsFourKind(pokers);
bool isFullHouse = IsFullHouse(pokers);
bool isThreeKind = IsThreeKind(pokers);
bool isTwoPairs = IsTwoPairs(pokers);
bool isOnePair = IsOnePair(pokers);
if (isFlush && isStraight)
{
//同花顺:同花 并且 顺子
return CardCategory.StraightFlush;
}
else if (isFourKind)
{
return CardCategory.FourOfKind;
}
else if (isFullHouse)
{
return CardCategory.FullHouse;
}
else if (isFlush)
{
return CardCategory.Flush;
}
else if (isStraight)
{
return CardCategory.Straight;
}
else if (isThreeKind)
{
return CardCategory.ThreeOfKind;
}
else if (isTwoPairs)
{
return CardCategory.TwoPairs;
}
else if (isOnePair)
{
return CardCategory.OnePair;
}
return CardCategory.HighCard;
}
/// <summary>
/// 玩家手上的五张牌组成的牌型
/// </summary>
/// <param name="player"></param>
/// <returns></returns>
public static CardCategory GetCurrentCategory(Player player)
{
return GetCurrentCategory(player.ListCard.ToArray());
}
/// <summary>
/// 玩家进行比较,然后按照牌的牌型,点数进行从大到小排序
/// </summary>
/// <param name="players"></param>
public static void CompareCardAndSort(List<Player> players)
{
players.Sort((x, y) => CompareCard(x, y).Item1 == 1 ? -1 : 1);
}
/// <summary>
/// 两个玩家进行扑克牌大小比较【先进行牌型比较】
/// 元组的第一个元素为1代表玩家一赢,为2代表玩家二赢
/// </summary>
/// <param name="player1"></param>
/// <param name="player2"></param>
/// <returns></returns>
public static Tuple<int, string> CompareCard(Player player1, Player player2)
{
CardCategory cardCategory1 = GetCurrentCategory(player1);
CardCategory cardCategory2 = GetCurrentCategory(player2);
if (cardCategory1 == CardCategory.Unknown || cardCategory2 == CardCategory.Unknown)
{
throw new Exception($"玩家一或者玩家二尚未有五张牌");
}
string msg = $"玩家1【{player1.PlayerName}】的牌型是【{cardCategory1}】-【{cardCategory1.GetEnumDescription()}】,玩家2【{player2.PlayerName}】的牌型是【{cardCategory2}】-【{cardCategory2.GetEnumDescription()}】.";
string win1 = $"{msg}玩家1【{player1.PlayerName}】赢";
string win2 = $"{msg}玩家2【{player2.PlayerName}】赢";
int compareValue = cardCategory2 - cardCategory1;//枚举相减,就类似于 整数的减法运算
if (compareValue == 0)
{
//如果牌型一致,就对牌进行排序
player1.Sort();
player2.Sort();
switch (cardCategory1)
{
case CardCategory.StraightFlush:
case CardCategory.Flush:
case CardCategory.Straight:
case CardCategory.HighCard:
//同花顺: 比较最大的一张牌的点数,如果点数一致,就比较花色
//同花: 比较最大的一张牌的点数,如果点数一致,就比较花色
//顺子: 比较最大的一张牌的点数,如果点数一致,就比较花色
//高牌: 比较最大的一张牌的点数,如果点数一致,就比较花色
int point1 = Dict[player1.ListCard[0]];
int point2 = Dict[player2.ListCard[0]];
SuitCategory suit1 = GetSuitCategory(player1.ListCard[0]);
SuitCategory suit2 = GetSuitCategory(player2.ListCard[0]);
if (point1 == point2)
{
if (suit1 - suit2 < 0)
{
return Tuple.Create(1, win1);
}
else
{
return Tuple.Create(2, win2);
}
}
return Tuple.Create(point1 > point2 ? 1 : 2, point1 > point2 ? win1 : win2);
case CardCategory.FourOfKind:
//【四条】,有ABBBB或者AAAAB,判断 炸弹的点数,第三个一定是炸弹的点数,比较点数即可
point1 = Dict[player1.ListCard[2]];
point2 = Dict[player2.ListCard[2]];
return Tuple.Create(point1 > point2 ? 1 : 2, point1 > point2 ? win1 : win2);
case CardCategory.FullHouse:
//【葫芦、满堂红】,有AABBB或者 AAABB
point1 = Dict[player1.ListCard[2]];
point2 = Dict[player2.ListCard[2]];
return Tuple.Create(point1 > point2 ? 1 : 2, point1 > point2 ? win1 : win2);
case CardCategory.ThreeOfKind:
//【三条】,有AAABC或者 ABBBC 或者ABCCC
point1 = Dict[player1.ListCard[2]];
point2 = Dict[player2.ListCard[2]];
return Tuple.Create(point1 > point2 ? 1 : 2, point1 > point2 ? win1 : win2);
case CardCategory.TwoPairs:
//【两对】,先比较对子,如果两个对子的点数都一样,就比较杂牌
return CompareTwoPairs(player1, player2, win1, win2);
case CardCategory.OnePair:
//【对子】有一对,先比较对子的点数,如果点数一致,就比较杂牌
GetIndexFromOnePair(player1, out int pairIndex1, out int highCardIndex1);
GetIndexFromOnePair(player2, out int pairIndex2, out int highCardIndex2);
point1 = Dict[player1.ListCard[pairIndex1]];//对子点数
point2 = Dict[player2.ListCard[pairIndex2]];//对子点数
int pointHigh1 = Dict[player1.ListCard[highCardIndex1]];//高牌点数
int pointHigh2 = Dict[player2.ListCard[highCardIndex2]];//高牌点数
suit1 = GetSuitCategory(player1.ListCard[highCardIndex1]);//高牌花色
suit2 = GetSuitCategory(player2.ListCard[highCardIndex2]);//高牌花色
if (point1 == point2)
{
if (pointHigh1 == pointHigh2)
{
if (suit1 - suit2 < 0)
{
return Tuple.Create(1, win1);
}
else
{
return Tuple.Create(2, win2);
}
}
return Tuple.Create(pointHigh1 > pointHigh2 ? 1 : 2, pointHigh1 > pointHigh2 ? win1 : win2);
}
return Tuple.Create(point1 > point2 ? 1 : 2, point1 > point2 ? win1 : win2);
default:
throw new Exception($"玩家一或者玩家二尚未有五张牌");
}
}
else if (compareValue < 0)
{
return Tuple.Create(2, win2);
}
else
{
return Tuple.Create(1, win1);
}
}
/// <summary>
/// 两个对子进行比较:先比较较大的对子,再比较较小的对子。如果两个对子的点数都一样,就比较杂牌
/// </summary>
/// <param name="player1"></param>
/// <param name="player2"></param>
/// <returns></returns>
private static Tuple<int, string> CompareTwoPairs(Player player1, Player player2, string win1, string win2)
{
GetIndexFromTwoPairs(player1, out int pairIndexFirst1, out int pairIndexSecond1, out int highCardIndex1);
GetIndexFromTwoPairs(player2, out int pairIndexFirst2, out int pairIndexSecond2, out int highCardIndex2);
int pointFirst1 = Dict[player1.ListCard[pairIndexFirst1]];//大对子点数
int pointFirst2 = Dict[player2.ListCard[pairIndexFirst2]];//大对子点数
int pointSecond1 = Dict[player1.ListCard[pairIndexSecond1]];//小对子点数
int pointSecond2 = Dict[player2.ListCard[pairIndexSecond2]];//小对子点数
int pointHigh1 = Dict[player1.ListCard[highCardIndex1]];//高牌点数
int pointHigh2 = Dict[player2.ListCard[highCardIndex2]];//高牌点数
SuitCategory suit1 = GetSuitCategory(player1.ListCard[highCardIndex1]);//高牌花色
SuitCategory suit2 = GetSuitCategory(player2.ListCard[highCardIndex2]);//高牌花色
if (pointFirst1 == pointFirst2)
{
if (pointSecond1 == pointSecond2)
{
if (pointHigh1 == pointHigh2)
{
if (suit1 - suit2 < 0)
{
return Tuple.Create(1, win1);
}
else
{
return Tuple.Create(2, win2);
}
}
return Tuple.Create(pointHigh1 > pointHigh2 ? 1 : 2, pointHigh1 > pointHigh2 ? win1 : win2);
}
return Tuple.Create(pointSecond1 > pointSecond2 ? 1 : 2, pointSecond1 > pointSecond2 ? win1 : win2);
}
return Tuple.Create(pointFirst1 > pointFirst2 ? 1 : 2, pointFirst1 > pointFirst2 ? win1 : win2);
}
/// <summary>
/// 从两对【已排序完成】中,找出 第一个对子对应的数组索引,第二个对子对应的数组索引 以及 剩余的高牌索引
/// </summary>
/// <param name="player"></param>
/// <param name="pairIndexFirst"></param>
/// <param name="pairIndexSecond"></param>
/// <param name="highCardIndex"></param>
private static void GetIndexFromTwoPairs(Player player, out int pairIndexFirst, out int pairIndexSecond, out int highCardIndex)
{
pairIndexFirst = -1;
pairIndexSecond = -1;
highCardIndex = -1;
List<int> pairIndexList = new List<int>();//所有对子的索引
//找出第一个较大的对子 的索引
for (int i = 0; i < 4; i++)
{
if (Dict[player.ListCard[i]] == Dict[player.ListCard[i + 1]])
{
pairIndexFirst = i;
pairIndexList.AddRange(new int[] { pairIndexFirst, pairIndexFirst + 1 });
break;
}
}
//找出第二个对子 的索引
for (int i = pairIndexFirst + 1; i < 4; i++)
{
if (Dict[player.ListCard[i]] == Dict[player.ListCard[i + 1]])
{
pairIndexSecond = i;
pairIndexList.AddRange(new int[] { pairIndexSecond, pairIndexSecond + 1 });
break;
}
}
//找出高牌【杂牌】 的索引:去除两个对子的索引,剩下的就是高牌
for (int i = 0; i < 5; i++)
{
if (!pairIndexList.Contains(i))
{
highCardIndex = i;
break;
}
}
}
/// <summary>
/// 从单个对子【已排序完成】中,找出 对子对应的数组索引 以及 最大的高牌索引
/// </summary>
/// <param name="player"></param>
/// <param name="pairIndex"></param>
/// <param name="highCardIndex"></param>
private static void GetIndexFromOnePair(Player player, out int pairIndex, out int highCardIndex)
{
pairIndex = -1;
highCardIndex = -1;
for (int i = 0; i < 4; i++)
{
if (Dict[player.ListCard[i]] == Dict[player.ListCard[i + 1]])
{
pairIndex = i;
if (pairIndex == 0)
{
highCardIndex = 2;//对子 AABCD
}
else
{
highCardIndex = 0;//ABBCD 或 ABCCD 或 ABCDD
}
break;
}
}
}
/// <summary>
/// 是否同花,比如 五张牌都是 红心♥
/// 五张牌 全都是 四种花色【黑桃♠,红心♥,梅花♣,方块♦】中的同一种
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsFlush(string[] pokers)
{
SuitCategory suit1 = GetSuitCategory(pokers[0]);
SuitCategory suit2 = GetSuitCategory(pokers[1]);
SuitCategory suit3 = GetSuitCategory(pokers[2]);
SuitCategory suit4 = GetSuitCategory(pokers[3]);
SuitCategory suit5 = GetSuitCategory(pokers[4]);
return suit1 == suit2 && suit2 == suit3 && suit3 == suit4 && suit4 == suit5;
}
/// <summary>
/// 是否顺子,点数连续
/// 点数:相邻的五个为顺子,比如:"Q", "J", "10", "9", "8"
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsStraight(string[] pokers)
{
for (int i = 0; i < pokers.Length - 1; i++)
{
if (Dict[pokers[i]] - Dict[pokers[i + 1]] != 1)
{
return false;
}
}
return true;
}
/// <summary>
/// 是否四条 【四条】,也叫铁支,炸弹,有4张相邻的牌点数相同
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsFourKind(string[] pokers)
{
return (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]])
|| (Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]]);
}
/// <summary>
/// 是否【葫芦、满堂红】3张点数相同的牌,并且 加上一对子。
/// 即排序后的五张牌点数为 AAA BB 或者 AA BBB
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsFullHouse(string[] pokers)
{
return (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] != Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]])
|| (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] != Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]]);
}
/// <summary>
/// 【三条】有3张点数相同的牌 AAABC或者 ABBBC 或者 ABCCC
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsThreeKind(string[] pokers)
{
return (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] != Dict[pokers[3]] && Dict[pokers[3]] != Dict[pokers[4]])
|| (Dict[pokers[0]] != Dict[pokers[1]] && Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]] && Dict[pokers[3]] != Dict[pokers[4]])
|| (Dict[pokers[0]] != Dict[pokers[1]] && Dict[pokers[1]] != Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]]);
}
/// <summary>
/// 【两对】有两对点数一样的牌,加1张杂牌。AABBC 或者 AABCC 或者 ABBCC
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsTwoPairs(string[] pokers)
{
return (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] != Dict[pokers[2]] && Dict[pokers[2]] == Dict[pokers[3]] && Dict[pokers[3]] != Dict[pokers[4]])
|| (Dict[pokers[0]] == Dict[pokers[1]] && Dict[pokers[1]] != Dict[pokers[2]] && Dict[pokers[2]] != Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]])
|| (Dict[pokers[0]] != Dict[pokers[1]] && Dict[pokers[1]] == Dict[pokers[2]] && Dict[pokers[2]] != Dict[pokers[3]] && Dict[pokers[3]] == Dict[pokers[4]]);
}
/// <summary>
/// 只有一对,加3张杂牌组成。五张牌按点数分组,可以分成四组【肯定有两张牌点数一样】
/// </summary>
/// <param name="pokers"></param>
/// <returns></returns>
public static bool IsOnePair(string[] pokers)
{
IEnumerable<IGrouping<int, string>> groups = pokers.GroupBy(element => Dict[element]);
if (groups.Count() == 4)
{
return groups.ToList().Exists(x => x.Count() == 2);
}
return false;
}
/// <summary>
/// 获取当前扑克牌对应的花色,【黑桃♠,红心♥,梅花♣,方块♦】中的一种
/// </summary>
/// <param name="poker"></param>
/// <returns></returns>
public static SuitCategory GetSuitCategory(string poker)
{
if (poker == null || poker.Length == 0)
{
throw new ArgumentException("当前扑克牌不能为空");
}
char suit = poker[0];
switch (suit)
{
case '♠':
return SuitCategory.Spade;
case '♥':
return SuitCategory.Heart;
case '♣':
return SuitCategory.Club;
case '♦':
return SuitCategory.Diamond;
default:
return SuitCategory.None;
}
}
}
}
展示扑克图片的辅助类:ShowImageUtil
ShowImageUtil源程序如下:
cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace FiveCardStud
{
public class ShowImageUtil
{
/// <summary>
/// 显示五张牌的扑克图片到面板Panel中
/// </summary>
/// <param name="player"></param>
/// <param name="form"></param>
/// <param name="pnlPoker"></param>
public static void DisplayPokerImage(Player player, Form form, Panel pnlPoker)
{
if (!form.IsHandleCreated)
{
return;
}
form.BeginInvoke(new Action(delegate ()
{
pnlPoker.Controls.Clear();
int pokerCount = player.ListCard.Count;
int rowCount = (pokerCount + 4) / 5;
for (int i = 0; i < rowCount; i++)
{
if (5 * i < pokerCount)
{
string joker = player.ListCard[5 * i];
AddPicture(0, 190 * i, CommonUtil.DictImage[joker], pnlPoker);
}
if (5 * i + 1 < pokerCount)
{
string joker2 = player.ListCard[5 * i + 1];
ShowImageUtil.AddPicture(130, 190 * i, CommonUtil.DictImage[joker2], pnlPoker);
}
if (5 * i + 2 < pokerCount)
{
string joker3 = player.ListCard[5 * i + 2];
AddPicture(260, 190 * i, CommonUtil.DictImage[joker3], pnlPoker);
}
if (5 * i + 3 < pokerCount)
{
string joker4 = player.ListCard[5 * i + 3];
ShowImageUtil.AddPicture(390, 190 * i, CommonUtil.DictImage[joker4], pnlPoker);
}
if (5 * i + 4 < pokerCount)
{
string joker5 = player.ListCard[5 * i + 4];
AddPicture(520, 190 * i, CommonUtil.DictImage[joker5], pnlPoker);
}
}
}));
}
/// <summary>
/// 增加一个图片
/// </summary>
/// <param name="xPoint"></param>
/// <param name="yPoint"></param>
/// <param name="fileName"></param>
/// <param name="pnlPoker"></param>
public static void AddPicture(int xPoint, int yPoint, string fileName, Panel pnlPoker)
{
PictureBox pb = new PictureBox();
pb.Name = fileName;
pb.Size = new Size(125, 182);
pb.Location = new Point(xPoint, yPoint);
pb.Image = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "pokerImg\\" + fileName);
pb.SizeMode = PictureBoxSizeMode.Zoom;
pnlPoker.Controls.Add(pb);
}
}
}
窗体FormFiveCardStudEx设计器如下:
文件FormFiveCardStudEx.Designer.cs
cs
using System.Drawing;
using System.Windows.Forms;
namespace FiveCardStud
{
partial class FormFiveCardStudEx
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.rtxtDisplay = new System.Windows.Forms.RichTextBox();
this.pnlPoker1 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.pnlPoker2 = new System.Windows.Forms.Panel();
this.pnlPoker3 = new System.Windows.Forms.Panel();
this.pnlPoker4 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// rtxtDisplay
//
this.rtxtDisplay.Location = new System.Drawing.Point(8, 6);
this.rtxtDisplay.Name = "rtxtDisplay";
this.rtxtDisplay.ReadOnly = true;
this.rtxtDisplay.Size = new System.Drawing.Size(593, 815);
this.rtxtDisplay.TabIndex = 0;
this.rtxtDisplay.Text = "";
//
// pnlPoker1
//
this.pnlPoker1.Location = new System.Drawing.Point(758, 2);
this.pnlPoker1.Name = "pnlPoker1";
this.pnlPoker1.Size = new System.Drawing.Size(660, 195);
this.pnlPoker1.TabIndex = 16;
//
// button1
//
this.button1.Font = new System.Drawing.Font("宋体", 13F);
this.button1.Location = new System.Drawing.Point(624, 178);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(101, 35);
this.button1.TabIndex = 17;
this.button1.Text = "刷新";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// pnlPoker2
//
this.pnlPoker2.Location = new System.Drawing.Point(758, 210);
this.pnlPoker2.Name = "pnlPoker2";
this.pnlPoker2.Size = new System.Drawing.Size(660, 195);
this.pnlPoker2.TabIndex = 17;
//
// pnlPoker3
//
this.pnlPoker3.Location = new System.Drawing.Point(758, 418);
this.pnlPoker3.Name = "pnlPoker3";
this.pnlPoker3.Size = new System.Drawing.Size(660, 195);
this.pnlPoker3.TabIndex = 18;
//
// pnlPoker4
//
this.pnlPoker4.Location = new System.Drawing.Point(758, 626);
this.pnlPoker4.Name = "pnlPoker4";
this.pnlPoker4.Size = new System.Drawing.Size(660, 195);
this.pnlPoker4.TabIndex = 18;
//
// FormFiveCardStudEx
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1436, 847);
this.Controls.Add(this.pnlPoker4);
this.Controls.Add(this.pnlPoker3);
this.Controls.Add(this.pnlPoker2);
this.Controls.Add(this.button1);
this.Controls.Add(this.pnlPoker1);
this.Controls.Add(this.rtxtDisplay);
this.Name = "FormFiveCardStudEx";
this.Text = "斯内科---德州扑克【梭哈】游戏";
this.Load += new System.EventHandler(this.FormFiveCardStudEx_Load);
this.ResumeLayout(false);
}
#endregion
private RichTextBox rtxtDisplay;
private Panel pnlPoker1;
private Panel pnlPoker2;
private Panel pnlPoker3;
private Panel pnlPoker4;
private Button button1;
}
}
FormFiveCardStudEx测试代码如下:
文件FormFiveCardStudEx.cs
cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FiveCardStud
{
public partial class FormFiveCardStudEx : Form
{
public FormFiveCardStudEx()
{
InitializeComponent();
}
/// <summary>
/// 显示消息
/// </summary>
/// <param name="addContent"></param>
private void DisplayContent(string addContent)
{
if (!IsHandleCreated)
{
return;
}
if (InvokeRequired)
{
Action<string> actionUpd = new Action<string>(this.DisplayContentEx);
actionUpd.BeginInvoke(addContent, null, null);
}
else
{
this.DisplayContentEx(addContent);
}
}
public void DisplayContentEx(string addContent)
{
Invoke(new MethodInvoker(delegate ()
{
if (this.rtxtDisplay.TextLength >= 10240)
{
this.rtxtDisplay.Clear();
}
this.rtxtDisplay.AppendText(addContent + "\n");
this.rtxtDisplay.ScrollToCaret();
}));
}
private void FormFiveCardStudEx_Load(object sender, EventArgs e)
{
FiveCardStudUtil.Init();
Player player1 = new Player("斯内科");
Player player2 = new Player("富饶格");
Player player3 = new Player("曹孟德");
Player player4 = new Player("刘玄德");
for (int i = 0; i < 5; i++)
{
FiveCardStudUtil.DealCard(player1);
FiveCardStudUtil.DealCard(player2);
FiveCardStudUtil.DealCard(player3);
FiveCardStudUtil.DealCard(player4);
}
player1.Sort();
player2.Sort();
player3.Sort();
player4.Sort();
DisplayContent(player1.ToString());
DisplayContent(player2.ToString());
DisplayContent(player3.ToString());
DisplayContent(player4.ToString());
ShowImageUtil.DisplayPokerImage(player1, this, pnlPoker1);
ShowImageUtil.DisplayPokerImage(player2, this, pnlPoker2);
ShowImageUtil.DisplayPokerImage(player3, this, pnlPoker3);
ShowImageUtil.DisplayPokerImage(player4, this, pnlPoker4);
List<Player> players = new List<Player>() { player1, player2, player3, player4 };
CommonUtil.CompareCardAndSort(players);
DisplayContent($"【{players.Count}】位玩家的牌型与点数从大到小排序为:");
for (int i = 0; i < players.Count; i++)
{
DisplayContent($"【{players[i].PlayerName}】,牌型为【{players[i].CurrentCardCategory}】-【{players[i].CurrentCardCategory.GetEnumDescription()}】");
}
}
private void button1_Click(object sender, EventArgs e)
{
FormFiveCardStudEx_Load(null, null);
}
}
}
运行如图:
