从二维价值矩阵中识别扑克牌

1 matlab matrix

我有一个1000 x 5排序矩阵,数字从1到13.每个数字表示扑克牌的数值.Ace的值为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]
Run Code Online (Sandbox Code Playgroud)

因此,在该矩阵中A,第一行具有一对(1,1).第二行有高卡(7),第三行有两对((3,3)和(5,5)),最后一行是满屋(9对和3对)(8).

在MATLAB中有一个很好的方法吗?

ray*_*ica 6

bsxfun不会适用于这种情况.这是一个计数问题.这都是计算你拥有的东西的问题.具体来说,扑克牌手可以计算每张牌的数量,并找出正确的计数组合以获得有效牌.这是一张很好的图片,向我们展示了人类所知道的每一个可能的扑克牌:

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

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

因为我们的矩阵中没有套装,所以我会忽略皇家同花顺,同花顺和同花顺情景.你想要识别的每一只手都可以用来获取每行的直方图,其中包含从1到13的区间,并确定是否(按排名顺序):

  • 情况#1:高手 - 所有垃圾箱的箱数都是1
  • 情况#2:一对 - 你有一个数量为2的bin
  • 情况#3:两对 - 你有两个数量为2的箱子
  • 情况#4:三种类型 - 你有一个数量为3的bin
  • 情况#5:直 - 您不需要在此计算直方图.只需对您的手进行排序,并获取相邻差异,并确保连续值之间的差异为1.
  • 情况6:浪漫满屋-你有完全相同1斌认为具有计数2 你有完全1斌认为具有计数3.
  • 情况#7:四种 - 你有一个数量为4的bin.

因此,请使用histchistcounts根据您的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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

因此,您可以执行以下操作来检查每种情况,并分配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; 
Run Code Online (Sandbox Code Playgroud)

情境#1基本上检查是否所有遇到的箱子都包含1张卡.如果我们检查只有1个计数的所有垃圾箱并将它们全部加在一起,我们应该得到5张卡.

情况#2检查我们是否只有1个有2张卡的垃圾箱,而且只有一个垃圾箱.

情况#3检查我们是否有2个包含2张卡的箱子.

情况#4检查我们是否只有1个包含3张卡的bin.

情形#5检查排序结果的每一行的相邻差异是否都等于1.这意味着在找到相邻距离时整行包括1.如果是这种情况,那么我们就是顺利的.我们all独立使用并检查每一行,看看是否所有值都等于1.

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

最后,情境#7检查我们是否有1个包含4张卡的bin.


有几点需要注意:

  • 根据我们的定义,直手在技术上也是高手,但由于直接检查发生在管道的后期,所以最初被分配为高手的任何手都被指定为直线......所以对我们来说没问题.

  • 此外,满屋也可以是三种类型,因为我们只考虑满屋所包含的三种类型.然而,后来检查整个房子还将包括检查一对卡,因此任何被分配三种类型的手最终将成为满屋.


我还要注意的另一件事是,如果你有一个无效的扑克牌,它会自动被赋值为0.


通过你的例子,这是我得到的:

>> out

out =

     2
     1
     3
     6
Run Code Online (Sandbox Code Playgroud)

这说第一只手是一对,下一只手是高牌,下一对是两对,最后一只手是满满的.作为奖励,我们实际上可以输出每只手的字符串:

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

我为无效的手做了一个占位符,如果我们在向量中有一个合法的手,你只需要为每个索引添加1来访问右手.如果我们没有好手,它会告诉你一个Invalid Hand字符串.

我们得到这个字符串:

hands = 

    'One Pair'    'High Card'    'Two Pair'    'Full House'
Run Code Online (Sandbox Code Playgroud)