# Creating a Maze Game in .NET, Part 1: Structure

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

When I was teaching programming full time, I always tried to enable the students to think for themselves, and figure out how their own logic works, because it is quite difficult teaching people logic. With the introduction to programming exam (which was mostly theoretical), I included a scenario about a programmable mouse that needs to escape a maze so that it can eat a slice of cheese.

Inside this maze were electronic doors that needed to be tested whether or not they were open before continuing. The robotic mouse also understood a very basic set of instructions (such as move left, smell, and look), for it to navigate through the maze.

These tasks enable students to think critically to solve a problem with the instructions provided. This test has been in existence for almost 15 years, and ever since I made it, I wanted to create my own Maze game. Now, finally, with some time on my hands, I can finally show you how to create a Maze.

Welcome to Part 1, where we will create the gaming structure. This project can be done in either VB.NET or C#; I will provide code for both. Let’s start!

## Practical

Create either a VB.NET or C# Windows Application, and add two classes named:

• clsGrid
• clsGame

C#

```using System;

public class clsGrid
{
public struct Cell
{
public bool blnNorth;
public bool blnSouth;
public bool blnWest;
public bool blnEast;
public bool blnDirty;
public int intNorth;
public int intSouth;
public int intWest;
public int intEast;
}

public static Cell[][] Cells;
public static Cell[][] Solution;

public static Point ptStart;
public static Point ptEnd;
}
```

VB.NET

```Public Class clsGrid

Public Structure Cell

Dim blnNorth As Boolean
Dim blnSouth As Boolean
Dim blnWest As Boolean
Dim blnEast As Boolean
Dim blnDirty As Boolean
Dim intNorth As Integer
Dim intSouth As Integer
Dim intWest As Integer
Dim intEast As Integer

End Structure

Public Shared Cells()() As Cell
Public Shared Solution()() As Cell

Public Shared ptStart As Point
Public Shared ptEnd As Point

End Class
```

There isn’t much in the class, but it does set the boundaries for the walls of the grid, as well as holding the Cell arrays and their various Starting and Ending points. Add the Generate code for clsGame.

C#

```   public void Generate(int intCols, Random rndRand)
{

for (int cell = 0; cell <= intCols - 1; cell++)
{

for (int r = 0; r <= intCols - 1; r++)

clsGrid.Cells(cell)(r) = new clsGrid.Cell();
}

for (int col = 0; col <= clsGrid.Cells.GetUpperBound(0);
col++)
{
for (int row = 0; row <=
clsGrid.Cells(0).GetUpperBound(0); row++)
{
clsGrid.Cells(col)(row).blnDirty = false;
clsGrid.Cells(col)(row).blnNorth = true;
clsGrid.Cells(col)(row).blnSouth = true;
clsGrid.Cells(col)(row).blnWest = true;
clsGrid.Cells(col)(row).blnEast = true;
}
}

List<Point> lstMaze = new List<Point>();

int intEmpty = Math.Pow(intCols, 2);

clsGrid.ptStart = new Point(rndRand.Next(0, intCols),
intCols - 1);

clsGrid.Cells(clsGrid.ptStart.X)(intCols - 1).blnSouth =
false;

intEmpty -= 1;

while (intEmpty > 0)
{
Point pPoint = lstMaze[rndRand.Next(0, lstMaze.Count)];

List<Point> lstChoice = new List<Point>();

if (pPoint.X > 0 & pPoint.X < intCols - 1)
{
if (pPoint.Y > 0 & pPoint.Y < intCols - 1)
// l,t,r,b
- 1, pPoint.Y), new Point(pPoint.X, pPoint.Y -
1), new Point(pPoint.X + 1, pPoint.Y), new
Point(pPoint.X, pPoint.Y + 1) });
else if (pPoint.Y == 0)
// l,r,b
- 1, pPoint.Y), new Point(pPoint.X + 1,
pPoint.Y), new Point(pPoint.X, pPoint.Y + 1) });
else if (pPoint.Y == intCols - 1)
// l,t,r
- 1, pPoint.Y), new Point(pPoint.X, pPoint.Y - 1),
new Point(pPoint.X + 1, pPoint.Y) });
}
else if (pPoint.X == 0)
{
if (pPoint.Y > 0 & pPoint.Y < intCols - 1)
// t,r,b
pPoint.Y - 1), new Point(pPoint.X + 1, pPoint.Y),
new Point(pPoint.X, pPoint.Y + 1) });
else if (pPoint.Y == 0)
// r,b
+ 1, pPoint.Y), new Point(pPoint.X, pPoint.Y
+ 1) });
else if (pPoint.Y == intCols - 1)
// t,r
pPoint.Y - 1), new Point(pPoint.X + 1,
pPoint.Y) });
}
else if (pPoint.X == intCols - 1)
{
if (pPoint.Y > 0 & pPoint.Y < intCols - 1)
// l,t,b
- 1, pPoint.Y), new Point(pPoint.X, pPoint.Y
- 1), new Point(pPoint.X, pPoint.Y + 1) });
else if (pPoint.Y == 0)
// l,b
- 1, pPoint.Y), new Point(pPoint.X, pPoint.Y
+ 1) });
else if (pPoint.Y == intCols - 1)
// l,t
- 1, pPoint.Y), new Point(pPoint.X, pPoint.Y
- 1) });
}

lstChoice.RemoveAll(pt => clsGrid.Cells(pt.X)(pt.Y)
.blnDirty);

if (lstChoice.Count == 0)
continue;

Point pPoint2 = lstChoice[rndRand.Next(0,
lstChoice.Count)];

if (pPoint.X == pPoint2.X & pPoint2.Y < pPoint.Y)
{
if (clsGrid.Cells(pPoint.X)(pPoint.Y).blnNorth)
{
clsGrid.Cells(pPoint.X)(pPoint.Y).blnNorth = false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnSouth =
false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = true;
intEmpty -= 1;
}
else
continue;
}
else if (pPoint.X == pPoint2.X & pPoint2.Y > pPoint.Y)
{
if (clsGrid.Cells(pPoint.X)(pPoint.Y).blnSouth)
{
clsGrid.Cells(pPoint.X)(pPoint.Y).blnSouth = false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnNorth =
false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = true;
intEmpty -= 1;
}
else
continue;
}
else if (pPoint.X > pPoint2.X & pPoint2.Y == pPoint.Y)
{
if (clsGrid.Cells(pPoint.X)(pPoint.Y).blnWest)
{
clsGrid.Cells(pPoint.X)(pPoint.Y).blnWest = false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnEast =
false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = true;
intEmpty -= 1;
}
else
continue;
}
else if (pPoint.X < pPoint2.X & pPoint2.Y == pPoint.Y)
{
if (clsGrid.Cells(pPoint.X)(pPoint.Y).blnEast)
{
clsGrid.Cells(pPoint.X)(pPoint.Y).blnEast = false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnWest = false;
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = true;
intEmpty -= 1;
}
else
continue;
}
}
}
```

