예제 #1
0
        bool CheckLineToPrint(SlotLine lineId, GenSymbolId symbolId, SymbolCombination symbolCombination, MatrixInWork matrix)
        {
            int maxMajorSymbols = symbolCombination.count;

            for (int i = 0; i < lineId.indexOnDrum.Length; i++)
            {
                int          indexInDrum  = lineId.indexOnDrum[i];
                SymbolInWork matrixSymbol = matrix.symbols[i][indexInDrum];

                if (i < maxMajorSymbols)
                {
                    if ((matrixSymbol.symbolMask & symbolId.symbolId) == 0)
                    {
                        return(false);
                    }
                }
                else
                {
                    if ((matrixSymbol.symbolMask & symbolId.symbolId) != 0 && matrixSymbol.fixedSymbol)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
예제 #2
0
        bool RemoveLine(SlotLine lineId, GenSymbolId symbolId, MatrixInWork matrix)
        {
            int maxMajorDrums = symbolId.symbolConfig.combinations[0].count;

            for (int i = 1; i < maxMajorDrums; i++)
            {
                SymbolInWork workSymbol = matrix.symbols[i][lineId.indexOnDrum[i]];
                uint         symbolMask = workSymbol.symbolMask;
                if ((symbolMask & symbolId.symbolId) == 0)
                {
                    return(true);
                }
                else if (!workSymbol.fixedSymbol)
                {
                    workSymbol.symbolMask = workSymbol.symbolMask - symbolId.symbolId;
                    return(true);
                }
            }

            for (int i = maxMajorDrums; i < lineId.indexOnDrum.Length; i++)
            {
                SymbolInWork workSymbol = matrix.symbols[i][lineId.indexOnDrum[i]];
                if (!workSymbol.fixedSymbol)
                {
                    workSymbol.symbolMask = workSymbol.symbolMask - symbolId.symbolId;
                }
            }

            return(false);
        }
예제 #3
0
        bool RemoveLinesForSymbol(int posOnFirstDrum, GenSymbolId symbolId, MatrixInWork startMatrix, List <string> usedLines, out List <SlotLine> linesNotRemoved)
        {
            List <GenLineId> linesForIndex = new List <GenLineId>();

            foreach (var curLine in lineIdToGenLine.Values)
            {
                if (curLine.lineConfig.indexOnDrum[0] == posOnFirstDrum && !usedLines.Contains(curLine.lineConfig.tag) && CheckForAvaliableLine(symbolId, curLine, startMatrix))
                {
                    linesForIndex.Add(curLine);
                }
            }

            if (linesForIndex.Count == 0)
            {
                linesNotRemoved = null;
                return(true);
            }

            linesNotRemoved = new List <SlotLine>();
            bool successRemoved = true;

            foreach (var curLine in linesForIndex)
            {
                if (!RemoveLine(curLine.lineConfig, symbolId, startMatrix))
                {
                    linesNotRemoved.Add(curLine.lineConfig);
                    successRemoved = false;
                }
            }

            return(successRemoved);
        }
예제 #4
0
        bool CheckSymbolByFirstUsed(int[] firstIndicies, MatrixInWork matrix, GenSymbolId symbolId)
        {
            for (int i = 0; i < firstIndicies.Length; i++)
            {
                if (matrix.symbols[0][firstIndicies[i]].symbolMask == symbolId.symbolId)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        bool AddLineCombination(List <SlotLine> lineCombination, GenSymbolId symbolId, List <SymbolCombination> symbolCombinations, MatrixInWork matrix)
        {
            int combIndex = 0;

            foreach (var curLine in lineCombination)
            {
                if (!PrintSymbolLineToMatrix(curLine, symbolId, symbolCombinations[combIndex++], matrix))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #6
0
        bool CheckForAvaliableLine(GenSymbolId symbolId, GenLineId lineId, MatrixInWork processMatrix)
        {
            int maxAgreeDrumIndex = symbolId.symbolConfig.combinations[0].count;

            for (int i = 0; i < maxAgreeDrumIndex; i++)
            {
                int  indexOnDrum = lineId.lineConfig.indexOnDrum[i];
                uint cellMask    = processMatrix.symbols[i][indexOnDrum].symbolMask;
                if ((cellMask & symbolId.symbolId) == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #7
0
 void CalculateRewardBySymbol(int index, GenSymbolId symbolId, FinalSpinReward inputReward)
 {
     /*List<GenLineId> linesForIndex = new List<GenLineId>();
      * foreach (var curLine in lineIdToGenLine.Values)
      * {
      *  if (curLine.lineConfig.indexOnDrum[0] == index)
      *      linesForIndex.Add(curLine);
      * }
      * Shuffle(linesForIndex);
      *
      * List<uint> excludeLines = new List<uint>();
      *
      * while (true)
      * {
      *  uint linesCombination = 0b10101; // calculate by need reward and possible lines
      *  CalculateRewardByLines(index, symbolId, linesCombination, linesForIndex);
      * }
      */
 }
예제 #8
0
 void AddPlayingLinesToSteps(GenSymbolId symbolId, MatrixInWork startMatrix, List <SlotLine> lines, List <MatrixStepBySymbol> linesToPlay, List <string> usedLines)
 {
     foreach (var curLine in lines)
     {
         foreach (var curCombination in symbolId.symbolConfig.combinations)
         {
             if (CheckLineToPrint(curLine, symbolId, curCombination, startMatrix))
             {
                 MatrixStepBySymbol newStep = new MatrixStepBySymbol();
                 newStep.symbolId        = symbolId;
                 newStep.matrix          = startMatrix;
                 newStep.combination     = curCombination;
                 newStep.currentReward   = curCombination.reward;
                 newStep.lineCombination = curLine;
                 linesToPlay.Add(newStep);
                 usedLines.Add(curLine.tag);
             }
         }
     }
 }
예제 #9
0
        void CalculateRewardByLines(int index, GenSymbolId symbolId, uint linesCombination, List <GenLineId> linesForIndex)
        {
            int combinationCount    = symbolId.symbolConfig.combinations.Length;
            int curCombinationIndex = 0;

            int[] currentCombinations = new int[combinationCount];
            while (true)
            {
                int i = 0;
                foreach (var curLineId in linesForIndex)
                {
                    if ((curLineId.lineId & linesCombination) != 0)
                    {
                        currentCombinations[i++] = curCombinationIndex;
                    }
                }

                curCombinationIndex++;
            }

            //symbolId.symbolConfig.combinations[0].
        }
예제 #10
0
        SymbolStepResultType FindMatrixForSymbol(int posOnFirstDrum, GenSymbolId symbolId, MatrixInWork startMatrix, float maxEstimateReward, float chanceModificator, List <string> usedLines, out MatrixStepBySymbol result)
        {
            result = new MatrixStepBySymbol();

            List <GenLineId> linesForIndex = new List <GenLineId>();

            foreach (var curLine in lineIdToGenLine.Values)
            {
                if (curLine.lineConfig.indexOnDrum[0] == posOnFirstDrum && !usedLines.Contains(curLine.lineConfig.tag) && CheckForAvaliableLine(symbolId, curLine, startMatrix))
                {
                    linesForIndex.Add(curLine);
                }
            }

            if (linesForIndex.Count == 0)
            {
                return(SymbolStepResultType.NoAvaliableLines);
            }

            float maxThreshold = symbolId.symbolConfig.GetMinimumReward() / 2.0f;

            var chances = CalculateFactorChances(symbolId.symbolConfig.combinations, chanceModificator);

            SymbolCombination selectedCombination = null;

            if (symbolId.symbolConfig.combinations[0].reward > (maxEstimateReward + maxThreshold))
            {
                return(SymbolStepResultType.EstimateRewardIsSmall);
            }
            else if (Mathf.Abs(symbolId.symbolConfig.combinations[0].reward - maxEstimateReward) < maxThreshold)
            {
                selectedCombination = symbolId.symbolConfig.combinations[0];
            }

            while (selectedCombination == null)
            {
                SymbolCombination randomCombination = GetRandomCombination(chances);
                if (randomCombination.reward > (maxEstimateReward + maxThreshold) && chances[0].combination.reward < (maxEstimateReward + maxThreshold))
                {
                    continue;
                }

                selectedCombination = randomCombination;
            }

            Shuffle(linesForIndex);

            SlotLine     resultLine = null;
            MatrixInWork newMatrix  = startMatrix.Copy();

            foreach (var curLine in linesForIndex)
            {
                if (CheckLineToPrint(curLine.lineConfig, symbolId, selectedCombination, newMatrix))
                {
                    PrintSymbolLineToMatrix(curLine.lineConfig, symbolId, selectedCombination, newMatrix);
                    resultLine = curLine.lineConfig;
                    break;
                }
            }

            if (resultLine == null)
            {
                return(SymbolStepResultType.LinesNotFound);
            }

            result.symbolId        = symbolId;
            result.matrix          = newMatrix;
            result.combination     = selectedCombination;
            result.lineCombination = resultLine;
            result.currentReward   = selectedCombination.reward;

            return(SymbolStepResultType.Success);
        }
예제 #11
0
        void ProcessSymbols(int[] firstIndicies, MatrixInWork startMatrix)
        {
            List <MatrixStepBySymbol> steps = new List <MatrixStepBySymbol>();

            int   currentIndex       = 0;
            float symbolRewardFactor = 1.0f;
            float curReward          = 0.0f;

            float rewardChanceModifier = 1.0f;
            float maxRewardChanceValue = 16.0f;

            List <string> excludedLines   = new List <string>();
            int           countClearStart = 0;
            int           countIterations = 0;

            List <GenSymbolId> symbolsToGenerate = symbolIdToGenSymbol.Values.ToList();


            while (true)
            {
                countIterations++;

                if (currentIndex >= firstIndicies.Length)
                {
                    currentIndex = 0;
                }

                GenSymbolId  currentSymbol = symbolsToGenerate[Random.Range(0, symbolsToGenerate.Count)];
                MatrixInWork curMatrix;
                if (steps.Count == 0)
                {
                    curMatrix = startMatrix;
                    countClearStart++;
                }
                else
                {
                    curMatrix = steps.Last().matrix;
                }

                float needAllReward = (currentSpinInfo.finalRewardPercent - curReward);
                MatrixStepBySymbol   newStep;
                SymbolStepResultType result = FindMatrixForSymbol(firstIndicies[currentIndex], currentSymbol, curMatrix, needAllReward, rewardChanceModifier, excludedLines, out newStep);

                //если успешно добавили новую линию
                if (result == SymbolStepResultType.Success)
                {
                    float newFinalReward = curReward + newStep.currentReward;

                    //если достигли требуемой награды, прекращаем алгоритм
                    if (Mathf.Abs(newFinalReward - currentSpinInfo.finalRewardPercent) < currentSymbol.symbolConfig.GetMinimumReward() * 0.5f)
                    {
                        Debug.LogError("Reward reached!");
                        curReward += newStep.currentReward;
                        excludedLines.Add(newStep.lineCombination.tag);
                        steps.Add(newStep);
                        break;
                    }
                    else if (newFinalReward > (currentSpinInfo.finalRewardPercent +
                                               currentSymbol.symbolConfig.GetMinimumReward()))
                    {
                        //если не получилось за несколько раз, выдаем текущий результат (хоть он и не валидный)
                        if (rewardChanceModifier < (-maxRewardChanceValue + 0.001f))
                        {
                            Debug.LogError("Reward is very big! Finished");
                            curReward += newStep.currentReward;
                            excludedLines.Add(newStep.lineCombination.tag);
                            steps.Add(newStep);
                            break;
                        }
                        else
                        {
                            //уменьшаем вероятность больших наград и начинаем сначала
                            steps.Clear();
                            currentIndex = 0;
                            curReward    = 0.0f;
                            excludedLines.Clear();
                            rewardChanceModifier = Mathf.Min(rewardChanceModifier, -1.0f);
                            rewardChanceModifier = rewardChanceModifier * 2.0f;
                        }

                        continue;
                    }

                    curReward += newStep.currentReward;
                    currentIndex++;
                    steps.Add(newStep);
                    excludedLines.Add(newStep.lineCombination.tag);
                }
                else if (result == SymbolStepResultType.EstimateRewardIsSmall)
                {
                    //минимальная комбинация слишком большая для награды, которую осталось набрать, значит все ок, прерываем алгоритм.
                    break;
                }
                else if (result == SymbolStepResultType.NoAvaliableLines || result == SymbolStepResultType.LinesNotFound)
                {
                    //если не получилось за несколько раз, выдаем текущий результат (хоть он и не валидный)
                    if (rewardChanceModifier > (maxRewardChanceValue - 0.0001f))
                    {
                        Debug.LogError("Reward not reached, lines incorrect..");
                        break;
                    }
                    else
                    {
                        //уменьшаем вероятность больших наград и начинаем сначала
                        steps.Clear();
                        currentIndex = 0;
                        curReward    = 0.0f;
                        excludedLines.Clear();
                        rewardChanceModifier = Mathf.Max(rewardChanceModifier, 1.0f);
                        rewardChanceModifier = rewardChanceModifier * 2.0f;
                    }

                    continue;
                }
                else
                {
                    Debug.LogError("Something wrong! Unknown SymbolStepResultType");
                    steps.Clear();
                    excludedLines.Clear();
                    currentIndex         = 0;
                    curReward            = 0.0f;
                    rewardChanceModifier = 0.0f;
                }
            }

            Shuffle(symbolsToGenerate);

            //убираем линии которые еще могут сыграть, также генерим первые символы, если они еще не созданы, таким образом, что они не сыграют
            foreach (var curFirstindex in firstIndicies)
            {
                MatrixInWork lastMatrix   = steps.Last().matrix;
                SymbolInWork matrixSymbol = lastMatrix.symbols[0][curFirstindex];
                if (symbolIdToGenSymbol.ContainsKey(matrixSymbol.symbolMask))
                {
                    GenSymbolId foundSymbol;
                    if (symbolIdToGenSymbol.TryGetValue(matrixSymbol.symbolMask, out foundSymbol))
                    {
                        List <SlotLine> noRemoveLines;
                        bool            isRemoved = RemoveLinesForSymbol(curFirstindex, foundSymbol, lastMatrix, excludedLines, out noRemoveLines);
                        if (!isRemoved && noRemoveLines != null)
                        {
                            AddPlayingLinesToSteps(foundSymbol, lastMatrix, noRemoveLines, steps, excludedLines);
                        }
                    }
                }
                else
                {
                    GenSymbolId symbolFound = null;
                    for (int j = 0; j < symbolsToGenerate.Count; j++)
                    {
                        GenSymbolId curSymbol = symbolsToGenerate[j];
                        if ((curSymbol.symbolId & matrixSymbol.symbolMask) != 0 && !CheckSymbolByFirstUsed(firstIndicies, lastMatrix, curSymbol))
                        {
                            lastMatrix.symbols[0][curFirstindex].symbolMask = curSymbol.symbolId;
                            symbolFound = curSymbol;
                            break;
                        }
                    }

                    if (symbolFound == null)
                    {
                        symbolFound = symbolsToGenerate[0];
                    }

                    List <SlotLine> noRemoveLines;
                    bool            isRemoved = RemoveLinesForSymbol(curFirstindex, symbolFound, lastMatrix, excludedLines, out noRemoveLines);
                    if (!isRemoved && noRemoveLines != null)
                    {
                        AddPlayingLinesToSteps(symbolFound, lastMatrix, noRemoveLines, steps, excludedLines);
                    }
                }
            }

            //генерим оставшиеся символы, которые точно не сыграют
            MatrixInWork matrix = steps.Last().matrix;

            for (int i = 0; i < matrix.symbols.Length; i++)
            {
                for (int j = 0; j < matrix.symbols[i].Length; j++)
                {
                    SymbolInWork symbol = matrix.symbols[i][j];
                    if (!symbol.fixedSymbol)
                    {
                        Shuffle(symbolsToGenerate);
                        foreach (var curSymbolId in symbolsToGenerate)
                        {
                            if ((symbol.symbolMask & curSymbolId.symbolId) != 0)
                            {
                                symbol.symbolMask  = curSymbolId.symbolId;
                                symbol.fixedSymbol = true;
                            }
                        }
                    }
                }
            }

            Debug.Log("Finish generate! Need reward=" + currentSpinInfo.finalRewardPercent + "; real reward=" + curReward + "; steps=" + steps.Count + "; clearStart=" + countClearStart + "; allIterations=" + countIterations);

            int k1 = 0;

            foreach (var curStep in steps)
            {
                Debug.Log("Step" + (k1++) + ": Symbol=" + curStep.symbolId.symbolConfig.tag + "; Line=" + curStep.lineCombination.ToString() + "; reward=" + curStep.combination.reward);
            }

            matrix = steps.Last().matrix;
            for (int i = 0; i < matrix.symbols.Length; i++)
            {
                string curLine = i + ": ";
                for (int j = 0; j < matrix.symbols[i].Length; j++)
                {
                    string curSymbolStr = "[";
                    foreach (var s in symbolsToGenerate)
                    {
                        if ((matrix.symbols[i][j].symbolMask & s.symbolId) == 0)
                        {
                            curSymbolStr += "<_" + s.symbolConfig.tag + "_>";
                        }
                        else
                        {
                            curSymbolStr += "<" + s.symbolConfig.tag + ">";
                        }
                    }

                    curSymbolStr = curSymbolStr.Trim(new char[] { ',' }) + "]";
                    curLine     += curSymbolStr + ",";
                }
                curLine = curLine.Trim(new char[] { ',' }) + "]";

                Debug.Log("Matrix line " + curLine);
            }
        }