bsxfun 不适用于这种情况。这是一个计数问题。这完全是计算你拥有什么的问题。具体来说,扑克牌涉及计算您拥有的每张牌的数量,并找出正确的计数组合以获得有效手牌。这是一张漂亮的图片,向我们展示了人类已知的所有可能的扑克牌:
来源:http://www.bestonlinecasino.tips
因为我们的矩阵中没有花色,所以我将忽略皇家同花顺、同花顺和同花顺场景。您想识别的每只手都可以归结为使用从 1 到 13 的箱的每一行的直方图,并确定是否(按排名顺序):
- 情况 #1:高手 - 所有 bin 的 bin 计数正好为 1
- 情况 #2:一对 - 您正好有 1 个计数为 2 的箱子
- 情况 #3:两对 - 您正好有 2 个计数为 2 的箱子
- 情况 #4:三种类型 - 您恰好有 1 个计数为 3 的箱子
- 情况 #5:直线 - 您无需在此处计算直方图。只需对您的手进行排序,并取相邻的差异,并确保连续值之间的差异为 1。
- 情况 #6:满屋 - 您正好有 1 个计数为 2 的箱子并且您正好有 1 个计数为 3 的箱子。
- 情况 #7:四种类型 - 您恰好有 1 个计数为 4 的箱子。
因此,根据您的 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 以包含我们的 ID:
%// 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 张卡片的箱子。
Situation #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'