public static bool[,] GenerateMazeTile(MazeTileType tileType, bool includeCenter)
        {
            var tile = new bool[3, 3];

            // Corners
            tile[0, 0] = true;
            tile[0, 2] = true;
            tile[2, 0] = true;
            tile[2, 2] = true;

            if (includeCenter && tileType == MazeTileType.None)
            {
                tile[1, 1] = true;
            }

            if (!tileType.HasFlag(MazeTileType.North))
            {
                tile[1, 0] = true;
            }
            if (!tileType.HasFlag(MazeTileType.East))
            {
                tile[2, 1] = true;
            }
            if (!tileType.HasFlag(MazeTileType.South))
            {
                tile[1, 2] = true;
            }
            if (!tileType.HasFlag(MazeTileType.West))
            {
                tile[0, 1] = true;
            }

            return(tile);
        }
Esempio n. 2
0
 public static MapTile GetTile(MazeTileType mazeTileType)
 {
     return(mazeTileType switch
     {
         MazeTileType.None => new MazeTile(),
         MazeTileType.Start => new StartTile(),
         MazeTileType.Finish => new FinishTile(),
         MazeTileType.Player => new PlayerTile(),
         MazeTileType.Wall => new WallTile(),
         _ => throw new Exception()
     });
Esempio n. 3
0
        private MazeTileType GenerateCompatibleTileType(MazeTileType tileType)
        {
            var resultTile = tileType;

            if (Random.NextDouble() > 0.7)
            {
                resultTile |= MazeTileType.East;
            }
            if (Random.NextDouble() > 0.7)
            {
                resultTile |= MazeTileType.South;
            }
            return(resultTile);
        }
Esempio n. 4
0
        private MazeTileType[] GenerateTilesRow(out MazeTileType[] path)
        {
            var rowTiles = new MazeTileType[TilesInRow];

            rowTiles[LastTilePassIndex] |= MazeTileType.North;
            var direction        = GenerateRandomDirection();
            var length           = Random.Next(1, TilesInRow);
            var newTilePassIndex = Math.Abs((LastTilePassIndex + direction * length) % (TilesInRow));

            rowTiles[newTilePassIndex] |= MazeTileType.South;

            var fromIndex = Math.Min(LastTilePassIndex, newTilePassIndex);
            var toIndex   = Math.Max(LastTilePassIndex, newTilePassIndex);

            for (int i = fromIndex; i < toIndex; i++)
            {
                rowTiles[i]     |= MazeTileType.East;
                rowTiles[i + 1] |= MazeTileType.West;
            }

            path = new MazeTileType[TilesInRow];
            rowTiles.CopyTo(path, 0);

            LastTilePassIndex = newTilePassIndex;
            for (int i = 0; i < rowTiles.Length; i++)
            {
                var          top  = LastRowTiles[i].HasFlag(MazeTileType.South) ? MazeTileType.North : default;
                MazeTileType left = default;
                if (i > 0)
                {
                    left = LastRowTiles[i - 1].HasFlag(MazeTileType.East) ? MazeTileType.West : default;
                }
                rowTiles[i] = GenerateCompatibleTileType(rowTiles[i] | top | left);
            }

            return(rowTiles);
        }
Esempio n. 5
0
        /// <summary>
        /// Sets some default values
        /// </summary>
        private void SetupMazeEditor(ScreenBuffer screenBuffer)
        {
            // maze properties
            _mazeOffsetX = 1;
            _mazeOffsetY = 6;

            // cursor properties
            _cursorEnabled   = true;
            _cursorX         = _mazeOffsetX;
            _cursorY         = _mazeOffsetY;
            _cursorSpeed     = 1;
            _cursorDirection = Direction.Down;

            // trigger updates
            _mazeUpdated = true;

            // minX, maxX, minY, maxY
            _cursorBoundaries = new Tuple <int, int, int, int>(_mazeOffsetX, screenBuffer.BufferWidth - 2, _mazeOffsetY, screenBuffer.BufferHeight - 2);

            // map a direction to a set of delta x,y values
            _cursorDirectionDeltaMap = new Dictionary <Direction, Tuple <int, int> >()
            {
                { Direction.Down, new Tuple <int, int>(0, 1) },
                { Direction.Left, new Tuple <int, int>(-1, 0) },
                { Direction.Right, new Tuple <int, int>(1, 0) },
                { Direction.Up, new Tuple <int, int>(0, -1) }
            };

            // pre-calculate ui outline strings
            const int uiTopSplitA = 72;
            const int uiTopSplitB = 80;

            _uiOutline = new string[screenBuffer.BufferHeight];

            string uiLineTop       = $"{Character.TopLeft}{Utils.Repeat(Character.Horizontal, uiTopSplitA)}{Character.TopCentre}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.TopCentre}{Utils.Repeat(Character.Horizontal, uiTopSplitB)}{Character.TopRight}";
            string uiLineTopMiddle = $"{Character.Vertical}{Utils.Repeat(" ", uiTopSplitA)}{Character.Vertical}{Utils.Repeat(" ", screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.Vertical}{Utils.Repeat(" ", uiTopSplitB)}{Character.Vertical}";
            string uiLineTopSplit  = $"{Character.MiddleLeft}{Utils.Repeat(Character.Horizontal, uiTopSplitA)}{Character.BottomCentre}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.BottomCentre}{Utils.Repeat(Character.Horizontal, uiTopSplitB)}{Character.MiddleRight}";
            string uiLineMiddle    = $"{Character.Vertical}{Utils.Repeat(" ", screenBuffer.BufferWidth - 2)}{Character.Vertical}";
            string uiLineBottom    = $"{Character.BottomLeft}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - 2)}{Character.BottomRight}";

            // draw screen outline
            for (var y = 0; y < screenBuffer.BufferHeight; y++)
            {
                switch (y)
                {
                case 0:
                    _uiOutline[y] = uiLineTop;
                    break;

                case 1:
                case 2:
                case 3:
                case 4:
                    _uiOutline[y] = uiLineTopMiddle;
                    break;

                case 5:
                    _uiOutline[y] = uiLineTopSplit;
                    break;

                default:
                    _uiOutline[y] = y == screenBuffer.BufferHeight - 1 ? uiLineBottom : uiLineMiddle;
                    break;
                }
            }

            // create the pixel styles
            _cursorPixel   = new Pixel(Character.MediumBlock, Style.ForegroundColor.Cyan, Style.BackgroundColor.Grayscale235);
            _blankMapPixel = new Pixel(Style.ForegroundColor.White, Style.BackgroundColor.Grayscale235);

            // set the current pixel
            _currentTileTool = MazeTileType.None;

            // get the background colours
            _isBackgroundColourSelector = true;
            _currentBackgroundColour    = 0;
            _currentForegroundColour    = 0;
            _backgroundColours          = typeof(Style.BackgroundColor).GetFields().Select(fi => fi.GetValue(fi)?.ToString()).ToArray();
            _foregroundColours          = typeof(Style.ForegroundColor).GetFields().Select(fi => fi.GetValue(fi)?.ToString()).ToArray();

            /*
             * Setup menus
             */

            // file menu
            _fileMenu = new Menu("File Menu");
            _fileMenu.AddItem("Save", (sb) => { _maze.Save(); _fileMenu.Enabled = false; });
            _fileMenu.AddItem("Rename");
            _fileMenu.AddItem("Close File Menu", (sb) => _fileMenu.Enabled = false);
            _fileMenu.AddItem("Exit to main menu", (sb) => { new MazeGame().Start(); /* basically a hacky way to restart */ });

            // edit menu
            _editMenu = new Menu("Edit Menu");
            _editMenu.AddItem("Eraser Tool", (sb) => { _currentTileTool = MazeTileType.None; _editMenu.Enabled = false; });
            _editMenu.AddItem("Wall Tool", (sb) => { _currentTileTool = MazeTileType.Wall; _editMenu.Enabled = false; });
            _editMenu.AddItem("Start Tool", (sb) => { _currentTileTool = MazeTileType.Start; _editMenu.Enabled = false; });
            _editMenu.AddItem("Finish Tool", (sb) => { _currentTileTool = MazeTileType.Finish; _editMenu.Enabled = false; });
            _editMenu.AddItem("Player Spawn Tool", (sb) => { _currentTileTool = MazeTileType.Player; _editMenu.Enabled = false; });
            _editMenu.AddItem("Close Edit Menu", (sb) => _editMenu.Enabled = false);

            // debug menu
            _debugMenu = new Menu("Debug Menu");
            _debugMenu.AddItem("Shrink maze size", (sb) =>
            {
                _maze.ResizeMaze();

                // force the maze to be drawn
                _mazeUpdated = true;
                DrawMaze(screenBuffer);
                _debugMenu.Enabled = false; // close the menu after execution
            });

            _debugMenu.AddItem("Toggle cursor", (sb) => { _cursorEnabled = !_cursorEnabled; _debugMenu.Enabled = false; });
            _debugMenu.AddItem("Close Debug Menu", (sb) => _debugMenu.Enabled = false);
        }
Esempio n. 6
0
        /// <summary>
        /// Display the maze along with the editor UI and handle all of the User Inputs
        /// </summary>
        /// <param name="screenBuffer"></param>
        public void Show(ScreenBuffer screenBuffer)
        {
            _isEditorRunning = true;

            SetupMazeEditor(screenBuffer);

            // add the ui border as a constant render
            screenBuffer.AddConstantRender(0, 0, _uiOutline);

            while (_isEditorRunning)
            {
                // we shouldn't need to check whether we need to update as this loop will only continue
                // on user input
                Draw(screenBuffer);

                // read input
                var consoleKeyInfo = Console.ReadKey(true);
                var consoleKey     = consoleKeyInfo.Key;

                // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
                switch (consoleKey)
                {
                /*
                 * Cursor Movement
                 */
                case ConsoleKey.UpArrow:
                    // only move if cursor enabled
                    if (!_cursorEnabled)
                    {
                        break;
                    }

                    MoveCursor(0, -1);
                    _cursorDirection = Direction.Up;
                    break;

                case ConsoleKey.DownArrow:
                    // only move if cursor enabled
                    if (!_cursorEnabled)
                    {
                        break;
                    }

                    MoveCursor(0, 1);
                    _cursorDirection = Direction.Down;
                    break;

                case ConsoleKey.LeftArrow:
                    // only move if cursor enabled
                    if (!_cursorEnabled)
                    {
                        break;
                    }

                    MoveCursor(-1, 0);
                    _cursorDirection = Direction.Left;
                    break;

                case ConsoleKey.RightArrow:
                    // only move if cursor enabled
                    if (!_cursorEnabled)
                    {
                        break;
                    }

                    MoveCursor(1, 0);
                    _cursorDirection = Direction.Right;
                    break;

                /*
                 * Cursor Speed
                 */
                case ConsoleKey.Add:
                    ModifyCursorSpeed(+1);
                    break;

                case ConsoleKey.Subtract:
                    ModifyCursorSpeed(-1);
                    break;

                /*
                 * Draw a Map tile
                 */
                case ConsoleKey.Spacebar:
                    // only draw if the cursor is enabled
                    if (!_cursorEnabled)
                    {
                        break;
                    }

                    DrawTile();
                    break;

                /*
                 * Map Tile Selection
                 */
                case ConsoleKey.D1:
                    _currentTileTool = MazeTileType.None;
                    break;

                case ConsoleKey.D2:
                    _currentTileTool = MazeTileType.Wall;
                    break;

                case ConsoleKey.D3:
                    _currentTileTool = MazeTileType.Start;
                    break;

                case ConsoleKey.D4:
                    _currentTileTool = MazeTileType.Finish;
                    break;

                case ConsoleKey.D5:
                    _currentTileTool = MazeTileType.Player;
                    break;

                /*
                 * Colour selector
                 */
                case ConsoleKey.Tab:
                    CycleColourSelector();
                    break;

                case ConsoleKey.Oem8:
                    _isBackgroundColourSelector = !_isBackgroundColourSelector;
                    break;

                /*
                 * Menus
                 */

                // File menu
                case ConsoleKey.F1:
                    _fileMenu.Show(screenBuffer);
                    break;

                // Edit menu
                case ConsoleKey.F2:
                    _editMenu.Show(screenBuffer);
                    break;

                // Debug Menu
                case ConsoleKey.F3:
                    _debugMenu.Show(screenBuffer);
                    break;
                }

                // clear any other input
                // NOTE: This isn't ideal but this prevents a queue of keys to be read
                //       if the user holds down a key which would cause "input lag" of
                //       considerable effect.
                while (Console.KeyAvailable)
                {
                    Console.ReadKey(true);
                }
            }
        }
Esempio n. 7
0
    private void Awake()
    {
        _mazeTileType = (MazeTileType)Enum.Parse(typeof(MazeTileType), gameObject.tag);

        OnPlayerInteract.AddListener(ConsumePellet);
    }
Esempio n. 8
0
    private void BuildMaze(Vector2 tilePosition, MazeTileType tileType)
    {
        GameObject tilePrefab;
        Transform  tileParent;

        switch (tileType)
        {
        case MazeTileType.Wall:
            tilePrefab = WallPrefab;
            tileParent = WallsParent.transform;
            break;

        case MazeTileType.Pellet:
            tilePrefab = PelletPrefab;
            tileParent = PelletsParent.transform;
            break;

        case MazeTileType.Energizer:
            tilePrefab = EnergizerPrefab;
            tileParent = EnergizersParent.transform;
            break;

        case MazeTileType.Intersection:
            tilePrefab = IntersectionPrefab;
            tileParent = IntersectionsParent.transform;
            break;

        case MazeTileType.OutOfBound:
            tilePrefab = OutOfBoundPrefab;
            tileParent = OutOfBoundsParent.transform;
            break;

        case MazeTileType.Empty:
            tilePrefab = EmptyPrefab;
            tileParent = EmptiesParent.transform;
            break;

        case MazeTileType.GhostHouse:
            tilePrefab = GhostHousePrefab;
            tileParent = GhostHouseParent.transform;
            break;

        case MazeTileType.Tunnel:
            tilePrefab = TunnelPrefab;
            tileParent = TunnelsParent.transform;
            break;

        case MazeTileType.Fruit:
            tilePrefab = FruitPrefab;
            tileParent = FruitParent.transform;
            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(tileType), tileType, null);
        }

        var newItem = Instantiate(tilePrefab, tileParent, false);

        newItem.transform.localPosition = new Vector3(tilePosition.x, tilePosition.y, 0);

        var newTile = newItem.GetComponent <MazeTile>();

        newTile.SetTilePosition(tilePosition.x, tilePosition.y);
        newTile.SetTilePosition(tilePosition.x, tilePosition.y);
    }
Esempio n. 9
0
 public MazeGenerator(int tilesCount)
 {
     TilesInRow   = tilesCount;
     LastRowTiles = new MazeTileType[TilesInRow];
     Random       = new Random();
 }