2016-09-22 16 views
8

私はC#でポーカーハンド評価法を書こうとしています。私はストレートを除いてlinqを使って、すべてのポーカーハンドでこれを行うことができました。 ストレートで演奏されないものは、各カードごとに1ずつ増加する5枚のカードで構成されています。エースは高くても低くてもよい。c#ポーカーストレートを確認する

スーツ、ランク、値(J = 11、Q = 12など)を持つcardというオブジェクトを作成しました。私の方法には、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

[配列の配列が連続しているかどうかを確認するための機能的な方法](0120-998-002) – fubo

+5

こんにちは、それはちょうど挑戦のabitのです。 –

答えて

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としてmoddeledされていると確信していますか?おそらく、私がAce = 0と言うコードでの私のコメントは、物事を混乱させる(笑)。エースは低いストレートのときは0に、高いストレートのときは15に等しい必要があります。どんなやり方であなたはあなた次第です。 (ヒント:エースを検出し、検出が真を返すときに最初のメソッドの両端の順序付きリストに手動でエースを追加することができます)。 – Glubus

0

であれば、私はGlubusの答えにいくつかの小さな変更を行いました。下のコードは仕事をしますが、車輪(A、1,2,3,4,5)を手動でチェックする必要があります。

Aが1または14とすることができるが、これは良いことがありますので、私は、本当の1つのライナーを考えることはできません
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

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; 

(更新 - 私は、コードを修正した、あなたのヤンネに感謝)

+0

5,6,7,8,9ストレートでは機能しません。 –

+0

@JanneMatikainenありがとう、私はコードを修正しました。 –

+0

ところで、{A、1,14}、{"2"、2、2} ... {"K"、13、13}のようにカードが{Rank、Value、HighValue}さらに良い。 –

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; 
} 
関連する問題