鱼C-小师妹 发表于 2021-9-16 18:15:45

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-9-16 18:54:25

本帖最后由 傻眼貓咪 于 2021-12-23 19:22 编辑

{:10_266:}

我叫武炜昊 发表于 2021-9-16 21:21:10

应该很有趣

一弦丶 发表于 2021-10-7 19:14:51

love_qj 发表于 2021-10-9 17:30:41

{:5_90:}

游刃鱿鱼 发表于 2021-11-20 22:17:59

random

hjc757 发表于 2021-11-21 01:41:43

人生的奔跑,不在于瞬间的爆发,而取决于途中的坚持。

学习编程中的Ben 发表于 2021-11-21 11:22:48

牛逼

傻眼貓咪 发表于 2021-11-21 11:52:24

{:7_146:}{:7_146:}{:7_146:}{:7_146:}{:7_146:}

l68ooo 发表于 2021-11-24 00:28:51

看了看看看

疾风怪盗 发表于 2021-11-27 18:11:56

学习下代码

春风亭朝小树 发表于 2021-12-2 16:58:35

学习一下

寻找XX中 发表于 2021-12-14 16:26:18

游戏中学习python

鱼C-小师妹 发表于 2021-12-23 19:09:06

傻眼貓咪 发表于 2021-9-16 18:54
代码:输出结果:

剧透警告!!

傻眼貓咪 发表于 2021-12-23 19:22:34

鱼C-小师妹 发表于 2021-12-23 19:09
剧透警告!!

已删

aironeng 发表于 2021-12-24 15:10:30

Thanks♪(・ω・)ノ

落花盈满绣! 发表于 2022-3-8 20:33:00

{:5_95:}

Hyjxsssss 发表于 2022-5-12 19:22:10

# 题干
# 动手设计一个程序完成自动发牌的工作, 分别将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))

hornwong 发表于 2022-5-12 19:57:32

{:5_109:}

zfxsdhr 发表于 2023-7-2 11:02:20

random.randint(a,b)函数包含a和b吧,如果是random.randint(0,52)的话就有53个值了,后续打印的过程会出问题
页: [1] 2
查看完整版本: 24 - 制作发牌器