老虎机有 5 个转轴,每个转轴显示 3 个符号(没有空格或“空”符号)。
支付可以通过多种方式进行。一些例子...
- 出现一个特殊的菱形符号
- 3个幸运7出现
- 支付线上的所有五个符号都是相同的
- 所有五个符号都是相同的数字,但颜色不同
- 等等。
还有多条支付线需要检查支付。
计算每次旋转奖金的最有效方法是什么?或者,有没有比蛮力更有效的方法将每个支付场景应用于每条支付线?
老虎机有 5 个转轴,每个转轴显示 3 个符号(没有空格或“空”符号)。
支付可以通过多种方式进行。一些例子...
还有多条支付线需要检查支付。
计算每次旋转奖金的最有效方法是什么?或者,有没有比蛮力更有效的方法将每个支付场景应用于每条支付线?
除了支付线之外,每笔支出似乎都是微不足道的。对于三个幸运的 7,只需遍历可见方块并计算 7。检查钻石也是如此。如果我们让h是行数,w是列数,这个操作是 O( h w*),对于实际大小的老虎机来说是相当低的。
不过,支付线更有趣。从理论上讲,支付线的数量(从这里开始的m)比 *h ** w* 大得多;在抛出比 *h ** w大得多的跳跃m = h^w的非法支付线之前。更重要的是,它们似乎有很多相似之处。例如,示例中的第 2 行和第 6 行都需要匹配左上角和左上角的正方形。如果这两个不匹配,那么您将无法在第 2 行或第 6 行中获胜。
为了表示支付线,我将使用[1, h ] 范围内的长度为w的整数数组,这样 payline[i] = 解决方案中第 i 行的列(1 索引)中的索引。例如,支付线 1 是 [1, 1, 1, 1, 1],支付线 17 是 [3, 3, 2, 1, 2]。
为此,后缀树似乎是一种适用的数据结构,可以极大地提高您根据给定的棋盘状态检查所有支付线的运行时间。考虑以下算法来构建封装所有支付线的后缀树。
Initialize:
Create a root node at column 0 (off-screen, non-column part of all solutions)
root node.length = 0
root node.terminal = false
Add all paylines (in the form of length w arrays of integers ranging from 1 to h) to the root nodes' "toDistribute set"
Create a toWork queue, add the root node to it
Iterate: while toWork not empty:
let node n = toWork.pop()
if n.length < w
create children of n with length n.length + 1 and terminal = (n.length + 1 == w).
for payline p in n.toDistribute
remove p from n.toDistribute
if(p.length > 1)
add p.subArray(1, end) to child of n as applicable.
add children of n to toWork
在第 1-11 行的示例中运行此构造算法会得到一个如下所示的树:
这棵树的计算相当密集;它涉及sum i = 1 to w of h ^ i
节点的创建。树的大小仅取决于棋盘的大小(高度和宽度),而不是支付线的数量,这是这种方法的主要优势。另一个优点是它都是预处理;您可以在玩家坐下来拉动杠杆之前很久就建造这棵树。
构建树后,您可以为每个节点提供每个匹配条件的字段(相同的符号、相同的颜色等)。然后,在评估板状态时,您可以对树进行 dfs,并在每个新节点处询问(针对每个标准)它是否与其父节点匹配。如果是这样,将该标准标记为真并继续。否则,将其标记为 false 并且不要在子项中搜索该条件。例如,如果您在子数组 [1, 1, ...] 上专门寻找相同的标记,并发现第 1 列的第 1 行和第 2 列的第 1 行不匹配,则任何包含 [1, 1, ...] (2, 6, 16, 20) 都无法获胜,您不必对树的那部分进行 dfs。
很难对这种 dfs 方法比单独检查每条支付线的效率高多少进行彻底的算法分析,因为这样的分析需要知道支付线之间的左侧重叠(平均)有多少。这当然不会更糟,至少对你的例子来说要好得多。此外,您添加到板上的支付线越多,重叠就越大,使用此方法检查所有支付线所节省的时间就越多。
为了计算 RTP,您应该拥有完整的老虎机信息。最重要的部分是卷轴带。蒙特卡洛通常是为了获得所需的统计数据而完成的。例如:https ://raw.githubusercontent.com/VelbazhdSoftwareLLC/BugABoomSimulator/master/Main.cs
支付宝信息:
private static int[][] paytable = {
new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0},
new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0},
new int[]{0,0,0,0,0,0,0,0,2,2,2,10,2},
new int[]{5,5,5,10,10,10,15,15,25,25,50,250,5},
new int[]{25,25,25,50,50,50,75,75,125,125,250,2500,0},
new int[]{125,125,125,250,250,250,500,500,750,750,1250,10000,0},
};
投注线:
private static int[][] lines = {
new int[]{1,1,1,1,1},
new int[]{0,0,0,0,0},
new int[]{2,2,2,2,2},
new int[]{0,1,2,1,0},
new int[]{2,1,0,1,2},
new int[]{0,0,1,2,2},
new int[]{2,2,1,0,0},
new int[]{1,0,1,2,1},
new int[]{1,2,1,0,1},
new int[]{1,0,0,1,0},
new int[]{1,2,2,1,2},
new int[]{0,1,0,0,1},
new int[]{2,1,2,2,1},
new int[]{0,2,0,2,0},
new int[]{2,0,2,0,2},
new int[]{1,0,2,0,1},
new int[]{1,2,0,2,1},
new int[]{0,1,1,1,0},
new int[]{2,1,1,1,2},
new int[]{0,2,2,2,0},
};
卷轴条:
private static int[][] baseReels = {
new int[]{0,4,11,1,3,2,5,9,0,4,2,7,8,0,5,2,6,10,0,5,1,3,9,4,2,7,8,0,5,2,6,9,0,5,2,4,10,0,5,1,7,9,2,5},
new int[]{4,1,11,2,7,0,9,5,1,3,8,4,2,6,12,4,0,3,1,8,4,2,6,0,10,4,1,3,2,12,4,0,7,1,8,2,4,0,9,1,6,2,8,0},
new int[]{1,7,11,5,1,7,8,6,0,3,12,4,1,6,9,5,2,7,10,1,3,2,8,1,3,0,9,5,1,3,10,6,0,3,8,7,1,6,12,3,2,5,9,3},
new int[]{5,2,11,3,0,6,1,5,12,2,4,0,10,3,1,7,3,2,11,5,4,6,0,5,12,1,3,7,2,4,8,0,3,6,1,4,12,2,5,7,0,4,9,1},
new int[]{7,0,11,4,6,1,9,5,10,2,7,3,8,0,4,9,1,6,5,10,2,8,3},
};
private static int[][] freeReels = {
new int[]{2,4,11,0,3,7,1,4,8,2,5,6,0,5,9,1,3,7,2,4,10,0,3,1,8,4,2,5,6,0,4,1,10,5,2,3,7,0,5,9,1,3,6},
new int[]{4,2,11,0,5,2,12,1,7,0,9,2,3,0,12,2,4,0,5,8,2,6,0,12,2,7,1,3,10,6,0},
new int[]{1,4,11,2,7,8,1,5,12,0,3,9,1,7,8,1,5,12,2,6,10,1,4,9,3,1,8,0,12,6,9},
new int[]{6,4,11,2,7,3,9,1,6,5,12,0,4,10,2,3,8,1,7,5,12,0},
new int[]{3,4,11,0,6,5,3,8,1,7,4,9,2,5,10,0,3,8,1,4,10,2,5,9},
};
为了计算 RTP,应该多次调用 spin 函数:
private static void spin(int[][] reels) {
for (int i = 0, r, u, d; i < view.Length && i < reels.Length; i++) {
if (bruteForce == true) {
u = reelsStops [i];
r = u + 1;
d = u + 2;
} else {
u = prng.Next (reels [i].Length);
r = u + 1;
d = u + 2;
}
r = r % reels[i].Length;
d = d % reels[i].Length;
view[i][0] = reels[i][u];
view[i][1] = reels[i][r];
view[i][2] = reels[i][d];
}
}
每次旋转后,应计算所有胜利。