3

I'm trying to make a text-based dungeon explorer in C#, and I have the maze-part all working. I used some methods that refer to each other when you pick a direction you want to go in.

The "map" is divided in 13 rooms total. This is an example for when you leave the starting room .

Console.WriteLine("REMEMBER! You are always looking north when deciding which room you go in.");
Console.WriteLine("one room goes right in front of you, one goes behind you, another one goes to the right and the third one goes straight in front of you.");
Console.WriteLine("if you want to give up, type 'give up'");
Console.WriteLine("which way do you go?");
choice = Console.ReadLine().ToLower();

while (choice != "behind" && choice != "right" && choice != "in front" && choice != "give up")
{
    Console.WriteLine("you cant stay here, can you?");
    Console.WriteLine("Type: 'behind', 'right' of 'in front' to move in a specific direction.");
    choice = Console.ReadLine().ToLower();
}

switch (choice)
{
    case "in front":
        Console.Clear();
        room1();
        break;

    case "behind":
        Console.Clear();
        room11();
        break;

    case "right":
        Console.Clear();
        room7();
        break;
}

And this is the maze itself: maze Just a maze is fun, but I would like there to be an element of surprise. I was thinking of putting a monster in room 8, for example. The monster doesn't have to be there every game. At the beginning of the game, I would like to define a variable that decides if there is going to be a monster or not (I was planning on doing this with an array and a random number so it would be 50/50 chance). The problem is to keep the variable, so it doesn't change every time you move to a different room.

Does anyone know how I can define a variable (or maybe something else that I don't know? I'm somewhat new to programming in multiple methods) at the beginning of the game to determine if there is a monster or not? I have tried working with various classes, but I have never done this before, so I don't know how I can work in different classes in de same namespace.

I will also further use this to determine in what room the sword to slay the monster is in and in what room the key to the escape door is etc.

Simon
  • 33
  • 3
  • Hi, welcome to StackOverflow. Unless you have a very good reason not to (like a team who doesn't speak English), I would at least have the variable names in english, alongside some comments, for the texts (strings) which are important to the understanding. This will make it a lot easier for people to help (both now and in the future). – Jakob Busk Sørensen Jan 12 '20 at 20:30
  • Hi, welcome to the fantastic world of programming! just declare your variable outside your main and you good to go. – Carlo Capuano Jan 12 '20 at 20:31
  • @Noceo okay! thanks for pointing that out, I will edit it so that it may be better to understand. – Simon Jan 13 '20 at 21:02

2 Answers2

3

I am not quite sure I understand what you want to achieve, but a simple answer could be to have a Room class, which itself determines if it has a monster. This can be randomized in the objects constructor (the method which is called, when a new instance of the object is initialized).

As mentioned by Olivier though, you cannot have the actual random number generator in the class itself, so I have placed that in a utility class...

Something like this:

public static class Utility
{
    private static readonly Random random = new Random();

    // Returns true or false, with a user defined chance of 'True'
    // E.g. chanceForTrue = 30 means a 30% chance of 'True'
    public static bool GetRandomBool(int chanceForTrue)
    {
        return random.Next(101) < chanceForTrue;
    }
}

public class Room 
{
    // If true, there is a monster in the room
    private readonly bool hasMonster;

    // Constructor
    public Room()
    {
        // 50% chance of having a monster
        hasMonster = Utility.GetRandomBool(50);
    }
    // ...rest of the class
}

The method Random.Next(2) will return an integer less than 2 (so 0 or 1), meaning there is a 50/50 chance of the room containing a monster. You can adjust this to whatever you like.

You simple get a room by saying:

var room8 = new Room();

However, this is generally not a good way of storing multiple instances of the same object (class). You should look into storing them in a collection of some sort, maybe a dictionary:

var rooms = new Dictionary<int, Room>();
rooms.Add(8, new Room()); // Adds a room with key '8'

And the logic of which rooms are adjecant, could be stored in a map or in the Room class itself, by having a list of AdjecantRooms. But now we are kinda getting away from the orignal question, so I will stop myself :-).

Jakob Busk Sørensen
  • 5,599
  • 7
  • 44
  • 96
  • 3
    Since the `Random` is initialized from the PC clock, which ticks rather slowly, this will very likely generate the same random numbers in every room if they are created in a fast loop. Declare the Random as static field in the `Room` class, or even better, as a global public readonly static field or property, so the same random generator will be used through out the whole application. See: [Random number generator only generating one random number](https://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number). – Olivier Jacot-Descombes Jan 12 '20 at 22:05
  • 2
    @OlivierJacot-Descombes is absolutely right. I have changed my example to move the random number generation outside the class. The request for a random boolean still happens in the constructor though. Thanks for poiting this out. – Jakob Busk Sørensen Jan 13 '20 at 08:22
  • @Noceo thank you, this seems like a solution that will work. Will I have to put my program class (the class where the rest of the game is written) as a public static class or just a static class? I don't yet understant the whole public vs. static situation, even after looking at many tutorials online. – Simon Jan 13 '20 at 21:14
  • @Simon a class should (in most cases) have its own file, with the same name as the class (e.g. Utility.cs). Regarding the `public` vs. `static`: They are two different things. The `public` part means that the method (or class) can be accessed from any other class (even in different projects). This is as opposed to `private` which would make the method only available to other methods in the same class. The `static` part means that you cannot initialize the class (i.e. `new`), but rather call it directly. – Jakob Busk Sørensen Jan 14 '20 at 12:00
0

A solution would be to have code run through those variables and react accordingly (spawn the monster in the specified room, or not at all) before the game starts.

You could put these variables in your dungeon generator class either as is, or wrapped inside a struct for easy-reading. As your dungeon-generator class would persist throughout the whole game, you should have no problem with keeping the variable the same when moving through rooms.

If this solution is inappropriate or inaccurate for your situation, please provide more details in your current implementation so we can give more correct advice.

TozBoggle
  • 1
  • 2