List <int> GetJoyRowCounts(IsLuckyModePredicate pred, MachineTestLuckyMode mode, SpinResultType resultType, List <MachineTestRoundResult> roundResults)
    {
        int        rowCount = MachineTestUtility.GetJoyRowCount(_machineConfig, mode, resultType);
        List <int> result   = new List <int>(rowCount);

        for (int i = 0; i < rowCount; i++)
        {
            result.Add(0);
        }

        foreach (var r in roundResults)
        {
            if (pred(r) && r._output._spinResult.Type == resultType)
            {
                int id = r._output._spinResult.GetJoyId();
                if (id > result.Count)
                {
                    Debug.LogError("index out of range");
                    Debug.Assert(false);
                }
                ++result[id - 1];
            }
        }

        return(result);
    }
    MachineTestAnalysisLuckyModeResult GetLuckyModeResult(MachineTestLuckyMode mode, List <MachineTestRoundResult> roundResults)
    {
        MachineTestAnalysisLuckyModeResult result = new MachineTestAnalysisLuckyModeResult();
        IsLuckyModePredicate luckyPred            = _luckyPredicateDict[mode];
        IsLuckyModePredicate luckyNoRespinPred    = _luckyNoRespinPredicateDict[mode];

        result._totalConsumedBetAmount = GetTotalConsumedBetAmount(luckyPred, roundResults);
        result._totalWinAmount         = GetTotalWinAmount(luckyPred, roundResults);
        result._rtp = GetRTP(result._totalConsumedBetAmount, result._totalWinAmount);
        result._spinCountInCurrentMode          = GetSpinCountInCurrentMode(luckyPred, roundResults);
        result._enterSpecialSmallGameStateCount = GetEnterSpecialSmallGameStateCount(luckyPred, roundResults);
        result._respinCount = GetRespinCount(luckyPred, roundResults);
        result._enterSpecialSmallGameStateCountProb = GetEnterSpecialSmallGameStateCountProb(result);
        result._respinCountProb = GetRespinCountProb(result);

        if (mode != MachineTestLuckyMode.Hybrid && ShouldAnalysisDetail(_machineConfig))
        {
            result._payoutRowCounts  = GetJoyRowCounts(luckyNoRespinPred, mode, SpinResultType.Win, roundResults);
            result._nearHitRowCounts = GetJoyRowCounts(luckyNoRespinPred, mode, SpinResultType.NearHit, roundResults);

            result._payoutRowProbs  = GetJoyRowProbs(result._payoutRowCounts, result._spinCountInCurrentMode);
            result._nearHitRowProbs = GetJoyRowProbs(result._nearHitRowCounts, result._spinCountInCurrentMode);

            result._payoutRowProbDeviations  = GetJoyRowProbDeviations(mode, SpinResultType.Win, result._payoutRowProbs);
            result._nearHitRowProbDeviations = GetJoyRowProbDeviations(mode, SpinResultType.NearHit, result._nearHitRowProbs);

            result._payoutTotalProb  = GetJoyTotalProb(result._payoutRowProbs);
            result._nearHitTotalProb = GetJoyTotalProb(result._nearHitRowProbs);

            result._payoutTotalProbDeviation  = GetJoyTotalProbDeviation(mode, SpinResultType.Win, result._payoutTotalProb);
            result._nearHitTotalProbDeviation = GetJoyTotalProbDeviation(mode, SpinResultType.NearHit, result._nearHitTotalProb);
        }

        return(result);
    }
    int GetSpinCountInCurrentMode(IsLuckyModePredicate pred, List <MachineTestRoundResult> roundResults)
    {
        int result = ListUtility.FoldList(roundResults, 0, (int acc, MachineTestRoundResult r) => {
            if (pred(r))
            {
                ++acc;
            }
            return(acc);
        });

        return(result);
    }
    int GetRespinCount(IsLuckyModePredicate pred, List <MachineTestRoundResult> roundResults)
    {
        int result = ListUtility.FoldList <MachineTestRoundResult, int>(roundResults, 0, (int acc, MachineTestRoundResult rr) => {
            if (pred(rr) && IsRespinRound(rr))
            {
                ++acc;
            }
            return(acc);
        });

        return(result);
    }
    int GetEnterSpecialSmallGameStateCount(IsLuckyModePredicate pred, List <MachineTestRoundResult> roundResults)
    {
        int result = ListUtility.FoldList <MachineTestRoundResult, int>(roundResults, 0, (int acc, MachineTestRoundResult rr) => {
            if (pred(rr) && rr._output._isChangeToSpecialSmallGameState)
            {
                ++acc;
            }
            return(acc);
        });

        return(result);
    }
    ulong GetTotalWinAmount(IsLuckyModePredicate pred, List <MachineTestRoundResult> roundResults)
    {
        ulong result = ListUtility.FoldList <MachineTestRoundResult, ulong>(roundResults, 0, (ulong acc, MachineTestRoundResult rr) => {
            if (pred(rr))
            {
                acc += rr._output._spinResult.WinAmount;
            }
            return(acc);
        });

        return(result);
    }