背景
如果您玩过冒险游戏,就会熟悉掷骰子来决定战斗的结果。如果没有,这里有一个简短的概要:
确定玩家可以摇动多少个骰子的规则如下:
- 攻击者可以比他的国家的军队数量少摇动一颗骰子,最多三颗。
- 防御者可以摇动与其国家军队数量一样多的骰子,最多两个。
决定特定掷骰子结果的规则如下:
- 将最高攻击者死亡与最高防御者死亡进行比较。人数较少的人将失去一支军队。领带归后卫。
- 对第二大骰子重复该过程。
如果进攻方或防守方只掷一个骰子,则总共只会损失一支军队;在所有其他情况下,总共将损失两支军队。
我想分析每对掷骰子的赢/输频率。我可以遍历所有可能性,但我对使用 ndarrays
和切片进行计算很感兴趣。
例如,考虑攻击者掷一枚骰子而防御者掷一枚骰子的场景。我们可以在 ndarray
中安排所有可能的结果。
In [1]: import numpy as np
In [2]: x = np.tile(np.arange(1,7),(6,1))
In [3]: x
Out[3]:
array([[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6]])
如果防御者掷骰是列,攻击者掷骰是行,那么防御者获胜的区域就是这个数组的上三角部分
defence_win_region= array([[1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1]])
问题
如何从 x
这样的数组中获取像 defence_win_region
这样的数组?我如何将该方法扩展到更高维度的数组以分析 2-1,3-1,3-2,1-2 卷?
最佳答案
import numpy as np
import scipy
import itertools
def riskRoll(ad,dd): #Never gonna give you up . . .
minD=min(ad,dd)
a=np.array(list(itertools.combinations_with_replacement(
np.arange(6,0,-1),ad)))
d=np.array(list(itertools.combinations_with_replacement(
np.arange(6,0,-1),dd)))
na=np.array([scipy.misc.factorial(ad)/np.prod(
scipy.misc.factorial(np.unique(roll,return_counts=True)[1])) for roll in a])
nd=np.array([scipy.misc.factorial(dd)/np.prod(
scipy.misc.factorial(np.unique(roll,return_counts=True)[1])) for roll in d])
a_wins= np.sum(p.where(a[None,:,0:minD]>d[:,None,0:minD],1,-1), axis=-1)+ad-dd
nd_count=na[:,None]*nd[None,:]
return a_wins*nd_count
工作原理:
- 输出是一个大小为
C((6,ad)) x C((6,dd))
的矩阵,所有组合均按降序排列 - 矩阵
a_wins
中的值是攻击方获胜的次数,负数是防御方获胜的次数。这包括非竞争骰子。 nd_count
中的值是权重因子,等于该组合在6**ad x 6**dd
组合矩阵中存在的次数- 最终输出是两者的乘积,显示按发生次数加权的获胜次数。求和并除以 6**(ad+dd) 以获得预期的赢/输
关于python - 如何找到二维数组满足某些条件的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41091349/