用Python简单模拟《原神》抽卡系统

本文详细讲解了如何基于Python实现一个《原神》风格的抽卡系统,涉及概率计算、保底机制和结果展示。
摘要由CSDN通过智能技术生成

原始代码参考自另一位博主的文章:

用Python简单模拟《原神》抽卡系统_抽卡系统怎么做出来的-CSDN博客

在其代码上修复了一些概率的小问题,以及增加了显示效果和统计。

效果如下

直接贴上code

"""
要求:180抽大保底,90抽小保底
10抽必出4星
90抽必出5星  抽到的时候up和常驻各占50%
P = {
0.006                       i<=73
0.006 + 0.06(i - 73)        74<=i<=89
1                           i=90
}
五星中奖概率为0.6%
四星概率为5.1%
其余的三星概率是96.85%
大保底小报底各占50%
"""
import os
import random
from collections import Counter
import colorama
from colorama import Fore, Back, Style

# 初始化抽卡的概率
def rate_initialization():
    rate_list.clear()
    rate_list.extend(['蓝' for temp in range(9430)])
    rate_list.extend(['紫' for temp in range(510)])
    rate_list.extend(['金' for temp in range(60)])
    random.shuffle(rate_list)

# 74抽之后增加概率
def rate_update(already_times):
    rate_threshold = 73
    rate_dict = Counter(rate_list)
    if already_times >= rate_threshold:
        expected_fiveStar_num = 60 + 600 * (already_times + 1 - rate_threshold)
        if expected_fiveStar_num > rate_dict['金']:
            for _ in range(expected_fiveStar_num-rate_dict['金']):
                if '蓝' in rate_list:
                    rate_list.remove('蓝')
                elif '紫' in rate_list:
                    rate_list.remove('紫')
                else:
                    return
                rate_list.append('金')
            random.shuffle(rate_list)

# 大保底还是小保底
def get_isGuarantees():
    try:
        with open('recording\\isGuarantees.txt', 'r', encoding='utf-8') as file:
            if file.read() == 'true':
                isGuarantees = True 
            else:
                isGuarantees = False
    except BaseException:
        with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:
            file.write('false')
        with open('recording\\isGuarantees.txt', 'r', encoding='utf-8') as file:
            if file.read() == 'true':
                isGuarantees = True
            else:
                isGuarantees = False
    return isGuarantees

# 根据是否大保底,出金
def guarantees():
    isGuarantees = get_isGuarantees()

    if isGuarantees:
        with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:
            file.write('false')
        return True
    else:
        res = random.choice(['up', 'resident'])
        if res == 'up':
            with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:
                file.write('false')
            return True
        else:
            with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:
                file.write('true')
            return False


# 创建一个文件夹在同一个目录下
def mkdir(path):
    folder = os.path.exists(path)
    if not folder:  # 判断文件夹是否存在
        os.makedirs(path)  # 不存在就新建一个


# 抽卡次数记录
def record_times(number):
    with open('recording\\times.txt', 'w+', encoding='utf-8') as file:
        file.write(str(number))


# 抽卡次数读取
def read_times():
    try:
        with open('recording\\times.txt', 'r', encoding='utf-8') as file:
            number = int(file.read())
            return number
    except BaseException:
        with open('recording\\times.txt', 'w+', encoding='utf-8') as file:
            file.write('0')
        return 0

# 记录紫色保底,10抽必出紫色
def record_rare(number):
    with open('recording\\rare.txt', 'w+', encoding='utf-8') as file:
        file.write(str(number))


# 读取紫色保底
def read_rare():
    try:
        with open('recording\\rare.txt', 'r', encoding='utf-8') as file:
            return int(file.read())
    except BaseException:
        with open('recording\\rare.txt', 'w+', encoding='utf-8') as file:
            file.write('0')
            return 0

# 写入抽卡记录
def recode_gacha(result):
    with open('抽卡记录.txt', 'r', encoding='utf-8') as file:
        record_list = file.read()
        if len(record_list) >= 300:
            with open('抽卡记录.txt', 'a+', encoding='utf-8') as writeFile:
                pass
            file.write(result)
        else:
            with open('抽卡记录.txt', 'a+', encoding='utf-8') as writeFile:
                pass


mkdir('卡池')
mkdir('recording')
while True:
    try:
        with open('卡池\\up.txt', 'r', encoding='utf-8') as tempFile:
            up = tempFile.read()
        with open('卡池\\fiveStar.txt', 'r', encoding='utf-8') as tempFile:
            fiveStar = tempFile.read().split(sep=' ')
            random.shuffle(fiveStar)
        with open('卡池\\fourStar_up.txt', 'r', encoding='utf-8') as tempFile:
            fourStar_up = tempFile.read().split(sep=' ')
            random.shuffle(fourStar_up)
        with open('卡池\\fourStar.txt', 'r', encoding='utf-8') as tempFile:
            fourStar = tempFile.read().split(sep=' ')
            fourStar = [item for item in fourStar if item not in fourStar_up]
            random.shuffle(fourStar)
        with open('卡池\\threeStar.txt', 'r', encoding='utf-8') as tempFile:
            threeStar = tempFile.read().split(sep=' ')
            random.shuffle(threeStar)
        break
    except BaseException:
        print('你好,欢迎使用本模拟器,我在上面帮你创建了几文件夹,在里面填入卡池的东西就好了,用空格隔开')
        with open('卡池\\up.txt', 'w+', encoding='utf-8'):
            pass
        with open('卡池\\fiveStar.txt', 'w+', encoding='utf-8'):
            pass
        with open('卡池\\fourStar.txt', 'w+', encoding='utf-8'):
            pass
        with open('卡池\\threeStar.txt', 'w+', encoding='utf-8'):
            pass
        input('填好了就回个车')

