初学者制作控制台应用程序生存游戏,不确定如何在正方形网格上生成房间位置

问题描述 投票:-2回答:1

我将回顾到目前为止的内容,然后解释问题。

我有一个称为Room的类,每个房间都有XPos和YPos,以及多个其他不相关的参数。到目前为止,我已经在main方法中分配了这些值,并手动创建了具有指定值的新Room。这变得不切实际和无聊,所以我决定尝试随机生成房间。

我首先制作了一个称为GenerateRooms的方法,其返回类型为List。这被分配给在运行时与之通信的房间列表。GenerateRooms:

private static List<Room> GenerateRooms(int gridSize)
    {
        RandomRoomGenerator randomRoomGenerator = new RandomRoomGenerator();
        int numRooms = gridSize * gridSize;
        List<Room> rooms = new List<Room>();

        for (int i = 0; i < numRooms; i++)
        {
            rooms.Add(randomRoomGenerator.GenerateRoom(gridSize, rooms));
        }

        return rooms;
    }

如您所见,它也接受一个名为gridSize的参数。这是世界的长度/宽度。稍后在尝试生成房间位置时会使用它。在GenerateRoom内部,我将值分配给房间构造函数。对于房间的描述或物品之类的东西,我在随机分配方面没有太多问题,但是位置给我带来了很多麻烦。

GenerateRoom:

public class RandomRoomGenerator
{
    public Room GenerateRoom(int gridSize, List<Room> rooms)
    {
        RandomRoomDescriptions randomRoomDescriptions = new RandomRoomDescriptions();
        RandomItemGenerator randomItemGenerator = new RandomItemGenerator();
        ItemDB itemDb = new ItemDB();

        string description = randomRoomDescriptions.roomDescriptions[new Random().Next(0, randomRoomDescriptions.roomDescriptions.Count)];

        Room room = new Room(description, GenerateXPos(rooms, gridSize), GenerateYPos(rooms, gridSize), new Random().Next(1, 7), new Random().Next(1, 7), new Random().Next(1, 7), randomItemGenerator.GenerateRandomItems(itemDb));
        return room;
    }

    private int GenerateXPos(List<Room> rooms, int gridSize)
    {
        int xPos = 0;

        foreach (var room in rooms)
        {
            if (room.XPos == xPos)
            {
                xPos++;
                if (xPos == gridSize)
                {
                    return xPos;
                }
            } 
        }


        return xPos;

    }

    private int GenerateYPos(List<Room> rooms, int gridSize)
    {
        int yPos = 0;

        foreach (var room in rooms)
        {
            if (room.XPos == gridSize && room.YPos == yPos)
            {
                yPos++; 
                return yPos;
            }
        }

        return yPos;

    }

使用您可以在此处看到的代码,我可以创建一个水平线的房间,三个房间长,以及六个(3,1)处的堆叠房间。

问题:我需要这样做,以便GenerateXPos仅在当前行的房间中进行迭代。我尝试过在GenerateRoom类中创建一个名为YPos的变量,并在XPos达到GridSize时对其进行递增,但这是行不通的。

我认为另一种解决方案可能是一起消除Room构造函数中对X和Y pos的需求,并在main方法中分配位置。但这只是最后的手段。我想增加我的经验并消除神秘感,以便更好地学习。如果我没有提供足够的信息,请告诉我。以下是一些相关的类,以防万一:主要:

static void Main(string[] args)
    {
        Console.WriteLine("Welcome to the wasteland.");
        List<Room> rooms = GenerateRooms(3);
        var currentRoom = rooms[0];



        Player player = new Player(100, 10, 10, 10, 0,0);
        player.Inventory.Add(player.CurrentWeapon = new Weapon("Fists", "Regular fists.", 1));

        GameState.GameStates currentGameState = GameState.GameStates.Exploring;


        while (player.Health > 0 && player.Hunger < 50 && player.Thirst < 50 && player.Radiation < 50)
        {
            while (currentGameState == GameState.GameStates.Exploring)
            {
                Input.HandleExplorationInput(player, ref currentRoom, rooms, ref currentGameState);

            }

            while (currentGameState == GameState.GameStates.Fighting)
            {
                Input.HandleEncounterInput(player, currentRoom.Enemy, player.CurrentWeapon, ref currentGameState, currentRoom);
            }
        }

        Console.WriteLine("You died!");

    }

房间:

public class Room
{
    public string Description { get; set; }
    public int XPos { get; set; }
    public int YPos { get; set; }
    public int HungerToAdd { get; set; }
    public int ThirstToAdd { get; set; }
    public int RadiationToAdd { get; set; }
    public List<Item> Items { get; set; }
    public Enemy Enemy { get; set; }


