C# Workshop - Project 1: Maze Generator - Solutions

Published October 27, 2012
Advertisement
Post your solutions here!
0 likes 1 comments

Comments

Alpha_ProgDes
Well I took a Room-centric approach to my solution. I'm convinced that this is not the THE WAY or an optimal way. But it works [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[spoiler]
[CODE]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CW_Project1
{
class Program
{
static void Main(string[] args)
{
MazeCreator mc = new MazeCreator();
mc.createMaze(4, 4);
mc.createPerfectMaze();
mc.displayMaze();
}
}
class Room
{
int roomNumber;
int[] wallArray;
public Room()
{
}
public Room(int roomNum, int[] walls)
{
roomNumber = roomNum;
wallArray = walls;
}
public int RoomNumber
{
get
{
return roomNumber;
}

set
{
roomNumber = value;
}
}
public int[] WallArray
{
get
{
return wallArray;
}
set
{
wallArray = value;
}
}

}
class MazeCreator
{
int rows;
int columns;
int topOffset;
int leftOffset;
int rightOffset;
int bottomOffset;
int rowOffset;
List<int> knockedDownRooms;
Room[,] initialRooms;
int[] wallsToKnockDown;
public void createMaze(int rows, int columns)
{
this.rows = rows;
this.columns = columns;
initialRooms = new Room[rows, columns];
int numOfRooms = rows * columns;
int rowOfWalls = (columns - 1) + columns;
int totalNumberOfWalls = (rowOfWalls * rows) - columns;

for (int i = 0; i < rows; ++i)
{
adjustRowOffsets(i, columns, rowOfWalls);
for (int j = 0; j < columns; ++j)
{
int roomNum = (i * columns) + j;
int tO = roomNum + topOffset;
int lO = roomNum + leftOffset;
int rO = roomNum + rightOffset;
int bO = roomNum + bottomOffset;
setWallsToRoom(rowOfWalls, ref tO, ref lO, ref rO, ref bO);
checkOverflowOfBottomFloors(totalNumberOfWalls, ref bO);
initialRooms[i,j] = new Room(roomNum, new int[] {tO, lO, rO, bO});
}
}
}
public void createPerfectMaze()
{
int rowOfWalls = (columns - 1) + columns;
int totalNumberOfWalls = (rowOfWalls * rows) - columns;
knockedDownRooms = new List<int>();
wallsToKnockDown = wallToKnockDownArray(totalNumberOfWalls);
int[] roomsAndFloorType;
for (int i = 0; i < wallsToKnockDown.Length; ++i)
{
roomsAndFloorType = getRoomsFromWall(wallsToKnockDown[i], rowOfWalls, columns);
// rowNum * columns + cell
int y = roomsAndFloorType[0] / columns;
int x = roomsAndFloorType[0] % columns;
int floorType = roomsAndFloorType[2];
if (knockedDownRooms.Contains(roomsAndFloorType[0]) &&
knockedDownRooms.Contains(roomsAndFloorType[1]))
continue;
for (int j = 0; j < initialRooms[y, x].WallArray.Length; ++j)
{
if (initialRooms[y, x].WallArray[j] == wallsToKnockDown[i])
{
initialRooms[y, x].WallArray[j] = -2;

if (!knockedDownRooms.Contains(roomsAndFloorType[0]))
knockedDownRooms.Add(roomsAndFloorType[0]);
break;
}
}

if (floorType == 0)
{
int y0 = y + 1;
for (int j = 0; j < initialRooms[y0, x].WallArray.Length; ++j)
{
if (initialRooms[y0, x].WallArray[j] == wallsToKnockDown[i])
{
initialRooms[y0, x].WallArray[j] = -2;
if (!knockedDownRooms.Contains(roomsAndFloorType[1]))
knockedDownRooms.Add(roomsAndFloorType[1]);
break;
}
}
}
else if (floorType == 1)
{
int x0 = x + 1;
for (int j = 0; j < initialRooms[y, x0].WallArray.Length; ++j)
{
if (initialRooms[y, x0].WallArray[j] == wallsToKnockDown[i])
{
initialRooms[y, x0].WallArray[j] = -2;
if (!knockedDownRooms.Contains(roomsAndFloorType[1]))
knockedDownRooms.Add(roomsAndFloorType[1]);
break;
}
}
}
}
}
public void displayMaze()
{
int totalRooms = initialRooms.Length;
for (int j = 0; j < rows; ++j)
{
for (int i = 0; i < columns; ++i)
{
Console.Write(" ");
if (initialRooms[j, i].WallArray[0] == -1)
Console.Write("-");
else if (initialRooms[j, i].WallArray[0] >= 0)
Console.Write("-");
else if (initialRooms[j, i].WallArray[0] == -2)
Console.Write(" ");
}
Console.Write(" ");
Console.WriteLine();
for (int i = 0; i < columns; ++i)
{
if (initialRooms[j, i].WallArray[1] == -1)
Console.Write("|");
else if (initialRooms[j, i].WallArray[1] >= 0)
Console.Write("|");
else if (initialRooms[j, i].WallArray[1] == -2)
Console.Write(" ");
Console.Write(" ");
}
Console.Write("|");
Console.WriteLine();
if (j == rows - 1)
{
for (int i = 0; i < columns; ++i)
{
Console.Write(" ");
if (initialRooms[j, i].WallArray[3] == -1)
Console.Write("-");
else if (initialRooms[j, i].WallArray[3] >= 0)
Console.Write("-");
else if (initialRooms[j, i].WallArray[3] == -2)
Console.Write(" ");
}
Console.Write(" ");
Console.WriteLine();
}
}
}
public Room[,] getInitialRooms()
{
return initialRooms;
}
private int[] getRoomsFromWall(int wallNumber, int rowOfWalls, int columns)
{
int x = (wallNumber % rowOfWalls);
int y = (wallNumber / rowOfWalls);
int colLimit = columns - 1;
int roomA = -1;
int roomB = -1;
int floorOrWall = -1;
if (0 <= x && x < colLimit)
{
roomA = (y * columns) + x;
roomB = roomA + 1;
floorOrWall = 1;
}
else if (colLimit <= x && x < rowOfWalls)
{
roomA = (y * columns) + (x - colLimit);
roomB = roomA + columns;
floorOrWall = 0;
}
int[] knockDownRooms = new int[3];
knockDownRooms[0] = roomA;
knockDownRooms[1] = roomB;
knockDownRooms[2] = floorOrWall;
return knockDownRooms;
}
private int[] wallToKnockDownArray(int totalNumberOfWalls)
{
int[] wallsArray = new int[totalNumberOfWalls];
for (int i = 0; i < totalNumberOfWalls; ++i)
{
wallsArray[i] = i;
}
shuffle(wallsArray);
return wallsArray;
}
private void shuffle(int[] array)
{
//Fisher-Yates algorithm, gotten from Stack Overflow
Random rng = new Random(); // i.e., java.util.Random.
int n = array.Length; // The number of items left to shuffle (loop invariant).
while (n > 1)
{
int k = rng.Next(n); // 0 <= k < n.
n--; // n is now the last pertinent index;
int temp = array[n]; // swap array[n] with array[k] (does nothing if k == n).
array[n] = array[k];
array[k] = temp;
}
}
private void adjustRowOffsets(int indexedRow, int columns, int rowOfWalls)
{
rowOffset = -columns + (indexedRow * (columns - 1));
topOffset = rowOffset;
leftOffset = (topOffset + (columns - 1));
rightOffset = leftOffset + 1;
bottomOffset = topOffset + rowOfWalls;
}
private void setWallsToRoom(int rowOfWalls, ref int tO, ref int lO, ref int rO, ref int bO)
{
tO = (columns - 1) <= (tO % rowOfWalls) && (tO % rowOfWalls) < rowOfWalls ? tO : -1;
lO = 0 <= (lO % rowOfWalls) && (lO % rowOfWalls) < (columns - 1) ? lO : -1;
rO = 0 <= (rO % rowOfWalls) && (rO % rowOfWalls) < (columns - 1) ? rO : -1;
bO = (columns - 1) <= (bO % rowOfWalls) && (bO % rowOfWalls) < rowOfWalls ? bO : -1;
}
private void checkOverflowOfBottomFloors(int totalNumberOfWalls, ref int bO)
{
int wallLimit = totalNumberOfWalls - 1;
if (bO > wallLimit)
bO = -1;
}
}
}
[/CODE][/spoiler]
October 27, 2012 10:30 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement