作者laechan (小太保)
看板X-Legend
標題[閒聊][幻想] 禮盒福袋程式寫法推敲
時間Thu Oct 3 15:47:13 2013
http://ppt.cc/8cz8
這是網路隨便找到的一張圖,通常帶機率的東西會用 mapping
的方式宣告
mapping box=([
"高級服飾附魔‧傷害x1" : a, // 假設開出機率 a%
"高級服飾附魔‧爆擊x1" : b, // 假設開出機率 b%
"高級服飾附魔‧堅硬x1" : c, // 假設開出機率 c%
.
.
"HP治療藥劑x3" : z, // 假設開出機率 z%
]);
冒號 : 前面是可以開出的東西,keys(box) = 這些東西的集
合;冒號後面則是機率數字,假設用直觀寫法 10 = 10%,而
random(n) 代表隨機跑出 0~n-1 之間的整數。
則有一點很明顯: a < b < c < d < ..... < y < z
而且越底下的東西越好開,越上面的東西越難開。
根據自己的 coding 經驗,我試著寫了一個 box 並模擬開一
萬次的結果如下
==========================================
高級服飾附魔‧傷害x1 : 11 組
高級服飾附魔‧爆擊x1 : 18 組
高級服飾附魔‧堅硬x1 : 50 組
服飾附魔‧傷害x1 : 76 組
服飾附魔‧爆擊x1 : 79 組
服飾附魔‧堅硬x1 : 209 組
源神能量光球(小)x3 : 186 組
幸運之證x1 : 179 組
怪物經驗書x2 : 307 組
中級尋寶護符x2 : 159 組
高級尋寶護符x1 : 151 組
璀璨的經驗秘石x3 : 206 組
源神經驗結晶(中)x3 : 2805 組
未鑑定的源神徽紀寶箱x3 : 2763 組
HP治療藥劑x3 : 2801 組
========== 程式執行區 ====================
前 20 組結果大致如下
怪物經驗書x2
HP治療藥劑x3
未鑑定的源神徽紀寶箱x3
未鑑定的源神徽紀寶箱x3
HP治療藥劑x3
服飾附魔‧爆擊x1
未鑑定的源神徽紀寶箱x3
源神經驗結晶(中)x3
未鑑定的源神徽紀寶箱x3
源神經驗結晶(中)x3
HP治療藥劑x3
未鑑定的源神徽紀寶箱x3
HP治療藥劑x3
源神經驗結晶(中)x3
未鑑定的源神徽紀寶箱x3
未鑑定的源神徽紀寶箱x3
源神經驗結晶(中)x3
未鑑定的源神徽紀寶箱x3
未鑑定的源神徽紀寶箱x3
未鑑定的源神徽紀寶箱x3
那我是怎麼設計這個 box 的呢?我將寶盒裡面 15 件物品分成
五組,每三個一組,最底下三個物品是「最好開的那一組」。
這是最直覺的想法,因為玩家開來開去,「總是開到那三個」。
其次,因為越上面的東西越難開,因此另一個直覺想法就是
for(i=0;i<15;i++)
j=j+random(2);
但通常除非運氣好到爆跑 15 次都是 0 才會累加後為 0,也就
是開出第一個,不然第一個是幾乎開不出來的。
但是這與現況不符(有人開過),而且搭配上面將物品分成五組
的想法,就變成如下
for(i=0;i<4;i++)
j=j+random(2);
j=j*3+random(4);
if(j>1) j=j-1;
上面的意思是說 j 的範圍一樣是 0~14,但是一開始是用五組
去分的,我用程式實測結果跑 10000 次約可跑出一千多次的「
開出第一組的機率」,機率是很高的。
但是再跑一次機率的話就不同了:
if(random(n)<box[keys_box[k]])
data[keys_box[k]]++;
else
{
k=12+random(3);
data[keys_box[k]]++;
}
上面的意思就是說 k 跑出 0~14 任一數字了,然後我定義了
每一組每一項物品的開出機率數字,例如第一組是 1,再用一
個 random(n) 去跑,比方說 n = 10:
if(random(10) < box[keys_box[k]])
隨機跑出 0~9 比 第一組的數字1 還小 (所以機率是 1/10)
這樣就跑出 keys_box[k] 這個東西(第一組的物品),反之,如
果隨機跑出的數字比第一組的數字 1 還大,就跑「預設讓玩家
開出的物品=最後一組任一物品」。
我寫的這種箱子的特性如下
一、越上面的東西越難開,而且是非常難開
因為是機率x機率,第一個機率是指跑出哪一組,如上所示
跑出第一組的機率差不多是 1/10 其實這機率是很不錯的,
但是「再機率的結果」就變成 1/10 x 1/10 = 1/100。
二、可是它又不是完全開不到
例如我的實測結果
高級服飾附魔‧傷害x1: 11 組 約 0.1%
高級服飾附魔‧爆擊x1: 18 組 約 0.2%
高級服飾附魔‧堅硬x1: 50 組 約 0.5%
==============================
而實際情況因為多人在買(類似簽樂透),每個人大概買個十
幾到幾十盒就能開到,因為物品只分五組、多人在買、在開
,有時人品好幾盒就能開到。
三、最底下三個東西一定是最常開到的
例如大家對總是開到源神結晶、治療藥劑這類的一定印象深
刻。
寫這個,有三個用意
一、勸世
真要拼,用招待券買一盒或少少幾盒試試手氣就好了,與其
每一期買 n 盒還不如每期買一兩盒就好,它幾乎每一期都會
出新的禮盒、寶盒等。
但基本上如果要做機關的話
if(是用招待券買的)
box->add("機率數字",-n); // 機率降低
甚至還可以跟你是否為 VIP 會員、是否在簽約網咖上網、是
否是儲值大戶、....等等掛勾。
二、隨便小小調整一個數字就能任意調整機率
這個通常最常用在農怪機率的調整上,但寶盒也是可以的,
比方它覺得怎麼才一天而已就被人開出十幾雙的翅膀背飾,
它是可以馬上調整讓玩家幾乎是開不到的。
反過來說,如果它覺得雖然才半天、禮盒銷了一兩千個了怎
麼還沒有人開到,「這樣下去可不行」,就偷偷調一下機率
,這時買到並開禮盒的人就會爽到。
所以我是覺得早買晚買、早開晚開都一樣,但是遊戲官方也
可能為了刺激消費而一開始讓機率較高,這是可能的,因為
有人開到就會貼炫耀文。
三、如果寶盒裡面垃圾放很多,這種寶盒不要買
像某仙x傳說的轉蛋通常會塞一堆料理箱子或沒啥路用的東
西,通常超過 6 個我就會說那種轉蛋不值得買。
因為複合機率運算的結果就是那六個一定是最好開的,而且
「再機率運算的結果」如果你不符合取得機率,它又會繞回
「讓你隨機取得那六個其中一個」的結果,這怎麼看都是不
划算的。
底下是部份 code,實際禮盒的程式跟下面必定相差無幾:
mapping box;
string msg="";
mixed keys_box=({});
box=([
"高級服飾附魔‧傷害x1" : 1,
"高級服飾附魔‧爆擊x1" : 1,
"高級服飾附魔‧堅硬x1" : 1,
"服飾附魔‧傷害x1" : 2,
"服飾附魔‧爆擊x1" : 2,
"服飾附魔‧堅硬x1" : 2,
"源神能量光球(小)x3" : 3,
"幸運之證x1" : 3,
"怪物經驗書x2" : 3,
"中級尋寶護符x2" : 4,
"高級尋寶護符x1" : 4,
"璀璨的經驗秘石x3" : 4,
"源神經驗結晶(中)x3" : 5,
"未鑑定的源神徽紀寶箱x3" : 5,
"HP治療藥劑x3" : 5,
]);
keys_box=keys(box);
// 跑一萬次
for(i=0;i<10000;i++)
{
k=0;
for(j=0;j<4;j++)
k=k+random(2);
k=k*3+random(4);
if(k>1) k=k-1;
if(random(15)<box[keys_box[k]])
data[keys_box[k]]++;
// 不符合機率的話一律開出最底下三個東西
else
{
k=12+random(3);
data[keys_box[k]]++;
}
}
for(i=0;i<15;i++)
msg+=sprintf("%-30s : %3d 組\n",keys_box[i],data[keys_box[i]]);
write(msg);
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.61.157.53
1F:推 aaa5566:可惡,看不懂 10/03 15:48
2F:→ ronlai:快推 雖然看不懂 10/03 15:49
3F:→ aaa5566:你沒推啊!! 10/03 15:51
4F:推 ronlai:補推 科科 10/03 15:51
5F:推 zMidTwo5566:這一篇文章值 757 Ptt幣 10/03 15:52
6F:推 Kmer:最常開到的是原神經驗結晶(中) 10/03 15:53
7F:推 AFIAC:快推 不然人家以為我看不懂 10/03 15:54
8F:推 GoldenFinger:嗯 跟我想的差不多 10/03 15:56
9F:推 StinOAO:看的懂給推XD 10/03 15:56
10F:推 s963870:我曾經買個3包拿到9個能量球,這個寫法我基本上是相信的 10/03 15:57
11F:推 Chantaljones:看不懂啦 10/03 15:58
12F:→ s963870:禮包機率雖能因節省網路設備成本而寫成獨立事件型機率 10/03 15:59
13F:→ s963870:但是因此而死的是消費者沒錯,這種轉蛋跟MH的素材型 10/03 16:00
14F:推 howlongbing:看不懂給推 10/03 16:01
15F:→ s963870:差異甚遠.. 甚至能說就是給你買樂透或送你一張發票 10/03 16:01
16F:→ s963870:依以前買MH包的經驗,同樣是轉蛋素材卻超好湊的... 10/03 16:02
17F:推 narcimeow:推,其實結論就是心情好買幾包就好別太執著.. 10/03 16:02
18F:→ s963870:因為它讓你至少開不到完整的也能開到材料去做 10/03 16:02
19F:→ s963870:材料取得甚至能從任務或活動獲得.. 10/03 16:03
20F:→ s963870:而幻想的做法就是單純機率,不論是活動跟禮包 10/03 16:03
21F:→ s963870:所有東西都是買了一開定生死這種除了逼你投資大量以外 10/03 16:05
22F:→ s963870:你不會有別的方式入手.. ,想用副本寶箱開手染? 10/03 16:06
23F:→ s963870:我可以跟你說開10000個開不到,這才是正常的情況 10/03 16:07
24F:→ s963870:因為數據跟機率告訴你就是如此 10/03 16:08
25F:→ laechan:可以開到啊, 開到「手染OX禮盒」→再拼一次機率 XD 10/03 16:14
26F:→ s963870:基本上這種看不到進度的東西,我花過一次錢就不會想再買了 10/03 16:17
27F:→ s963870:如果商城導致遊戲的失衡,那麼這款遊戲流失的會是大多數 10/03 16:18
28F:→ s963870:不會花大錢的平民等級玩家 10/03 16:19
29F:→ s963870:這款能玩的東西說實在的有點少.. 想投入就要更花錢 10/03 16:20
30F:推 skyitmexp:快推,這樣不會被發現看不懂 10/03 16:28
31F:→ gangray:這篇文章簡單一句話就是:機率,有錢你就去玩 10/03 16:32
32F:→ gangray:上面其他甚麼design隨便看看就好 10/03 16:33
33F:推 ronlai:轉蛋=機率*砸錢-讀心 10/03 16:33
34F:→ gangray:就算知道method也不能改變機率就是如此這個事實 10/03 16:34
35F:→ s963870:但是這篇沒有告訴你說買了10000包沒中 10/03 16:34
36F:→ s963870:就獨立機率來說 這是正常的結果 10/03 16:34
37F:→ gangray:如果說知道開福袋還會跟home連絡,攔截封包解密他還有可能 10/03 16:35
38F:→ aaa5566:樓上小組長 戳戳 10/03 16:36
39F:推 ozlm0806:曾經買20包眼鏡都抽垃圾,昨天招待卷買1包中橘色!我信了 10/03 16:41
40F:→ laechan:轉蛋或福袋絕對不會套用「單純的機率」這種做法去做的 10/03 16:43
41F:→ laechan:只有「最終看的是運氣跟人品」這句話才是對的,但是其過程 10/03 16:44
42F:→ laechan:絕對不單純,要很黑也可以很黑,這才是這篇文要講的東西 10/03 16:44
43F:→ s963870:說真的我比較想知道打怪的額外掉寶加成是怎算的 10/03 16:46
一般來說有三種做法
1.加法堆疊: 機率直覺累加
比方 (100% + 3% + 4% + 5%) = 112%
2.乘法堆疊: 機率累乘, 可控制在一定範圍
比方 100% x (100+3)% x (100+4)% + (100+5)% = 112.476%
3.混合堆疊: 比方為區別不同的效果(通常累乘優於累加)
比方 (100% + 3% + 4%) x (100 + 5%) = 112.35%
44F:→ s963870:禮包會用這種累加型的多面骰其實不是很意外 10/03 16:47
45F:推 sai0224sai:我真的覺得招待券的機率有比現金高 10/03 16:48
※ 編輯: laechan 來自: 210.61.157.53 (10/03 16:58)
46F:→ nrezw:不信拉 之前梭哈招待15包 只有三天版 10/03 16:53
47F:→ laechan:現金 15 包一堆源神, 招待 15 包還沒幹過, 嗯~ 說不定招待 10/03 16:59
48F:→ laechan:券反而較好, 畢竟現金只要儲值就有, 招待券要屯得下功夫 10/03 17:00
49F:→ s963870:問題是怪有LOOT阿,一次只噴一個這樣機率到底是差在哪? 10/03 17:01
以 RO 為例,假設某怪 LOOT = ([
"a物品": 30%,
"b物品": 10%,
"c物品": 1%,
]);
keys_loot = keys(LOOT);
j = sizeof(keys_loot);
k = 0;
for(i=0;i<j;i++)
{
if(random(100)<LOOT[keys_loot[i]])
{
掉落該物品;
k=k+1;
if(k >= 一定數量)
break; // 跳出迴圈
}
}
這是最簡單的寫法,打怪通常一次掉一個東西的話,就是只要
掉落物品就立刻 break; 跳出迴圈。
這樣它所公布的機率(就是RO各大攻略網站可看到的)就確實是
物品的實際掉落機率,因為每一物品的掉落是獨立的。
但是寶盒、禮盒、福袋、轉蛋絕對不會這樣寫,因為這是官方
要拿來賺錢的,設定絕對不會如此單純。
※ 編輯: laechan 來自: 210.61.157.53 (10/03 17:06)
50F:→ s963870:這樣看來要刷裝只能拚寶箱配護符 讓LOOT多2多3而已 10/03 17:19
51F:→ s963870:幸運之證可以不用買.... 10/03 17:19
52F:推 c77110901:推個 我就知道是這樣子 10/03 17:49
53F:推 arcss:恩恩...沒錯,跟我想的一樣(點頭) 10/03 17:51
54F:推 l85206605:招待卷真的比較好重!!!我兩個源神都用招待卷抽的.... 10/03 17:58
55F:推 LayerZ:好累@@ 10/03 18:58
56F:推 beyblade5566:推一個以免別人認為我看不董 XDD 10/03 19:14
57F:→ herryherry:有沒有懶人包XDDDD 10/03 21:23
58F:推 jack4019:這真的要推!! 10/03 21:58
59F:推 clickslither:懶人包就在文內啊,那個模擬一萬次的結果 10/03 22:59
60F:→ clickslither:不過傳奇轉蛋的機率應該人性化一些,我投入不多,但抽 10/03 22:59
61F:→ clickslither:到前三樣的機率還不低... 10/03 23:00
62F:推 Ekmund:你還蠻屌的... 10/04 01:31
63F:推 WinRARdotrar:換作是黑橘的話機關大概就用log函數做了XD 10/04 10:00