Example #1
0
        /// <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();
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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();
            }
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }