2009-03-04 3 views
1

Это всего лишь часть кода, поэтому не обращайте внимания, если вы не видите массивы или что-то еще. Идея состоит в том, что у меня есть 5 карт, и я хочу определить, какие из них - пары. Кто-нибудь понимает, что я имею в виду?Нужна помощь в определении руки в покере (одна пара)

boolean IsOnePair=true; 

int [] cont = new int [6]; 

for (int i=0;i<Game.length;i++) 
{ 
    cont[Game[i].getValue()] ++; 
} 

for (int i=0;i<cont.length;i++) 
{ 
    if (cont[Game[i].getValue()]==2) 
    { 
     IsOnePair=false; 
     System.out.println(Game+" : "+cont[i]+" times"); 
    } 
} 

ответ

4

Ну, для одного, у вашего массива должно быть только 5 элементов, а не 6, если вы хотите, чтобы это была настоящая рука в покере.

Что касается определения наличия пары или нет, я бы просто проверил каждую карту на каждой другой карте справа. Это будет работать в O (N^2), но это приемлемо до тех пор, пока размер руки остается на уровне около 5.

Вот код, чтобы сделать это:

for(i=0; i<5; i++) 
{ 
    for(j=i+1; j<5; j++) 
    { 
    if(hand[i] == hand[j]) 
     return true; 
    } 
} 

Кроме того, причина, по которой код не работает, потому что вы пытаетесь получить доступ к индексу, равному значению карт, а не номеру карты. Вы могли бы использовать словарь для этого, но код выше намного проще для программирования и для такого небольшого размера проблемы, это приемлемо.

+0

О, хороший звонок. Я отредактирую. – samoz

+0

Ударьте меня тоже :-D – overstood

+0

Однако это не учитывает тройки и четыре типа, а также несколько пар. – Smashery

1

Я предполагаю, что вы ищете пару, отличную от трех или четырех в своем роде. В этом случае лучше всего пройти через каждую из карт и сохранить количество тузов, сколько 2s, сколько 3s и т. Д. Есть. Это решение даст вам количество пар, а также есть ли три или четыре в своем роде или фулл-хаус. Разумеется, вам придется делать разные проверки при поиске флеша или прямой.

Card[] hand = new Card[numberOfCards]; 
int[] frequencies = new int[13]; // there are 13 card values 
... 
for (int i = 0; i < hand.Count; i++) 
{ 
    frequencies[hand[i].CardNumber] += 1; // assume Ace = 0, King = 12 
} 
// Now look through the frequencies: 
int numberOfPairs = 0; 
bool hasTriple = false; 
bool hasFour = false; 
for (int f = 0; j < frequencies.Count; j++) 
{ 
    switch (frequencies[f]) 
    { 
     case 2: 
      numberOfPairs++; 
      break; 
     case 3: 
      hasTriple = true; 
      break; 
     case 4: 
      hasFour = true; 
      break; 
     default: 
      break; 
    } 
} 
// Now you know how many pairs you have, and whether you have a triple or four-of-a-kind 
if (numberOfPairs == 1 && hasTriple) 
{ 
    // It's a full house 
} 

EDIT: Было бы тривиальным, чтобы изменить это, чтобы сохранить запись о том, что цифры составляли пары (пары тузов или Квинс и т.д.)

+0

Вам нужно будет добавить некоторую проверку, чтобы удалить пару, если есть три вида, или удалить три типа, если есть четыре вида. – samoz

+0

Нет, это принято во внимание по дизайну - сначала вы создаете частоты, а затем проверяете. Поэтому, когда вы просматриваете пары, вы уже знаете, есть ли 0, 1, 2, 3 или 4 из них. Тогда нет путаницы в том, что это пара, три в своем роде или четыре в своем роде. – Smashery

+0

Я думаю, что вы оставили на приращении инструкции в своем первом цикле: 'frequency [hand [i] .CardNumber]; // Не имеет эффекта' – Leonard

4

Если вам это нужно, чтобы быть быстро, вы можете подумать о переоценке своего подхода. Или подумайте об использовании существующей библиотеки обнаружения рук в покер или, по крайней мере, изучите источник, по крайней мере, для одного из них для какого-то «вдохновения». Кактус Кев имеет хорошую рецензию о его довольно хорошо 5 card hand detection algorithm:

Вы также можете прочитать http://www.codingthewheel.com/archives/how-i-built-a-working-online-poker-bot-8

+0

Ничего себе, это хорошая ссылка. Он определяет ранг руки примерно в 20 строках кода. удивительно! – dotjoe

2

Как вы обработку костюмов на палубе? Если вы представляете карты как простые ints, то я предполагаю, что действительные значения карт равны 0 - 51. Если это так, то, я думаю, карты 0 - 12 - все один костюм, 13 - 25 - другой, и т. Д. Присвоение костюмов может быть произвольным, пока вам не понадобятся очки, которые учитывают его.

С помощью этой схемы вы можете обнаружить пару так же, как и samoz, с модификацией операции сравнения. Вы должны убедиться, что карты являются сравнимыми по модулю 13. Просто измените строку

