public void Set(MatrixInWork src) { if (src.symbols.Length != symbols.Length) { return; } for (int i = 0; i < src.symbols.Length; i++) { if (src.symbols[i].Length != symbols[i].Length) { return; } } for (int i = 0; i < src.symbols.Length; i++) { for (int j = 0; j < src.symbols[i].Length; j++) { symbols[i][j].Set(src.symbols[i][j]); } } }
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); }
bool PrintSymbolLineToMatrix(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); } if (!matrixSymbol.fixedSymbol) { matrixSymbol.symbolMask = symbolId.symbolId; matrixSymbol.fixedSymbol = true; } } else { if ((matrixSymbol.symbolMask & symbolId.symbolId) != 0) { if (matrixSymbol.fixedSymbol) { return(false); } matrixSymbol.symbolMask = matrixSymbol.symbolMask - symbolId.symbolId; } } } return(true); }
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); }
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); } }