public Game(Random random, int left, int top, String mazeFileName) { this.left = left; this.top = top; this.maze = Maze.Load(left, top, mazeFileName); this.player = this.maze.CreatePlayer(random, BACKGROUND); }
private static void Load() { var filename = stack.Pop(); using (var stream = File.OpenRead(filename)) { maze = Maze.FromStream(stream); } }
public static List<Point> GetNeighbors(Point origin, int bounds, Maze labrynth) { var neighbors = new List<Point>(); int inc = 2; int buffer = 2; if (origin.X > buffer) { var cell = new Point(origin.X - inc, origin.Y); if (isSurroundedByWalls(cell)) neighbors.Add(cell); } if (origin.X < bounds - buffer) { var cell = new Point(origin.X + inc, origin.Y); if (isSurroundedByWalls(cell)) neighbors.Add(cell); } if (origin.Y > buffer) { var cell = new Point(origin.X, origin.Y - inc); if (isSurroundedByWalls(cell)) neighbors.Add(cell); } if (origin.Y < bounds - buffer) { var cell = new Point(origin.X, origin.Y + inc); if (isSurroundedByWalls(cell)) neighbors.Add(cell); } return neighbors; }
public void Move(Maze maze, Direction direction) { this.Draw(this.background, maze.Left, maze.Top); switch (direction) { case Direction.LEFT: if (!maze.IsWall(this.row, this.column - 1)) { this.column--; } break; case Direction.RIGHT: if (!maze.IsWall(this.row, this.column + 1)) { this.column++; } break; case Direction.UP: if (!maze.IsWall(this.row - 1, this.column)) { this.row--; } break; case Direction.DOWN: if (!maze.IsWall(this.row + 1, this.column)) { this.row++; } break; } this.Draw(ConsoleColor.Green, maze.Left, maze.Top); }
/// <summary> /// Find the solution for a perfect maze. /// </summary> /// <param name="source">The perfect maze</param> /// <returns>The solution maze</returns> public static Maze Trim(Maze source) { var maze = new Maze(source); var stack = new Stack<Cell>(); Console.WriteLine("Trimming maze"); // Phase 1: Queue all non-special tails for (var y = 0; y < maze.Height; y++) { for (var x = 0; x < maze.Width; x++) { var cell = maze[x, y]; if (!IsSpecial(cell) && IsTail(cell)) { stack.Push(cell); } } } // Phase 2: Trim the tails while (stack.Count != 0) { var cell = stack.Pop(); Direction dir; if (TryGetTailDir(cell, out dir)) { cell.SetWall(dir, true); var other = cell.Move(dir); if (IsTail(other) && !IsSpecial(other)) { stack.Push(other); } } } return maze; }
public void InvalidMazeDimensionsTest() { string m = "__________\r\n" + "__________\r\n" + "___________"; Maze.Maze maze = new Maze.Maze(m); }
/// <summary> /// Create a copy of another maze. /// </summary> /// <param name="other">The other maze</param> public Maze(Maze other) { Width = other.Width; Height = other.Height; Start = new Cell(this, other.Start.Key); End = new Cell(this, other.End.Key); _northWalls = new BitList(other._northWalls); _westWalls = new BitList(other._westWalls); }
private Maze Generate() { var maze = new Maze(_source.Width * _factor, _source.Height * _factor); var gens = new List<DFSGenerator>(); // Spawn the generators var offset = _factor / 2; var rnd = new Random(); var mapping = new int[maze.Width * maze.Height]; for (var y = 0; y < _source.Height; y++) { for (var x = 0; x < _source.Width; x++) { var cx = x * _factor + offset; var cy = y * _factor + offset; var x1 = (x - 1) * _factor + offset; var y1 = (y - 1) * _factor + offset; var x2 = (x + 1) * _factor + offset; var y2 = (y + 1) * _factor + offset; gens.Add(new DFSGenerator(gens.Count, maze, mapping, rnd, maze[cx, cy], x1, y1, x2, y2)); } } // Generate! Console.WriteLine("Generating"); while (true) { var hasMore = false; foreach (var gen in gens) { hasMore |= gen.Generate(); } if (!hasMore) { break; } } // Connect...sometime later Console.WriteLine("Welding"); for (var y = 0; y < _source.Height; y++) { for (var x = 0; x < _source.Width; x++) { var sourceCell = _source[x, y]; foreach (var dir in Utils.ULDirs) { Cell otherCell; if (!sourceCell.HasWall(dir) && sourceCell.TryMove(dir, out otherCell)) { var id2 = (int)otherCell.Key; gens[(int)sourceCell.Key].Weld(id2); } } } } // Find the start and exit Console.WriteLine("Finding start/end"); maze.Start = gens[(int)_source.Start.Key].FindStartExit(); maze.End = gens[(int)_source.End.Key].FindStartExit(); return maze; }
public static void Main(string[] args) { stack = new Stack<string>(); maze = null; var start = Environment.TickCount; foreach (var token in args) { Action action; if (Commands.TryGetValue(token, out action)) { action(); } else { stack.Push(token); } } Console.WriteLine("Time: " + (Environment.TickCount - start) + " ms"); }
/// <summary> /// Solves the maze by walking it. /// </summary> /// <param name="m">Maze to solve.</param> /// <param name="formatter">Formatter to use when creating /// the solution steps.</param> /// <returns>True if maze is solveable, false otherwise.</returns> public bool SolveMaze(Maze m, ISolutionFormatter formatter) { mazeSteps = string.Empty; mazeGraphSteps = new List<string>(); this.formatter = formatter; // Find the beggining. MazeCoordinate start = m.StartingPoint; // Solve the maze. MazeCoordinate coord = RecursiveSolve(m, start); if (coord != null) { formatter.CreateSteps(m, out mazeSteps, out mazeGraphSteps); } return (coord != null); }
public void DirectionTests() { string m = "____X_____\r\n" + "____X___XX\r\n" + "S___X___XG"; Maze.Maze maze = new Maze.Maze(m); Assert.IsNull(maze.PeekToDirection(new MazeCoordinate(0, 0), Direction.Left)); Assert.IsNull(maze.PeekToDirection(new MazeCoordinate(0, 0), Direction.Up)); Assert.AreEqual(maze.GetPosition(new MazeCoordinate(0, 1)), maze.PeekToDirection(new MazeCoordinate(0, 0), Direction.Down)); Assert.AreEqual(maze.GetPosition(new MazeCoordinate(1, 0)), maze.PeekToDirection(new MazeCoordinate(0, 0), Direction.Right)); Assert.IsNull(maze.PeekToDirection(new MazeCoordinate(9, 2), Direction.Right)); Assert.IsNull(maze.PeekToDirection(new MazeCoordinate(9, 2), Direction.Down)); Assert.AreEqual(maze.GetPosition(new MazeCoordinate(9, 1)), maze.PeekToDirection(new MazeCoordinate(9, 2), Direction.Up)); Assert.AreEqual(maze.GetPosition(new MazeCoordinate(8, 2)), maze.PeekToDirection(new MazeCoordinate(9, 2), Direction.Left)); }
/// <summary> /// Generate a labryinth from a maze. /// </summary> /// <param name="source">The source maze</param> /// <returns>The labryinth</returns> public static Maze Generate(Maze source) { var maze = new Maze(source.Width * 2, source.Height * 2); Console.WriteLine("Converting to labyrinth"); for (var y = 0; y < source.Height; y++) { for (var x = 0; x < source.Width; x++) { var sc = source[x, y]; if (!sc.HasWall(Direction.North)) { maze[x * 2, y * 2].ClearWall(Direction.North); maze[x * 2 + 1, y * 2].ClearWall(Direction.North); } else { maze[x * 2, y * 2].ClearWall(Direction.East); } if (!sc.HasWall(Direction.East)) { maze[x * 2 + 1, y * 2].ClearWall(Direction.East); maze[x * 2 + 1, y * 2 + 1].ClearWall(Direction.East); } else { maze[x * 2 + 1, y * 2].ClearWall(Direction.South); } if (!sc.HasWall(Direction.South)) { maze[x * 2, y * 2 + 1].ClearWall(Direction.South); maze[x * 2 + 1, y * 2 + 1].ClearWall(Direction.South); } else { maze[x * 2, y * 2 + 1].ClearWall(Direction.East); } if (!sc.HasWall(Direction.West)) { maze[x * 2, y * 2].ClearWall(Direction.West); maze[x * 2, y * 2 + 1].ClearWall(Direction.West); } else { maze[x * 2, y * 2].ClearWall(Direction.South); } } } maze[0, 0].SetWall(Direction.East, true); maze.Start = maze[0, 0]; maze.End = maze[1, 0]; return maze; }
public static Maze CreateMaze() { Room room1 = new Room(1); Room room2 = new Room(2); Door door = new Door(room1, room2); room1.SetSide(Direction.North, new Wall()); room1.SetSide(Direction.East, door); room1.SetSide(Direction.South, new Wall()); room1.SetSide(Direction.West, new Wall()); room2.SetSide(Direction.North, new Wall()); room2.SetSide(Direction.East, new Wall()); room2.SetSide(Direction.South, new Wall()); room2.SetSide(Direction.West, door); Maze maze = new Maze(); maze.AddRoom(room1); maze.AddRoom(room2); return maze; }
/// <summary> /// Creates the strings with steps taken to solve the maze. /// </summary> /// <param name="m">Solved maze.</param> /// <param name="simple">Simple list of steps.</param> /// <param name="graphical">Graphical list of steps</param> public void CreateSteps(Maze m, out string simple, out List<string> graphical) { graphical = new List<string>(); StringBuilder sb1 = new StringBuilder(); string mazeText = m.ToString(); while (steps.Count > 0) { MazeCoordinate coord = steps.Dequeue(); sb1.AppendLine(string.Format("{0}, {1}", coord.x + 1, m.Height - coord.y)); int pos = (m.Width + 2) * coord.y + coord.x; string player = mazeText.Remove(pos, 1); player = player.Insert(pos, "@"); graphical.Add(player); } simple = sb1.ToString(); }
/// <summary> /// Recursively solves the maze. /// </summary> /// <param name="m">Maze to solve.</param> /// <param name="coord">Current position.</param> /// <returns>Coordinate with finish or null if the algorithm dead-ended.</returns> private MazeCoordinate RecursiveSolve(Maze m, MazeCoordinate coord) { // Indicate we've visited this position. m.GetPosition(coord).Visited = true; //...and record our step. formatter.RecordStep(coord); // If we're finished, return this coordinate. if (m.GetPosition(coord).Artifact == MazeArtifact.Finish) { return coord; } MazeCoordinate nextCoord = null; // Start looking around. for (Direction dir = Direction.Up; dir <= Direction.Down; dir++) { MazePosition next = m.PeekToDirection(coord, dir); // Can we go towards that direction? if (TryNext(next)) { // If yes, try to solve from there. nextCoord = RecursiveSolve(m, next.Coordinate); if (nextCoord != null) { // Solution reached. return nextCoord; } // Backtrack. formatter.RecordStep(coord); } } return null; }
/// <summary> /// Render a maze to a .png file. /// </summary> /// <param name="maze">The maze</param> /// <param name="scale">The size of the cells in pixels</param> /// <param name="filename">The name of the file to produce</param> public static void Render(Maze maze, int scale, string filename) { Console.WriteLine("Writing file"); var walls = (scale + 3) / 4; var total = scale + walls; using (var bmp = new Bitmap(maze.Width * total + walls, maze.Height * total + walls)) { using (var gfx = Graphics.FromImage(bmp)) { gfx.FillRectangle(Brushes.Black, 0, 0, bmp.Width, bmp.Height); for (var y = 0; y < maze.Height; y++) { for (var x = 0; x < maze.Width; x++) { var cell = maze[x, y]; var color = Brushes.White; if (cell.IsInactive()) { color = Brushes.Black; } if (maze.Start == cell) { color = Brushes.Green; } if (maze.End == cell) { color = Brushes.Red; } gfx.FillRectangle(color, x * total + walls, y * total + walls, scale , scale); if (!maze[x, y].HasWall(Direction.North)) { gfx.FillRectangle(color, x * total + walls, y * total, scale, walls); } if (!maze[x, y].HasWall(Direction.West)) { gfx.FillRectangle(color, x * total, y * total + walls, walls, scale); } } } } bmp.Save(filename, ImageFormat.Png); } }
public Maze GenerateMaze(int dimesions) { _maze = new Maze(dimesions); List <List <bool> > visited = GenerateVisitedList(dimesions); int x = START_X; int y = START_Y; visited[x][y] = true; List <Tuple <GridItem, Side> > walls = new List <Tuple <GridItem, Side> >(); Random random = new Random(); if (y != 0) { walls.Add(new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.TOP)); } if (y < _maze.Dimensions) { walls.Add(new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.BOTTOM)); } if (x != 0) { walls.Add(new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.LEFT)); } if (x < _maze.Dimensions) { walls.Add(new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.RIGHT)); } while (walls.Count > 0) { //pick a random wall from list var index = random.Next(0, walls.Count); var wall = walls[index]; // if only one of the two cells that the wall divides are visited, then if (!BothVisited(wall, visited)) { //wall.Item1.setWall(wall.Item2, false); Tuple <int, int> delta = GetChangeDirection(wall.Item2); var prevX = wall.Item1.X; var prevY = wall.Item1.Y; x = wall.Item1.X + delta.Item1; y = wall.Item1.Y + delta.Item2; if (x < 0 || y < 0 || x > _maze.Dimensions || y > _maze.Dimensions) { continue; } RemoveCorrectWalls(prevX, prevY, delta); visited[x][y] = true; bool addTop = (y > 0); bool addBottom = (y < _maze.Dimensions); bool addLeft = (x > 0); bool addRight = (x < _maze.Dimensions); if (addTop) { if (!isInTupleArray(walls, _maze.Grid[x][y], Side.TOP)) { Tuple <GridItem, Side> tuple = new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.TOP); walls.Add(tuple); } } if (addBottom) { if (!isInTupleArray(walls, _maze.Grid[x][y], Side.BOTTOM)) { Tuple <GridItem, Side> tuple = new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.BOTTOM); walls.Add(tuple); } } if (addLeft) { if (!isInTupleArray(walls, _maze.Grid[x][y], Side.LEFT)) { Tuple <GridItem, Side> tuple = new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.LEFT); walls.Add(tuple); } } if (addRight) { if (!isInTupleArray(walls, _maze.Grid[x][y], Side.RIGHT)) { Tuple <GridItem, Side> tuple = new Tuple <GridItem, Side>(_maze.Grid[x][y], Side.RIGHT); walls.Add(tuple); } } } walls.RemoveAt(index); // make the wall a passage and mark the unvisited cell as part of the maze // add the neighboring walls of the cell to the wall list // remove the wall from the list } return(_maze); }
public abstract void SpawnMazeOnScene(Maze maze);
public void NoStartPointsTest() { string m = "_____G____\r\n" + "__________\r\n" + "__________"; Maze.Maze maze = new Maze.Maze(m); }
private bool _canPlaceDoor(int randomX, int randomY, Vector2 direction) { return(randomY + direction.y >= 0 && randomX + direction.x >= 0 && randomY + direction.y < Maze.GetLength(1) && randomX + direction.x < Maze.GetLength(0) && _noDoorsAround(randomX, randomY) && Maze[randomX + (int)direction.x, randomY + (int)direction.y] == Tiles.floor); }
public Game(string file) { playerCount = 0; maze = new Maze(); maze.CreateMaze(file); }
private MazeExpander(Maze source, int factor) { _source = source; _factor = factor; }
public void MultipleStartPointsTest() { string m = "S____G____\r\n" + "__________\r\n" + "_________S"; Maze.Maze maze = new Maze.Maze(m); }
public void NullMazeSuppliedTest() { Maze.Maze m = new Maze.Maze(null); }
private bool _noDoorsAround(int x, int y) { if (Maze[x, y] == Tiles.door) { return(false); } for (int i = 0; i < Directions.Cardinals.Length; i++) { if (x + (int)Directions.Cardinals[i].x >= 0 && y + (int)Directions.Cardinals[i].y >= 0 && x + (int)Directions.Cardinals[i].x < Maze.GetLength(0) && y + (int)Directions.Cardinals[i].y < Maze.GetLength(1) && Maze[x + (int)Directions.Cardinals[i].x, y + (int)Directions.Cardinals[i].y] == Tiles.door) { return(false); } } return(true); }
void GenDepthFirstMaze() { labrynth = new Maze(size, size); int CellsVisited = 1; Stack<Point> CellStack = new Stack<Point>(); List<Point> AllCells = new List<Point>(); for (int y = 0; y < size; y++) for (int x = 0; x < size; x++) labrynth.maze[y, x] = 'x'; for (int y = 1; y < size; y += 2) { for (int x = 1; x < size; x += 2) { AllCells.Add(new Point(y, x)); labrynth.maze[y, x] = 'o'; } } int TotalCells = AllCells.Count; Random r = new Random(); //Point CurrentCell = new Point(1,1); Point CurrentCell = AllCells[r.Next(0, AllCells.Count)]; labrynth.SetCell(CurrentCell, 'b'); while (CellsVisited < TotalCells && Alive) { var Neighbors = GetNeighbors(CurrentCell, size); if (Neighbors.Count > 0) { //Pick a random neighbor var SelectedNeighbor = Neighbors[r.Next(0, Neighbors.Count)]; //var SelectedNeighbor = Neighbors.OrderBy<Point, int>(x => r.Next()).Take(1); //Knock down wall between neighbor if (CurrentCell.Y == SelectedNeighbor.Y) { Point Wall = new Point((CurrentCell.X + SelectedNeighbor.X) / 2, CurrentCell.Y); labrynth.SetCell(Wall, 'o'); } else if (CurrentCell.X == SelectedNeighbor.X) { Point Wall = new Point(CurrentCell.X, (CurrentCell.Y + SelectedNeighbor.Y) / 2); labrynth.SetCell(Wall, 'o'); } CellStack.Push(CurrentCell); CurrentCell = SelectedNeighbor; CellsVisited++; if (GenerateRealTime) Thread.Sleep(10); } else { try { CurrentCell = CellStack.Pop(); } catch (InvalidOperationException) { break; } } } labrynth.SetCell(CurrentCell, 'e'); }
/// <summary> /// Create a cell corresponding to the given key in a given maze. /// </summary> /// <param name="maze">The maze</param> /// <param name="key">The key</param> public Cell(Maze maze, long key) { _maze = maze; _key = key; }
public void NoGoalPointsTest() { string m = "__________\r\n" + "__________\r\n" + "____S_____"; Maze.Maze maze = new Maze.Maze(m); }
public DFSGenerator(int id, Maze maze, int[] mapping, Random rnd, Cell cell, int x1, int y1, int x2, int y2) { _id = id; _rnd = rnd; _maze = maze; _mapping = mapping; _stack = new Stack<long>(); _stack.Push(cell.Key); cell.GetPosition(out _cx, out _cy); _mapping[(int)cell.Key] = _id; _x1 = x1; _y1 = y1; _x2 = x2; _y2 = y2; }
public void EmptyMazeSuppliedTest() { Maze.Maze m = new Maze.Maze(string.Empty); }
/// <summary> /// Generate a perfect maze from another perfect maze. /// </summary> /// <param name="source">The input maze</param> /// <param name="factor">The scaling factor</param> /// <returns>The generated maze</returns> public static Maze Generate(Maze source, int factor) { return new MazeExpander(source, factor).Generate(); }
public void MultipleFinishPointsTest() { string m = "_____G____\r\n" + "__G_______\r\n" + "____S_____"; Maze.Maze maze = new Maze.Maze(m); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); maze = new Maze(); reset(); }
void GenCheckerboard() { labrynth = new Maze(8,8); bool flip = true; for (int x = 0; x < labrynth.Dimensions.X; x++) { labrynth.maze[0, x] = 'x'; labrynth.maze[labrynth.Dimensions.Y - 1, x] = 'x'; } for (int y = 1; y < labrynth.Dimensions.Y - 1; y++) { labrynth.maze[y, 0] = 'x'; labrynth.maze[y, labrynth.Dimensions.X - 1] = 'x'; for (int x = 1; x < labrynth.Dimensions.X - 1; x++) { if (flip) labrynth.maze[y, x] = 'x'; else labrynth.maze[y, x] = 'o'; flip = !flip; } flip = !flip; } }
//WORKING F**K YEAH public bool isSurroundedByWalls(Point cell, Maze labrynth) { if (isWall(labrynth.GetCell(new Point(cell.X - 1, cell.Y))) && isWall(labrynth.GetCell(new Point(cell.X + 1, cell.Y))) && isWall(labrynth.GetCell(new Point(cell.X, cell.Y - 1))) && isWall(labrynth.GetCell(new Point(cell.X, cell.Y + 1)))) return true; return false; }
public AILearning(Maze maze) { this.maze = maze; }