编程计算影之诗准时降神概率
视频中有小伙伴想要源码,我也懒得整GitHub了,直接搁这当博客写吧,顺便聊聊思路。想自己电脑上跑代码的话,VS中建个C#控制台工程,建几个.cs文件把下面代码扔进去应该就能直接运行的。研究代码也建议用VS或者随便一个其他的代码编辑器,方便控制代码块显示。

编程语言选择
首先语言选择C#,虽然我最熟悉的语言是C++但是影之诗本身是C#的,这样我们就能用影之诗同款随机数生成器了。
卡组选择
不同卡组肯定得出的结果是不同的,我采用的是

建模
我们的目的并不是模仿实战,而是最大化准时降神的概率,所以实际上一些像牌堆洗牌的如雷琉、艾葳米亞是完全不考虑出的。賈絲珀进化前是白板,只有在手牌极烂的情况下才会拍出来提供狗或者激奏吃的目标。


我们把雷琉和977这两张卡直接合并为“绝对不会出的卡”。这里设置为随从是为了让他能被301葬送。艾葳米亞也不会出,但她在造物检索链中,所以需要单独写一张卡。

其他的,对卡进行一些简化,如神器鸣动,只考虑出3费过牌护符就直接当3费过牌护符就行。(草写文的时候发现神器鸣动没写回合结束后抽卡的那个能力,概率又少算了一丢丢。)1费激奏的本体是个随从,这里直接简化成1费法术。
对301葬送把召唤535吸血简化为召唤301,能少写一个类。罗夏卡西姆因为效果一直,直接简化成同一张卡。对于遗物的同步简化为111造物,但会在造物检索中移除。
因为真正考虑谢幕曲的只有111造物这一张卡,我把谢幕曲剩了,把能力写进狗和1费激奏的“使用”里了。
上图中“优先级”并不是出牌的优先级,而是在进行301葬送和罗夏卡西姆洗牌时,挑最不需要的牌去扔。
游戏的换牌机制
应该大部分人不知到留牌的底层机制,所以很多人自己算的时候,在留牌这步就出问题了。经过一些黑科技查看游戏代码,在单人游戏中,换牌并不是把牌扔进牌堆然后再抽一张,实际上是一开始就抽了6张,先展示前3张卡,换牌是换的后3张上来。在联机对战中换牌算法不透明,但是考虑代码在思想上的一致性的话,联机换牌算法应该和单机是一样的。
模拟对局的结束检测
对于第一第二回合和先手第三回合如果手牌中有转动的命运或者菈姿莉,则直接结束对局,判定为能准时降神。
对于后手第三回合,先判断是否有费用出菈姿莉,否则判断是否有转动的命运。
对于先手第四回合,判断是否在余四费的时候有菈姿莉,或者在余1费的时候有转动的命运。
对于后手第四回合,判断是否在余四费的时候神抽了转动的命运。
出牌算法
我现在不会写啥AI之类东西,我出牌的算法是这样的,列出很多出牌的子策略,并按优先级排列。一个子策略就是什么时候该出哪张牌。每次出牌时,先判断最高优先级子策略能否出牌,如果不能则检查下一个子策略。出牌后,又重新从最高策略开始遍历一次,直到没有任何符合出牌策略的牌,回合结束。
为此我按优先级定义了下列子策略(视频中右侧绿字部分)

这些子策略是我自己按“最大化过牌”的经验来拟定的,不同的人有不同的经验和理解,拟定出来的子策略可能不一样,我也不知道这个策略算不算是最优解,只是我自己来实操找降神的话大概会这么出。所以不是最优解的话计算结果可能比真正的最大概率小一些(但应该差距在千分之2以下)
主要内容完毕,下面是代码部分。

一共三个文件。写着玩的,代码规范是什么能吃吗ヾ(•ω•`)o。
CardBase.cs定义卡牌能力,视频中展示策略也是直接用借用了这个文件
GameSimulator.cs定义对局模拟器。
Program.cs主程序。