【问题标题】:Beginner, making a Console based RPG in C# but having a problem初学者,用 C# 制作基于控制台的 RPG 但遇到问题
【发布时间】:2020-05-21 00:13:18
【问题描述】:

到目前为止,这是我所拥有的:玩家可以键入诸如 North、East、South、West 和 Help 之类的命令,并且可以正常工作。当我实现 Look 命令时,我的问题就来了。我记录了当前房间的描述,但它永远不会改变。我相信,问题可能与那些神秘的引用和值类型有关,但我没有足够的经验来确定,或者如何解决它。 但是,当我将 Console.WriteLine(CurrentRoom.RoomDescription) 放在任何 currentRoom.SetCurrentRoom(rooms, player) 下时,它工作得很好。

主类:

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.");
        }

    }
}

房间等级:

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;

    }
}

玩家等级:

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;

        }
    }


}

方向类:

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

我是初学者,所以代码可能会让有经验的程序员感到反感。

【问题讨论】:

  • @stuartd 我很高兴我的代码没问题。然后我猜我的问题变成了“我该如何调试?”。在我参加的 C# 在线课程中,我有一些简短的调试经验,但它从未真正设置过。我设置了一个断点,但是控件和监视项是灰色的。
  • 值得花时间尝试设置断点和单步执行代码 - 它并不能真正帮助您理解这里发生的事情,但这是一项非常宝贵的技能。

标签: c# console-application


【解决方案1】:

我相信,问题可能与那些神秘的引用和值类型有关

你很亲密。问题是因为currentRoom 是“按值”而不是“按引用”传递给HandleInput 方法的,但您试图为其分配不同的Room

HandleInput 方法的签名是这样的:

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

在您尝试将currentRoom设置为另一个Room的方法中。

但默认情况下,当某些东西被传递给一个方法时,它是“按值”传递的,这意味着您可以更改该变量的属性,但您不能更改它所引用的 actual 变量 - 比如在currentRoom = SetCurrentRoom(rooms, player); - 除非你'通过引用'传递它,像这样:

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

在这种情况下,您必须这样称呼它:

HandleInput(player, ref currentRoom, rooms);

ref关键字的意思是,你调用的方法可以改变值类型currentRoom所指的“底层对象”。

【讨论】:

  • 非常感谢。我知道这与调用的基值有关,但我不知道为什么它没有改变。很高兴知道如何解决这个问题,现在 Value 和 Reference 类型不那么令人生畏了。
  • 命名没有帮助 - “引用和值类型是按值传递的,除非你说它们应该通过引用传递”..
猜你喜欢
  • 1970-01-01
  • 2021-05-13
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多