找回密码
 点一下
查看: 1569|回复: 19

关于德州扑克的算法我整理了下,希望有空的朋友帮我用触发器写下

[复制链接]
发表于 2016-4-13 11:14:18 | 显示全部楼层 |阅读模式
本帖最后由 aolinge2017 于 2016-4-13 20:06 编辑

算法001
在变量数组D[L][M](L为花色,M为1-13的数值),挑选21个数值,每个数值不能重复




-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------



算法002
给7个随机大小的数值排序

所有数组忽略0

变量数组A[7],([1]、[2]、[3]、[4]、[5]、[6]、[7]分别代表1-13之间的随机整数)
变量数组B[7],([1]代表A[7]中最大的数,[2]代表A[7]中第二大的数,依次类推,[7]代表A[7]中最小的;如果数值相等,就依次排列如9999762或8776641等)

变量数组H[7],([1]、[2]、[3]、[4]、[5]、[6]、[7]分别代表1-4之间的随机整数)
变量数组G[7],([1]代表H[7]中最大的数,[2]代表H[7]中第二大的数,依次类推,[7]代表H[7]中最小的;如果数值相等,就依次排列如4444432或2222222等)


-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------


算法003
设定牌型规则

变量数组G[7]中,代表花色(1>=2>=3>=4)
变量数组B[7]中,代表牌值大小位置([1]>=[2]>=[3]>=[4]>=[5]>=[6]>=[7])

对子数变量 i

牌型最大数值变量数组J[a](a取决于玩家数,b当前牌型)


-------------------------------------------------------------------------------------------------------------------------------------
规则设定


单牌  B[7]设置 [1]>[2]>[3]>[4]>[5]>[6]>[7]  ---(J[a][1])

一对  B[7]设置 [1]=[2] / [2]=[3] / [3]=[4] / [4]=[5] / [5]=[6] / [6]=[7],对子数变量 i=1  ---(J[a][2])

双对  B[7]设置 [1]=[2] / [2]=[3] / [3]=[4] / [4]=[5] / [5]=[6] / [6]=[7],对子数变量 i=2  ---(J[a][3])

三条  B[7]设置 [1]=[2]=[3] / [2]=[3]=[4] / [3]=[4]=[5] / [4]=[5]=[6] / [5]=[6]=[7]   ---(J[a][4])