    //Description, coord, and stats.
    public Room(string description, int xPos, int yPos, int hungerToAdd, int thirstToAdd, int radiationToAdd)
    {
        this.Description = description;
        this.XPos = xPos;
        this.YPos = yPos;
        this.HungerToAdd = hungerToAdd;
        this.ThirstToAdd = thirstToAdd;
        this.RadiationToAdd = radiationToAdd;
    }

    //Description, coord, stats, and items.
    public Room(string description, int xPos, int yPos, int hungerToAdd, int thirstToAdd, int radiationToAdd, List<Item> items)
    {
        this.Description = description;
        this.XPos = xPos;
        this.YPos = yPos;
        this.Items = items;
        this.HungerToAdd = hungerToAdd;
        this.ThirstToAdd = thirstToAdd;
        this.RadiationToAdd = radiationToAdd;
    }

    //Description, coord, stats, items, and enemy.
    public Room(string description, int xPos, int yPos, int hungerToAdd, int thirstToAdd, int radiationToAdd, List<Item> items, Enemy enemy)
    {
        this.Description = description;
        this.XPos = xPos;
        this.YPos = yPos;
        this.Items = items;
        this.Enemy = enemy;
        this.HungerToAdd = hungerToAdd;
        this.ThirstToAdd = thirstToAdd;
        this.RadiationToAdd = radiationToAdd;

    }

    //Description, coord, stats, and enemy.
    public Room(string description, int xPos, int yPos, int hungerToAdd, int thirstToAdd, int radiationToAdd, Enemy enemy)
    {
        this.Description = description;
        this.XPos = xPos;
        this.YPos = yPos;
        this.Enemy = enemy;
        this.HungerToAdd = hungerToAdd;
        this.ThirstToAdd = thirstToAdd;
        this.RadiationToAdd = radiationToAdd;

    }
}
c# console-application adventure
1个回答
0
投票

似乎您是一种在其中具有多个属性的房间(包含宽度和高度= gridSize的单元格)创建网格的方法。其中之一是房间说明。此房间描述应从您拥有的列表(某处)中随机选择。为此,您真正需要做的就是创建一个随机整数列表(在这种情况下为HashSet-请参见下面的原因),其中HashSet中的最大值最多应为“ randomRoomDescriptions“列表(或数组?)。

因此,您的代码可以大大简化。

Room类可能看起来像:

public class Room
{
    public string Description { get; set; }
    public int XPos { get; set; }
    public int YPos { get; set; }
    public int HungerToAdd { get; set; }
    public int ThirstToAdd { get; set; }
    public int RadiationToAdd { get; set; }
    public List<int> Items { get; set; }
    public string Enemy { get; set; }

    //Description, coord, and stats.
    public Room(string description, int xPos, int yPos)
    {
        CreateDescriptionList();
        Random rand = new Random();

        this.Description = description;
        this.XPos = xPos;
        this.YPos = yPos;
        this.HungerToAdd = rand.Next(1, 7);
        this.ThirstToAdd = rand.Next(1, 7);
        this.RadiationToAdd = rand.Next(1, 7);
        //this.Items = do something here!
        //this.Enemy = "Fred"; //Do something here, too!
    }
}

现在只需填充Room列表“房间”:

        var maxGrid = 3;
        var rooms = CreateRandomRooms(maxGrid);

使用以下方法:

    private List<Room> CreateRandomRooms(int grid)
    {
        RandomRoomDescriptions randomRoomDescriptions = new RandomRoomDescriptions();
        var listRooms = new List<Room>();
        var rand = GetRandomRoomIndicies(grid, Room.maxDecriptionEntries);

        int index = 0;
        for (int x = 0; x < grid; x++)
        {
            for (int y = 0; y < grid; y++)
            {
                var descr = randomRoomDescriptions.roomDescriptions[index];
                var room = new Room(descr, x, y);
                listRooms.Add(room);
                index++;
            }
        }

        return listRooms;
    }



    private HashSet<int> GetRandomRoomIndicies(int grid, int maxRand)
    {
        int minRand = 0;
        int maxCount = grid * grid;
        var rand = new Random();

        var randHashset = new HashSet<int>();

        while (randHashset.Count < maxCount)
        {
            randHashset.Add(rand.Next(minRand, maxRand));
        }

        return randHashset;
    }

关键基本上是方法“ GetRandomRoomIndicies”。它创建一个随机整数值的HashSet(最大值=描述列表中的最大描述数)。此HashSet将用于从您的列表中获得随机描述,并使用它来描述Room。创建Room时,将使用一个随机数生成器来填充“饥饿”,“口渴”和“辐射”之类的内容。您将需要对“物品”和“敌人”做些事情。

关于HashSet的好处是,它仅允许添加唯一值。因此,您只需保持“正在添加”,直到集合达到所需大小为止。

© www.soinside.com 2019 - 2024. All rights reserved.