2016-09-22 51 views
8

我想在c#中编写一个扑克手评估方法。我已经设法为每个使用LINQ的扑克手执行此操作,除了直线。 对于那些不玩直板的玩家来说,每张卡片由5张卡片组成,每张卡片增量为1。 Ace可以高或低。c#直接检查扑克

我已经创建了一个名为卡的对象,它具有套装,等级和值(J = 11,Q = 12等)。我的方法将被传递含7卡的这个对象的列表(孔卡和主板。)

另一件事要记住的是,如果玩家有5或10

只能做成直

查看下面我的其他扑克手的方法,请让我知道,如果你有一个直接的方法的想法。伪代码也可以。


public bool CheckPair(List<Card> cards) 
{ 
    //see if exactly 2 cards card the same rank. 
    return cards.GroupBy(card => card.Rank).Count(group => group.Count() == 2) == 1; 
} 

public bool CheckTwoPair(List<Card> cards) 
{ 
    //see if there are 2 lots of exactly 2 cards card the same rank. 
    return cards.GroupBy(card => card.Rank).Count(group => group.Count() >= 2) == 2; 
} 

public bool CheckTrips(List<Card> cards) 
{ 
    //see if exactly 3 cards card the same rank. 
    return cards.GroupBy(card => card.Rank).Any(group => group.Count() == 3); 
} 
public bool CheckStraight(List<Card> cards) 
{ 
    // order by decending to see order 
    var cardsInOrder = cards.OrderByDescending(a => a.Value).ToList(); 
    // check for ace as can be high and low 
    if (cardsInOrder.First().Rank == "A") 
    { 
     // check if straight with ace has has 2 values 
     bool highStraight = cards.Where(a => a.Rank == "K" || a.Rank == "Q" || a.Rank == "J" || a.Rank == "10").Count() == 4; 
     bool lowStraight = cards.Where(a => a.Rank == "2" || a.Rank == "3" || a.Rank == "4" || a.Rank == "5").Count() == 4; 
     // return true if straight with ace 
     if (lowStraight == true || highStraight == true) 
     { 
      return true; 
     } 
    } 
    else 
    { 
     // check for straight here 
     return true; 
    } 
    // no straight if reached here. 
    return false; 

} 

public bool CheckFlush(List<Card> cards) 
{ 
    //see if 5 or more cards card the same rank. 
    return cards.GroupBy(card => card.Suit).Count(group => group.Count() >= 5) == 1; 
} 

public bool CheckFullHouse(List<Card> cards) 
{ 
    // check if trips and pair is true 
    return CheckPair(cards) && CheckTrips(cards); 
} 
public bool CheckQuads(List<Card> cards) 
{ 
    //see if exactly 4 cards card the same rank. 
    return cards.GroupBy(card => card.Rank).Any(group => group.Count() == 4); 
} 

// need to check same 5 cards 
public bool CheckStraightFlush(List<Card> cards) 
{ 
    // check if flush and straight are true. 
    return CheckFlush(cards) && CheckStraight(cards); 
} 
+0

你要去这只是为了好玩,或为真正的使用情况?因为实际使用情况,现有的库经过精心设计,速度非常快。 – Evk

+0

[检查数组数组是否连续的函数方法]的可能重复(http://stackoverflow.com/questions/18225010/functional-way-to-check-if-array-of-numbers-is-sequential) – fubo

+5

嗨,这只是为了应对挑战 –

回答

2

这可能不是表现最好的检查,但我会说这是非常具有可读性这通常是一个不错的酒店。

只需抓住5张牌,跳过你已经看到每次迭代的牌,并检查每个序列的直线。有序序列是一条直线,如果它不包含双打,如果第一个和最后卡不同的是5

public bool CheckStraight(List<Card> cards) 
{ 
    //maybe check 5 and 10 here first for performance 

    var ordered = cards.OrderByDescending(a => a.Value).ToList(); 
    for(i = 0; i < ordered.Count - 5; i++) { 
      var skipped = ordered.Skip(i); 
      var possibleStraight = skipped.Take(5); 
      if(IsStraight(possibleStraight)) { 
       return true; 
      } 
    } 
    return false; 
} 

public bool IsStraight(List<Card> fiveOrderedCards) { 
    var doubles = cards.GroupBy(card => card.Rank).Count(group => group.Count() > 1); 
    var inARow = cards[4] - cards[0] = 5; //Ace is 0 

    return !doubles && inARow; 
} 
+0

这似乎没有检测到10-J-Q-K-A直。 – wimh

+0

这可能是因为它对“A”不满意。你确定“A”在那里被改写为15吗?也许我在代码中对Ace = 0的评论会让事情变得混乱(lol)。低直线时A必须等于0,高直线时A必须等于0。你以什么样的模式取决于你。 (提示:当检测返回真时,您可以检测到一个ace并手动将其添加到第一个方法两端的有序列表中)。 – Glubus

0

我已经取得了一些小的改动Glubus答案。下面的代码完成这项工作,但是您必须手动检查车轮(A,1,2,3,4,5)。

public bool CheckStraight(List<Card> cards) 
    { 
     //maybe check 5 and 10 here first for performance 

     var ordered = cards.OrderByDescending(a => a.Value).ToList(); 
     for (var i = 0; i < ordered.Count - 4; i++) 
     { 
      var skipped = ordered.Skip(i); 
      var possibleStraight = skipped.Take(5).ToList(); 
      if (IsStraight(possibleStraight)) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
public bool IsStraight(List<Card> cards) 
{ 
    return cards.GroupBy(card => card.Value).Count() == cards.Count() && cards.Max(card => (int)card.Value) - cards.Min(card => (int)card.Value) == 4; 
    } 
+0

确保关闭您的问题,将问题标记为已回答或完全删除问题。 – Glubus

0

我不敢去想真正的眼线,因为A可以是1或者14,但是这应该是不错的:

int c = 5; // How many cards straight 
bool Ais1 = cards.OrderBy(a => a.Value).Select((i,j) => i.Value-j).Distinct().Skip(1).Count() <= (cards.Count - c); 
bool Ais14 = cards.OrderBy(a => (a.Value == 1 ? 14 : a.Value)).Select((i,j) => (i.Value == 1 ? 14 : i.Value)-j).Distinct().Skip(1).Count() <= (cards.Count - c); 
return Ais1 || Ais14; 

(更新 - 谢谢你的Janne,我已经固定的代码)

+0

不适用于5,6,7,8,9直。 –

+0

@JanneMatikainen谢谢你,我修复了代码。 –

+0

顺便说一句,如果卡将{{A,1,14},{“2”,2,2} ... {“K”,13,13} {Rank,Value,HighValue} {code}甚至更好。 –

0

呃,

function bool IsStraight(IEnumerable<int> cards) 
{ 
    var orderedCards = cards.OrderBy(n => n).ToList(); 
    var test = orderdCards.Zip(orderdCards.Skip(1), (a, b) => b - a); 

    var count = 0; 
    foreach(var n in test) 
    { 
     if (n == 1) 
     { 
      count++; 
      if (count == 4) 
      { 
       return true; 
      } 
     } 
     else 
     { 
      count = 0; 
     } 
    } 

    return false; 
}