模拟随机发牌
四个人打扑克,用一副扑克牌,抽掉大小王,剩余 52 张牌,洗牌后平分给四个人,每人 13 张,并按花色和点数整理。现在用 ♠,♥,♦,♣表示扑克牌花色,例如 ♠8 表示黑桃 8,♥K 表示红桃 K,请写一个程序实现发牌过程,输出 4 个序列。
首先将 52 个数字使用随机数排序,将数分成 4 组,调用子程序,将当前数作为参数传入,在子程序中计算该数对应的牌,返回一张由花色和点数组成的牌,此过程即为发牌过程。
A |
B |
|
1 |
=52.sort(rand()) |
|
2 |
=A1.group((#-1)\13) |
|
3 |
=A2.(~.sort().(cardid(~))) |
=A3.(~.concat@c()) |
4 |
||
5 |
func cardid(n) |
=mid("KA234567890JQ",1+n%13,1) |
6 |
=mid("♠♥♦♣", (n-1)\13+1,1) |
|
7 |
return B6+if(B5=="0","10",B5) |
http://try.scudata.com.cn/try.jsp?splx=ExA005mnsjfp1.splx
A1将52个数随机打乱,rand生成一个随机数,用sort即可将序列随机排序。
A2把这些数分为4组,由于这些数是随机排序的,因此按顺序依次分到4组即可,每组13张牌。SPL可以用A.group(x)把集合A的成员分组,x计算结果相同的在同一组中,a\b表示整数除法,结果只保留整数部分。
A3循环每人的牌组,排序后,调用子程序将数转换为对应的扑克牌花色和点数。
B3用concat将每个人得到的牌用字符串表示,结果如下:
A5定义了子程序cardid,用牌对应的数作为参数n。转换时1~13表示黑桃A~K,14~26表示红桃A~K,以此类推。B5计算牌的点数,用字符串中对应的一个字符表示,特别的,10用0表示。SPL中,用mid()函数可以获得字符串中的一部分。B6计算牌的花色,同样用字符串中的一个字符表示。B6将花色和点数拼接后返回,在这里将0转为10。
在发牌时,每张牌都会出现,因此也可以用循环生成每张牌的花色和点数再分组和排序,而无需调用子程序转换。如:
A |
|
1 |
[♠,♥,♦,♣] |
2 |
[A,2,3,4,5,6,7,8,9,10,J,Q,K] |
3 |
=A1.conj(A2.(A1.~/~)) |
4 |
=52.sort(rand()).group(#%4) |
5 |
=A4.(~.sort().(A3(~)).concat@c()) |
http://try.scudata.com.cn/try.jsp?splx=ExA005mnsjfp2.splx
A1和A2中分别列出花色序列和点数序列。
A3循环计算每个花色,在循环中又嵌套循环每个点数,生成每张牌的花色和点数,用conj将各个花色的牌点拼为一个序列,如下:
A4将52个序号随机排序,然后平均分为4组。此时每组中的序号是乱序的:
A55按照需要先将每组中的序号排序,排序后再根据序号从A3中取出对应牌的花色和点数,由于是随机发牌,A5中结果和前一种方法是不同的:
英文版