Slay-the-Spire

選擇的敵人順序是否會影響您的稀有卡機會?

  • July 20, 2020

在觀看這個過度解釋的回放時,玩家評論了他如何選擇一條特定的路徑,並相信在你的普通敵人之間“展開”精英戰鬥會增加找到更多稀有卡片的機會。

Slay the spire 通過首先滾動選擇一種類型(普通、非普通或稀有),然後從該類型中隨機抽取一張牌,每個類型成員具有相同的機率,從而拉出它的牌。類型滾動是隨機加權的,方式如下:

有一個隱藏變數c,通用計數器。牌的機率分別從P = [-2%, 37%, 63%]稀有、不常見、常見的牌開始。每當擲出普通牌時,在虛擬碼中:

if(P[0] < 43%) P[0] += 1%; 
if(P[0] > 0% && P[0] < 43%) P[2] -= 1%;

每當擲出一張稀有牌時,機率將P = [-2%, 37%, 63%]再次重置為基礎值。在精英戰鬥中,稀有機率被修改:改為P[0] + 10%普通機率為P[2] - 10%。在商店裡,它P[0] + 6%P[2] - 6%

下面的圖表非常有洞察力地說明了這個機制:

[

在每一幕開始時,找到稀有卡的機率也會被重置,因為 Boss 總是會在 3 個稀有卡之間做出選擇。


尋路

在動作開始時,玩家通常會決定在動作中走哪條路,從哪條開始。提前計劃時,了解敵人的特定順序是否會影響收到的稀有卡片的預期數量可能會很有見地。

我們希望最大化上述內容。像rrrErrrE“展開精英戰鬥”這樣的序列是否比rrrEErrr“聚集他們”這樣的序列更好?

簡短的回答:不。相反是正確的


詳情

我寫了一個小控制台程序來測試這個,模擬 10 8次並輸出 no。您希望看到的稀有卡片。(在現代 CPU 上執行大約需要一分鐘)。它允許任何行為路徑作為輸入,並輸出卡片獎勵說明中看到的稀有卡片的數量。結果如下:

Simulate rare chance. Input a string formatted like rrresrrre. r = regular, e =
elite, s = shop.
It is assumed shop rares are not bought
Input: rrrerrre
Result: 2.4346
Input: rrreerrr
Result: 2.5110
Input: rrrerre
Result: 2.0444
Input: rrreerr
Result: 2.1136
Input: rrrere
Result: 1.6491
Input: rrreer
Result: 1.6962

注意:由於大數定律,上面的輸出精確到小數點後 4 位,非常精確到小數點後 3 位。(增加模擬計數將使結果更準確,但會線性增加更多時間)。

我們可以看到影片中建議的方法看到的稀有數量存在明顯的劣勢,因此實際上與所述技術相反是有優點的!平均而言,與選擇 3 戰、2 精英、3 戰作為路徑的行為相比,具有 3 戰、1 精英、3 戰、1 精英的行為會少 0.076 稀有牌。對於 3-2,我們看到了 0.069 的差異,對於 3-1,我們看到了 0.047 稀有的差異。

注:模擬事件,修改卡牌獎勵,部分遺物留給讀者練習。我的假設是基本結果不太可能改變:只有影響的大小可能會有所不同。


原始碼(C#)如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace raresExpected {

class Program {
   static void Main(string[] args) {
       string input;
       System.Console.WriteLine("Simulate rare chance. Input a string formatted like rrresrrre. r = regular, e = elite, s = shop.");
       System.Console.WriteLine("It is assumed shop rares are not bought");
       do {
           System.Console.Write("Input: ");
           input = System.Console.ReadLine();
           double result = estimate(input.ToLowerInvariant());
           System.Console.WriteLine("Result: " + result.ToString("N4"));
       }
       while (input != "" && input != "exit");
   }
   static double estimate(string input) {
       int simulations = 100000000;
       double total = 0;
       Random rand = new Random();
       char[] ca = input.ToCharArray();
       for (int i = 0; i < simulations; ++i) {
           // Ok not to use Kahan: the numbers will be close.
           total += runSimulation(ca, rand);
       }
       return total / simulations;
   }
   static int runSimulation(char[] input, Random rand) {
       int cards;
       int rares = 0;
       int p = -2; // Probability
       int mod = 0;
       int q = 0; // Modified probability
       int r = 0; // Running total
       foreach (char c in input) {
           if (c == 'r') {
               mod = 10;
               cards = 3;
           } else if (c == 'e') {
               mod = 0;
               cards = 3;
           } else if (c == 's') {
               mod = 6;
               cards = 7;
           } else {
               cards = 0;
           }
           for (int i = 0; i < cards; ++i) {
               q = p + mod;
               r = rand.Next() % 100;
               if (r < q) {
                   if (c != 's') {
                       ++rares;
                   }
                   p = -2;
               } else  if (r > q + 0.37) {
                   // Common card is rolled. 
                   ++p;
               }
           }
       }
       return rares;
   }
}
}

引用自:https://gaming.stackexchange.com/questions/372745