編程計算影之詩準時降神概率
視頻中有小伙伴想要源碼,我也懶得整GitHub了,直接擱這當博客寫吧,順便聊聊思路。想自己電腦上跑代碼的話,VS中建個C#控制臺工程,建幾個.cs文件把下面代碼扔進去應該就能直接運行的。研究代碼也建議用VS或者隨便一個其他的代碼編輯器,方便控制代碼塊顯示。

編程語言選擇
首先語言選擇C#,雖然我最熟悉的語言是C++但是影之詩本身是C#的,這樣我們就能用影之詩同款隨機數生成器了。
卡組選擇
不同卡組肯定得出的結果是不同的,我采用的是

建模
我們的目的并不是模仿實戰(zhàn),而是最大化準時降神的概率,所以實際上一些像牌堆洗牌的如雷琉、艾葳米亞是完全不考慮出的。賈絲珀進化前是白板,只有在手牌極爛的情況下才會拍出來提供狗或者激奏吃的目標。


我們把雷琉和977這兩張卡直接合并為“絕對不會出的卡”。這里設置為隨從是為了讓他能被301葬送。艾葳米亞也不會出,但她在造物檢索鏈中,所以需要單獨寫一張卡。

其他的,對卡進行一些簡化,如神器鳴動,只考慮出3費過牌護符就直接當3費過牌護符就行。(草寫文的時候發(fā)現神器鳴動沒寫回合結束后抽卡的那個能力,概率又少算了一丟丟。)1費激奏的本體是個隨從,這里直接簡化成1費法術。
對301葬送把召喚535吸血簡化為召喚301,能少寫一個類。羅夏卡西姆因為效果一直,直接簡化成同一張卡。對于遺物的同步簡化為111造物,但會在造物檢索中移除。
因為真正考慮謝幕曲的只有111造物這一張卡,我把謝幕曲剩了,把能力寫進狗和1費激奏的“使用”里了。
上圖中“優(yōu)先級”并不是出牌的優(yōu)先級,而是在進行301葬送和羅夏卡西姆洗牌時,挑最不需要的牌去扔。
游戲的換牌機制
應該大部分人不知到留牌的底層機制,所以很多人自己算的時候,在留牌這步就出問題了。經過一些黑科技查看游戲代碼,在單人游戲中,換牌并不是把牌扔進牌堆然后再抽一張,實際上是一開始就抽了6張,先展示前3張卡,換牌是換的后3張上來。在聯(lián)機對戰(zhàn)中換牌算法不透明,但是考慮代碼在思想上的一致性的話,聯(lián)機換牌算法應該和單機是一樣的。
模擬對局的結束檢測
對于第一第二回合和先手第三回合如果手牌中有轉動的命運或者菈姿莉,則直接結束對局,判定為能準時降神。
對于后手第三回合,先判斷是否有費用出菈姿莉,否則判斷是否有轉動的命運。
對于先手第四回合,判斷是否在余四費的時候有菈姿莉,或者在余1費的時候有轉動的命運。
對于后手第四回合,判斷是否在余四費的時候神抽了轉動的命運。
出牌算法
我現在不會寫啥AI之類東西,我出牌的算法是這樣的,列出很多出牌的子策略,并按優(yōu)先級排列。一個子策略就是什么時候該出哪張牌。每次出牌時,先判斷最高優(yōu)先級子策略能否出牌,如果不能則檢查下一個子策略。出牌后,又重新從最高策略開始遍歷一次,直到沒有任何符合出牌策略的牌,回合結束。
為此我按優(yōu)先級定義了下列子策略(視頻中右側綠字部分)

這些子策略是我自己按“最大化過牌”的經驗來擬定的,不同的人有不同的經驗和理解,擬定出來的子策略可能不一樣,我也不知道這個策略算不算是最優(yōu)解,只是我自己來實操找降神的話大概會這么出。所以不是最優(yōu)解的話計算結果可能比真正的最大概率小一些(但應該差距在千分之2以下)
主要內容完畢,下面是代碼部分。

一共三個文件。寫著玩的,代碼規(guī)范是什么能吃嗎ヾ(?ω?`)o。
CardBase.cs定義卡牌能力,視頻中展示策略也是直接用借用了這個文件
GameSimulator.cs定義對局模擬器。
Program.cs主程序。