繁体   English   中英

从2D值矩阵识别扑克手

[英]Recognizing poker hands from a 2D matrix of values

我有一个1000 x 5排序的矩阵,其编号为1-13。 每个数字表示纸牌的数值。 A的值是1,接着是数字2到10,然后Jack的值是11,Queen的值是12,King的值是13。因此,此矩阵的每一行构成一手扑克牌。 我正在尝试创建一个程序,使用这些枚举的卡来识别扑克手。

例如:

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)),最后一排是满屋(成对的9s和3(8)。

有没有在MATLAB中执行此操作的好方法?

bsxfun在这种情况下不起作用。 这是一个计数问题 这都是计算您拥有的东西。 具体来说,扑克手处理的是计算您拥有的每张纸牌的数量,并弄清楚正确的计数组合以获得有效的手牌。 这是一张很好的图片,向我们展示了人类已知的每一种扑克手:

资料来源: http//www.bestonlinecasino.tips

因为您的矩阵中没有花色,所以我将忽略皇家同花顺,同花顺和同花顺方案。 您想要识别的每只手都可以用直觉图来表示,每行的直方图的bin范围为1到13,并确定是否(按等级顺序):

  • 情况#1:高手-所有垃圾箱的垃圾箱计数刚好为1
  • 情况2:一对-您正好有1个bin,其计数为2
  • 情况3:两对-您正好有2个垃圾箱,计数为2
  • 情况#4:一个3的类型-您恰好有1个垃圾箱,其数量为3
  • 情况5:直线-您无需在此处计算直方图。 只需对您的手进行排序,并取下相邻的差,并确保连续值之间的差为1。
  • 情况#6:满屋子-您只有1个垃圾箱,其计数为2, 您只有1个垃圾箱,其计数为3。
  • 情况#7:有四种情况-您正好有1个bin,其计数为4。

因此,根据您的MATLAB版本,使用histchistcounts查找您的手的直方图。 我还会在每行上对您的手进行预排序,以使找到直线时的事情变得更简单。 您在您的文章中提到矩阵是预先排序的,但我将假设一般情况下可能无法排序。

因此,假设您的矩阵位于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数组,它是一个向量,其大小与您拥有的手数相同,并且ID告诉您我们玩过哪一手。 特别:

* 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张卡。 如果我们检查所有只有1个计数的垃圾箱,然后将它们全部加在一起,则应该得到5张卡片。

情况2检查我们是否只有1个垃圾箱,其中有2张卡,并且只有一个这样的垃圾箱

情况#3检查我们是否有2个包含2张卡的垃圾箱。

情况#4检查我们是否只有1个垃圾箱包含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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM