2015-07-28 2 views
1

У меня есть отсортированная матрица размером 1000 х 5 с номерами от 1 до 13. Каждое число обозначает числовое значение игровой карты. Туз имеет значение 1, затем следуют числа от 2 до 10, затем у Джека значение 11, королева со значением 12 и король со значением 13. Следовательно, каждая строка этой матрицы составляет руку в покере. Я пытаюсь создать программу, которая распознает покерные руки, используя эти карты, которые перечислены таким образом.Распознавание рук в покере из 2D-матрицы значений

Например:

A = [1 1 2 4 5; 2 3 4 5 7; 3, 3, 5, 5, 6; 8, 8, 8, 9, 9] 

Таким образом, в этой матрице A, первая строка имеет пару (1,1). Второй ряд имеет высокую карту (7), третья строка имеет две пары ((3,3) и (5,5)), а последняя - фулл-хаус (пара 9 и 3 вида (8).

есть хороший способ сделать это в MATLAB?

+0

Project Euler упражнения? –

+1

'bsxfun' не будет работать для этого. – rlbond

+0

Теперь, когда мы знаем, чего вы хотите, было бы интересно узнать, что вы сделали. – thewaywewalk

ответ

6

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

http://www.bestonlinecasino.tips/wp-content/uploads/2013/07/poker-hand-rankings3.png

Источник: http://www.bestonlinecasino.tips

Потому что мы не имеем костюмы в вашей матрице, я буду игнорировать Флеш-рояль, стрит-флеш и Flush сценарий. Каждая руку, вы хотите признать, может быть мел до принятия гистограммы каждой строки с бункерами от 1 до 13, и определения, если (в порядке убывания ранга):

  • Ситуация # 1: высокая рука - все у бункеров есть счетчик бункеров ровно 1
  • Ситуация № 2: Пара - у вас есть ровно 1 бит, у которого есть счет 2
  • Ситуация № 3: Две пары - у вас есть ровно 2 бункера, у которых есть счет от 2
  • Ситуация № 4: Три вида - у вас есть ровно 1 бит, у которого есть счет 3
  • Ситуация №5: Прямая - вы не нужно вычислить гистограмму здесь. Просто отсортируйте свою руку и выполните соседние различия и убедитесь, что разница между последовательными значениями равна 1.
  • Ситуация № 6: Full House - у вас есть ровно 1 бит, у которого есть счет 2 и у вас есть ровно 1 бит который имеет счетчик 3.
  • Ситуация # 7: каре - у вас есть ровно 1 бункер, который имеет счетчик 4.

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

Таким образом, вот некоторая предварительная обработка коды, при условии, что ваша матрица в A:

Asort = sort(A,2); %// Sort rowwise 
diffSort = diff(Asort, 1, 2); %// Take row-wise differences 
counts = histc(Asort, 1:13, 2); %// Count each row up 

diffSort содержит столбцы разногласия по каждой строке и counts дает вам N x 13 матрицу, где N являются общее количество рук, которое вы рассматриваете ... так что в вашем случае это 1000. Для каждой строки он сообщает вам, сколько из определенной карты было встречено. Итак, все, что вам нужно сделать, это пройти через каждую ситуацию и посмотреть, что у вас есть.

Давайте сделаем массив идентификаторов, где это вектор, который имеет тот же размер, что и количество рук, которое вы имеете, и идентификатор указывает вам, какую руку мы сыграли. В частности:

* ID = 1 --> High Hand 
* ID = 2 --> One Pair 
* ID = 3 --> Two Pairs 
* ID = 4 --> Three of a Kind 
* ID = 5 --> Straight 
* ID = 6 --> Full House 
* ID = 7 --> Four of a Kind 

Таким образом, вот что вам нужно сделать, чтобы проверить для каждой ситуации, и выделение out содержать наши идентификаторы:

%// To store IDs 
out = zeros(size(A,1),1); 

%// Variables for later 
counts1 = sum(counts == 1, 2); 
counts2 = sum(counts == 2, 2); 
counts3 = sum(counts == 3, 2); 
counts4 = sum(counts == 4, 2); 

%// Situation 1 - High Hand 
check = counts1 == 5; 
out(check) = 1; 

%// Situation 2 - One Pair 
check = counts2 == 1; 
out(check) = 2; 

%// Situation 3 - Two Pair 
check = counts2 == 2; 
out(check) = 3; 

%// Situation 4 - Three of a Kind 
check = counts3 == 1; 
out(check) = 4; 

%// Situation 5 - Straight 
check = all(diffSort == 1, 2); 
out(check) = 5; 

%// Situation 6 - Full House 
check = counts2 == 1 & counts3 == 1; 
out(check) = 6; 

%// Situation 7 - Four of a Kind 
check = counts4 == 1; 
out(check) = 7; 

Ситуация # 1 в основном проверяет, является ли все бины, которые встречаются, содержат только одну карту. Если мы проверим все ячейки, у которых есть только 1 счет, и мы суммируем их все вместе, мы должны получить 5 карт.

Ситуация №2 проверяет, есть ли у нас только один ящик, который имеет 2 карты, и есть только один из таких бункеров.

Ситуация №3 проверяет, есть ли у нас 2 бункера, которые содержат 2 карты.

Ситуация №4 проверяет, есть ли у нас только один ящик, содержащий 3 карты.

Ситуация №5 проверяет, соответствуют ли соседние различия для каждой строки отсортированного результата равным 1. Это означает, что вся строка состоит из 1 при поиске соседних расстояний. Если это так, то у нас есть прямая. Мы используем all и проверить каждую строку независимо друг от друга, чтобы увидеть, если все значения равны 1.

Ситуация # 6 проверяет, если у нас есть один ящик, который содержит 2 карты и один бункер, который содержит 3 карты.

И, наконец, ситуация № 7 проверяет, есть ли у нас 1 ящик, который содержит 4 карты.


Пару вещей отметить:

  • прямая рука также технически высокая рука учитывая наше определение, а потому, что прямая проверка происходит в конце трубопровода, любые руки, которые были первоначально назначил высокопоставленную руку, которой назначено быть прямым ... так что это нормально для нас.

  • Кроме того, фулл-хаус также может быть трех видов, потому что мы рассматриваем только три вида, которые содержит полный дом. Тем не менее, более поздняя проверка для фулл-хауса также будет включать проверку пары карт, и поэтому любые руки, которые были назначены втроем, в конечном итоге станут полноценными.


Еще одна вещь, которую я хотел бы отметить, что если у вас есть недопустимое покер, он будет автоматически присваивается значение 0.


Запуск через ваш пример это то, что я получаю:

>> out 

out = 

    2 
    1 
    3 
    6 

Это говорит о том, что первая часть является одна пара, следующая рука высокая карта, следующая пара две пары а последняя рука - фулл-хаус. В качестве бонуса, мы можем на самом деле выход, какие строки для каждой стороны:

str = {'Invalid Hand', 'High Card', 'One Pair', 'Two Pair', 'Three of a Kind', 'Straight', 'Full House', 'Four of a Kind'}; 
hands = str(out+1); 

Я сделал заполнитель для недействительных стороны, и если мы получили законную руку в нашем векторе, вам просто нужно добавить 1 для каждого индекса для доступа к правой руке. Если у нас нет хорошей руки, она покажет вам строку Invalid Hand.

Мы получаем это для строк:

hands = 

    'One Pair' 'High Card' 'Two Pair' 'Full House' 
+1

ничего себе. Теперь мне нравится играть в покер. –

+1

@ Benoit_11 - LOL Я знаю, а? – rayryeng

+1

Я знаю, что подобные комментарии не приветствуются, но * wow *. Очень хороший ответ чувак. – Justin

Смежные вопросы