🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

You may now post code

Started by
40 comments, last by Washu 14 years, 10 months ago
Now its probably slow because as you get closer to the end, it gets harder and harder for it to "guess" the next startpoint. In fact, its not guaranteed to terminate at all (= bad).

If you want to maintain your current design, the easiest thing I can see is using dynamic containers, in which you can actually remove the wall from a copy of the container once you have tried to destroy it.

Also, when you randomly choose a wall that has already been checked, you could just increase it (and reset to 0 when needed), until you find one that hasn't been. This is not completely random, and becomes less random as you test more walls. Fortunately, randomness becomes less important as you try new walls, so it might be fine :)
I mean, why would you get your medical advice anywhere else?
Advertisement
Quote: Original post by Emmanuel Deloget
I'm going to comment everything and put that into a ZIP later.

And in fact, I did a RAR archive. Have fun!

Here's my version. I couldn't bring myself to do it with just arrays; I used some of the classes from System.Collections.Generic: Dictionary<> and List<>. To make up for that deviation, I added some functionality. If the maze generated is small enough to fit completely on the console window, you can run through the maze with the arrow keys. Random entrance is placed on the left and an exit placed on the right. Reaching the exit cycles things back to generate a new maze. I think the maximum runnable maze size is 28 rows by 50 columns.
using System;using System.Collections.Generic;using System.Text;//// Maze is organized in cells, numbered from 0 to rows - 1 and 0 to columns - 1////  +------+------+------+------+------+//  | 0, 0 | 0, 1 | 0, 2 | 0, 3 | 0, 4 |//  +------+------+------+------+------+//  | 1, 0 | 1, 1 | 1, 2 | 1, 3 | 1, 4 |//  +------+------+------+------+------+//  | 2, 0 | 2, 1 | 2, 2 | 2, 3 | 2, 4 |//  +------+------+------+------+------+//// Walls are numbered according to the cells they are adjacent to. A horizontal//   wall is given the same number as the cell to the south. A vertical wall is//   given the same number as the cell to the east. So a vertical and a horizontal//   wall will both share the same number. A bool is added to distinguish the two://   true indicates a horizontal wall and false indicates a vertical wall////                  Wall(5, 4, true)//                         \///                      +------+// Wall(5, 4, false) -> | 5, 4 | <- Wall(5, 5, false)//                      +------+//                         ^//                  Wall(6, 4, true)////namespace PerfectMaze {  struct Cell {    internal Cell(int r, int c) {      row = r;      column = c;    }    internal int row;    internal int column;  }  struct Wall {    internal Wall(int r, int c, bool t) {      row = r;      column = c;      top = t;    }    internal int row;    internal int column;    internal bool top;  }  class Maze {    internal Dictionary<Wall, int> walls = new Dictionary<Wall, int>();    int rows;    int columns;        internal Cell entrance;    internal Cell exit;    Maze(int row, int col) {      // Maze generation algorithm:      //   Create all the cells; give each cell a unique group number      //   Create a list of cells that aren't in the first group      //   Create all the walls      //   Create a list of walls that haven't been processed      //   While there are cells not in the first group      //     Choose a random unprocessed wall      //     Remove wall from unprocessed list      //     Find the two cells that the wall separates      //     If the two cells are in different groups      //       Remove the wall from the list of walls      //       Move all the cells in the group with the bigger number      //           into the group with the smaller number      //       If the group with the smaller number is also the first      //           group, remove the cells from the outside cell list      rows = row;      columns = col;            Dictionary<Cell, int> cell_dict = new Dictionary<Cell, int>();      Dictionary<Cell, int> outside_cells = new Dictionary<Cell, int>();      for (int i = 0, k = 0; i < rows; i++) {        for (int j = 0; j < columns; j++, k++) {          cell_dict[new Cell(i, j)] = k;          if (k != 0) outside_cells[new Cell(i, j)] = k;        }      }      List<Wall> unprocessed_walls = new List<Wall>();      for (int i = 0; i < rows + 1; i++) {        for (int j = 0; j < columns + 1; j++) {          walls.Add(new Wall(i, j, true), 0);          walls.Add(new Wall(i, j, false), 0);          unprocessed_walls.Add(new Wall(i, j, true));          unprocessed_walls.Add(new Wall(i, j, false));        }      }      System.Random rng = new System.Random();      while (outside_cells.Count != 0) {        int index = rng.Next(0, unprocessed_walls.Count);        Wall w = unprocessed_walls[index];        unprocessed_walls.RemoveAt(index);                Cell c1, c2;        if (w.top) {          c1 = new Cell(w.row, w.column);          c2 = new Cell(w.row - 1, w.column);        } else {          c1 = new Cell(w.row, w.column);          c2 = new Cell(w.row, w.column - 1);        }        if (!cell_dict.ContainsKey(c1) && !cell_dict.ContainsKey(c2))          walls.Remove(w);        else if (cell_dict.ContainsKey(c1) &&                  cell_dict.ContainsKey(c2) &&                 (cell_dict[c1] != cell_dict[c2])) {          walls.Remove(w);          int min_group = System.Math.Min(cell_dict[c1], cell_dict[c2]);          int max_group = System.Math.Max(cell_dict[c1], cell_dict[c2]);          List<Cell> merger_cells = new List<Cell>();          foreach (Cell cell in outside_cells.Keys) {            if (outside_cells[cell] == max_group)              merger_cells.Add(cell);          }          foreach (Cell cell in merger_cells) {            if (min_group == 0) {              cell_dict[cell] = 0;              outside_cells.Remove(cell);            } else {              cell_dict[cell] = min_group;              outside_cells[cell] = min_group;            }          }        }      }            entrance = new Cell(rng.Next(0, rows), 0);      walls.Remove(new Wall(entrance.row, 0, false));      exit = new Cell(rng.Next(0, rows), columns - 1);      walls.Remove(new Wall(exit.row, columns, false));    }    void display() {      for (int i = 0; i < rows; ++i) {        for (int j = 0; j < columns; ++j) {          if (walls.ContainsKey(new Wall(i, j, true)))            Console.Write("+-");          else            Console.Write("+ ");        }        Console.WriteLine("+");        for (int j = 0; j < columns; ++j) {          if (walls.ContainsKey(new Wall(i, j, false)))            Console.Write("| ");          else            Console.Write("  ");        }        if (walls.ContainsKey(new Wall(i, columns, false)))          Console.WriteLine("|");        else          Console.WriteLine();      }      for (int j = 0; j < columns; ++j) {        if (walls.ContainsKey(new Wall(rows, j, true)))          Console.Write("+-");        else          Console.Write("+ ");      }      Console.WriteLine("+");    }        static void write(Cell position, string p) {      Console.CursorLeft = position.column * 2 + 1;      Console.CursorTop = position.row * 2 + 1;      Console.Write(p);    }    static void Main(string[] args) {      Console.Title = "Welcome to the C# Random Maze Generator!";      Console.WriteLine("\nWelcome to the C# Random Maze Generator!\n\n");      for (;;) {        int height = 0;        bool input_valid = false;        do {          Console.Write("Enter number of rows (2-50): ");          input_valid = int.TryParse(Console.ReadLine(), out height) &&                        (height >= 2) &&                        (height <= 50);          if (!input_valid) {            Console.Write("Sorry that's an invalid number. ");            Console.WriteLine("Please try a number between 2 and 50.\n");          }        } while (!input_valid);        int width;        do {          Console.Write("Enter number of columns (2-50): ");          input_valid = int.TryParse(Console.ReadLine(), out width) &&                        (width >= 2) &&                        (width <= 50);          if (!input_valid) {            Console.Write("Sorry that's an invalid number. ");            Console.WriteLine("Please try a number between 2 and 50.\n");          }        } while (!input_valid);                bool run_maze = true;        int new_height = height * 2 + 3;        if (Console.WindowHeight < new_height) {          if (new_height <= Console.LargestWindowHeight) {            Console.WindowHeight = new_height;          } else {            run_maze = false;            Console.WindowHeight = Console.LargestWindowHeight;            Console.WriteLine("Warning: Console cannot display enough lines to hold maze.");          }        }        int new_width = width * 2 + 3;        if (Console.WindowWidth < new_width) {          if (new_width <= Console.LargestWindowWidth) {            Console.WindowWidth = new_width;          } else {            run_maze = false;            Console.WindowWidth = Console.LargestWindowWidth;            Console.WriteLine("Warning: Console cannot display enough columns to hold maze.");          }        }        Maze m = new Maze(height, width);        Console.Clear();        m.display();        Console.Write("\nNice maze! ");        Console.Write("Would you like to create another ([y]es|[n]o): ");        ConsoleKeyInfo key;                Cell position = m.entrance;        if (run_maze) {          write(position, "@");        }        do {          key = Console.ReadKey(true);          if (run_maze) {            switch (key.Key) {              case ConsoleKey.UpArrow:                if (!m.walls.ContainsKey(new Wall(position.row, position.column, true))) {                  write(position, " ");                  --position.row;                  write(position, "@");                }                break;              case ConsoleKey.DownArrow:                if (!m.walls.ContainsKey(new Wall(position.row + 1, position.column, true))) {                  write(position, " ");                  ++position.row;                  write(position, "@");                }                break;              case ConsoleKey.RightArrow:                if ((position.column != (width - 1)) &&                    !m.walls.ContainsKey(new Wall(position.row, position.column + 1, false))) {                  write(position, " ");                  ++position.column;                  write(position, "@");                }                break;              case ConsoleKey.LeftArrow:                if ((position.column != 0) &&                    !m.walls.ContainsKey(new Wall(position.row, position.column, false))) {                  write(position, " ");                  --position.column;                  write(position, "@");                }                break;            }            if ((position.column == m.exit.column) &&                (position.row == m.exit.row)) {              break;            }          }        } while (char.ToUpper(key.KeyChar) != 'Y' &&                 char.ToUpper(key.KeyChar) != 'N');        if (char.ToUpper(key.KeyChar) == 'N') return;        Console.Clear();      }    }  }}
^ Overachiever.
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Hi everyone. This is actually my first post in this workshop.

