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

  • 简介
  • 代码思想
    • 保底机制
    • 概率
    • 概率公式
  • 代码构建
    • 导入软件包random和os
    • 初始化概率
    • 增加概率
    • 保底机制
    • 创建文件夹
    • 抽卡次数读取
    • 出金之后的判断
    • 10抽必出紫
    • 主体部分
  • 完整代码
  • 使用提醒
    • 记得在卡池放东西
    • UP角色
    • 五星常驻
    • 四星角色
    • 三星武器
    • 重要的事情重复一遍,别忘了往卡池放东西
  • 结束

欢迎
这是我第一次发布文章,就爱闲的没事整点活玩,写的不好还请见谅
使用的语言是Python,因为实在是太方便了o(TヘTo)
对了,要是懒得看代码思想直接跳到完整代码就彳亍

简介

想必大家都听说过原神吧,是米哈游开发的大世界探索游戏。大学一放假就太闲了,于是就用python写了个模拟原神抽卡的程序,其实星铁也适用这个机制
大家可以用它来试试运气,我在测试的时候一次出了三金,两个纳西妲一个琴(炫耀)[为什么我游戏中就没这运气,天天大保底,气死了]
好的,那么废话不多说,我们先说一下原理

代码思想

根据我从网上和官方给出的概率浏览获得的信息:

  • 保底机制

    180抽大保底,90抽小保底

  • 概率

    五星中奖概率为0.6%
    四星角色概率为2.55%
    其余的三星概率是96.85%
    大保底小报底各占50%
    五星概率会从第74抽开始逐渐提高6%

  • 概率公式

    概率 抽卡次数i
    0.006 (i<=73)
    0.006 + 0.06(i - 73) (74<=i<=89)
    1 (i=90)

代码构建

导入软件包random和os

毕竟是抽卡,怎么能少了random
然后这个os是新建文件夹用的
用来保存你的抽卡记录,还有创建你的卡池

import os
import random

初始化概率

其实简单说说就是,先加入9685个蓝色,然后加入255个紫色,再加入6个金色,然后打乱

# 初始化抽卡的概率
def rate_initialization():rate_list.extend(['蓝' for temp in range(9685)])  # 蓝色概率是96.85%rate_list.extend(['紫' for temp in range(255)])  # 紫色概率是2.55%rate_list.extend(['蓝' for temp in range(6)])  # 金色概率是0.6%random.shuffle(rate_list)  # 打乱这个列表

增加概率

其实就是74抽之后,每次把60个蓝色去掉,然后随机插入60个金色
啊,这个踹他的原因就是怕一开始初始化蓝色数量不够,其实没啥用,可以删掉

# 74抽之后增加概率
def rate_add():try:for _ in range(60):rate_list.remove('蓝')rate_list.insert(random.randint(0, len(rate_list) - 1), '金')except ValueError:print('程序异常,概率增加异常')exit()

保底机制

有点小长,说简单点其实就是检测是否有保底这个文本文档,如果有就读一下,没有就创建并写入false表示是小报底,true是大保底。如果是false就在up和常驻中随机抽取,抽到up还是false,抽到常驻变成true,就这么个原理

# 大保底还是小保底
def guarantees():try:with open('recording\\isGuarantees.txt', 'r', encoding='utf-8') as file:if file.read() == 'true':certainly = Trueelse:certainly = Falseexcept 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':certainly = Trueelse:certainly = Falseif certainly:with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:file.write('false')return Trueelse:res = random.choice(['up', 'resident'])if res == 'up':with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:file.write('false')return Trueelse: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)  # 不存在就新建一个

抽卡次数读取

这个其实和上面的保底一样的,找不到文件就新建一个,然后初始化为0

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

出金之后的判断

这就是为什么上面的保底返回的是True和False,出了就append一个up角色,歪了就append一个常驻的角色上去