VB.NET

```   Public Sub Generate(ByVal intCols As Integer, ByVal rndRand _
As Random)

ReDim clsGrid.Cells(intCols - 1)

For cell As Integer = 0 To intCols - 1

ReDim clsGrid.Cells(cell)(intCols - 1)

For r As Integer = 0 To intCols - 1

clsGrid.Cells(cell)(r) = New clsGrid.Cell

Next

Next

For col As Integer = 0 To clsGrid.Cells.GetUpperBound(0)

For row As Integer = 0 To clsGrid.Cells(0) _
.GetUpperBound(0)

clsGrid.Cells(col)(row).blnDirty = False
clsGrid.Cells(col)(row).blnNorth = True
clsGrid.Cells(col)(row).blnSouth = True
clsGrid.Cells(col)(row).blnWest = True
clsGrid.Cells(col)(row).blnEast = True

Next

Next

Dim lstMaze As New List(Of Point)

Dim intEmpty As Integer = intCols ^ 2

clsGrid.ptStart = New Point(rndRand.Next(0, intCols), _
intCols - 1)

clsGrid.Cells(clsGrid.ptStart.X)(intCols - 1).blnSouth = _
False

intEmpty -= 1

While intEmpty > 0

Dim pPoint As Point = lstMaze(rndRand.Next(0, _
lstMaze.Count))

Dim lstChoice As New List(Of Point)

If pPoint.X > 0 And pPoint.X < intCols - 1 Then

If pPoint.Y > 0 And pPoint.Y < intCols - 1 Then

'l,t,r,b'
- 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
- 1), New Point(pPoint.X + 1, pPoint.Y), _
New Point(pPoint.X, pPoint.Y + 1)})

ElseIf pPoint.Y = 0 Then

'l,r,b'
- 1, pPoint.Y), New Point(pPoint.X + 1, _
pPoint.Y), New Point(pPoint.X, pPoint.Y + 1)})

ElseIf pPoint.Y = intCols - 1 Then

'l,t,r'
- 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
- 1), New Point(pPoint.X + 1, pPoint.Y)})

End If

ElseIf pPoint.X = 0 Then

If pPoint.Y > 0 And pPoint.Y < intCols - 1 Then

't,r,b'
pPoint.Y - 1), New Point(pPoint.X + 1, _
pPoint.Y), New Point(pPoint.X, pPoint.Y + 1)})

ElseIf pPoint.Y = 0 Then

'r,b'
+ 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
+ 1)})

ElseIf pPoint.Y = intCols - 1 Then

't,r'
pPoint.Y - 1), New Point(pPoint.X + 1, pPoint.Y)})

End If

ElseIf pPoint.X = intCols - 1 Then

If pPoint.Y > 0 And pPoint.Y < intCols - 1 Then

'l,t,b'
- 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
- 1), New Point(pPoint.X, pPoint.Y + 1)})

ElseIf pPoint.Y = 0 Then

'l,b'
- 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
+ 1)})

ElseIf pPoint.Y = intCols - 1 Then

'l,t'
- 1, pPoint.Y), New Point(pPoint.X, pPoint.Y _
- 1)})

End If

End If

lstChoice.RemoveAll(Function(pt) clsGrid.Cells(pt.X) _
(pt.Y).blnDirty)

If lstChoice.Count = 0 Then Continue While

Dim pPoint2 As Point = lstChoice(rndRand.Next(0, _
lstChoice.Count))

If pPoint.X = pPoint2.X And pPoint2.Y < pPoint.Y Then

If clsGrid.Cells(pPoint.X)(pPoint.Y).blnNorth Then

clsGrid.Cells(pPoint.X)(pPoint.Y).blnNorth = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnSouth = _
False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = True
intEmpty -= 1

Else

Continue While

End If

ElseIf pPoint.X = pPoint2.X And pPoint2.Y > pPoint.Y Then

If clsGrid.Cells(pPoint.X)(pPoint.Y).blnSouth Then
clsGrid.Cells(pPoint.X)(pPoint.Y).blnSouth = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnNorth = _
False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = True
intEmpty -= 1

Else

Continue While

End If

ElseIf pPoint.X > pPoint2.X And pPoint2.Y = pPoint.Y Then

If clsGrid.Cells(pPoint.X)(pPoint.Y).blnWest Then

clsGrid.Cells(pPoint.X)(pPoint.Y).blnWest = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnEast = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = True
intEmpty -= 1

Else

Continue While

End If

ElseIf pPoint.X < pPoint2.X And pPoint2.Y = pPoint.Y Then

If clsGrid.Cells(pPoint.X)(pPoint.Y).blnEast Then
clsGrid.Cells(pPoint.X)(pPoint.Y).blnEast = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnWest = False
clsGrid.Cells(pPoint2.X)(pPoint2.Y).blnDirty = True
intEmpty -= 1

Else

Continue While

End If

End If

End While

End Sub
```

