2016-09-22 9 views
8

Próbuję napisać metodę oceny strony pokera w języku C#. Udało mi się to zrobić dla każdego rozdania z pokera używając linq oprócz straight. Dla osób, które nie grają w strita, składa się z 5 kart z przyrostem 1 na każdą kartę. As może być wysoki lub niski.C# sprawdzić na poker prosto

Utworzyłem obiekt zwany kartą, która ma kolor, stopień i wartość (J = 11, Q = 12 itd.). Moja metoda zostanie przekazana lista tego obiektu zawierającego 7 kart (karty własne i plansza).

Należy również pamiętać, że strit może zostać wykonany, jeśli gracz ma 5 lub 10.

Zobacz poniżej moje metody dla innych rąk pokerowych i daj mi znać, jeśli masz pomysł na prostą metodę. Pseudo kod również byłby w porządku.


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

idziesz to tylko dla zabawy lub na prawdziwe użytkowania? Ponieważ do rzeczywistego użycia istnieją już starannie zaprojektowane biblioteki, aby były bardzo szybkie. – Evk

+0

Możliwy duplikat funkcji [Funkcjonalny sposób sprawdzania, czy tablica liczb jest sekwencyjna] (http://stackoverflow.com/questions/18225010/functional-way-to-check-if-array-of-numbers-is-sequential) – fubo

+5

Cześć, to tylko dla odrobiny wyzwania –

Odpowiedz

2

To może nie być najlepszym sprawdzić jego efektywności, ale powiedziałbym, że jest bardzo czytelny, który jest zwykle dobrym nieruchomość.

Po prostu chwyć 5 kart, pomijając karty, które już widziałeś w każdej iteracji, i sprawdzaj, czy nie ma prostej dla każdej sekwencji. Uporządkowana sekwencja jest prosta, jeśli nie zawierają podwójne i jeśli różnica pierwsze i ostatnie karty wynosi 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

To nie wydaje się wykrywać prostej 10-J-Q-K-A. – wimh

+0

To pewnie dlatego, że nie jest zadowolony z "A". Czy jesteś pewien, że "A" jest zmodyfikowane jako 15? Być może mój komentarz w kodzie, w którym mówię Ace = 0 sprawia, że ​​rzeczy są mylące (lol). As musi być równy 0, gdy ma niski strit, a 15, gdy jest wysoki. W jaki sposób modelujesz, który należy do Ciebie. (Wskazówka: Możesz wykryć asa i ręcznie dodać go do uporządkowanej listy na obu końcach w pierwszej metodzie, gdy wykrycie zwróci true). – Glubus

0

Zrobiłem kilka małych zmian Glubus odpowiedź. Poniższy kod wykonuje zadanie, ale musisz ręcznie sprawdzić koło (A, 1,2,3,4,5) prosto.

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

Pamiętaj, aby zamknąć pytanie, zaznaczając pytanie jako odpowiadające lub usuwając pytanie w ogóle. – Glubus

0

Nie mogę myśleć o realnej jednej liniowej, od A może być 1 lub 14, ale to powinno być dobre: ​​

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; 

(Aktualizacja - dziękuję Janne, Naprawiłem kod)

+0

Nie działa z 5,6,7,8,9 prosto. –

+0

@JanneMatikainen dziękuję, naprawiłem kod. –

+0

BTW, jeśli karta będzie miała {Rank, Value, HighValue}, więc {"A", 1, 14}, {"2", 2, 2} ... {"K", 13, 13} wtedy kod może wyglądać jeszcze ładniej. –

0

erm,

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; 
} 
Powiązane problemy