计算老虎机支出

时间:2014-08-18 16:56:15

标签: algorithm data-structures language-agnostic gambling

老虎机有5个卷轴,每个卷轴显示3个符号(没有空格或"空"符号)。

付款可以通过多种方式进行。一些例子......

  • 出现一个特殊的钻石符号
  • 3 Lucky 7&#39出现
  • 支付线中的所有五个符号都相同
  • 所有五个符号都是相同的数字,但颜色不同

还需要检查多条支付线以获得付款。

Examples of 30 different paylines

每次旋转计算奖金的最有效方法是什么?或者,是否有比蛮力更有效的方式将每个支付方案应用于每条支付线?

2 个答案:

答案 0 :(得分:9)

支付线以外的每一笔支出都显得微不足道。对于三个幸运的7,只需迭代可见的方块并计算7s。检查钻石也是如此。如果我们让 h 为行数且 w 为列数,则此操作为O( h w *),其中实际尺寸的老虎机非常低。

但是,支付线更有趣。从理论上讲,支付线的数量( m 从此处开始)远远大于* h ** w *;在抛出跳过 m = h ^ w 的非法支付线之前,它远远大于* 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]。

为此,suffix tree似乎是一个适用的数据结构,可以极大地改善检查给定董事会状态的所有支付线的运行时间。请考虑以下算法来构建封装所有支付线的后缀树。

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行的示例中运行此构造算法会得到如下所示的树:

enter image description here

这棵树的计算相当密集;它涉及创建sum i = 1 to w of h ^ i个节点。树的大小仅取决于板的大小(高度和宽度),而不取决于支付线的数量,这是这种方法的主要优点。另一个优点是它都是预处理;你可以在玩家坐下来拉杆之前很久就建造这棵树。

构建树后,您可以为每个节点提供每个匹配条件的字段(相同的符号,相同的颜色等)。然后,在评估板状态时,您可以对树进行dfs,并在每个新节点上询问(对于每个critera)它是否与其父节点匹配。如果是,请将该标准标记为true并继续。否则,将其标记为false并且不要搜索孩子的标准。例如,如果您专门查找子阵列[1,1,...]上的相同令牌,并找到第1列第1行和第2列第1行并且#39 ;匹配,然后包括[1,1,...](2,6,16,20)的任何支付线都不能赢,而且你不必dfs那部分dfs树。

很难对这种dfs方法的效率进行彻底的算法分析,而不是单独检查每条支付线,因为这样的分析需要知道左侧重叠(平均)有多少支付线。它当然不会更糟,至少对你的例子来说是一个更好的交易。此外,您添加到电路板的支付线越多,重叠越大,使用此方法检查所有支付线的时间就越长。

答案 1 :(得分:1)

为了计算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:

    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];
        }
    }

每次旋转后,应计算所有胜利。