The Generate sub is responsible for creating the design of the Maze. This is done by generating random points and identifying if the current spot is already used. Then, it draws the connecting lines to the various points.

C#

```   public bool Solve(int intCol, int intX, int intY, bool[,]
blnScanned, List<Point> lstSol)
{
bool blnCorrect = false;
bool blnCheck = true;

if (intX >= intCol || intX < 0 || intY >= intCol
|| intY < 0)
blnCheck = false;
else
{
if (new Point(intX, intY) == clsGrid.ptEnd)
{
blnCorrect = true;
blnCheck = false;
}

if (blnScanned[intX, intY])
blnCheck = false;
}

if (blnCheck)
{
blnScanned[intX, intY] = true;

blnCorrect = blnCorrect | clsGrid.Cells(intX)(intY)
.blnEast == false ? Solve(intCol, intX + 1, intY,
blnScanned, lstSol) : false;

blnCorrect = blnCorrect | clsGrid.Cells(intX)(intY)
.blnSouth == false ? Solve(intCol, intX, intY + 1,
blnScanned, lstSol) : false;

blnCorrect = blnCorrect | clsGrid.Cells(intX)(intY)
.blnWest == false ? Solve(intCol, intX - 1, intY,
blnScanned, lstSol) : false;

blnCorrect = blnCorrect | clsGrid.Cells(intX)(intY)
.blnNorth == false ? Solve(intCol, intX, intY - 1,
blnScanned, lstSol) : false;
}

if (blnCorrect)

return blnCorrect;
}
```

VB.NET

```   Public Function Solve(ByVal intCol As Integer, ByVal intX As -
Integer, ByVal intY As Integer, ByVal blnScanned(,) _
As Boolean, ByVal lstSol As List(Of Point)) As Boolean

Dim blnCorrect As Boolean = False
Dim blnCheck As Boolean = True

If intX >= intCol OrElse intX < 0 OrElse intY >= _
intCol OrElse intY < 0 Then

blnCheck = False

Else

If New Point(intX, intY) = clsGrid.ptEnd Then

blnCorrect = True
blnCheck = False

End If

If blnScanned(intX, intY) Then

blnCheck = False

End If

End If

If blnCheck Then

blnScanned(intX, intY) = True

blnCorrect = blnCorrect Or If(clsGrid.Cells(intX)(intY) _
.blnEast = False, Solve(intCol, intX + 1, intY, _
blnScanned, lstSol), False)

blnCorrect = blnCorrect Or If(clsGrid.Cells(intX)(intY) _
.blnSouth = False, Solve(intCol, intX, intY + 1, _
blnScanned, lstSol), False)

blnCorrect = blnCorrect Or If(clsGrid.Cells(intX)(intY) _
.blnWest = False, Solve(intCol, intX - 1, intY, _
blnScanned, lstSol), False)

blnCorrect = blnCorrect Or If(clsGrid.Cells(intX)(intY) _
.blnNorth = False, Solve(intCol, intX, intY - 1, _
blnScanned, lstSol), False)

End If

If blnCorrect Then

End If

Return blnCorrect

End Function
```

## Conclusion

Now that we have the structure, we can build the gaming logic into it in Part 2. I hope you look forward to it.

Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).