2024-07-28 初始暴击率30%,若连续2次攻击均未造成暴

2024-07-27  本文已影响0人  黄昭鸿

考虑连续2次未暴击后必定暴击的规则, p 是单次攻击的暴击概率,暴击概率序列实际上是一个无限几何级数,其首项为 p,公比为 (1-p)^3。可以使用无限几何级数的求和公式来计算这个级数的和,计算平均暴击率的公式:E(p) = \frac{p}{1 - (1-p)^3} = \frac{100}{219} \approx 0.4566,而不是\frac{9}{19}


写个程序模拟一下:

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ThreadLocalRandom;
public class CriticalHitSimulationOptimized {
    
    /*
    初始暴击率30%,若连续两次攻击均未造成暴击,则第3次攻击必定暴击。求平均暴击率。
    */
    private static final int TOTAL_ATTACKS = 99999999;//模拟99999999次攻击
    private static final double CRITICAL_HIT_CHANCE = 0.3;
    private static final int THREAD_COUNT = Runtime.getRuntime().availableProcessors();
    private static AtomicInteger criticalHits = new AtomicInteger(0);
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
        int attacksPerThread = (int) Math.ceil((double) TOTAL_ATTACKS / THREAD_COUNT);
        for (int i = 0; i < THREAD_COUNT; i++) {
            int attacksForThisThread = i < TOTAL_ATTACKS % THREAD_COUNT ? attacksPerThread + 1 : attacksPerThread;
            executor.submit(new AttackSimulator(attacksForThisThread));
        }
        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.HOURS);
        BigDecimal statisticalCriticalRate = new BigDecimal(criticalHits.get())
                .divide(new BigDecimal(TOTAL_ATTACKS), 10, RoundingMode.HALF_UP);
        System.out.println("统计暴击率: " + statisticalCriticalRate);
    }
    static class AttackSimulator implements Runnable {
        private final int attacks;
        AttackSimulator(int attacks) {
            this.attacks = attacks;
        }
        @Override
        public void run() {
            int consecutiveNonCriticals = 0;
            boolean guaranteeCritical = false;
            for (int i = 0; i < attacks; i++) {
                if (guaranteeCritical || ThreadLocalRandom.current().nextDouble() < CRITICAL_HIT_CHANCE) {
                    criticalHits.incrementAndGet();
                    consecutiveNonCriticals = 0;
                    guaranteeCritical = false;
                } else {
                    consecutiveNonCriticals++;
                    if (consecutiveNonCriticals == 2) {
                        guaranteeCritical = true;
                    }
                }
            }
        }
    }
}

看看结果:

PS C:\Users\User\Desktop> javac .\CriticalHitSimulationOptimized.java -encoding UTF-8
PS C:\Users\User\Desktop> java CriticalHitSimulationOptimized
统计暴击率:0.4566302746
PS C:\Users\User\Desktop> java CriticalHitSimulationOptimized
统计暴击率:0.4566247346
PS C:\Users\User\Desktop> java CriticalHitSimulationOptimized
统计暴击率:0.4565899246
PS C:\Users\User\Desktop> java CriticalHitSimulationOptimized
统计暴击率:0.4566125346
PS C:\Users\User\Desktop>

结果与预期一致。

上一篇下一篇

猜你喜欢

热点阅读