最近被扭曲复联打的头疼,于是来研究一下世界扭曲之始(以下简称扭曲)这张牌的价值,主要比较带扭曲和不带扭曲的复联在第五回合的期望核心卡牌数量。
先直接上结论:在第五回合,对于复仇者联盟卡组来说(以下都对于复联举例)一张扭曲的期望价值在
10 费左右,这是个模糊的结论但是不会差很多。
假设
1. 我们考虑第五回合在五本的情况,金币的数量在25左右
2. 为了简化,我们将卡组中的卡分为三类,锁定卡(18-1=17张因为有一张浩克),可过滤卡(这里假设2费3费和4费的卡都需要过滤也就是24张) 以及核心卡5张:复联索尔,仙宫索尔,美队,浩克,蚁人这5张大多数玩家会这么带的牌。
3. 对于锁定卡每张卡可以带4张,对于过滤卡每张卡带一张,对于核心卡每张卡4张。
模拟
使用计算机模拟并分别比较了两种策略(带扭曲以及不带扭曲)
对于不带扭曲:看到核心卡直接拿,锁定卡直接跳过,过滤卡拿了再卖掉
对于使用扭曲之后:核心卡如果费用小于本身费用就拿,过滤卡看到费用小于本身费用拿了再卖,对于锁定卡只有0费或者1费才拿了卖
结果
对于不带扭曲的复仇者联盟卡组来说(时代的眼泪),第5回合抽到核心卡的期望数量在1.32张左右。可以看到有15%的概率没有拿到一张核心卡,40%概率拿到1张,35%拿到2张,10%拿到3张,几乎为0的概率拿到4张。

对于带扭曲的卡组来说,抽到核心卡的期望数量在3.32张左右,甚至有希望拿到8张核心牌(4星美队)!

可以看到带扭曲和不带扭曲价值相差约2张核心卡牌,对于复联卡组来说也就是10费
策划考虑削弱扭曲吧!!!
不足
这只是个很简化的模拟,没有考虑英雄技能,钢铁侠的托尼,缩小射线和加血等因素。
代码(python)
import random
import numpy as np
import seaborn as sns
class Card:
def __init__(self, name, type, price, num):
self.name = name
self.type = type
self.price = price
self.num = num
def __str__(self):
return self.name
class Deck:
def __init__(self, deck):
self.init_deck = deck
self.counter = dict()
self.type_list = dict()
self.price_list = dict()
for item in deck:
self.counter[item.name] = item.num
self.type_list[item.name] = item.type
self.price_list[item.name] = item.price
def get_valid_name(self):
l = []
for item in self.counter:
if self.counter[item] > 0:
l.append(item)
return l
def update(self, s):
self.counter[s] -= 1
deck_list = []
# 17 张锁定卡
for i in range(1, 18):
c = Card(name=f'锁定卡{i}', type='lock', price=5, num=4)
deck_list.append(c)
# 234 费要过滤的牌
for i in range(2, 5):
for j in range(8):
c = Card(name=f'滤牌{i}_{j}', type='filter', price=i, num=1)
deck_list.append(c)
# 核心卡牌(复仇者)
core = [
Card(name='索尔复仇', type='core', price=5, num=4),
Card(name='索尔仙宫', type='core', price=5, num=4),
Card(name='美队', type='core', price=5, num=4),
Card(name='浩克', type='core', price=5, num=4),
Card(name='蚁人', type='core', price=5, num=4),
]
deck_list = deck_list + core
for item in deck_list:
print(item)
# 假设有25块
def process_no_twist(money, deck):
hand = []
while money >= 0:
#print(money)
# 策略 过滤牌 + 拿核心牌 + 无视锁定牌
shop = random.sample(deck.get_valid_name(), k=5)
#print(shop)
for item in shop:
if deck.type_list[item] == 'core' and money >= deck.price_list[item]:
money -= deck.price_list[item]
hand.append(item)
deck.update(item)
if deck.type_list[item] == 'filter' and money >= deck.price_list[item]:
money -= deck.price_list[item]
money += 1 # 买了卖
deck.update(item)
# 刷新商店
if money >= 2:
money -= 2
else:
break
return hand
def process_with_twist(money, deck):
hand = []
while money >= 0:
# 策略 过滤牌 + 拿核心牌 + 无视锁定牌
shop = random.sample(deck.get_valid_name(), k=5)
for item in shop:
price = np.random.choice([0,1,2,3,4,5,6,7,8])
if price <= 1:
if deck.type_list[item] == 'core':
hand.append(item)
deck.update(item)
money -= price
else:
deck.update(item)
money -= price
money += 1
elif price <= 5:
if deck.type_list[item] == 'core':
hand.append(item)
deck.update(item)
money -= price
if deck.type_list[item] == 'filter' and price <= deck.price_list[item]:
money -= price
deck.update(item)
money += 1
# 刷新商店
if money >= 2:
money -= 2
else:
break
return hand
def run_experiment(n=1000, money=25, with_twist=True):
experiment = []
for i in range(n):
money = money
deck = Deck(deck_list)
if with_twist:
hand = process_with_twist(money, deck)
else:
hand = process_no_twist(money,deck)
experiment.append(hand)
print(experiment)
L = [len(item) for item in experiment]
Ls = [str(len(item)) for item in experiment]
if with_twist:
sns.histplot(L,color='blue')
print('有扭曲期望收益核心卡牌',np.mean(L))
else:
sns.histplot(L,color='blue')
print('没有扭曲期望收益核心卡牌',np.mean(L))
run_experiment(with_twist=True)
run_experiment(with_twist=False)


