C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 2)

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@dbzfan4awhile·
0.000 HBD
C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 2)
Hey everybody!!!

I hope you enjoyed my last Tutorial Lesson regarding the [_No-Frills Dungeon Crawler_](https://steemit.com/csharp-forbeginners/@dbzfan4awhile/c-sharp-programming-beginner-tutorial-no-frills-dungeon-crawler-part-1). Now we're going to dive into the C# fun of it all. We'll see what makes the game tick, what makes it tock, and what in the world is next in stock!

![CSharp-ForBeginners_FristImage.JPG](https://steemitimages.com/DQmZDfkpXihS3b34FdLVjsrWmV4bdrGpUZaBizVFdNJSsrg/CSharp-ForBeginners_FristImage.JPG)

Let's get right down to it, then, and see what the Code looks like. The animated image below shows me playing the game, which isn't much of a game yet. It does show a bit of what the game will look like (yes, it's _very_ simple and I could have done much more) and how to maneuver within the game interface.

![2018-01-28-08-26-23.gif](https://steemitimages.com/DQmXtMYp7R72yrVR8HVtopByQBkp8HzMgiNnF1N78yeUjRS/2018-01-28-08-26-23.gif)

And now for the Code...

___

_**The Grand Scale**_

So we've taken a look at the concept of the game in the previous post as well as the outlook for the future of the game. Now we are going to take an in-depth look at the C# Code for this game. We will get a glimpse of the overall program and then go deeper into the _functions_ and _variables_ and how the logic interacts.

Here you go, my fellow Nerds-in-Waiting and Chic-Geek-Knights, following is the code at a glimpse.

![](https://steemitimages.com/DQmQtzHMwjBjBVY5iahnNWFijm9DhrH1DhdhrXLQkrj8mGq/image.png)
![](https://steemitimages.com/DQmVg18fXAXfZ4ZKtcLyA5TLCXAASJErc1XNTkCkyzAmqBQ/image.png)
![](https://steemitimages.com/DQmRbFkaxJMk8dYHyrL8XQ5LJ1ZE5RLx1eJrMkuf6LBiQho/image.png)
![](https://steemitimages.com/DQmQok6AA28CYyR4WjkJCkwZsYzfgnYMvHSE5WnkTJMxSEM/image.png)
![](https://steemitimages.com/DQmZPzQJeNfCosTidrC43L62TypvXnU4vEubbcGTSFEBWnN/image.png)
![](https://steemitimages.com/DQma64e7uBvMhGK9kpXf4PXz8LLcNMvgQQg5dZkXxukFmGC/image.png)

As you can see, quite a bit of _switch_ logic and semi-repetitious checking. There are always a dozen ways to do the same thing, so this is just one way in many that can do the same/similar things. In essence, the _switch_ statement is like saying "I have a bunch of conditions and want to check them each on a case-by-case scenario. Hence, you see the _case_ statement that is part of the _switch_ logic... you cannot use _switch_ without it.

The whole scope may look a bit intimidating, but the logic within each segment can usually be summed up by just a few logical components. Following are the Bits & Pieces of it all.

___

_**Bits & Pieces**_

I'm going to go top-down through the code and explain what it all means without repeating myself over and over. I hope it all makes sense when I'm through with it all. The following sections will explain each of the parts of the code that will become the functional logic and representation to the game as a whole.

___

_**The Variables at Play**_

![](https://steemitimages.com/DQmR8R68BjQnZiwYXgJNmmkSNQDU8SDMeM2qM3TU3gB2KUh/image.png)

To start this section, we create an object of type _Random_ that you might recall represents a randomly-generated number. "map" is a _char_ based _variable_, which is an object that contains singular characters. 

"= { ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' };" says to create the _array_ and fill each with the comma-delimeted values inside the curly braces _{ }_.

An example of the _**Constants**_ to use: _public const int north = 0;_

_Constants_ are _variables_ (you remember what variables are, correct? names of things to represent something else) that stay constant and cannot be changed across time. As an example, the above line of code recognizes the variable called "north" as a _public_ (globally-usable) _const_ (constant) with a _dataype_ (type of variable) of _int_ (integer-based, therefore, numeric whole numbers). Setting "north" to a _constant variable_ sets it to a value (this time "0") that cannot be changed.

By using _constants_, I can now use the word "north" to mean "0". It makes the code far easier to read when it comes to debugging and/or change. I use the directional words to describe each, that way it made the coding of movements (turning left and right) a far simpler formula of addition or subtraction from the current directional number.

"direction" is the _variable_ that actually determines the direction that the game's character will be facing. The "map_x" and "map_y" _variables_ are only initialized and not used more than that. In future versions I may create maps from files that this will represent the map-based coordinates; but for now, it is not used.

"north_door", "east_door", "south_door", & "west_door" are _boolean_ (true/false) _variables_ that I use to represent whether or not there is a doorway in the corresponding wall. As an example, if "east_door" is _true_ it means that if you are facing the east (in the game) there will be a doorway showing, and if you are facing north, that same doorway will show up on the right-hand wall. These are used to draw the correct image.

The "backdrop" is a _PictureBox_ component that will be used for the game-screen itself. A _PictureBox_ is a dotNet component that can hold an image for later use. This object is contained within the structure of Visual Studio itself and, therefore, one can do a drag-and-drop through the Visual Studio interface. In this instance I just created the object within the code itself.

The _Images_ ("left_image", "front_image", "right_image" and so on) are actual _Image objects_ that will be used as the wall-based images. The "left_image" represents the wall image that shows _only_ a doorway on the right-hand wall. An _Image_ object can store the data for an image, whether from a file or some sort of data stream. In these examples (as below) the image itself will be loaded from a file in the next section.

___

_**Start & Finish**_

When the program begins it uses the "Form1_Load" _Function_ to begin loading the variables and components. This is where the _variables_ from the above section will actually become usable. That will occur behind-the-scenes prior to the below code being run.

![](https://steemitimages.com/DQmVf6xzqus1cKW1bUsPQ8AGp6XigDCgC2zvnnmMz7xS44q/image.png)

As you can see in the image above, I use the "Image.FromFile(...)" dotNet _Function_ in order to load the images from files. I could have drawn the images individually or dynamically, but it would have made the code harder to understand. I cannot say one way or another on whether big-name games use my technique or a dynamic technique or something completely different. All I know is that this is the way I am doing it so that it's easier to follow.

Essentially, "left_door = Image.FromFile(...);" tells us to pull the image from the file location marked by the ellipsis and load it into the _Image_ object called "left_door". The actual image is of 3 walls with the left wall as the only one that includes a doorway in it.

The same technique is used for the other images.

"map = room_types[r.Next(0, 15)];" represents logic to randomly create a room with a variable number of walls from 1-4 based on 16 alphabetic characters. "map = " says to set the "map" _variable_, while "room_types[...];" says to use the _char[]_ object, which is a _char_ array. An _array_ is an object type that holds multiple versions of the same _variable_ with the same name. This one in particular is identified by the _char_ values of the alphabet from "a" - "o" with the first as an empty space. This way "room_type[1]" would represent the 2nd value in the array (these are 0-indexed and, therefore, starts at [0]).

Arrays can be confusing, so don't be alarmed if you still need to learn more about them.

After the "Form1_Load(...)" _Function_ you can see the "Done_Click()" _Function_ that represents the action of clicking the Button that I called "Done" (as in the below image):

![](https://steemitimages.com/DQmPC1LaAE5zBWq6BxZwGs33pWySqtbFBvmtbcvz8ggopbM/image.png)
(_Done_ Button is circled in Red and labeled with "Quit")

The code itself shows "this.Close();" which is a call to the base "Close()" _Function_ that closes down "this" form. _this_ is a keyword that represents the main Form/object.

___

_**Movin' & Groovin'**_

In order to allow you to move forward through a doorway or backward through a doorway, if there is a doorway in that direction, I have 2 buttons that look like ![](https://steemitimages.com/DQmQKNt3GwCK8tte3XGzC1o9YzXGz24jkreVTE8aV6nX4yA/image.png) and ![](https://steemitimages.com/DQmZ7QovhvcrDh7ThTdmPbc7SSp5rYkqAezueEMTdGqxdzx/image.png).

![](https://steemitimages.com/DQmNgNLiDuHpBUGELmSwyShX3acABK6qbptaL4wCLdnnWam/image.png)

In the above code, "MoveForward_Click()" is the _Function_ linked to the ![](https://steemitimages.com/DQmQKNt3GwCK8tte3XGzC1o9YzXGz24jkreVTE8aV6nX4yA/image.png)  button called "MoveForward". The logic occurs when that button is clicked (hence the "_Click" portion of the _Function_ name.

```
            switch (direction)
            {
                case north: if (CheckDirection(true)) { map_y++; LastMessage.Text = "You moved forward."; map = room_types[r.Next(0, 15)]; } else { LastMessage.Text = "You cannot go that way. No Door."; }; break;
                case east: if (CheckDirection(true)) { map_x++; LastMessage.Text = "You moved forward."; map = room_types[r.Next(0, 15)]; } else { LastMessage.Text = "You cannot go that way. No Door."; }; break;
                case south: if (CheckDirection(true)) { map_y--; LastMessage.Text = "You moved forward."; map = room_types[r.Next(0, 15)]; } else { LastMessage.Text = "You cannot go that way. No Door."; }; break;
                case west: if (CheckDirection(true)) { map_x--; LastMessage.Text = "You moved forward."; map = room_types[r.Next(0, 15)]; } else { LastMessage.Text = "You cannot go that way. No Door."; }; break;
                default: break;
            }

            GetDoors(map);
            this.Update();
```

The _switch_ command uses the _variable_ inside the parantheses () to check different scenarios. Each scenario is prefaced by a "case ?: " where the "?" represents the value (in these cases the _constants_. 

So, if "direction" is equal to "north" (0) then it executes a _function_ called "CheckDirection(...)" to see if it returns as _true_ or _false_ (not to be confused by the parameter inside the parentheses). If that, in turn, returns as _true_ then it changes the text value of a label called "LastMessage" ![](https://steemitimages.com/DQmdoitQZkDCBec4gdym4ZFXxgTZemrrYSkT6v6Jz2F8Ftc/image.png) to show "You moved Forward.", otherwise if it returns as _false_ it executes the _else_ clause. The _else_ is the alternative of an _if_ statement's _true" clause... "if ... else" represents the question of "if _this_ then _do this_ else _do that_". If the _else_ clause runs, the label shows "You cannot go that way. No Door." as its text value.

The "MoveBackward_Click(...)" Function does the same of the "MoveBackward" _Button_ object.

`GetDoors(map);`
`this.Update();`

The first calls a _Function_ called "GetDoors" and passes in the "map" variable, the one that represents the number of doors in the room. The second line calles "this.Update();" which just refreshes and repaints _this_ form.

___

_**Turnaround, every now and then I get a little bit lonely**_

Ok, I don't get lonely, but it does run the formulas to turn a different direction. The code is fairly short, actually, as can be seen here:

```

        private void TurnRight_Click(object sender, EventArgs e)
        {
            direction++;

            if (direction > west) { direction = north; }

            GetDoors(map);
            LastMessage.Text = "Turn Right.";
            this.Update();
        }

        private void TurnLeft_Click(object sender, EventArgs e)
        {
            direction--;

            if (direction < north) { direction = west; }

            GetDoors(map);
            LastMessage.Text = "Turn Left.";
            this.Update();
        }
```

If you recall, the "direction" _variable_ is an integer number that represents the direction that the character is facing in the game. so if you turn to the right, it goes from the current direction to the next direction in line (eg. north->east... which is north (0) to east (1)). To do a right turn, all that needs to happen is the increase the "direction" by 1. "direction++;" means to do just that. 0 becomes 1, 1 becomes 2, and so on. The problem, however, is that there are only 4 directions (0 thru 3), so we need to check and reset if needed. The following line does that:

![](https://steemitimages.com/DQmc2BiQged1vhPc98PLNPvKzKSNxPKaZiHSsiQKH2bv91j/image.png)
[Directions anyone?](https://www.google.com/search?biw=1280&bih=633&tbm=isch&sa=1&ei=iQtuWv6FJoz3zgLuhrfIDw&q=compass+rose&oq=compass+rose&gs_l=psy-ab.3..0l10.94049.95718.0.95849.12.9.0.2.2.0.118.789.7j2.9.0....0...1c.1.64.psy-ab..1.11.794...0i67k1.0.If2_GBoIUC4#imgrc=2SLkb5fYl9E8RM:)

"if (direction > west) { direction = north; }"

_if_ the expression inside the parentheses evaluates to _true_ (eg. if "direction" is now greater than 3 (west)) then it executes the logic in the braces _{ direction = north; }_. Doing this sets "direction" equal to "north" (0).

`            GetDoors(map);`
`            LastMessage.Text = "Turn Left.";`
`            this.Update();`

This set of lines says **Execute the GetDoors(map) function, then set the text value of the _LastMessage_ label to "Turn Left." and finally to refresh and repaint _this_ form.**

To turn left, it just works in reverse.

___

_**What Direction Your Direction is in?**_

```
        private bool CheckDirection(bool forward)
        {
            bool result = false;

            if (forward)
            {
                if (direction == north)
                {
                    return north_door;
                }
                else if (direction == east)
                {
                    return east_door;
                }
                else if (direction == south)
                {
                    return south_door;
                }
                else if (direction == west)
                {
                    return west_door;
                }
            }
            else
            {
                if (direction == north)
                {
                    return south_door;
                }
                else if (direction == east)
                {
                    return west_door;
                }
                else if (direction == south)
                {
                    return north_door;
                }
                else if (direction == west)
                {
                    return east_door;
                }
            }

            return result;
        }
```

The above code basically checks the direction and, if you are moving forward, it checks to see if there's a doorway in that direction. The "forward" _variable_ is the response to "which way are you moving... forward or backward?". Therefore, if "forward" is true, then you're moving forward and, otherwise, you're _not_ moving forward (you're moving backward).

Then, after that check, it checks the appropriate wall to see if there's a doorway in the wall.

```
            if (forward)
            {
                if (direction == north)
                {
                    return north_door;
                }
```

This is the first check in the "forward" option. "if (direction == north)" says **if "direction" equals "north" then do this**. The double-equals (==) is a comparison logical expression. After that, if the "direction" _is_ "north" then return the _boolean_ (true/false) value of "north_door". This returns back to the code in the **Movin' & Groovin'** section above.

___

![](https://steemitimages.com/DQmaqUX4M5u5UT3CUA8ZNzYGyiGEBENjvEifFVXAUmG2rAD/image.png)
[Doorways, Doorways, everywhere](https://www.google.com/search?q=doorways&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjdg427mvvYAhVq6IMKHYzPCAgQ_AUICygC&biw=1280&bih=633#imgrc=Au0x08DEGFTqrM:)

_**Where have all the Doorways Gone?**_

This is the logic that determines the doorways and directions for a given room. The code below is a snippet of this _Function_ when the "room_identifier" parameter that is passed in is an 'a'. The letter 'a' represents a door _only_ in the north-facing wall. Therefore, if I check the "direction" value and I'm facing north, the doorway should be right in front of me only... this condition is represented by the "front_image" _Image variable_. You will see this _case_ scenario below where it says "case north: ...".

```
        private void GetDoors(char room_identifier)
        {
            switch (room_identifier)
            {
                case 'a':
                    north_door = true; east_door = false; south_door = false; west_door = false;
                    switch (direction)
                    {
                        case north: this.backdrop.Image = front_image; break;
                        case east: this.backdrop.Image = left_image; break;
                        case south: this.backdrop.Image = none_image; break;
                        case west: this.backdrop.Image = right_image; break;
                        default: break;
                    }
                    break;
```

The other logic is the same type of logic ("Which walls have doors? and what direction am I facing?") to show which doorways to draw.

___

_**Lessons Learned**_

Here are the links to your lessons learned (or not learned, if you need to go back and learn them):

[C# Programming Beginner Tutorial: Basic Concepts and Ideas](https://steemit.com/programming/@dbzfan4awhile/c-programming-beginner-tutorial-basic-concepts-and-ideas)

[C# Programming Beginner Tutorial: A First look at actual code using D&D as the Project](https://steemit.com/programming/@dbzfan4awhile/c-programming-beginner-tutorial-a-first-look-at-actual-code-using-d-and-d-as-the-project)

[C# Programming Beginner Tutorial: Variables & Data Types to Fuel the Gaming Engine!](https://steemit.com/steemiteduction/@dbzfan4awhile/c-programming-beginner-tutorial-variables-and-data-types-to-fuel-the-gaming-engine)

[C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 1)](https://steemit.com/csharp-forbeginners/@dbzfan4awhile/c-programming-beginner-tutorial-designing-the-game-with-programming-logic-in-mind-part-1)

[C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 2)](https://steemit.com/utopian-io/@dbzfan4awhile/c-programming-beginner-tutorial-designing-the-game-with-programming-logic-in-mind-part-2)

[C# Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 3)](https://steemit.com/utopian-io/@dbzfan4awhile/https-steemit-com-utopian-io-dbzfan4awhile-c-programming-beginner-tutorial-designing-the-game-with-programming-logic-in-mind)

[C-Sharp Programming Beginner Tutorial: Designing the Game with Programming Logic in Mind (Part 4)](https://steemit.com/csharp-forbeginners/@dbzfan4awhile/c-sharp-programming-beginner-tutorial-designing-the-game-with-programming-logic-in-mind-part-4)

[C-Sharp Programming Beginner Tutorial: Rock! Paper! Scissors!](https://steemit.com/csharp-forbeginners/@dbzfan4awhile/c-sharp-programming-beginner-tutorial-rock-paper-scissors)

[C-Sharp Programming Beginner Tutorial: No-Frills Dungeon Crawler (Part 1)](https://steemit.com/csharp-forbeginners/@dbzfan4awhile/c-sharp-programming-beginner-tutorial-no-frills-dungeon-crawler-part-1)

___
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,