[英]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,并确定是否(按等级顺序):
因此,根据您的MATLAB版本,使用histc
或histcounts
查找您的手的直方图。 我还会在每行上对您的手进行预排序,以使找到直线时的事情变得更简单。 您在您的文章中提到矩阵是预先排序的,但我将假设一般情况下可能无法排序。
因此,假设您的矩阵位于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.