if(hand[i] == hand[j]) 

в

if((hand[i] % 13) == (hand[j] % 13)) 

модуля оператора (%) возвращает остаток после деления, так

0 % 13 = 0 
1 % 13 = 1 
2 % 13 = 2 
    ... 
12 % 13 = 12 
13 % 13 = 0 
14 % 14 = 1 

и т. Д. Это позволяет вам рассказать, когда последовательность обтекает определенное значение, модуль в этом случае 13, поскольку в каждом из четырех костюмов имеется 13 разных карт.

Скажем, например, что в вашей колоде из 52 карт с номером 0 - 51, что карты 0 - 12 представляют туз через король клубов, карты 13-25 представляют собой сердца, 26 - 38 представляют собой пики и 39 - 51 представляют собой бриллианты.

Теперь вы нанесли руку: 0, 12, 32, 21, 47

Принимая остаток модулю 13 каждой карты вы остаетесь с 0, 12, 6, 8, 8

Вы можете видеть, что две последние карты - это пара, 9 сердец и 9 бриллиантов (помните, что нумерация начинается с 0, так что она отключена одним).

0

Если вы сортируете руку, то прочитайте ее слева направо, что должно быть относительно легко вычислить силу руки.

Если вы стремитесь к простоте, вы можете попробовать что-то вроде этого (псевдокод):

def handStrength(hand): 
    sort(hand) //sorts hand in ascending order 
    if hasPair(hand): 
     if isTwoPair(hand): 
      return "two pair" 
     else if isTrips(hand): 
      return "three of a kind" 
     else if isBoat(hand): 
      return "full house" 
     else if isQuads(hand): 
      return "four of a kind" 
     else: 
      return "pair" 
    else: 
     straightFlag = isStraight(hand) 
     flushFlag = isFlush(hand) 
     if straightFlag: 
      if flushFlag: 
       return "straight flush" 
      else: 
       return "straight" 
     else if flushFlag: 
      return "flush" 
     else: 
      return "high card" 

def hasPair(hand): //requires sorted hand 
    for i = 1 to 4: 
     if hand[i].rank == hand[i-1].rank: 
      return True 
    return False 

def isTwoPair(hand): //requires sorted hand 
    return (hand[0].rank == hand[1].rank and hand[2].rank == hand[3].rank and hand[0].rank != hand[2].rank) or 
      (hand[1].rank == hand[2].rank and hand[3].rank == hand[4].rank and hand[1].rank != hand[3].rank) 

def isTrips(hand): //requires sorted hand 
    return (hand[0].rank == hand[2].rank and hand[0].rank != hand[3].rank and hand[3].rank != hand[4].rank) or 
      (hand[1].rank == hand[3].rank and hand[0].rank != hand[1].rank and hand[0].rank != hand[4]) or 
      (hand[2].rank == hand[4].rank and hand[1].rank != hand[2].rank and hand[1].rank != hand[0].rank) 

def isBoat(hand): //requires sorted hand 
    return (hand[0].rank == hand[1].rank and hand[2].rank == hand[3].rank == hand[4].rank) or 
      (hand[0].rank == hand[1].rank == hand[2].rank and hand[3].rank == hand[4].rank) 

def isQuads(hand): //requires sorted hand 
    return hand[1].rank == hand[2].rank == hand[3].rank and (hand[0].rank == hand[1].rank or hand[4].rank == hand[1].rank) 

def isStraight(hand): //requires sorted hand with no pair 
    return (hand[0].rank == hand[4].rank - 4) or (isAce(hand[0]) and hand[4].rank == 5) 

def isFlush(hand): 
    return hand[0].suit == hand[1].suit == hand[2].suit == hand[3].suit == hand[4].suit 
0

Проверка пары и возвращает логическое значение в значительной степени бесполезны. Вам нужно проверить, чтобы руки начинались от наивысшего до самого низкого (стрит-флеш, 4 вида, фулл-хаус, флеш, прямой и т. Д.) И создавали способ ранжировать ваши руки, чтобы вы могли определить победителя. На мой взгляд, это не тривиально.

0

нетрадиционный, но немногословен:

import fj.P; 
import fj.data.Stream; 
import static fj.P2.untuple; 
import static fj.pre.Equal.intEqual; 

public Stream<Integer> pairs(Stream<Integer> hand) { 
    return hand.apply(hand.map(P.<Integer, Integer>p2())) 
      .filter(untuple(intEqual.eq())) 
      .map(P1.<Integer>__1()); 
} 

Get the imported libraries here

0

Полный исходный код Техасский Холдем покер игры оценщиком можно найти здесь:

http://www.advancedmcode.org/poker-predictor.html

Он построен для matlab, идентификатор GUI m-кодирован, но вычислительный движок - C++.

Это позволяет рассчитывать вероятность и вероятность. На моем 2.4Ghz-ноутбуке он может иметь дело с вычислением игры 100 000 10 игроков за 0,3 секунды.

Точное компьютер в реальном масштабе времени :-)