Определение вероятности 4 одинаковых в 5-карточной покерной руке Matlab

Я должен определить вероятность 4 одинаковых карт в 5-карточном покере с использованием Matlab. Я понимаю, что первое, что мне нужно сделать, это собрать колоду и перетасовать карты, а затем взять 5 карт. У меня возникли проблемы с определением, является ли рука четверкой или нет. Ниже я написал код, который работает для перетасовки колоды и вытягивания 5 карт. Я попытался использовать оператор if, чтобы определить, является ли рука четверкой или нет, но это не сработало. Мое обоснование утверждения if заключалось в том, что если бы у меня уже был отсортированный вектор, единственными двумя возможными вариантами были бы первые 4 или последние 4 числа, которые должны быть равны друг другу.

Бывший. АААА_

_2222

Любые советы о том, как определить 4 вида, были бы очень полезны :)

DECK = ['AH';'2H';'3H';'4H';'5H';'6H';'7H';'8H';'9H';'TH';'JH';'QH';'KH'; ...
    'AS';'2S';'3S';'4S';'5S';'6S';'7S';'8S';'9S';'TS';'JS';'QS';'KS'; ...
    'AD';'2D';'3D';'4D';'5D';'6D';'7D';'8D';'9D';'TD';'JD';'QD';'KD'; ...
    'AC';'2C';'3C';'4C';'5C';'6C';'7C';'8C';'9C';'TC';'JC';'QC';'KC'];
%deck of 52 cards
total_runs=10000;
n=0;
for i=1:total_runs
  index=randperm(52);
  shuffle=DECK(index);
%shuffles the 52 columns 
  b=shuffle(1:5);
%chooses the first 5 cards
d=sort(b);

 if d(1)==d(2)==d(3)==d(4)||d(2)==d(3)==d(4)==d(5)
   %attempt to determine 4 of a kind
   disp(d);
   n=n+1;
 end
end
 prob=n/total_runs

person azumakazuma    schedule 01.09.2014    source источник
comment
Просто вопрос стиля, но почти все оставляют комментарии выше (или позади) того, что они описывают. Ваши текущие комментарии могут ввести в заблуждение быстрого читателя.   -  person Dennis Jaheruddin    schedule 01.09.2014


Ответы (3)


Вы не можете цеплять сравнения, как это. Вы написали:

d(1)==d(2)==d(3)==d(4)

Но d(1) == d(2) оценивается как логическое, либо true, либо false. Это не будет равно d(3).

Поскольку они отсортированы, вы можете просто проверить

d(1)==d(4) || d(2)==d(5)
person Ben Voigt    schedule 01.09.2014
comment
ничего себе, я думаю, я узнаю что-то новое каждый день, спасибо! Вы отличный учитель :) - person azumakazuma; 01.09.2014
comment
@azumakazuma В общем, проверка равенства нескольких значений может быть выполнена следующим образом: isequal(d(1),d(2),d(3),d(4)) - person Dennis Jaheruddin; 01.09.2014

Я ломал голову над этим последние 30 минут и начал задаваться вопросом, а зачем нам указывать масть? Он может просто получить вектор от [1 до 13... от 1 до 13] размером 1x52 и использовать randperm(52,5). Или следующим образом:

DECK = [1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13];
draw = randperm(52,5);
for k = 1:5;
   hand(k) = DECK(draw(k));
end

Затем вы можете проверить первые два индекса hand() и сравнить их с hand; или:

for i=1:2
   if sum(hand(i)==hand) == 4
      n = n+1;
   end
end

Я думаю, что этот способ достаточно короткий, хотя было бы более идеально сравнивать значения столбца или строки. Это занимает около 1 секунды, чтобы выполнить N = 100 000 итераций на i5 5-го поколения. Когда я устанавливаю его на 10 миллионов итераций, я получаю около 0,04% успеха, что значительно выше теоретических 0,02401%. Моя первая попытка выглядит так:

hand = randperm(52,5);
for k=1:5
   match = 0;
   for i=1:3
      if sum(hand(k)+13*i == hand) > 0
         match = match+1;
      end
   end
   if match == 3
      four = four +1;
   end
end
prob = four/N;

Мне нравится этот, потому что мне не нужно тратить место на большой вектор; однако требуется больше вычислительной мощности из-за 15 циклов/больше сравнений. Я получаю около 0,024% успеха за N = 100 000 итераций для этого, что почти в точку с теорией. Идея самого внутреннего цикла заключается в том, что одна из карт в каре будет равна другой карте, если вы прибавите к ней 13*a, где a = 1,2,3. Написание этого метода заняло у меня почти час, так как я немного углубился в циклы. Пожалуйста, сообщите мне о любых проблемах с кодом, это очень ценно.

edit: Ха-ха, я только что понял, что повторяю результаты с помощью своего первого сценария. Давайте сделаем это так:

for i=1:2
   if sum(hand(i)==hand) == 4
      n = n+1;
   end
end

должно быть:

if sum(hand(1)==hand) == 4
   n = n+1;
elseif sum(hand(2)==hand) == 4
   n = n+1;
end

что-то подобное.

person TimK    schedule 03.09.2018

Спасибо за публикацию интересного вопроса.

Мне несколько неудобно смешивать строки и целые числа в MATLAB. Однако эта проблема разрешима, если рассматривать только целые числа от 1 до 52.

% 1 through 52
% ['AH';'2H';'3H';'4H';'5H';'6H';'7H';'8H';'9H';'TH';'JH';'QH';'KH'; ...
%     'AS';'2S';'3S';'4S';'5S';'6S';'7S';'8S';'9S';'TS';'JS';'QS';'KS'; ...
%     'AD';'2D';'3D';'4D';'5D';'6D';'7D';'8D';'9D';'TD';'JD';'QD';'KD'; ...
%     'AC';'2C';'3C';'4C';'5C';'6C';'7C';'8C';'9C';'TC';'JC';'QC';'KC'];
%deck of 52 cards . . from wikipedia
total_runs=2598960;
n=0;
for i=1:total_runs
  index=randperm(52,5);
  value = mod(index-1, 14);

 if length(unique(value)) == 2
   %attempt to determine 4 of a kind
   n=n+1;
 end
end
 prob=n/total_runs

ИЗМЕНИТЬ:

исправлено на length(unique(value)) == 2 Вероятность того, что это дало, составляет от 0,1% до 0,2%. Что кажется разумным.

Однако мод не должен быть 13, потому что нам нужно 13 различных значений для каждого цвета.

person Anoop    schedule 01.09.2014
comment
Должно быть по модулю 13, конечно - person Ben Voigt; 01.09.2014
comment
Кроме того, ваше правило обнаруживает 5 одинаковых, что действительно имеет нулевую вероятность. - person Ben Voigt; 01.09.2014
comment
Теперь вы не различаете каре и фулл-хаус (3 одного, 2 другого) - person Ben Voigt; 01.09.2014
comment
Просто сравните mod(1:52,13) с mod(1:52,14), должно быть легко увидеть, что 13 - это правильное число, как упомянул @BenVoigt. (Использование 0:51 не меняет этого) - person Dennis Jaheruddin; 01.09.2014