colorama.init()
rate_list = list()
rate_initialization()
get_rare_roles = []
total_num = 0
fourStar_isGuarantees = False
while True:

    already_times = read_times()
    already_rare = read_rare()

    print("\n -> 小保底已垫了%d抽" % already_times)
    isGuarantees = get_isGuarantees()
    if isGuarantees:
        print(" -> 大保底在手,不慌~")
    else:
        print(" -> 没大保底,祝您出金不歪~")
    print("已抽卡%d次" % total_num)

    try:
        input_content = input('\n请输入抽数,退出请输入q\n请输入:')
        if input_content == 'q':
            print("\n抽卡统计:")
            print("本次总计抽卡%d次" % total_num)
            print("出(4星/5星)角色情况:")
            counts = dict(Counter(get_rare_roles))
            print(counts)
            exit(0)
        else:
            count = int(input_content)
            total_num += count
    except ValueError:
        print('你这输入的啥玩意')
        continue

    round = []
    for _ in range(count // 10):
        round.append(10)
    if count % 10:
        round.append(count % 10)

    for draws in round:
        fiveStar_num = 0
        fourStar_num = 0
        res_list = [[], [], []] # 第一个放金,第二个放紫,第三个放蓝
        flag_up = False
        for _ in range(draws):
            rate_update(already_times)
            if (already_times==89 and already_rare==8 ) or already_rare >= 9:
                # 连续9 发没出紫,必出紫
                character_rank = '紫'
            else:
                character_rank = random.choice(rate_list)

            already_times += 1
        
            if character_rank == '蓝':
                role = random.choice(threeStar)
                res_list[2].append(f"{Fore.BLUE}{role}{Style.RESET_ALL}")

                already_rare += 1

            elif character_rank == '紫':
                fourStar_role = random.choice(fourStar)

                if fourStar_isGuarantees: # 四星角色小保底:如果上一个出的不是up四星,下一次必出
                    role = random.choice(fourStar_up)
                    fourStar_isGuarantees = False
                else:
                    fourStar_isGuarantees = random.choice([True, False])
                    if fourStar_isGuarantees:
                        role = random.choice(fourStar)
                    else:
                        role = random.choice(fourStar_up)

                get_rare_roles.append(role)
                res_list[1].append(f"{Fore.MAGENTA}{role}{Style.RESET_ALL}")

                fourStar_num += 1
                already_rare = 0

            elif character_rank == '金':
                rate_initialization()
                if guarantees():
                    role = up
                    flag_up = True
                else:
                    role = random.choice(fiveStar)
                get_rare_roles.insert(0, role)

                res_list[0].append(f"{Fore.YELLOW}{role}{Style.RESET_ALL}")

                fiveStar_num += 1
                already_rare += 1
                already_times = 0 # 垫卡次数清零

        record_times(already_times)
        record_rare(already_rare)

        print("\n%d连抽出货情况:" % draws)
        print('==================================================')

        if fiveStar_num > 1:
            print("恭喜!%d连%d金!" %(draws, fiveStar_num))
        elif fiveStar_num == 1:
            if flag_up:
                print("出货啦~")
            else:
                print("金色传...可惜歪了")
        elif fourStar_num > 0:
            print("%d紫" % fourStar_num)

        print(f' '.join(list(map(lambda x: f' '.join(x), res_list))))

        print('==================================================')
        print(" ")

UP角色

up.txt

就写一个限定角色就行,如:纳西妲

五星常驻

fiveStar.txt

刻晴 莫娜 七七 迪卢克 琴 迪希雅 提纳里

四星角色物品

fourStar.txt

香菱 行秋 班尼特 菲谢尔 鹿野院平藏 罗莎莉亚 芭芭拉 砂糖 凝光 柯莱 雷泽 重云 诺艾尔 云堇 五郎 九条裟罗 久岐忍 烟绯 辛焱 迪奥娜 早柚 北斗 托马 宗室大剑 祭礼大剑 西风大剑 黑岩斩刀 钟剑 白影剑 千岩古剑 西风剑 祭礼剑 笛剑 暗巷闪光 祭礼弓 破魔之弓 西风猎弓 绝弦 昭心 万国诸海图 西风秘典 流浪乐章 祭礼残章 千岩长枪 西风长枪

四星UP角色,一般是3个

夏洛蒂 北斗 柯莱

三星武器

threeStar.txt

就写了个蓝色,有兴趣的可以自己写一下

(记得在卡池里放东西,也就是上门这些txt文件)

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值