顺子  B[7]设置 [1]=[2]+[1],[2]=[3]+[1],[3]=[4]+[1],[4]=[5]+[1],[5]=[6]+[1] / [2]=[3]+[1],[3]=[4]+[1],[4]=[5]+[1],[5]=[6]+[1],[6]=[7]+[1] / [1]=[13],[2]=[12],[3]=[11[,[4]=[10],[7]=[1] (K Q J 10 A)  ---(J[a][5])

同花  G[7]设置 [1][2][3][4][5][6][7]其中5个以上数值都等于1 / 2 / 3 / 4
      B[7]设置 [1]>[2]>[3]>[4]>[5]>[6]>[7]
      ---(J[a][6])

葫芦  B[7]设置 [1]=[2]=[3]([4]=[5]/[5]=[6]/[6]=[7]/[4]=[5]=[6]/[5]=[6]=[7])  / [2]=[3]=[4] ([5]=[6]/[6]=[7]/[5]=[6]=[7]) / [3]=[4]=[5] ([1]=[2]/[6]=[7]) / [4]=[5]=[6] ([1]=[2]/[2]=[3]) / [5]=[6]=[7] ([1]=[2]/[2]=[3]/[3]=[4]/[1]=[2]=[3])   

      ---(J[a][7])

金刚  B7设置 [1]=[2]=[3]=[4] / [2]=[3]=[4]=[5] / [3]=[4]=[5]=[6] / [4]=[5]=[6]=[7]   ---(J[a][8])

同花顺 G7设置 [1][2][3][4][5][6][7]其中5个以上数值都等于1 / 2 / 3 / 4
       B[7]设置 [1]=[2]+[1],[2]=[3]+[1],[3]=[4]+[1],[4]=[5]+[1],[5]=[6]+[1] / [2]=[3]+[1],[3]=[4]+[1],[4]=[5]+[1],[5]=[6]+[1],[6]=[7]+[1] / [1]=[13],[2]=[12],[3]=[11[,[4]=[10],[7]=[1] (K Q J 10 A)
       ---(J[a][9])


-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------


算法004
大小比较
比较规则,先比较牌型,相同牌型再比较点数

如葫芦33322与44333,先比较333,再比较22与44谁大
如三条:83332与94333 或 99987与99962;顺子:98765与87654;金刚:96666与99996 或 96666与66663

之前 变量数组J[a],中的 决定了牌型
整数变量数组C[7]([1]每种牌型对应的最大点数,[2]每种牌型对应的第2大点数,[3]每种牌型对应的第3大点数,[4]每种牌型对应的第4大点数,[5]每种牌型对应的第5大点数,[6]每种牌型对应的第6大点数,[7]每种牌型对应的第7大点数)
先比较C[1],在比较C[2],依次类推

C[7]决定牌型值的大小。
C[7]的值还存在一个问题,
当B[7]中的[7]不等于 整数1 (就是扑克里的A)时,B[7]中的[1]最大
当B[7]中的[7]等于 整数1 (就是扑克里的A)时,B[7]中的[7]>[1]
(如顺子(KQJ10A)13 12 11 10 1与54321,65432与54321)

可能需要增加其他的变量进行比较,详见下面的比较规则)


高牌   C[1]=B[7]的[1](如9875432,那么C[1]=9,C[2]=8,C[3]=7,C[4]=5,C[5]=4)

一对   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](成一对的数值的值)(如9654322,那么C[1]=2,C[2]=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7]不成对的最大数值9,C[3]=B[7]中[1]/[2]/[3]/[4]/[5]/[6]/[7]不成对的第2大数值6,C[4]=B[7]中[1]/[2]/[3]/[4]/[5]/[6]/[7]不成对的第3大数值5;只需比较前面5张最大的后面忽略)

双对   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](两个成一对的数值中最大的一个对子的值,)(如9954322,那么C[1]=9,C[2]=2,C[3]=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7]不成对的最大数值5)

三条   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](三个相等数值)(如9998432,那么C[1]=9,C[2]=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7]相等3个数值外的最大数值8,C3=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7]相等3个数值外的第二大数值4)

顺子   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](至少5个相连数值中最大数值)(如9865432,那么C[1]=6,C[2]=5,C[3]=4,C[4]=3,C[5]=2)

同花   C[1]=B[7]的[1](如9875432,那么C[1]=9,C[2]=8,C[3]=7,C[4]=5,C[5]=4)

葫芦   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](三个相等数值最大的数值)C[2]=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7](三个相等数值第2大数值/成对的数值)(如9993332,那么C[1]=9,C[2]=3;9987222,那么C[1]=2,C[2]=9)

金刚   C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](四个相等数值最大的数值)C[2]=B[7]的B[7]的[1]/[2]/[3]/[4]/[5]/[6]/[7](四个相等数值第大数值)(如9999332,那么C[1]=9,C[2]=3;9872222,那么C[1]=2,C[2]=9)