I have managed to complete project 1 and enjoyed it very much. Will be interesting to see what project 2 will be like.

I have created 5 classes. Roomset, Room, Wall, MazeGenerator and Program.

Feel free to give any advice for anything. :)

Oh yeah, thanks J Walsh for this workshop. I really enjoyed the challenge this first project gave me and look forward to future projects in this workshop.

using System;namespace Project1_Maze_Generator{    // Room Set class.    class RoomSet    {        public int roomsetID;          // id number for room set        public int[] rooms;     // array containing rooms in this set.        public RoomSet(int roomsetID, int roomID)        {            // only require room id for one room as initially all the rooms            // are in there own unique sets.            this.roomsetID = roomsetID;     // set the id number of this room set            rooms = new int[1];             // initially room has only one room id.            rooms[0] = roomID;              // add room id to the array.        }        // Add a set to this room set.        public void AddSet(RoomSet set)        {            // Get a copy of the current array containing the room id numbers.            int[] oldSet = (int[])rooms.Clone();            // resize the array so that it is big enough to store all the             // room id numbers.            this.rooms = new int[oldSet.Length + set.rooms.Length];            // copy old set to the new array            oldSet.CopyTo(rooms, 0);            // copy the array of the room set that is being added to this room set.            set.rooms.CopyTo(rooms, oldSet.Length);        }        // Clears the array by creating a new empty array of length zero.        public void Clear()        {            // Resize the array to zero.            rooms = new int[0];        }        // Used for debugging - This method displays the room id numbers         // which are in this set.        public override string ToString()        {            string astring = "Set "+roomsetID+ " {";            for (int i = 0; i < rooms.Length; i++)            {                // Append all the room id numbers in the array.                astring += " "+rooms;            }            // Append a curly bracket at the end of the string.            astring += "}";            // Return the string.            return astring;        }    }    // Room class    class Room    {        public int id;          // id for room        public int set;         // which set the room is in        public Room()            : this(-1, -1)        {        }        public Room(int id, int set)        {            this.id = id;   // set the id number of this room            this.set = set; // Set the value of the set which this room is in.        }        // Used for debugging - This method prints out the room id number along        // with which set the room is in.        public override string ToString()        {            return ("Room " + id + ": Set " + set);        }    }    // Wall Types - There can only be two wall types.  These are vertical walls    // and horizontal walls.    enum WallType    {        WALLTYPE_VERTICAL,          // WALLTYPE_VERTICAL = 0        WALLTYPE_HORIZONTAL         // WALLTYPE_HORIZONTAL = 1    }    // Wall class.    class Wall    {        public int id;              // id number to identify this wall.        public Room room1;          // first room        public Room room2;          // second room        public WallType wallType;   // type of wall (horizontal or vertical)        public Boolean down;        // is wall knocked down        // Used for debugging - This method prints out the details of this wall.        public override string ToString()        {            return ("Wall: "+id+" connects room "+room1.id+" with room "+room2.id+".");        }    }    // Maze Generator class.    class MazeGenerator    {        int rows, columns;  // Rows and columns in maze.        Wall[] walls;       // Array for containing the walls in the maze        Room[] rooms;       // Array for containing the rooms in the maze;        RoomSet[]roomSets;   // Room sets        Random random;      // used for getting random numbers        public MazeGenerator(int row, int column)        {            rows = row;         // set the rows value            columns = column;   // set the columns value            // Calculate number of rooms.            int numberOfRooms = CalculateNumberOfRooms();               // create rooms            rooms = new Room[numberOfRooms];            // Create room sets            roomSets = new RoomSet[numberOfRooms];            // initialise rooms and room sets            for (int i = 0; i < rooms.Length; i++)            {                rooms = new Room(i, i);          // initialise room                roomSets = new RoomSet(i, i);    // initialise room set            }            // Calculate number of walls.            int numberOfWalls = CalculateNumberOfWalls();            // Create array of walls.            walls = new Wall[numberOfWalls];            // initialise walls            for (int i = 0; i < walls.Length; i++)            {                walls = new Wall();                walls.id = i;                walls.down = false;                // Determine the two rooms which this wall connects.                DetermineRoomsForWall(walls);            }            random = new Random();        }        public void GenerateMaze()        {            // Randomly Permutate all the walls            RandomPermutateAllWalls(walls.Length);            // Now go through each wall in the array.  If the 2 rooms connected            // to the wall are in the same set then don't do anything.  Otherwise            // knock down the wall and put all the room id numbers which            // are in the same set as the second room into the same set as the            // first room.            for (int i = 0; i < walls.Length; i++)            {                // if the room sets of both rooms are different                if (!(walls.room1.set.Equals(walls.room2.set)))                {                    // The two rooms which will be connected as the wall in                     // between will be knocked down.                    Room room1 = walls.room1;                    Room room2 = walls.room2;                    // room 2 will be moved to the same set as room 1 so store                    // the value of the room 2 set now so that we can use it                     // later to clear the appropriate room set.                    int oldRoom2Set = room2.set;                        // The room set that room 1 is in.                    RoomSet room1RoomSet = roomSets[walls.room1.set];                                       // move all the rooms (including room 2) which are in the                     // same set as room 2 to the same set as room 1.                    room1RoomSet.AddSet(roomSets[oldRoom2Set]);                                    // loop through all the rooms in the room 1 set and ensure                     // that all the rooms with there room id stored in it have                     // been updated so that there set attribute contains the                     // same value as the room 1 room set id value.                    for (int x = 0; x < room1RoomSet.rooms.Length; x++)                    {                        // get room id number                        int roomId = room1RoomSet.rooms[x];                        // Check to see if this room's set value is correct.                        if (!rooms[roomId].set.Equals(room1RoomSet.roomsetID))                        {                            // Value is not correct so correct it.                            rooms[roomId].set = room1RoomSet.roomsetID;                        }                    }                                      // Clear the old set which previously had room 2 in it.  As                    // this is now empty.                    roomSets[oldRoom2Set].Clear();                    walls.down = true;   // wall has now been knocked down.                }            }        }        public void Display()        {            int mazeColumns = 2 * columns - 1;            int mazeRows = rows;            // Compare buffer size of console and if it is too small then             // increase the buffer width.  This ensures that the maze is displayed            // appropriately if its columns size is bigger than the buffer width.            if (mazeColumns+5 > Console.BufferWidth)            {                // Set the buffer size width to size of the columns of the map                // plus 5.  The plus 5 just creates a little gap between the                 // right edge of the map and the window.                Console.SetBufferSize(mazeColumns+5, Console.BufferHeight);            }            // Char array storing the look of the maze.            char[,] maze = new char[mazeColumns, mazeRows];            // Initialise the char array map.            for (int row = 0; row < mazeRows; row++)            {                for (int col = 0; col < mazeColumns; col++)                {                    if (row == rows - 1)    // if is the last row then append '_'                    {                        maze[col, row] = '_';                    }                    else                    // else just append a space.                    {                        maze[col, row] = ' ';    // append a space                     }                }                // insert walls into array                for (int i = 0; i < walls.Length; i++)                {                    // if wall has not been knocked down then display it.                    if (!walls.down)                    {                        // calculate position of wall in array.                        int c = walls.room1.id % columns;                        int r = walls.room1.id / columns;                        // Display the wall appropriately in the appropriate                         // position in the char array using the c and r values                        // calculated above.                        // If wall is a vertical type.                        if (walls.wallType == WallType.WALLTYPE_VERTICAL)                        {                            maze[c * 2, r] = '_';                            // If no horizontal walls exist to the above wall then                            // add a second vertical wall.  This improves the look                             // of the maze.                            if (c*2+1 < mazeColumns && maze[c*2+1,r].Equals(' '))                                maze[c * 2 + 1, r] = '_';                        }                        else    // Else wall is a horizontal type.                        {                            maze[c * 2 + 1, r] = '|';                        }                    }                }            }            Console.WriteLine();        // Create a new line at the beginning.            // Display the maze            for (int row = 0; row < mazeRows; row++)            {                // If at the first row then print top of map                if (row == 0)                {                    char[] top = new char[mazeColumns + 2];                    for (int i = 0; i < top.Length; i++)                        top = '_';                    // Make spaces at the beginning and end.                    top[0] = ' ';                    top[top.Length - 1] = ' ';                    String topwall = new String(top);                    Console.WriteLine(topwall);                }                // print left side of maze for this row                Console.Write('|');                // Print a row of the maze                for (int col = 0; col < mazeColumns; col++)                {                    Console.Write(maze[col, row]);                }                // print right wall for maze                Console.Write("|\n");            }            Console.WriteLine();        }        // Calculates and returns the number of rooms.        private int CalculateNumberOfRooms()        {            return (columns * rows);        }        // Calculates and returns the number of walls.        private int CalculateNumberOfWalls()        {            return ((columns - 1) * rows) + ((rows - 1) * columns);        }        // Determines the 2 rooms which are separated by the wall.        private void DetermineRoomsForWall(Wall wall)        {            int room1Id = 0;            int room2Id = 0;            // calculate room number for room 1.            if (wall.id < (columns - 1))                room1Id = wall.id;            else            {                room1Id = wall.id -                     ((((wall.id - (columns - 1)) / (2 * columns - 1)) + 1)                     * (columns - 1));            }            wall.room1 = rooms[room1Id];    // set room 1 for wall.            // calculate room number for room 2.            room2Id = wall.id +                 (1 + ((wall.id / (2 * columns - 1)) * (-(columns - 1))));                        wall.room2 = rooms[room2Id];    // set room 2 for wall.            // Determine type of wall            if (room2Id - room1Id == 1)                wall.wallType = WallType.WALLTYPE_HORIZONTAL;            else                wall.wallType = WallType.WALLTYPE_VERTICAL;        }                private void RandomPermutateAllWalls(int numberOfWalls)        {            for (int i = 0; i < walls.Length; i++)            {                // generate random number to determine new position of this wall in array.                int randNumber = random.Next(0, walls.Length);                if (!randNumber.Equals(i))  // if number does not equal the index value 'i'.                {                    // swap this wall with the wall at the position randomly chosen.                    Wall tempWall;                    // swap wall at index 'i' with wall at index 'number'.                    tempWall = walls;                    walls = walls[randNumber];                    walls[randNumber] = tempWall;                }            }        }    }    class Program    {        const int minMazeSize = 2;  // minimum value for rows or columns for the maze.        const int maxMazeSize = 50; // maximum value for rows or columns for the maze.        const string welcomeText = "Welcome to the C# Random Maze Generator!";        // Entry point for program.        static void Main(string[] args)        {            Console.Title = welcomeText;    // set title of the console.            bool createMaze = true;         // Is true when user wants to create a maze.            MazeGenerator mazeGenerator;    // Object which generates a maze            // while user wants to create a maze             while (createMaze)            {                Console.Clear();                // Clears the screen.                // print welcome text to console.                Console.WriteLine("\n"+welcomeText+"\n");                                 // First get the number of rows for the maze from the user.                  int noOfRows = 0;                GetValidSize("Enter number of rows (2-50): ", out noOfRows);                // Then get the number of columns for the maze from the user                int noOfColumns = 0;                GetValidSize("Enter number of columns (2-50): ", out noOfColumns);                // Generate a maze using the rows and column values.                mazeGenerator = new MazeGenerator(noOfRows, noOfColumns);                mazeGenerator.GenerateMaze();                // Display the maze generated.                mazeGenerator.Display();                // Prompt user if they want to create another maze.  The Boolean value                // value returned from this method is assigned to createMaze variable.                // When the users does not want to create another map then this                 // method returns false, so createMaze becomes false and the program                // exits the while loop and terminates the program.                createMaze = CreateAnotherMaze();            }        }        // This method prints the question and then gets input from the user.        // The method will then check to see if the input from the user was        // valid.  If so then the integer value entered by the user is stored         // in the value variable.  Otherwise the user is prompted again to enter        // another value.  This will keep happening until the user enters a valid        // value for the map.        static void GetValidSize(string request, out int value)        {            // get input from the user to determine the dimensions of the maze.            string input = null;    // used for storing the input from the user.                        // Keep requesting input from the user until a valid value is entered.            while (true)            {                Console.WriteLine();            // print blank line.                Console.Write(request);         // print the request                input = Console.ReadLine();     // get input from the user.                //  Now check to ensure the the input from the user is valid.                // First try to parse the input from user into an integer.                  // If this fails then that means the user entered an invalid                 // input as their input could not be parsed into an integer.                if (Int32.TryParse(input, out value))                {                    // User input parsed successfully into an integer.                    // Now check if the integer value is within 2 - 50.                    if (value >= minMazeSize && value <= maxMazeSize)                    {                        // valid input for size of maze entered by the user so                         // break from infinite loop.                        break;                      }                }                                // If reached here then the user has entered invalid input so                 // let the user know.                Console.WriteLine("Sorry, that's an invalid number. Please try a " +                    "number between {0} and {1}.", minMazeSize, maxMazeSize);            }   // end of infinite while loop        }   // end of GetValidSize method.        // Asks the user if they wish to create another maze.  The user         // must enter yes or no.  If the user enters yes then this method        // returns true otherwise it returns false if the user enters no.        static bool CreateAnotherMaze()        {            while (true)            {                Console.WriteLine("\nNice Maze! Would you like to create another ([y]es:[n]o): ");                                string input = Console.ReadLine();  // get input from the user                input = input.ToLower();      // convert to lower case                if (input.Equals("yes") || input.Equals("y"))                {                    // player has entered yes so wishes to create another maze.                    return true;                    }                else if (input.Equals("no") || input.Equals("n"))                {                    // player has entered no so does not wish to create another maze.                    return false;                   }                // reached here so could not understand the response from the user.                // So let them know.                Console.WriteLine("Could not understand your response!");            }        }    }}
Quote: Original post by SiCrane
Here's my version. I couldn't bring myself to do it with just arrays; I used some of the classes from System.Collections.Generic: Dictionary<> and List<>. To make up for that deviation, I added some functionality. If the maze generated is small enough to fit completely on the console window, you can run through the maze with the arrow keys. Random entrance is placed on the left and an exit placed on the right. Reaching the exit cycles things back to generate a new maze. I think the maximum runnable maze size is 28 rows by 50 columns.
*** Source Snippet Removed ***


Ha, I knew someone would make it do that. I like it though. I ran through it a couple of times.

I finally had time to start mine last night. If I program hard enough I should be able to finish it tonight.

Quote: Original post by SiCrane
To make up for that deviation, I added some functionality. If the maze generated is small enough to fit completely on the console window, you can run through the maze with the arrow keys.

I tried to implement this as well; corresponding code here.



The target is the blue character (it's either a x if there is no south wall, or it's a blue south wall). You can stop the navigation by pressing [ESC].
Hi to all
I would be really pleased if someone could help me...following is my code.

My problem arise in the evaluatePath() method, in my code i've 2 array : the first is MAZE and contain all rooms...the second one is WALLS and contain all the walls...

inside each Wall i want to have a reference to both rooms each wall is between...the probelm is that (in my understanding) i'm passing copies of rooms to the wall instead of references...

/* * I CAU USE : * The System.Console Class * Strings and Primitive Types  * Expressions, Selection, Iteration, and Arrays * Classes, Structs, Methods, Fields, and Objects */using System;using System.Collections.Generic;using System.Text;namespace Project1{    /*** WALL ***/    public struct Wall    {        /* Fields */        private int numW;        private bool state;         private Room room1,room2;                /* Constructor */        public Wall(int numW) {            this.numW = numW;            state = true;            room1 = new Room();            room2 = new Room();        }        /* STATE */        public void setState(bool state)        {            this.state = state;        }        public bool getState()        {            return this.state;        }              /* ROOM1 - ROOM2 */        public void assignR1(Room r1)        {            this.room1 = r1;        }        public Room getR1()        {            return this.room1;        }        public void assignR2(Room r2)        {            this.room2 = r2;        }        public Room getR2()        {            return this.room2;        }    }    /*** ROOM ***/    public struct Room    {        private int roomId,roomSet;                /* Constructor */        public Room(int roomId)        {            this.roomId = roomId;            this.roomSet = roomId;        }        public int getRoomId()        {            return this.roomId;        }        /** roomSet **/        public int getRoomSet()        {            return roomSet;          }        public void setRoomSet(int roomSet)        {            this.roomSet = roomSet;        }    }    /***************/    /* MAZEBUILDER */    /***************/    public class MazeBuilder    {        /*** CREATE MAZE ***/        public Room[,] roomBuilder(int row, int col)        {            int roomset = 0;            Room[,] maze = new Room[row,col];            for (int i=0;i<row;i++)                for (int j=0;j<col;j++)                {                    maze[i, j] = new Room(roomset++);                }            return maze;        }        /*** CREATE WALLS ***/        public Wall[] wallBuilder(int row, int col)        {            int numWalls = evalNumTotWalls(row,col);            Wall[] walls = new Wall[numWalls];            for (int i = 0; i < numWalls; i++)            {                walls = new Wall(i);            }                        return walls;        }                /*** EVALUATE WALL NUMBER ***/        private int evalNumTotWalls(int row, int col)        {            int numWalls = 0;            for (int i = 0; i < row-1 ; i++)                for (int j = 0; j<col ; j++)                {                    numWalls++;                }            for (int i = 0; i < row ; i++)                for (int j = 0; j<col-1 ; j++)                {                    numWalls++;                }            return numWalls;        }                /*** Set two room to each wall ***/        private void setTwoRoomEachWall(Room[,] maze,Wall[] walls, int row, int col){            Console.WriteLine("Enter setTwoRoomEachWall()");            if(maze.Length != 0 && walls.Length != 0){                int numW = 0;                for(int i=0 ; i<row ; i++){                    for(int j=0 ; j<col ; j++){                        if (j < col-1)            // j < 5                        {                            (walls[numW]).assignR1 ((Room)maze[i,j]);                            (walls[numW]).assignR2((Room)maze[i, j + 1]);                        }                        if (i < row-1)            // i < 2                        {                            (walls[numW + col-1]).assignR1(maze[i, j]);                            (walls[numW + col - 1]).assignR2(maze);<br>                        }<br>                        numW++;<br>                    }<br>                    numW += (col -<span class="cpp-number">1</span>);<br>                }<br>            }<br>            Console.WriteLine(<span class="cpp-literal">"Exit setTwoRoomEachWall()"</span>);<br>        }<br><br>        <span class="cpp-comment">/* EVALUATE PATH */</span><br>        <span class="cpp-keyword">public</span> <span class="cpp-keyword">void</span> evaluatePath(Wall[] walls)<br>        {<br>            <span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; walls.Length; i++)<br>            {<br>                <span class="cpp-keyword">if</span> (((Wall)walls<span style="font-weight:bold;">).getR1().getRoomSet() != ((Wall)walls<span style="font-weight:bold;">).getR2().getRoomSet())<br>                {<br>                    walls<span style="font-weight:bold;">.setState(<span class="cpp-keyword">false</span>);<br><br>                    <span class="cpp-comment">// WHY AM I NOT ABLE TO MODIFY THE ROOMS ROOMSET PROPERTY?</span><br>                    ((Wall)walls<span style="font-weight:bold;">).getR1().setRoomSet(<span class="cpp-number">0</span>);<br>                    ((Wall)walls<span style="font-weight:bold;">).getR2().setRoomSet(<span class="cpp-number">0</span>);  <span class="cpp-comment">// it doesn't work</span><br><br>                }<br>            }<br>        }<br><br>        <span class="cpp-comment">/* TO DO */</span><br>        <span class="cpp-keyword">public</span> <span class="cpp-keyword">void</span> sortWalls(Wall[] walls)<br>        {<br><br>        }<br><br>        <span class="cpp-comment">/*** TODO ***/</span><br>        <span class="cpp-keyword">public</span> <span class="cpp-keyword">void</span> displayMaze()<br>        {<br><br>        }<br><br><br>        <br><br>        <span class="cpp-keyword">public</span> <span class="cpp-keyword">static</span> <span class="cpp-keyword">void</span> Main()<br>        {<br>            MazeBuilder builder = <span class="cpp-keyword">new</span> MazeBuilder();<br><br>            <span class="cpp-keyword">int</span> row = <span class="cpp-number">3</span>;<br>            <span class="cpp-keyword">int</span> col = <span class="cpp-number">6</span>;<br>            <br>            Room[,] maze = builder.roomBuilder(row, col);<br>            Wall[] walls = builder.wallBuilder(row,col);<br><br>            builder.setTwoRoomEachWall(maze, walls,row, col);<br><br>            builder.evaluatePath(walls);<br><br>            Console.WriteLine(<span class="cpp-literal">"END"</span>);<br><br>         }<br>    }<br><br>}<br><br></pre></div><!–ENDSCRIPT–><br><br>What am i missing?<br><br>Thx in advance to everyone will help me!<br><br>Nico
Try changing "struct room" to "class room"
Structs are value types, while classes are created as reference types.
You could also force it to be a reference type when you pass it by boxing and unboxing.

For example...
foo((object)someroom);

private void foo(object obj){
Room someroom = (Room)obj;
//etc
}
I mean, why would you get your medical advice anywhere else?
Thx for your help, i'm going to chenge my structs to class immediately!!

Nico

This topic is closed to new replies.

Advertisement