We've talked a bit about types so far, but not in much detail. A type is the definition of an object, with the details of all of the methods and variables in that object. A class is a type of type that you can define in C#. There is another kind, called a struct, but you don't need to worry about those. The only time when you should make your own struct is when you're absolutely sure that you understand what one is and definitely should use one. Even then, half the time you still shouldn't. Classes, though, you will define frequently.
The main class we'll define first is going to be the Dungeon class, which will contain data about the dungeon and methods used to manipulate it. We'll also define the Coordinate class. Let's begin.
Right click your project file in the Solution Explorer which is usually located on the right side of the screen. The Project file is the one just under the Solution, and contains the Program.cs you've been working in. Choose Add, and then choose Class.
We'll name the new class Coordinate. Classes are typically named with a capital letter.
You'll now be faced with a lot of information:
You don't need most of this, so let's clean it up so that it looks like this:
This file contains two things: A namespace, and within it a class. You know vaguely what a class is already, so let's quickly touch on namespaces. A namespace is a container which provides an extra name to a class. The proper name of this class is now DungeonCrawler1.Coordinate. While there is more to namespaces than just this, you don't need to worry about it.
Below the namespace is the class. It's defined as public, which means that any other code can access it, from inside or outside this project. Most classes you define will have public access. Next is the type of thing you are defining, class, followed by the name. Then, inside of that a scope defines the content of the class. Unlike other scopes you have defined, this one cannot contain normal lines of code. It is just a container for type members, or the variables and methods that make up the class.
Within the class, we have created two properties. A property is a type of variable used in a class. It is the most common kind, suitable for variables that can be seen from outside the class. They are defined using an access modifier (public), a type (int in this case, which means a whole number), a name (South and East respectively), and the accessor list, surrounded by curly braces. The accessor list we're using here is just a get accessor, because we don't need code outside to change them (which would mean including a set).
Below the properties, we have the constructor, also marked as public so that objects of this class type can be made by external code. The constructor's name must always match the class name, and there is no return type even though it looks like a method, because the object itself is returned. The class has two parameters, which are integers. We name them south and east, because that is what they will be used for: the body of the constructor assigns their values to the properties, and with that the Coordinate class is complete.
The next class will use this one, which should help things to make more sense. So, we'll be adding another class, the same way as the last time. This one will be named Dungeon.
We'll be taking a similar approach with this one, adding two properties and a constructor.
This time, however, we've added a set accessor to the Position property, with a private accessor. This accessor makes it so that only this class can set the value of the property, but ensures that it can be set. The Map property's type looks rather funny, because it is an array of arrays of strings, but that really is correct.
Next, we're going to move the canGo variables from Program.cs here:
By making these properties with only a get, we have made it so that they are used like a variable, but in actuallity are calculated on getting the value.
The last things we'll be adding to this class are some new methods to make you move.
These methods move the current position, but only if it is valid to do so. Now, I missed something before - the constructor parameter and property for the map need to be specifically defined as allowing null, which can be done by adding a question mark to their type specifiers.
Now, back to Program.cs! First, we'll change our position variable into a Coordinate:
This probably will have an error underline until you add this at the top of the file, which tells C# that you want to use classes from a certain namespace:
And then we'll create our dungeon, just before the loop.
Then, we can use our new dungeon variable in the main loop.
Now I think I want to move the DisplayDirections method to the Dungeon... But I think it needs some changes. Let's go back to Dungeon.cs and work on that.
At the end of the file, we're adding a new method that returns a string. Currently there is an error, because no string is being returned even though we said one has to be. To calm it down, let's create and return a value:
Next, we'll start adding the code from the DisplayDirections method here, with some changes:
We've changed the canGo variables to use the properties defined above, but we've also removed all of the Console.Write calls. We're using some kind of += thing. What this does is adds the following value to the result, and then reassigns result. We're building up the result string, so that we can return it all at once. Let's add the rest.
We'll need one more quick method here:
Now, we'll go back to Program.cs and use our new methods.
Look how much simpler this has gotten! Your main program is now very clear. Like the last lesson, this one hasn't changed what the code does. If you run it now, you should see no changes in behavior, but now your code has a bit more structure: The dungeon data and interacting with it are seperate from the logic of the game, where you take inputs and return outputs. One could argue that moving DisplayDirections into there is going too far, since building a message specifically for the console output may be considered game logic, rather than the concern of the more narrowly-focused Dungeon class. Many design choices like this will come your way on any program, so think about it carefully!