private void Start() { _gameManager = GameManager.Instance; _playerColor = _gameManager.GetPlayerColor(); _playerColorIndex = Array.IndexOf(_colorVariation, _playerColor); var differentFiguresVariation = _obstaclePrefabs.Length * _sizeVariation.Length; _differentFigures = new FigureVariation[differentFiguresVariation]; for (int i = 0, index = 0; i < _obstaclePrefabs.Length; i++) { for (int j = 0; j < _sizeVariation.Length; j++, index++) { _differentFigures[index] = new FigureVariation(_obstaclePrefabs[i], _sizeVariation[j]); } } _lines = new List <ObstacleDescription> [_lineCount]; var zPosition = _zStart; for (var i = 0; i < _lineCount; i++) { _lines[i] = new List <ObstacleDescription>(15); var lastFigureBorder = -_xRange; while (lastFigureBorder < _xRange) { var currentVariation = _differentFigures[UnityEngine.Random.Range(0, _differentFigures.Length)]; var instance = Instantiate <Obstacle>(currentVariation.Prefab, transform); var colorIndex = UnityEngine.Random.Range(0, _colorVariation.Length); instance.Init(_materialVariation[colorIndex], _colorVariation[colorIndex], currentVariation.Size); var figureXSize = instance.GetXSize(); var newXPosition = _xStep + lastFigureBorder + figureXSize / 2; lastFigureBorder = newXPosition + figureXSize / 2; if (lastFigureBorder > _xRange) { GameObject.Destroy(instance.gameObject); break; } var position = new Vector3(newXPosition, instance.GetYSize() / 2, zPosition); instance.SetPosition(position); _lines[i].Add(new ObstacleDescription(instance, colorIndex, position, figureXSize)); } zPosition += _lineStep; // change color to ensure there are exists one way to pass int currentGroupIndex = 0; int previousColorIndex = _lines[i][0].ColorIndex; List <List <int> > matchIndeces = new List <List <int> >(); for (int j = 0; j < _lines[i].Count; j++) { if (j == 0) { if (_lines[i][j].ColorIndex == _playerColorIndex) { matchIndeces.Add(new List <int>()); matchIndeces[currentGroupIndex].Add(j); } continue; } if (_lines[i][j].ColorIndex == _playerColorIndex) { if (previousColorIndex != _playerColorIndex) { matchIndeces.Add(new List <int>()); } matchIndeces[currentGroupIndex].Add(j); } else { if (previousColorIndex == _playerColorIndex) { currentGroupIndex++; } } previousColorIndex = _lines[i][j].ColorIndex; } var playerWidth = _gameManager.GetPlayerWidth(); if (matchIndeces.Any()) { bool exitGroupFound = false; var nonPlayerColors = _colorVariation.Where((w, index) => index != _playerColorIndex).ToArray(); var nonPlayerMaterials = _materialVariation.Where((w, index) => index != _playerColorIndex).ToArray(); for (int j = 0; j < matchIndeces.Count; j++) { var exitWidth = GroupWidth(matchIndeces[j], _lines[i]); if (playerWidth <= exitWidth) { if (exitGroupFound) // replace other exits { for (int k = 0; k < matchIndeces[j].Count; k++) { var newColorIndex = UnityEngine.Random.Range(0, nonPlayerColors.Length); _lines[i][matchIndeces[j][k]].Instance.Init(nonPlayerMaterials[newColorIndex], nonPlayerColors[newColorIndex]); _lines[i][matchIndeces[j][k]].ColorIndex = newColorIndex; } } else { exitGroupFound = true; Debug.Log($"<color=green>For line {i} width is {exitWidth}</color>"); } } } if (!exitGroupFound) { List <int> group = matchIndeces.Last(); float exitWidth = 0; while (exitWidth < playerWidth) { int firstIndex = group[0]; int lastIndex = group[group.Count - 1]; if (lastIndex < (_lines[i].Count - 1)) // group is not in the end of set { _lines[i][++lastIndex].Instance.Init(_materialVariation[_playerColorIndex], _colorVariation[_playerColorIndex]); Debug.Log($"<color=yellow>Change color in line {i} for index {lastIndex}</color>"); group.Add(lastIndex); exitWidth = GroupWidth(group, _lines[i]); } else if (firstIndex > 0) // group is not in the begin of set { _lines[i][--firstIndex].Instance.Init(_materialVariation[_playerColorIndex], _colorVariation[_playerColorIndex]); Debug.Log($"<color=yellow>Change color in line {i} for index {firstIndex}</color>"); var newGroup = new List <int>(group.Count + 1); newGroup.Add(firstIndex); newGroup.AddRange(group); group = newGroup; exitWidth = GroupWidth(group, _lines[i]); } } Debug.Log($"<color=green>For line {i} width is {exitWidth}</color>"); } } else // no matching groups (no player color in line at all) { float exitWidth = 0; int index = 0; var group = new List <int>(); while (exitWidth < playerWidth) { _lines[i][index].Instance.Init(_materialVariation[_playerColorIndex], _colorVariation[_playerColorIndex]); Debug.Log($"<color=yellow>Change color in line {i} for index {index}</color>"); group.Add(index); exitWidth = GroupWidth(group, _lines[i]); index++; } Debug.Log($"<color=green>For line {i} width is {exitWidth}</color>"); } } }