马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 鱼C-小师妹 于 2022-3-2 20:39 编辑
在线讲解:
关于递归的玩法,我们先告一段落。
从这讲开始,我们用 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,以此类推~
四种花色都遵循相同规则。
而这个规则背后是什么规律呢?
就是相同点数的余数一样!
拿第一列来说:
它们除以 13 的余数为 0。
第二列:
它们除以 13 的余数为 1。
没错啦可以直接拿 45 % 13,结果为 6,就对应 8。
这样就让计算机找到 45 为方块 8!
思路有了,我们来动手写代码吧。
发牌这个操作就可以变成将含有 0 到 51 个数的列表分成 4 个子列表的过程。
0 到 51 个数,就是生成一个随机数的过程,只不过随机数不能有重复。
还记得我们之前用的 random 模块吗?
这次又要用到它,生成 0~51 之间的共 52 个随机数,以产生洗牌的效果。
先来创建一个存放上面表格对应顺序的总长度列表:
要平均分成 4 个子列表,每个中都是 13 张牌:
card1 = [0] * 13
card2 = [0] * 13
card3 = [0] * 13
card4 = [0] * 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[i]:
flag = False
i += 1
如果产生新的随机数,则存入数组:
if flag:
a[t] == m
t += 1
接下来就要将牌分到不同花色中,既然是 4 种花色,就可以用 “%” 取余来分配。
然后根据 t 的余数,判断当前的牌应存入哪个数组中:while i <= t and flag:
if m == a[i]:
flag = 0
i += 1
if flag:
a[t] = m
t += 1
if t % 4 == 0:
card1[c1] = a[t - 1]
c1 += 1
elif t % 4 == 1:
card2[c2] = a[t - 1]
c2 += 1
elif t % 4 == 2:
card3[c3] = a[t - 1]
c3 += 1
elif t % 4 == 3:
card4[c4] = a[t - 1]
c4 += 1
到这一步 4 个子列表就分好啦,我们可以先打印下:
print(card1)
print(card2)
print(card3)
print(card4)
不对!!
怎么不是每组中都是 13 个值呢?
竟然是从 1 到 51,51 个数,哪里出问题了呢?
在这里:
我们原意是打算判断是否随机有重复~
初始化的 a 中全是 0!
0 这个数是我们需要的,那么 m 第一次有没有随机生成 0 的可能呢?
有!
所以 a 的初始化值不应该是 0 到 51 之间的整数,可以是其他的,我们就用 52:
现在再来打印看下:
没错啦,各 13 个数,而且没有重复。
接下来只需将它们转换成对应的牌即可。
总共 4 种花色,52 张牌,由于每个花色的符号不一样,就需要进行划分。
余数 0,1,2,3 对应 4种花色。
然后还要通过“取余”将值转换回对应牌值:
def finalPrint(card,n):
print("\n♠",end='')
for i in range(13):
if card[i] // 13 == 0:
print(n[card[i] % 13],end = '')
print("\n♥",end='')
for i in range(13):
if card[i] // 13 == 1:
print(n[card[i] % 13],end = '')
print("\n♣",end='')
for i in range(13):
if card[i] // 13 == 2:
print(n[card[i] % 13],end = '')
print("\n♦",end='')
for i in range(13):
if card[i] // 13 == 3:
print(n[card[i] % 13],end = '')
print()
代码中的乱码是因为论坛暂时不支持字符编码,复制到本地就能看到啦。
好啦,打印看下结果吧:
没错啦,是我们要的结果~
但是吧,作为一名负责任的开发者,要充分为用户考虑。
现在的排列顺序是乱的,可以不可以排序呢?
肯定可以啦,在打印前对 4 个 card 进行排序:
card1 = sorted(card1)
card2 = sorted(card2)
card3 = sorted(card3)
card4 = sorted(card4)
现在看下结果:
是不是好看很多啦!
源码:
py25.py.zip
(1.04 KB, 下载次数: 15, 售价: 10 鱼币)
搞定,下课! |