利用python语言模拟原神抽卡机制(小白也能看懂!!!)

最近一直沉迷原神无法自拔,每天花了好几个小时赚原石最后也捞不到几抽,一直体验不了抽卡的满足感。所以不如自己来设计一个抽卡机制模拟原神的抽卡让自己爽爽。

一:了解原神的抽卡机制

要模拟原神抽卡机制我们要先了解一下原神抽卡的概率和保底机制

原神UP池概率机制如下:

在 [1,73] 抽时, 每次出五星角色的概率为 0.6% , 在 [74,90] 抽每次抽卡概率比上次高 6% .

当获取到五星角色时, 有 50% 概率是UP角色, 若这次五星没有抽到UP角色, 下次五星角色必定是UP角色.

五星角色保底为 90 抽, 五星UP角色保底为 180 抽.

二:根据机制构建代码

在了解了原神抽卡机制后我们就开始构建代码了

首先导入必要的库并定义我们需要用到的变量

import random
qualified_five_star=["纳西妲","妮露"]
resident_five_star=["迪卢克","刻晴","莫娜","七七","琴"]
four_star_character=["久岐忍","多莉","莱依拉"]#定义包含卡池所有物品的列表
tsw_number=0#三星物品抽取的数量
fosc={}#所有四星物品
fsc={}#所有五星物品

接下来将五星角色构造成一个类,每次进行抽取都是在对五星角色类的实例方法进行引用

class fivestar():
    def __init__(self):
        self.probability=0.6/100
        self.xiaodabaodi=0
        self.baodichoushu=0
    def wish(self,times):
        self.baodichoushu+=1
        #保底抽数大于73时概率增长
        if self.baodichoushu>73:
            self.probability+=6/100
        if self.baodichoushu<90:
            #如果满足条件(p:=random.random())<=self.probability抽中了,有50%概率是up角色
            if (p:=random.random())<=self.probability and ((k:=random.choice([1,2]))==1 or self.xiaodabaodi==1):
                self.xiaodabaodi=0        #属性xiaodabaodi用来记录小保底时是否是up角色,不是则为0,如果是0则下一次保底必为up角色
                self.probability=0.6/100
                self.baodichoushu=0
                return random.choice(qualified_five_star)
            elif p<=self.probability and k==2:
                self.xiaodabaodi = 1
                self.probability = 0.6/100
                self.baodichoushu = 0
                return random.choice(resident_five_star)
            else:
                return False
        #保底抽数达到90时触发保底
        elif self.baodichoushu==90:
            if self.xiaodabaodi==1 or (k:=random.choice([1,2]))==1:
                self.xiaodabaodi=0
                self.probability=0.6/100
                self.baodichoushu=0
                return random.choice(qualified_five_star)
            else:
                self.xiaodabaodi = 1
                self.probability = 0.6/100
                self.baodichoushu = 0
                return random.choice(resident_five_star)

同样的,构造四星物品类(其实就是改了一下概率和保底抽数)

class fourstar():
    def __init__(self):
        self.probability=5.1/100
        self.baodichoushu=0
    def wish(self,times):
        self.baodichoushu+=1
        #概率增长
        if self.baodichoushu>5:
            if self.probability>=1:
                self.probability=1
            else:
                self.probability+=random.uniform(0.01/5,0.90/5)
        if self.baodichoushu<10:
            if (p:=random.random())<=self.probability and (k:=random.choice([1,2]))==1:
                self.probability=5.1/100
                self.baodichoushu=0
                return random.choice(four_star_character)
            elif p<=self.probability and k==2:
                self.probability = 5.1/100
                self.baodichoushu = 0
                return 'four star weapon'
            else:
                return False
        elif self.baodichoushu==10:
            if (k:=random.choice([1,2]))==1:
                self.probability=5.1/100
                self.baodichoushu=0
                return random.choice(four_star_character)
            else:
                self.probability = 5.1/100
                self.baodichoushu = 0
                return 'four star weapon'

然后再将两个类实例化,得到五星角色和四星角色的实例

a=fivestar()
b=fourstar()

最后利用循环模拟不停抽卡的过程并用try except语句防止输入无效内容,将每个抽到的角色存入字典,并在输出时调用。

try:
    times = int(input("how many wish times"))
    for t in range(1,times+1):
        if (j:=a.wish(t))!=False:

            fsc.update({t:j})
            continue
        elif (q:=b.wish(t))!=False:

            fosc.update({t:q})
            continue
        else:
            tsw_number+=1

    for key,value in fsc.items():
        print("你获得了五星角色\t{},在第{:0>5d}抽时获得".format(value,key))
    for key,value in fosc.items():
        print("你获得了四星角色/物品\t{},在第{:0>5d}抽时获得".format(value,key))
    print('你获得了{:0>5d}件三星武器'.format(tsw_number))
except ValueError:
    print("invalid input,please try again")

(注:因为抽到的角色可能重复,而重复的键会被字典吞掉,但抽数一直增长不会重复,所以这里用抽数作为键,角色名称作为值)

三:完整代码及运行结果

import random
qualified_five_star=["纳西妲","妮露"]
resident_five_star=["迪卢克","刻晴","莫娜","七七","琴"]
four_star_character=["久岐忍","多莉","莱依拉"]
tsw_number=0
fosc={}
fsc={}

