Beginner, making a Console based RPG in C# but having a problem

Viewed 120

Here's what I have so far: The player can type commands like North, East, South, West, And Help, and it works. My problem comes when I implement a Look command. I log the description from the current room, however it never changes. I belive, the problem may have to do with those mystical reference and value types, but I'm not experienced enough to be sure, or how to fix it. However, when I put Console.WriteLine(CurrentRoom.RoomDescription) under any currentRoom.SetCurrentRoom(rooms, player), it works just fine.

Main Class:

class Program
{
    static void Main(string[] args)
    {
        Room currentRoom;
        List<Room> rooms = new List<Room>();
        Player player = new Player();

        //Rooms
        Room startingRoom = new Room("Starting room", "This is the starting room", 0, 0);
        Room northRoom = new Room("North room", "This is the north room", 0, 1);
        Room eastRoom = new Room("East room", "This is the east room", 1, 0);
        Room southRoom = new Room("South room", "This is the south room", 0, -1);
        Room westRoom = new Room("West room", "This is the west room", -1, 0);

        //Add and set starting room as current room
        rooms.Add(startingRoom);
        currentRoom = startingRoom;

        //Adding rooms
        rooms.Add(northRoom);
        rooms.Add(eastRoom);
        rooms.Add(southRoom);
        rooms.Add(westRoom);

        Console.WriteLine("Welcome to the Dungeon. This is the starting room.");
        GetHelp();
        Console.WriteLine("There are four exits. Which way do you want to go?");
        while (true)
        {
            HandleInput(player, currentRoom, rooms);
        }



    }

    private static void GetHelp()
    {
        Console.WriteLine("You can move to locations by entering 'North', 'East', 'South', and 'West'.");
        Console.WriteLine("You can also examine the room by entering 'Look'.");
        Console.WriteLine("Type 'Help' at any time to view instructions.");
    }

    private static Room SetCurrentRoom(List<Room> rooms, Player player)
    {
        foreach (var room in rooms)
        {
            if (room.XPos == player.PlayerXPos && room.YPos == player.PlayerYPos)
            {
                return room;
            }

        }
        Console.WriteLine("Invalid direction.");

        return null;

    }

    private static void HandleInput(Player player, Room currentRoom, List<Room> rooms)
    {
        var input = Console.ReadLine();
        if (input == "North")
        {
            player.Move(Direction.Directions.North);
            currentRoom = SetCurrentRoom(rooms, player);


        }
        else if (input == "East")
        {
            player.Move(Direction.Directions.East);
            currentRoom = SetCurrentRoom(rooms, player);


        }
        else if (input == "South")
        {
            player.Move(Direction.Directions.South);
            currentRoom = SetCurrentRoom(rooms, player);


        }
        else if (input == "West")
        {
            player.Move(Direction.Directions.West);
            currentRoom = SetCurrentRoom(rooms, player);

        }
        else if (input == "Help")
        {
            GetHelp();
        }
        else if (input == "Look")
        {
            Console.WriteLine(currentRoom.RoomDescription);
        }
        else
        {
            Console.WriteLine("Invalid input.");
        }

    }
}

Room Class:

public class Room
{
    public string RoomName { get; set; }
    public string RoomDescription { get; set; }
    public int XPos { get; set; }
    public int YPos { get; set; }

    public Room(string roomName, string roomDescription, int xPos, int yPos)
    {
        this.RoomName = roomName;
        this.RoomDescription = roomDescription;
        this.XPos = xPos;
        this.YPos = yPos;

    }
}

Player Class:

public class Player
{
    public int Health { get; set; }
    public string Name { get; set; }
    public int PlayerXPos { get; set; }
    public int PlayerYPos { get; set; }

    public void Move(Direction.Directions direction)
    {
        switch (direction)
        {
            case Direction.Directions.North:
                PlayerYPos += 1;
                Console.WriteLine("Moving north");
                break;
            case Direction.Directions.East:
                PlayerXPos += 1;
                Console.WriteLine("Moving east.");
                break;
            case Direction.Directions.South:
                PlayerYPos -= 1;
                Console.WriteLine("Moving south.");
                break;
            case Direction.Directions.West:
                PlayerXPos -= 1;
                Console.WriteLine("Moving west.");
                break;

        }
    }


}

Direction Class:

public class Direction
{
    public enum Directions
    {
        North,
        East,
        South,
        West
    }
}

I am a beginner, so the code may be revolting to an experienced programmer.

1 Answers

I believe, the problem may have to do with those mystical reference and value types

You are very close. The problem is because the currentRoom is passed to the HandleInput method 'by value' instead of 'by reference', but you are trying to assign a different Room to it.

The signature of your HandleInput method is this:

private static void HandleInput(Player player, Room currentRoom, List<Room> rooms)

In the method you are trying to set currentRoomto another Room.

But by default when something is passed to a method it is passed 'by value', which means you can change properties on that variable, but you cannot change the actual variable it refers to - like in currentRoom = SetCurrentRoom(rooms, player); - unless you pass it 'by reference', like this:

private static void HandleInput(Player player, ref Room currentRoom, List<Room> rooms)

In which case you would then have to call it like this:

HandleInput(player, ref currentRoom, rooms);

What the ref keyword means is that the method you call can change the 'underlying object' that the value type currentRoom refers to.

Related