# 出金了
def gold():rate_initialization()record_times(0)if guarantees():res_list.append(up)return '出货了!!!!!'else:res_list.append(random.choice(fiveStar))return '哇!金色传。。。歪了。。。'

10抽必出紫

第十抽必是紫色,如果不满10抽出了紫色,那么记录则会清零,这是记录和读取的函数

# 记录紫色保底,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

主体部分

其实就是把刚刚的方法或者叫函数也行,统合到了一起初始化卡池,读取,打乱,因为每次抽卡都会有一个动画告诉你是蓝天白云还是出货了,还是只有紫色,所以加了一个描述的打印输出。然后每次出金色都会重置概率,重新初始化,其余的就是照着我写的代码思想写的,其实也不是很难

mkdir('卡池')
mkdir('recording')
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=' ')with open('卡池\\fourStar.txt', 'r', encoding='utf-8') as tempFile:fourStar = tempFile.read().split(sep=' ')with open('卡池\\threeStar.txt', 'r', encoding='utf-8') as tempFile:threeStar = tempFile.read().split(sep=' ')
except BaseException:print('你这还没创建卡池呢\n需要在文件夹卡池中创建上面4个txt文件')exit()
rate_list = list()
rate_initialization()
while True:try:wish = int(input('1、单抽 2、十连抽 3、退出\n请输入:'))except ValueError:print('你这输入的啥玩意')continueif wish == 1:count = 1elif wish == 2:count = 10elif wish == 3:breakelse:print('奇奇怪怪的数字')continueres_list = []result_report = '蓝天白云'temp_list = [random.choice(rate_list) for _ in range(count)]flag = Falsefor character_rank in temp_list:if 73 <= read_times() <= 88:rate_add()elif read_times() >= 89:result_report = gold()continuerecord_times(read_times() + 1)if character_rank == '蓝':record_rare(read_rare() + 1)if read_rare() >= 10:if not flag:result_report = '出了个紫色'record_rare(0)res_list.append(random.choice(fourStar))continueres_list.append(random.choice(threeStar))elif character_rank == '紫':if not flag:result_report = '出了个紫色'record_rare(0)res_list.append(random.choice(fourStar))elif character_rank == '金':flag = Trueresult_report = gold()print(result_report)print(' '.join(res_list))print('==================================================')

接下来是完整代码

完整代码

"""
要求: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%
四星角色概率为2.55%
其余的三星概率是96.85%
大保底小报底各占50%
"""
import os
import random# 初始化抽卡的概率
def rate_initialization():rate_list.extend(['蓝' for temp in range(9685)])rate_list.extend(['紫' for temp in range(255)])rate_list.extend(['蓝' for temp in range(6)])random.shuffle(rate_list)# 74抽之后增加概率
def rate_add():try:for _ in range(60):rate_list.remove('蓝')rate_list.insert(random.randint(0, len(rate_list) - 1), '金')except ValueError:print('程序异常,概率增加异常')exit()# 大保底还是小保底
def guarantees():try:with open('recording\\isGuarantees.txt', 'r', encoding='utf-8') as file:if file.read() == 'true':certainly = Trueelse:certainly = Falseexcept 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':certainly = Trueelse:certainly = Falseif certainly:with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:file.write('false')return Trueelse:res = random.choice(['up', 'resident'])if res == 'up':with open('recording\\isGuarantees.txt', 'w+', encoding='utf-8') as file:file.write('false')return Trueelse: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 numberexcept BaseException:with open('recording\\times.txt', 'w+', encoding='utf-8') as file:file.write('0')return 0# 出金了
def gold():rate_initialization()record_times(0)if guarantees():res_list.append(up)return '出货了!!!!!'else:res_list.append(random.choice(fiveStar))return '哇!金色传。。。歪了。。。'# 记录紫色保底,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 0mkdir('卡池')
mkdir('recording')
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=' ')with open('卡池\\fourStar.txt', 'r', encoding='utf-8') as tempFile:fourStar = tempFile.read().split(sep=' ')with open('卡池\\threeStar.txt', 'r', encoding='utf-8') as tempFile:threeStar = tempFile.read().split(sep=' ')
except BaseException:print('你这还没创建卡池呢\n需要在文件夹卡池中创建上面4个txt文件')exit()
rate_list = list()
rate_initialization()
while True:try:wish = int(input('1、单抽 2、十连抽 3、退出\n请输入:'))except ValueError:print('你这输入的啥玩意')continueif wish == 1:count = 1elif wish == 2:count = 10elif wish == 3:breakelse:print('奇奇怪怪的数字')continueres_list = []result_report = '蓝天白云'temp_list = [random.choice(rate_list) for _ in range(count)]flag = Falsefor character_rank in temp_list:if 73 <= read_times() <= 88:rate_add()elif read_times() >= 89:result_report = gold()continuerecord_times(read_times() + 1)if character_rank == '蓝':record_rare(read_rare() + 1)if read_rare() >= 10:if not flag:result_report = '出了个紫色'record_rare(0)res_list.append(random.choice(fourStar))continueres_list.append(random.choice(threeStar))elif character_rank == '紫':if not flag:result_report = '出了个紫色'record_rare(0)res_list.append(random.choice(fourStar))elif character_rank == '金':flag = Trueresult_report = gold()print(result_report)print(' '.join(res_list))print('==================================================')

