Python游戏概率保底算法PRD的实现

PRD介绍

PRD伪随机算法多用于游戏中,主要用于减弱真随机算法带来的运气成分

代码展示

下面用于展示PRD中概率增量的求解代码

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

ENV = "DEBUG"

def log_out(content):
    if "DEBUG" == ENV:
        print(content)

class PRD:

    def __init__(self):
        # 精度
        self.precision = 0.0000000000001

    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)
        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
            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
        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:
                log_out(f"--FINAL C: {mid_}")
                return mid_
            if p_avg > p:
                max_ = mid_
            else:
                min_ = mid_


if __name__ == '__main__':
    prd = PRD()
    prd.get_c_by_p(0.5)

运行日志

D:\software_install\Python\Python39\python.exe D:/projects/project-python/TestCase/game_prob/PseudoRandomDistribution.py
--当前[ c: 0.25, Nmax: 4 ]
1: [sum_pre_success_p: 0.25, curr_p: 0.25, sum_p: 0.25
2: [sum_pre_success_p: 0.625, curr_p: 0.375, sum_p: 1.0
3: [sum_pre_success_p: 0.90625, curr_p: 0.28125, sum_p: 1.84375
4: [sum_pre_success_p: 1.0, curr_p: 0.09375, sum_p: 2.21875
--p_avg: 0.4507042253521127
#
--当前[ c: 0.375, Nmax: 3 ]
1: [sum_pre_success_p: 0.375, curr_p: 0.375, sum_p: 0.375
2: [sum_pre_success_p: 0.84375, curr_p: 0.46875, sum_p: 1.3125
3: [sum_pre_success_p: 1.0, curr_p: 0.15625, sum_p: 1.78125
--p_avg: 0.5614035087719298
#
--当前[ c: 0.3125, Nmax: 4 ]
1: [sum_pre_success_p: 0.3125, curr_p: 0.3125, sum_p: 0.3125
2: [sum_pre_success_p: 0.7421875, curr_p: 0.4296875, sum_p: 1.171875
3: [sum_pre_success_p: 0.98388671875, curr_p: 0.24169921875, sum_p: 1.89697265625
4: [sum_pre_success_p: 1.0, curr_p: 0.01611328125, sum_p: 1.96142578125
--p_avg: 0.5098332088623351
#
--当前[ c: 0.28125, Nmax: 4 ]
1: [sum_pre_success_p: 0.28125, curr_p: 0.28125, sum_p: 0.28125
2: [sum_pre_success_p: 0.685546875, curr_p: 0.404296875, sum_p: 1.08984375
3: [sum_pre_success_p: 0.95086669921875, curr_p: 0.26531982421875, sum_p: 1.88580322265625
4: [sum_pre_success_p: 1.0, curr_p: 0.04913330078125, sum_p: 2.08233642578125
--p_avg: 0.480229797461676
#
--当前[ c: 0.296875, Nmax: 4 ]
1: [sum_pre_success_p: 0.296875, curr_p: 0.296875, sum_p: 0.296875
2: [sum_pre_success_p: 0.71435546875, curr_p: 0.41748046875, sum_p: 1.1318359375
3: [sum_pre_success_p: 0.9687576293945312, curr_p: 0.25440216064453125, sum_p: 1.8950424194335938
4: [sum_pre_success_p: 1.0, curr_p: 0.03124237060546875, sum_p: 2.0200119018554688
--p_avg: 0.4950465881322068
#
--当前[ c: 0.3046875, Nmax: 4 ]
1: [sum_pre_success_p: 0.3046875, curr_p: 0.3046875, sum_p:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值