24 - 制作发牌器
本帖最后由 鱼C-小师妹 于 2022-3-2 20:39 编辑在线讲解:
https://www.bilibili.com/video/BV1PU4y1f7kS
关于递归的玩法,我们先告一段落。
从这讲开始,我们用 Python 来编写几个小游戏~
众所周知,一副扑克有 54 张牌,现在假设玩某种扑克游戏,要将去除大小王的 52 张牌分给 4 个人。
我们自己动手设计一个程序完成自动发牌的工作。
52 张牌分给 4 位朋友,每人应当有 13 张牌。
人工发牌时,先进行洗牌,然后将洗好的牌按一定的顺序发给每一个人对不对。
我们为了便于计算机模拟,我们要将上面的人工方式进行修改。
既然是计算机模拟,如果我们一上来就传入黑桃,计算机就只会认为这是一串字符。
先要来建立一个对应关系,例如按照“黑红梅方”的顺序,从 2~A,按照顺序排列。
花色\点数 2 3 4 5 6 7 8 9 10 J Q K A
黑桃 0 1 2 3 4 5 6 7 8 9 10 11 12
红桃 13 14 15 16 17 18 19 20 21 22 23 24 25
梅花 26 27 28 29 30 31 32 33 34 35 36 37 38
方块 39 40 41 42 43 44 45 46 47 48 49 50 51
按照上面表格中的对应顺序将每一张牌用一个数字代表。
这样如果生成 45 ,我们通过观察,查表可知代表方块 8。
但是计算机没有眼睛,怎么让它知道 45 是什么呢?
注意观察,四种花色区间有什么特点呢?
没错啦,黑桃小于 13,红桃大等于 13 但是小于 25,以此类推。
这个规律进一步分析就是“取整”啦~
四种花色对 13 进行 // ,只会得到 0,1,2,3 四个值~
还是拿 45 举例子,因为 45 // 13 == 3,3 就对应方块。
每张牌都包含两个特性:花色和点数。
花色有了,那么如何找到点数呢?
我们可以先来创建一个代表牌点数的列表:
n = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
这个列表中对应 13 个点数~
索引 0 对应点数 2,索引 1 对应点数 3,以此类推~
四种花色都遵循相同规则。
而这个规则背后是什么规律呢?
就是相同点数的余数一样!
拿第一列来说:
0,13,26,39
它们除以 13 的余数为 0。
第二列:
1,14,27,40
它们除以 13 的余数为 1。
没错啦可以直接拿 45 % 13,结果为 6,就对应 8。
这样就让计算机找到 45 为方块 8!
思路有了,我们来动手写代码吧。
发牌这个操作就可以变成将含有 0 到 51 个数的列表分成 4 个子列表的过程。
0 到 51 个数,就是生成一个随机数的过程,只不过随机数不能有重复。
还记得我们之前用的 random 模块吗?
这次又要用到它,生成 0~51 之间的共 52 个随机数,以产生洗牌的效果。
先来创建一个存放上面表格对应顺序的总长度列表:
a = * 52
要平均分成 4 个子列表,每个中都是 13 张牌:
card1 = * 13
card2 = * 13
card3 = * 13
card4 = * 13
牌和点数需要建立对应关系,4 堆牌就需要四个索引。
创建一个变量 t 用来控制总的发牌数:
c1, c2, c3, c4, t = 0, 0, 0, 0, 0
接下来要控制发牌并产生 0 到 51 间的随机数:
while ( t <= 51):
m = random.randint(0,52)
既然是随机数肯定是随机产生的,牌的点数虽然可以重复,但是同色不可能有两张。
也就是说上面对应关系的 52 个数都应该是唯一不重复的。
所以这里我们就要加一个去重操作:
[*]flag = 1 表示产生的是新的随机数
[*]flag = 0 表示新产生的随机数已经存在
这种去重方式也用过几次啦,还没记住的,务必要记住用法哦:
flag, i = True, 1
while i <= t and flag:
if m == a:
flag = False
i += 1
如果产生新的随机数,则存入数组:
if flag:
a == m
t += 1
接下来就要将牌分到不同花色中,既然是 4 种花色,就可以用 “%” 取余来分配。
然后根据 t 的余数,判断当前的牌应存入哪个数组中:
while i <= t and flag:
if m == a:
flag = 0
i += 1
if flag:
a = m
t += 1
if t % 4 == 0:
card1 = a
c1 += 1
elif t % 4 == 1:
card2 = a
c2 += 1
elif t % 4 == 2:
card3 = a
c3 += 1
elif t % 4 == 3:
card4 = a
c4 += 1
到这一步 4 个子列表就分好啦,我们可以先打印下:
print(card1)
print(card2)
print(card3)
print(card4)
不对!!
怎么不是每组中都是 13 个值呢?
竟然是从 1 到 51,51 个数,哪里出问题了呢?
在这里:
if m == a:
我们原意是打算判断是否随机有重复~
初始化的 a 中全是 0!
0 这个数是我们需要的,那么 m 第一次有没有随机生成 0 的可能呢?
有!
所以 a 的初始化值不应该是 0 到 51 之间的整数,可以是其他的,我们就用 52:
a = * 52
现在再来打印看下:
没错啦,各 13 个数,而且没有重复。
接下来只需将它们转换成对应的牌即可。
总共 4 种花色,52 张牌,由于每个花色的符号不一样,就需要进行划分。
card1 // 13 == 0
余数 0,1,2,3 对应 4种花色。
然后还要通过“取余”将值转换回对应牌值:
def finalPrint(card,n):
print("\n♠",end='')
for i in range(13):
if card // 13 == 0:
print(n % 13],end = '')
print("\n♥",end='')
for i in range(13):
if card // 13 == 1:
print(n % 13],end = '')
print("\n♣",end='')
for i in range(13):
if card // 13 == 2:
print(n % 13],end = '')
print("\n♦",end='')
for i in range(13):
if card // 13 == 3:
print(n % 13],end = '')
print()
代码中的乱码是因为论坛暂时不支持字符编码,复制到本地就能看到啦。
好啦,打印看下结果吧:
没错啦,是我们要的结果~
但是吧,作为一名负责任的开发者,要充分为用户考虑。
现在的排列顺序是乱的,可以不可以排序呢?
肯定可以啦,在打印前对 4 个 card 进行排序:
card1 = sorted(card1)
card2 = sorted(card2)
card3 = sorted(card3)
card4 = sorted(card4)
现在看下结果:
是不是好看很多啦!
源码:
搞定,下课! 本帖最后由 傻眼貓咪 于 2021-12-23 19:22 编辑
{:10_266:} 应该很有趣 。 {:5_90:} random 人生的奔跑,不在于瞬间的爆发,而取决于途中的坚持。 牛逼 {:7_146:}{:7_146:}{:7_146:}{:7_146:}{:7_146:} 看了看看看 学习下代码 学习一下 游戏中学习python 傻眼貓咪 发表于 2021-9-16 18:54
代码:输出结果:
剧透警告!! 鱼C-小师妹 发表于 2021-12-23 19:09
剧透警告!!
已删 Thanks♪(・ω・)ノ {:5_95:} # 题干
# 动手设计一个程序完成自动发牌的工作, 分别将52 张牌分发给 4 位朋友,每人应当有 13 张牌。
def Print_result(Person):
cardfacechar = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
str1 = '♠ '
str2 = '♥ '
str3 = '♦ '
str4 = '♣ '
Person.sort()
for index in range(13):
number = Person
if 0 < number/13 <= 1:
str1 += f'{cardfacechar} '
elif 1 < number/13 <= 2:
str2 += f'{cardfacechar} '
elif 2 < number/13 <= 3:
str3 += f'{cardfacechar} '
else:
str4 += f'{cardfacechar} '
return (str1+'\n'+str2+'\n'+str3+'\n'+str4+'\n')
PersonTotal = ['*'] * 52
import random as r
index = 0
while index in range(52):
each = r.randint(1, 52)
if each not in PersonTotal:
PersonTotal = each
index += 1
else:
continue
Person1 = PersonTotal
Person2 = PersonTotal
Person3 = PersonTotal
Person4 = PersonTotal
print(Print_result(Person1))
print(Print_result(Person2))
print(Print_result(Person3))
print(Print_result(Person4)) {:5_109:} random.randint(a,b)函数包含a和b吧,如果是random.randint(0,52)的话就有53个值了,后续打印的过程会出问题
页:
[1]
2