使用提醒

记得在卡池放东西

记得要在卡池里放东西,因为这个为了灵活控制卡池,比如新增什么常驻,四星角色,或者三星武器什么的,用的读取文本文档的方式来进行卡池数据的储存的,虽然数据库也可以,但是多少有点大材小用了。
我这里给出一些我写好的用例吧,记得角色和角色,或者是武器和武器之间要用空格隔开,因为我这个是split(sep=’ ')劈分的是空格。我这里写了部分4星和目前5星常驻的角色,三星实在太多了,写不动了,这里我放出来

UP角色

up.txt

就写一个限定角色就行,我写的纳西妲,因为我最喜欢纳西妲了

五星常驻

fiveStar.txt

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

四星角色

fourStar.txt

安柏 丽莎 凯亚 芭芭拉 雷泽 菲谢尔 班尼特 诺艾尔 菲谢尔 砂糖 迪奥娜 北斗 凝光 香菱 行秋 重云 辛焱 绮罗罗

三星武器

threeStar.txt

这个我没写,我就写了个蓝色,有兴趣的可以自己写一下,反正也是狗粮,我就不写了

重要的事情重复一遍,别忘了往卡池放东西

结束

那么就到这里吧,感谢能读到这,我是喜欢整活的小狐,每天整点活玩就是我的乐趣。想想下次能玩点什么新花样,如果觉得有意思的话,还请点一个小小的赞。目前在忙项目,只能实现简单的逻辑,交互什么的下次一定。有时间再写到Django里。

用Python简单模拟《原神》抽卡系统相关推荐

  1. java 做的原神抽卡模拟小程序

    java做的原神抽卡模拟小程序 难度不大,适合学完面向对象后做着玩. import java.util.ArrayList; import java.util.Calendar; import jav ...

  2. 原神抽卡模拟器(java简易版)

    原神抽卡机制 单抽概率: 5★物品:0.6% 4★物品:5.1% 保底机制: 5★保底:如果连续89发没出5星,第90抽必定5星,然后重新计数 4★保底:如果连续9发没出4星,第10抽触发4星保底:0 ...

  3. 我用java分析了原神抽卡记录

    起因 我们都知道原神抽卡是有保底机制的,但是游戏里面只能按页查看抽卡记录,并没有各种数据统计,为了能够优化大家的游戏体验,本文就带大家用java爬虫来获取抽卡信息. 抽卡信息api解析 由于我用的是安 ...

  4. java原神抽卡器(可查询版本)

    原神官方给的概率: 5星基础:0.6%,5星保底:1.6%,90抽5星保底:         4星基础:5.1%,4星保底:13%,10抽4星保底. 一开始我也想着直接用官方给的概率设置直接写入,但发 ...

  5. 原神抽卡模拟器,unity制作(由于没有获得作者的视频授权,不会发布软件,只展示算法与开发等,效果图在个人主页类有资源下载,不会上传视频)

    五星效果图 以上为展示,没做优化 using System.Collections; using System.Collections.Generic; using UnityEngine; usin ...

  6. 原神抽卡模拟简单代码(概率还原)

    代码如下: import java.util.Scanner; import java.util.Random;public class Main {public static void main(S ...

  7. Python实现原神抽卡,生成桌面程序,tkinter

    这里写自定义目录标题 话不多说,直接贴所有代码 运行效果 需要用到的两张图片 话不多说,直接贴所有代码 import random import sys import tkinter as tk # ...

  8. 面向对象实现原神抽卡模拟功能

    主要涉及JAVA面向对象编程 [注:这里只完善了SSR部分] 最近学习Java正好学到了面向对象部分,想着觉得可以用来做个伪随机抽卡模拟功能,于是就做了,本人是萌新,代码结构设计很拉跨,所以花费了近两 ...

  9. 原神抽卡(题目出自:江西软件职业技术大学)

    描述: 在终于熬过了高中之后,你进入了大学,你听信了大人们的谎言,上了大学就轻松了,实际上你发现大学比高中更卷了.但是!你已经佛系了起来,凭借着高中学过oi,在大学开始了摸鱼,而一直打LOL的你,最近 ...

  10. 原神抽卡记录分析工具源码全开源

    简介: 原理是读取AppData\LocalLow\miHoYo\原神\output_log.txt这个文件中的链接,具体看源码,都给做了详细注释. 网盘下载地址: http://kekewangLu ...

最新文章

  1. SpringBoot第九篇: springboot整合Redis
  2. 新的 FreeBSD 核心团队选举结果出炉
  3. 如何获取ResultSet的行数和列数
  4. 信息系统服务器备机,医院信息系统业务连续性讨论:双机热备、RAC还是x86一体机?...
  5. 解决Windows 10 CPU占用高风扇吵问题
  6. java委_java双亲委派机制及作用
  7. 华为前端社招OD面试(已拿offer)
  8. 浅谈标签概念及应用场景
  9. amap和amapcrap使用
  10. java中String转Long类型
  11. 段誉和男人们的普遍困境
  12. 19款国产手机无一幸免:15分钟破解人脸识别,打印眼镜让刷脸形同虚设 ?
  13. 社会工程学攻击案例-伪装木马
  14. [COI2007] Sabor
  15. IDEA中Tomcat的安装与配置
  16. 【无标题】单例模式的两种创建方式:饿汉式和懒汉式
  17. 《炬丰科技-半导体工艺》抛光晶片和外延层晶片表面物理化学特性的比较
  18. 实验记录 | DNA数据的处理流程
  19. (转) 何为机器学习
  20. 191. 位1的个数

热门文章

  1. 数据结构之查找(六)——平衡二叉树(AVL树)
  2. 家用无线网络布置——小凡,晚安
  3. 【转载】10月30日,94岁的金庸老爷子去世!
  4. Python爬虫实战(十一) B站热门信息爬取(窗口版)| Tkinter实现GUI交互式界面
  5. Mysql添加用户与授权
  6. 2020年网络推广方案怎么做?
  7. 【工赋开发者社区】数字化转型路上不得不面对的3个问题
  8. 2022-2028年中国生活垃圾转运站行业竞争现状及投资决策建议报告
  9. 华为国际快递被转运至美国 联邦快递致歉:误送
  10. 移动硬盘已连接USB我的电脑不显示的全网最细汇总多种解决方法(保姆级图文详细步骤)