/// <inheritdoc /> protected override void Update() { _freeCursorPosition = UnityEngine.Input.mousePosition; // TODO handle cursor leaving and entering window var newCursorPos = (Vector2Int)levelGrid.WorldToCell(camera.ScreenToWorldPoint(_freeCursorPosition)); if (newCursorPos != _currentCursorGridPos) { _withinLevelBounds = levelSettings == null || LevelUtility.IsCellWithinBounds(newCursorPos, levelSettings.size); _currentCursorGridPos = newCursorPos; normalClick.currentCursorGridPos = specialClick.currentCursorGridPos = _currentCursorGridPos; if (enabled) { onCellHovered.Invoke(_withinLevelBounds ? _currentCursorGridPos : null); } normalClick.OnCellHovered(_currentCursorGridPos); specialClick.OnCellHovered(_currentCursorGridPos); } base.Update(); if (UnityEngine.Input.GetKeyUp(frameKey)) { onFrameAction.Invoke(); } }
public static void StartRevealChain(Cell[,] level, int x, int y, Func <Cell, Vector2Int, bool> onSouldReveal) { if (!level.TryGetValue(x, y, out Cell cell)) { return; // Indexes out of range } if (cell.isRevealed || cell.hasFlag) { return; // cell is no subject revelation. } if ((level[x, y].isRevealed = onSouldReveal(cell, new Vector2Int(x, y))) == false) { return; // reveal result asks to stop chain. } if (cell.value == 0) { const int neighborCount = 8; var neighbors = ArrayPool <Vector2Int> .Get(neighborCount); LevelUtility.GetAdjacentCellsSquare(new Vector2Int(x, y), neighbors); for (int i = 0; i < neighborCount; i++) { Vector2Int nPos = neighbors[i]; StartRevealChain(level, nPos.x, nPos.y, onSouldReveal); } ArrayPool <Vector2Int> .Release(neighbors); } }
private void CheckAccess(int x, int y) { if (_cells == null) { throw new LevelTableException("Level not generated"); } if (!LevelUtility.IsCellWithinBounds(x, y, Size)) { throw new CellPositionOutOfRangeException(x, y); } }
private void OnLeftClick(Vector2Int cellPos) { if (_levelState != LevelState.Running) { return; } if (_level.Generated == false) { var reservedEmpty = new Vector2Int[9]; LevelUtility.GetAdjacentCellsSquare(cellPos, reservedEmpty); reservedEmpty[8] = cellPos; _level.Generate(levelSettings, reservedEmpty); } Cell cell = _level[cellPos]; if (cell.hasFlag || cell.isRevealed) { return; } if (cell.hasMine) { OnGameOver(); return; } var toReveal = new Dictionary <Vector2Int, Cell>(); RevealHandler.RevealCellsRecursively(_level, cellPos.x, cellPos.y, toReveal); foreach (var pair in toReveal.OrderBy(a => Vector2Int.Distance(cellPos, a.Key))) { levelGridView.RevealCell(pair.Value, pair.Key.x, pair.Key.y); } cursorView.OnCellReveal(); _emptyCellsLeft -= toReveal.Count; if (_emptyCellsLeft <= _level.MineCount) { OnGameWon(); } }
public static void RevealCellsRecursively(LevelTable level, int x, int y, Dictionary <Vector2Int, Cell> revealList) { if (revealList.Count > level.CellCount) { throw new OverflowException(); } var pos = new Vector2Int(x, y); if (revealList.ContainsKey(pos)) { return; } if (!LevelUtility.IsCellWithinBounds(x, y, level.Size)) { return; // Indexes out of range. } Cell cell = level[x, y]; if (cell.isRevealed || cell.hasFlag) { return; // cell is not subject revelation. } level.MarkCellRevealed(pos); revealList[pos] = level[x, y]; if (cell.value == 0) { const int neighborCount = 8; var neighbors = ArrayPool <Vector2Int> .Get(neighborCount); LevelUtility.GetAdjacentCellsSquare(pos, neighbors); for (int i = 0; i < neighborCount; i++) { Vector2Int nPos = neighbors[i]; RevealCellsRecursively(level, nPos.x, nPos.y, revealList); } ArrayPool <Vector2Int> .Release(neighbors); } }
public static Cell[,] GenerateNewLevel(int xMax, int yMax, int mineCount, params Vector2Int[] reservedEmptyCells) { var cells = new Cell[xMax, yMax]; var mines = GenerateRandomPoints(mineCount, 0, xMax - 1, 0, yMax - 1, reservedEmptyCells ?? new Vector2Int[0]); foreach (Vector2Int pos in mines) { // place mine cells[pos.x, pos.y].value = int.MinValue; cells[pos.x, pos.y].hasMine = true; var mineNeighbors = new Vector2Int[8]; LevelUtility.GetAdjacentCellsSquare(pos, mineNeighbors); foreach (var neighbor in mineNeighbors) { if (cells.HasValuesIsInRange(neighbor)) { cells[neighbor.x, neighbor.y].value++; } } } return(cells); }