class fivestar():
    def __init__(self):
        self.probability=0.6/100
        self.xiaodabaodi=0
        self.baodichoushu=0
    def wish(self,times):
        self.baodichoushu+=1
        # 概率增长
        if self.baodichoushu>73:
            self.probability+=6/100
        if self.baodichoushu<90:
            if (p:=random.random())<=self.probability and ((k:=random.choice([1,2]))==1 or self.xiaodabaodi==1):
                self.xiaodabaodi=0
                self.probability=0.6/100
                self.baodichoushu=0
                return random.choice(qualified_five_star)
            elif p<=self.probability and k==2:
                self.xiaodabaodi = 1
                self.probability = 0.6/100
                self.baodichoushu = 0
                return random.choice(resident_five_star)
            else:
                return False
        elif self.baodichoushu==90:
            if self.xiaodabaodi==1 or (k:=random.choice([1,2]))==1:
                self.xiaodabaodi=0
                self.probability=0.6/100
                self.baodichoushu=0
                return random.choice(qualified_five_star)
            else:
                self.xiaodabaodi = 1
                self.probability = 0.6/100
                self.baodichoushu = 0
                return random.choice(resident_five_star)

class fourstar():
    def __init__(self):
        self.probability=5.1/100
        self.baodichoushu=0
    def wish(self,times):
        self.baodichoushu+=1
        #概率增长
        if self.baodichoushu>5:
            if self.probability>=1:
                self.probability=1
            else:
                self.probability+=random.uniform(0.01/5,0.90/5)
        if self.baodichoushu<10:
            if (p:=random.random())<=self.probability and (k:=random.choice([1,2]))==1:
                self.probability=5.1/100
                self.baodichoushu=0
                return random.choice(four_star_character)
            elif p<=self.probability and k==2:
                self.probability = 5.1/100
                self.baodichoushu = 0
                return 'four star weapon'
            else:
                return False
        elif self.baodichoushu==10:
            if (k:=random.choice([1,2]))==1:
                self.probability=5.1/100
                self.baodichoushu=0
                return random.choice(four_star_character)
            else:
                self.probability = 5.1/100
                self.baodichoushu = 0
                return 'four star weapon'

a=fivestar()
b=fourstar()
try:
    times = int(input("how many wish times"))
    for t in range(1,times+1):
        if (j:=a.wish(t))!=False:

            fsc.update({t:j})
            continue
        elif (q:=b.wish(t))!=False:

            fosc.update({t:q})
            continue
        else:
            tsw_number+=1

    for key,value in fsc.items():
        print("你获得了五星角色\t{},在第{:0>5d}抽时获得".format(value,key))
    for key,value in fosc.items():
        print("你获得了四星角色/物品\t{},在第{:0>5d}抽时获得".format(value,key))
    print('你获得了{:0>5d}件三星武器'.format(tsw_number))
except ValueError:
    print("invalid input,please try again")


那么我们这就完成了原神抽卡机制的初步模拟,当然也只是玩玩的程度,真正游戏的抽卡算法远不止这么简单。我也还是个小白,请各位大佬批评指正!!!

文章引用:【知乎】一文说清楚原神抽卡机制, 概率, 期望等问题——Pandora Eartha

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你实现一个简单的原神抽卡程序。假设你需要实现常驻池和角色池两种类型的抽卡,你可以按照以下步骤来完成: 1. 定义卡池 首先你需要定义两个类来表示常驻池和角色池。每个卡池应该有自己的名称、抽卡概率以及对应的角色/物品列表等属性。 ``` class Pool: def __init__(self, name, prob_list, item_list): self.name = name self.prob_list = prob_list # 抽卡概率列表,与item_list一一对应 self.item_list = item_list # 抽卡物品列表 class PermanentPool(Pool): def __init__(self): name = '常驻池' prob_list = [0.6, 0.34, 0.06] # 三星、四星、五星概率 item_list = ['三星角色A', '四星角色A', '五星角色A', ...] # 池中所有角色/物品列表 super().__init__(name, prob_list, item_list) class CharacterPool(Pool): def __init__(self): name = '角色池' prob_list = [0.006, 0.051, 0.093, 0.5, 0.35] # 五星角色、四星角色、四星武器、三星武器、三星角色概率 item_list = ['五星角色A', '五星角色B', '四星角色A', '四星角色B', ...] # 池中所有角色/物品列表 super().__init__(name, prob_list, item_list) ``` 2. 实现抽卡逻辑 接下来你需要实现抽卡的逻辑。你可以定义一个 `draw` 函数来模拟一次抽卡操作,该函数应该接受一个卡池对象作为参数,并返回一个随机的角色/物品。 ``` import random def draw(pool): rand_num = random.random() # 生成一个0到1之间的随机数 prob_sum = 0 for i in range(len(pool.prob_list)): prob_sum += pool.prob_list[i] if rand_num < prob_sum: return pool.item_list[i] return pool.item_list[-1] # 如果未匹配到任何一个概率,则返回最后一个物品 ``` 3. 进行抽卡 现在你可以进行抽卡了。你可以定义一个 `Gacha` 类来表示一个玩家,该类应该有自己的名称和已有的物品列表等属性。 ``` class Gacha: def __init__(self, name): self.name = name self.items = [] def draw_once(self, pool): item = draw(pool) self.items.append(item) print(f'{self.name}抽到了{item}') def draw_ten_times(self, pool): for i in range(10): self.draw_once(pool) ``` 现在你可以创建一个玩家对象并开始抽卡了: ``` p_pool = PermanentPool() c_pool = CharacterPool() player1 = Gacha('玩家1') player1.draw_once(p_pool) # 抽一次常驻池 player1.draw_ten_times(c_pool) # 抽十次角色池 ``` 以上就是一个简单的原神抽卡程序的实现。当然,如果你想让程序更加完善,你可以添加更多的功能,例如保底机制、十连保底等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值