同花顺 C[1]=B[7]的[[1]/[2]/[3]/[4]/[5]/[6]/[7](至少5个相连数值中最大数值)(如9865432,那么C[1]=6,C[2]=5,C[3]=4,C[4]=3,C[5]=2)



比较中设计到我上面说过的

当B[7]中的[7] 不等于 整数1 (就是扑克里的A)时,B[7]中的[1]最大
当B[7]中的[7] 等于 整数1   (就是扑克里的A)时,B[7]中的[7]>[1]

(如顺子(KQJ10A)13 12 11 10 1与54321,65432与54321)

这种情况的处理


发表于 2016-4-13 12:53:53 | 显示全部楼层
本帖最后由 priceles 于 2016-4-13 12:57 编辑

算法001:不重复很简单啊,首先设置变量A[52]B[52]C[52],重复A=i 52次,B[1~13]=1,B[14~26]=2,B[27~39]=3,B[40~52]=4,C[]表示牌面大小的1~13 14~26 27~39 40~52 从1~13重复 除了A可以用局部变量其他的可以一开始就设定好。然后设置E=随机1~d d为局部变量初始52 设置某个牌 =D[B[A[E]],C[A[E]]]设置d=d-1 循环F从E开始直到d 设置A[F]=A[F+1] 这样就做到不重复的挑选
我写的时候遗漏了很多步骤也没有规范,大体就是这样了。

点评

我按照你思路弄了下,结果花色和牌值不变化 回复发不来图片,从新开个帖子,空了帮我看下,谢谢了  详情 回复 发表于 2016-4-13 18:22
回复

使用道具 举报

 楼主| 发表于 2016-4-13 18:22:12 | 显示全部楼层
我按照你思路弄了下,结果花色和牌值不变化

回复发不来图片,从新开个帖子,空了帮我看下,谢谢了
回复

使用道具 举报

 楼主| 发表于 2016-4-13 18:22:27 | 显示全部楼层
priceles 发表于 2016-4-13 12:53
算法001:不重复很简单啊,首先设置变量A[52]B[52]C[52],重复A=i 52次,B[1~13]=1,B[14~26]=2,B[27~39]=3 ...

我按照你思路弄了下,结果花色和牌值不变化

回复发不来图片,从新开个帖子,空了帮我看下,谢谢了
回复

使用道具 举报

发表于 2016-4-13 19:53:17 | 显示全部楼层
1.关于如何表示一张牌。容易想到的是用一个2维数组,一维记录花色,一维记录牌面值。但是下边我们需要用到牌叠,这不好对应我们的牌叠,所以我们用牌的编号来表示牌,编号2-14表示黑桃的2-A,编号15-27表示红桃的2-A,以此类推。为什么不用1-13表示A-K呢?因为比较顺子的话,A是和K连着的,而不是和2连着的。
2.关于发牌。在实际游戏中,为什么发牌不能重复,因为每张牌只有一张,发完就没有了。为什么发牌是随机的,因为事先洗牌了,牌叠中的牌被随机交换了位置,尽管每次都从牌叠顶部拿牌,但是拿到的牌是随机的。我们也虚拟一个牌叠,发一张就去掉一张,这样就不会重复了,所以我们准备一个整数型一维数组,把第一条中提到的编号记录在里边,然后用一个整数Imax变量表示该数组当前最大下标,即牌顶的位置。每次发牌都发Imax对应的那张,然后Imax自减1。为了保证拿到的牌是随机的,我们需要乱序牌叠,于是我们洗牌就好了,首先创建一个有序牌叠,相当于拆开一副新牌,然后随机出两张牌,交换位置,再重新随机两张,交换位置,循环200次,这个牌叠就没啥顺序可言了吧。当然,乱序牌叠还有更好的算法,这里只是举了个最粗暴的算法。可能有人会提到随机出牌填入到一个空牌叠中,相当于发牌的逆向运算,但问题又回到了最初:你如何随机出不重复的数值呢。还有一种容易想到的算法,是模拟另一种发牌方案,即在有序牌叠中随机抽取一张,而不总是拿牌顶那张。这么做需要建立一个一维数组来做有序牌叠,再用一个整数变量记录牌叠最大下标。发牌时随机抽取其中的牌,每次抽取后,把后边的元素前移,填补空位,然后下标指针随之更新,这样也可以避免抽到重复的牌。
3.关于排序。自行百度吧,有N种算法可供使用,如果都不喜欢,简单粗暴地一一比较也可以,毕竟只有7张牌,复杂度什么的真心是浮云。
4.关于手牌规则。暴力的做法就是针对每种规则制作一个函数,一一比较手牌的组合是否符合该函数代表的规则。但是为了更好地写代码,我们可以把规则细化,具体做法我在你另一篇帖子也有叙述,这里在简单说一下。比如同花顺:需要符合同花的规则,同时需要符合顺子的规则,这时候就没必要单独写同花顺的规则了,直接判断“同花 and 顺子”就可以了。同理,葫芦则符合“三条 and 两对”(具体看你对子怎么判断,如果只要两张牌相同就算,那么葫芦会返回两对,这是推荐算法,否则你还要在判断对子时遍历所有的牌,以便确定它不是3条或4条)。
5.关于比牌规则。这里推荐在手牌规则里使用自定义事件,你可以很方便的在判定手牌规则里抛出一个事件,而这个事件是可以携带任意数量的参数的。这比单一靠函数返回值方便的多。你可以响应抛出的自定义事件来获取手牌规则函数判断的结果。比如一手牌的牌型得出结论是葫芦,那么葫芦中的3张是几,3张最大花色是什么,2张是几,2张最大花色是什么。你可以把这些参数记录到全局变量中,在最后比牌时,直接比较变量就很简单了。

点评

你说的这些都是大的方向性的东西,关键是我理解不了啊 我做了一个比较的排序,你下载我的文件可以看到, 虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了  详情 回复 发表于 2016-4-13 20:18
你说的这些都是大的方向性的东西,关键是我理解不了啊 我做了一个比较的排序,你下载我的文件可以看到, 虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了  详情 回复 发表于 2016-4-13 20:18
你说的这些都是大的方向性的东西,关键是我理解不了啊 我做了一个比较的排序,你下载我的文件可以看到, 虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了  详情 回复 发表于 2016-4-13 20:18
回复

使用道具 举报

 楼主| 发表于 2016-4-13 20:18:32 | 显示全部楼层
yxxiaobin 发表于 2016-4-13 19:53
1.关于如何表示一张牌。容易想到的是用一个2维数组,一维记录花色,一维记录牌面值。但是下边我们需要用到 ...

你说的这些都是大的方向性的东西,关键是我理解不了啊
我做了一个比较的排序,你下载我的文件可以看到,
虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了的,345偶尔还是会变成0的
花了一个晚上和一个白天,做出来的东西还是不对,我就很郁闷啦
回复

使用道具 举报

 楼主| 发表于 2016-4-13 20:18:43 | 显示全部楼层
yxxiaobin 发表于 2016-4-13 19:53
1.关于如何表示一张牌。容易想到的是用一个2维数组,一维记录花色,一维记录牌面值。但是下边我们需要用到 ...

你说的这些都是大的方向性的东西,关键是我理解不了啊
我做了一个比较的排序,你下载我的文件可以看到,
虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了的,345偶尔还是会变成0的
花了一个晚上和一个白天,做出来的东西还是不对,我就很郁闷啦
回复

使用道具 举报

 楼主| 发表于 2016-4-13 20:18:45 | 显示全部楼层
yxxiaobin 发表于 2016-4-13 19:53
1.关于如何表示一张牌。容易想到的是用一个2维数组,一维记录花色,一维记录牌面值。但是下边我们需要用到 ...

你说的这些都是大的方向性的东西,关键是我理解不了啊
我做了一个比较的排序,你下载我的文件可以看到,
虽然只有7个数,1267好确定,但是345不好确定,我用了近千个条件,每中情况进行比较,但是好像还是有漏掉了的,345偶尔还是会变成0的
花了一个晚上和一个白天,做出来的东西还是不对,我就很郁闷啦

点评

帮你做了个7数字插入排序函数,你可以直接或修改后使用。  详情 回复 发表于 2016-4-14 17:00
还有就是顺子的情况,2-A,和A-K区别不大吧,A2345 也是顺子,还是得返回来  详情 回复 发表于 2016-4-13 20:23
回复

使用道具 举报

 楼主| 发表于 2016-4-13 20:23:48 | 显示全部楼层
aolinge2017 发表于 2016-4-13 20:18
你说的这些都是大的方向性的东西,关键是我理解不了啊
我做了一个比较的排序,你下载我的文件可以看到, ...

还有就是顺子的情况,2-A,和A-K区别不大吧,A2345 也是顺子,还是得返回来

点评

我以为A2345不是顺子。如果是顺子的话,确实用1表示A更好一点。  发表于 2016-4-14 16:58
回复

使用道具 举报

发表于 2016-4-14 17:00:50 | 显示全部楼层
本帖最后由 yxxiaobin 于 2016-4-14 17:02 编辑
aolinge2017 发表于 2016-4-13 20:18
你说的这些都是大的方向性的东西,关键是我理解不了啊
我做了一个比较的排序,你下载我的文件可以看到, ...

帮你做了个7数字插入排序函数,你可以直接或修改后使用。
1.gif
2.gif


演示插入排序.SC2Map (13.17 KB, 下载次数: 4)



点评

非常感谢,我先研究下  详情 回复 发表于 2016-4-14 20:54
回复

使用道具 举报

 楼主| 发表于 2016-4-14 20:54:02 | 显示全部楼层
yxxiaobin 发表于 2016-4-14 17:00
帮你做了个7数字插入排序函数,你可以直接或修改后使用。

非常感谢,我先研究下

点评

判定顺子不需要对牌进行排序,我们可以比较最大的牌和最小的牌的差相减即可。用类似打擂台的办法进行比较,然后最大的数减最小的数差为4时可以判定顺子。如果是需要判定的牌大于组成顺子的牌,那还可以使用一种“启  详情 回复 发表于 2016-4-14 23:02
回复

使用道具 举报

发表于 2016-4-14 23:02:32 | 显示全部楼层
aolinge2017 发表于 2016-4-14 20:54
非常感谢,我先研究下

判定顺子不需要对牌进行排序,我们可以比较最大的牌和最小的牌的差相减即可。用类似打擂台的办法进行比较,然后最大的数减最小的数差为4时可以判定顺子。如果是需要判定的牌大于组成顺子的牌,那还可以使用一种“启发”式的算法,即每两张牌之间相减,当差为4时选择所有牌进行判定,比如5-1=4 那么选择所有牌判断是不是有2、3、4 即最小的牌假设为Amix 选取所有牌 是否满足Amix+1、Amix+2、Amix+3 满足一个设置一个局部变量为真比如a1、a2、a3 等待所有牌比较完后判断。
当然你不需要超过5张的牌所以红字后忽略

点评

你的意思是2,2,3,3,6是顺子?所以只判断最大和最小牌之差是不可靠的。必须要判定每一张牌,哪怕漏掉一张也不行。 启发式算法的思路不错。可以在最大牌和最小牌差不是4的时候直接弃掉顺子规则,而不必再判定其他  详情 回复 发表于 2016-4-14 23:07
回复

使用道具 举报

发表于 2016-4-14 23:07:47 | 显示全部楼层
priceles 发表于 2016-4-14 23:02
判定顺子不需要对牌进行排序,我们可以比较最大的牌和最小的牌的差相减即可。用类似打擂台的办法进行比较 ...

你的意思是2,2,3,3,6是顺子?所以只判断最大和最小牌之差是不可靠的。必须要判定每一张牌,哪怕漏掉一张也不行。
启发式算法的思路不错。可以在最大牌和最小牌差不是4的时候直接弃掉顺子规则,而不必再判定其他的牌。但是符合差值时,仍然要判定剩余牌是否也符合规则。

点评

判断最大牌和最小牌差的方法是可靠的,只需要在“打擂台”的时候把已经比较的牌大小记录下来,当有重复的时候终止。当然是我遗漏了这一步。  详情 回复 发表于 2016-4-15 12:22
回复

使用道具 举报

发表于 2016-4-15 12:22:53 | 显示全部楼层
yxxiaobin 发表于 2016-4-14 23:07
你的意思是2,2,3,3,6是顺子?所以只判断最大和最小牌之差是不可靠的。必须要判定每一张牌,哪怕漏掉 ...

判断最大牌和最小牌差的方法是可靠的,只需要在“打擂台”的时候把已经比较的牌大小记录下来,当有重复的时候终止。当然是我遗漏了这一步。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-27 18:09 , Processed in 0.745653 second(s), 37 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表