将Card封装起来
类中有花色和点数,继承IComparable接口,后面排序时会用到,用CompareTo方法定义排序方式。
enum EColor
{
红桃,
方片,
黑桃,
梅花,
大王,
小王
}
class Card:IComparable
{
int cardNum;
EColor cardColor;
public int CardNum { get => cardNum; set => cardNum = value; }
public EColor CardColor { get => cardColor; set => cardColor = value; }
public int CompareTo(object obj)
{
Card c = (Card)obj;
if (CardNum>c.cardNum)
{
return -1;
}
else if (CardNum < c.cardNum)
{
return 1;
}
else
{
return 0;
}
}
}
主函数中实现算法:
两个静态方法:打印Card对象的属性。 打印Card对象数组的属性。
public static void printCards(Card card)
{
Console.WriteLine(card.CardColor.ToString()+ card.CardNum);
}
public static void printCardsArr(Card[] cards)
{
for (int i = 0; i < cards.Length; i++)
{
Console.WriteLine(cards[i].CardColor.ToString()+ cards[i].CardNum);
}
}
将除了大小王以外的牌存入List中
//一副没开封的扑克
List<Card> allCards = new List<Card>();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
Card card = new();
card.CardNum = j+1;
card.CardColor = (EColor)i;
allCards.Add(card);
}
}
定义两张牌,分别是大王和小王 把这两张牌也存到list中
Card c1 = new();
Card c2= new();
c1.CardColor = (EColor)4;
c2.CardColor = (EColor)5;
allCards.Add(c1);
allCards.Add(c2);
随机从List中抽三张作为地主牌
Random rdm = new();
Card dzCard1 = allCards[rdm.Next(0, allCards.Count)];
allCards.Remove(dzCard1);
Card dzCard2 = allCards[rdm.Next(0, allCards.Count)];
allCards.Remove(dzCard2);
Card dzCard3 = allCards[rdm.Next(0, allCards.Count)];
allCards.Remove(dzCard3);
因为抽完地主牌后没人手牌是定数17张,随机将List中的牌分给三个玩家
//玩家1手牌
List<Card> player1 = new();
for (int i = 0; i < 17; i++)
{
int rdmNum = rdm.Next(0, allCards.Count);
player1.Add(allCards[rdmNum]);
allCards.Remove(allCards[rdmNum]);
}
//玩家2手牌
List<Card> player2 = new();
for (int i = 0; i < 17; i++)
{
int rdmNum = rdm.Next(0, allCards.Count);
player2.Add(allCards[rdmNum]);
allCards.Remove(allCards[rdmNum]);
}
//玩家3手牌
List<Card> player3 = new();
for (int i = 0; i < 17; i++)
{
int rdmNum = rdm.Next(0, allCards.Count);
player3.Add(allCards[rdmNum]);
allCards.Remove(allCards[rdmNum]);
}
定义一个新的List作为地主的手牌,从三个玩家中随一位当地主,把之前抽出来的地主牌分给地主
降序排好序后打印出来(排序的方式在Card类中已经写好)
List<Card> dz = new();
int rdnDzNum = rdm.Next(0, 3);
switch (rdnDzNum)
{
case 0:
dz = player1;
break;
case 1:
dz = player2;
break;
case 2:
dz = player3;
break;
}
dz.Add(dzCard1);
dz.Add(dzCard2);
dz.Add(dzCard3);
dz.Sort();
foreach (var item in dz)
{
printCards(item);
}
重头戏:判断顺子的算法
将第一张牌作为当前牌,当前的连续的牌(cc)数量是1,定义一个顺子的下标,默认先让牌组第一张牌作为顺子的第一张做判断。
遍历地主手牌,判断当前牌和遍历到的牌点数相同时直接跳过 continue ,当点数不相同时会有两个情况:
1.两张牌点数是连续的
将遍历到的牌存入顺子数组中,顺子数组的index+1 , 把这次遍历到的牌的点数作为当前牌点数与其他牌继续遍历比较 ,连续牌数量加一
2.两张牌点数不连续
顺子数组的下标归零,将当前遍历到的牌替换顺子数组中的第一张牌,顺子数组下标 +1 , 把这次遍历到的牌的点数作为当前牌点数与其他牌继续遍历比较 ,cc归为1;
当cc数量等于5时跳出循环,判断有无顺子 有的话就打印出来
int curCardNum = dz[0].CardNum;
int cc = 1;
Card[] shunzi = new Card[5];
int shunziIndex = 0;
shunzi[shunziIndex] = dz[0];
shunziIndex++;
for (int i = 1; i < dz.Count; i++)
{
if (dz[i].CardNum== curCardNum)
{
continue;
}
else
{
if (dz[i].CardNum == curCardNum - 1)
{
shunzi[shunziIndex] = dz[i];
shunziIndex++;
curCardNum = dz[i].CardNum;
cc++;
}
else
{
shunziIndex = 0;
shunzi[shunziIndex] = dz[i];
shunziIndex ++;
curCardNum = dz[i].CardNum;
cc = 1;
}
}
if (cc == 5)
{
break;
}
}
if (cc!=5)
{
Console.WriteLine("没有顺子");
}
else
{
Console.WriteLine("有顺子:");
printCardsArr(shunzi);
}