Python模拟暴击概率40%时的攻击操作

一、概率增量

这部分内容在前面讲解过,这里直接上代码

# _*_ coding: utf-8 _*_
# @Author : ******
# @Time   : 2022/8/24 9:48
# @File   : PseudoRandomDistribution.py
# @Project: TestCase
import math


class PRD:

    def __init__(self):
        # 环境
        self.env = None
        # 精度
        self.precision = 0.0000000000001

    def log_out(self, content):
        if "DEBUG" == self.env:
            print(content)

    def sum_arithmetic_sequence(self, N):
        """
        等差数列前N项求和
        :param N:第N项
        :return:和
        """
        res = 0
        for i in range(N + 1):
            res += i
        return res

    def get_avgp_by_c(self, c):
        """
        通过c求得Nmax次操作中的平均概率
        :param c:概率增量
        :return:平均概率
        """
        # 初始化变量
        p_sum_pre_success = 0
        p_sum = 0
        # 计算c值对应的最大操作次数
        Nmax = math.ceil(1 / c)
        self.log_out(f"--当前[ c: {c}, Nmax: {Nmax} ]")
        for i in range(1, Nmax + 1):
            p_curr = min(1, i * c) * (1 - p_sum_pre_success)
            p_sum_pre_success += p_curr
            p_sum += i * p_curr
            self.log_out(f"{i}: [sum_pre_success_p: {p_sum_pre_success}, curr_p: {p_curr}, sum_p: {p_sum}")
        p_avg = 1 / p_sum
        self.log_out(f"--p_avg: {p_avg}\n#")
        return p_avg

    def get_c_by_p(self, p):
        """
        通过已知触发某项操作的概率求得概率增量
        e.g.已知暴击率为50%,求概率增量c
        :param p:触发某项操作的概率
        :return:概率增量
        """
        min_ = 0
        max_ = p
        while True:
            mid_ = (min_ + max_) / 2
            p_avg = self.get_avgp_by_c(mid_)
            if abs(p_avg - p) < self.precision:
                self.log_out(f"--FINAL C: {mid_}")
                return mid_
            if p_avg > p:
                max_ = mid_
            else:
                min_ = mid_

二、模拟攻击操作

# _*_ coding: utf-8 _*_
# @Author : ******
# @Time   : 2022/8/25 10:07
# @File   : AnalogTrigger.py
# @Project: TestCase
import math
import random
from game_prob.PseudoRandomDistribution import PRD

class AT:

    def __init__(self, prob):
        # 触发某项事件的概率
        self.prob = prob

    def get_random(self, min_, max_):
        """
        在给定区间内取值
        :param min_:区间最小值
        :param max_:区间最大值
        :return:区间值
        """
        if min_ == max_: return min_
        num_ = random.random() * (max_ - min_ + 1) + min_
        num_ = int(num_)
        return num_

    def is_trigger(self,min_, max_, prob):
        """
        判定本次随机是否触发事件
        :param min_:区间最小值
        :param max_:区间最大值
        :param prob:触发事件所需概率
        :return:是否触发
        """
        num_random = self.get_random(min_, max_)
        return num_random <= prob, num_random

    def simulation(self):
        pdr = PRD()
        pdr.env = "Release"
        # 获取概率增量
        c = pdr.get_c_by_p(self.prob)
        # 获取最大操作次数
        Nmax = math.ceil(1 / c)
        # 观察Nmax次攻击内暴击情况
        N = 1
        for i in range(1, Nmax + 1):
            p_curr = N * c
            flag, num_random = self.is_trigger(1, 100, p_curr * 100)
            if flag:  # 触发暴击后,N重置为1
                N = 1
            print(f"第{i}次攻击: [暴击概率: {p_curr}, 程序随机: {num_random / 100}, 是否触发暴击: {flag}]")
            N += 1

if __name__ == '__main__':
    # 触发暴击的概率为50%
    prop = 0.4
    # 模拟攻击
    at = AT(prop)
    # 启动模拟
    at.simulation()

三、日志输出

第1次攻击: [暴击概率: 0.20154741360784098, 程序随机: 0.38, 是否触发暴击: False]
第2次攻击: [暴击概率: 0.40309482721568196, 程序随机: 0.05, 是否触发暴击: True]
第3次攻击: [暴击概率: 0.40309482721568196, 程序随机: 0.05, 是否触发暴击: True]
第4次攻击: [暴击概率: 0.40309482721568196, 程序随机: 0.95, 是否触发暴击: False]
第5次攻击: [暴击概率: 0.6046422408235229, 程序随机: 0.04, 是否触发暴击: True]

这里只是模拟Nmax次操作中的攻击情况

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值