Python控牌情况的模拟

Posted 余者皆可

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python控牌情况的模拟相关的知识,希望对你有一定的参考价值。

代码如下

# 构造必输牌池
import numpy as np
import random
# 定义多维数列转换函数,后面输出参数使用
def flatten(a):
    if not isinstance(a, (list, )):
        return [a]
    else:
        b = []
        for item in a:
            b += flatten(item)
    return b 
# 构造差牌牌池
pl_bad=range(1,6)
# 正常的差牌
pool_bad=(np.repeat(pl_bad,4)).tolist()
# 无炸的差牌
pool_bad_nb=(np.repeat(pl_bad,3)).tolist()
# 构造中间牌牌池
pl_mid=range(6,9)
pool_mid=(np.repeat(pl_mid,4)).tolist()
# 无炸的中牌
pool_mid_nb=(np.repeat(pl_mid,3)).tolist()
# 不含双王的好牌牌局
pl_gd=range(9,14)
pool_gd_nj=(np.repeat(pl_gd,4)).tolist()
# 不含双王且无炸的好牌牌局
pool_gd_nj_nb=(np.repeat(pl_gd,3)).tolist()
# 提示
# 差中好的发牌概率prob
prob=[0.8,0.1,0.1]
# 生成用于储存概率的数组
pick_num=np.repeat(0,len(prob))
# 发牌张数
for i in range(0,3):
    pick_num[i]=round(17*prob[i])
    
# 判断总牌数是否合理,调整差中好牌的牌数,若大于17张则减少好牌,反之增加差牌
if sum(pick_num)>17:
    pick_num[2]=pick_num[2]-(sum(pick_num)-17)
elif sum(pick_num)<17:
    pick_num[0]=pick_num[0]-(sum(pick_num)-17)
else:
    pass
    

# 分批抽取
result_ls=[]
for pool_kind,pick_n in zip((pool_bad_nb,pool_mid_nb,pool_gd_nj_nb),pick_num):
    result=np.random.choice(pool_kind,pick_n,replace=False).tolist()
    result_ls.append(result)
#败家从差中好牌中抽取的牌数
pl_bad_rm=result_ls[0]
pl_mid_rm=result_ls[1]
pl_gd_rm=result_ls[2]
# 转换为1维数组并排序
result_ls=flatten(result_ls)
result_ls.sort()

# 转换为列表
loser_1=result_ls
# 统计统计败家牌局中出现三张的牌值

temp=np.unique(result_ls,return_counts=True) #此时temp为tuple不能直接操作array,用temp临时转换一下
mat_ls=np.array(temp)

in_case=mat_ls[0,(np.where(mat_ls[1,]==3))] #incase代表败家手中三张牌的牌值,不能是最后三张,这三张将会发给一个normal的玩家

# 移除已经使用的牌以及in_case
# 构造牌池,不包括大小王
pool_1 = range(1, 14)
np.repeat(pool_1, 4)
# 转换为列表
pool = (np.repeat(pool_1, 4)).tolist()


#胜家从牌池中抽取15张
## 差牌移除败家
for bad in pl_bad_rm:
    pool_bad.remove(bad)
## 差牌中移除in_case
for bd in in_case[0,]:
    while bd in pool_bad:
        pool_bad.remove(bd)
## 中牌移除..
for mid in pl_mid_rm:
    pool_mid.remove(mid)
## 好牌移除..
for gd in pl_gd_rm:
    pool_gd_nj.remove(gd)
## 抽取个数
# 差中好的发牌概率prob_winer
prob_winer=[0.1,0.2,0.7]
# 生成用于储存概率的数组
pick_num=np.repeat(0,len(prob_winer))
# 发牌张数
for i in range(0,3):
    pick_num[i]=round(15*prob_winer[i])
# 判断各阶段牌数是否合理
# 判断总牌数是否合理,调整差中好牌的牌数,若大于15张则减少查牌,反之增加好牌
if sum(pick_num)>15:
    pick_num[0]=pick_num[0]-(sum(pick_num)-15)
elif sum(pick_num)<15:
    pick_num[2]=pick_num[2]-(sum(pick_num)-15)
else:
    pass
# 分批抽取
result_ls_winer=[]
for pool_kind,pick_n in zip((pool_bad,pool_mid,pool_gd_nj),pick_num):
    result=np.random.choice(pool_kind,pick_n,replace=False).tolist()
    result_ls_winer.append(result)
# 胜家手牌转换为一维数列
result_ls_winer=flatten(result_ls_winer)
result_ls_winer.sort()
#胜家添加双王
result_ls_winer.append(14)
result_ls_winer.append(15)
# 牌池移除胜家
for w_card in result_ls_winer[0:15]:
    pool.remove(w_card)
# 牌池移除败家
for l_card in loser_1:
    pool.remove(l_card)


# 牌池移除in_case
if len(in_case[0,])>0:
    for in_card in in_case[0,].tolist():
        pool.remove(in_card)
else:
    pass
# 牌池抽取17-len(in_case[0,])张牌
norm_er=np.random.choice(pool,(17-len(in_case[0,])),replace=False).tolist()
# 剩余牌数为normer
norm_ls=norm_er+in_case[0,].tolist()
norm_ls.sort()
# 胜家手牌result_ls_winer
# 败家手牌loser_1
# 另外一家norm_ls
# 以下内容为转换java牌值
def trans_card(loser_1,winer_1,norm_er):
    pool_dict={"0":12,"1":12,"2":12,"3":12,"4":13,"5":13,"6":13,"7":13,"8":1,"9":1,"10":1,"11":1,"12":2,"13":2,"14":2,"15":2
,"16":3,"17":3,"18":3,"19":3,"20":4,"21":4,"22":4,"23":4,"24":5,"25":5,"26":5,"27":5,"28":6,"29":6,"30":6,"31":6,"32":7,"33":7,"34":7,"35":7,"36":8,"37":8,"38":8,"39":8,"40":9,"41":9,"42":9,"43":9,"44":10,"45":10,"46":10,"47":10,"48":11,"49":11,"50":11,"51":11,"52":14,"53":15}
    key_list = []
    value_list = []
    for key, value in pool_dict.items():
        key_list.append(key)
        value_list.append(value)
    loser_card = []
    for number in loser_1:
        index_mid = value_list.index(number)
        add_card = key_list[index_mid]
        add_card = int(add_card)
        value_list.pop(index_mid)
        key_list.pop(index_mid)
        loser_card.append(add_card)
    winer_card = []
    for number1 in winer_1:
        index_mid = value_list.index(number1)
        add_card = key_list[index_mid]
        add_card = int(add_card)
        value_list.pop(index_mid)
        key_list.pop(index_mid)
        winer_card.append(add_card)
    norm_card = []
    for number2 in norm_er:
        index_mid = value_list.index(number2)
        add_card = key_list[index_mid]
        add_card = int(add_card)
        value_list.pop(index_mid)
        key_list.pop(index_mid)
        norm_card.append(add_card)
    for pt in (loser_card, winer_card, norm_card):
        print(pt)
#传递给java
trans_card(loser_1,result_ls_winer,norm_ls)

因为后端使用java,所以注释中写的是传递给java

其实质上是对牌型值一一对应起来

接收端是8对应牌值3

我书写的代码中1代表牌值3

以上是关于Python控牌情况的模拟的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

常用python日期日志获取内容循环的代码片段

python 有用的Python代码片段

Python 向 Postman 请求代码片段

python [代码片段]一些有趣的代码#sort

使用 Python 代码片段编写 LaTeX 文档