添加新项目时列表重置(编辑标题以反映实际问题)

List resetting when adding new items (Edited title to reflect actual issue)

原标题:Get-Set 将 Object w/multiple 属性添加到列表 C#

编辑:我最初认为问题出在为列表 object 设置属性,但问题是我在主代码中初始化列表的位置 class.

原文Post:

编码新手,正在学习 C# 课程。我们正在进行封装并得到:set/properties.

作业说我们必须构建一个 class 来创建一个具有输入面数的骰子,然后“掷”出一个随机数的骰子。简单!

一秒钟后 class,我们必须构建一个函数来向池中添加或删除任意数量的骰子,然后将它们全部掷出以获得结果。

我假设他们希望骰子池是一个私有列表。

我的逻辑是创建单个 OneDie class,然后在主程序提示符中使用 xDy 符号将 x 个 y 面的骰子添加到列表中。 (即:加 2d6)

我已经构建了一个应该执行此操作的 AddDie 函数,但是当我在完成后检查我的列表计数时,计数为 0。私有列表 (_dicePool) 似乎 re-setting 每次都归零是时候我尝试向列表中添加一个新的 object 了。我怀疑我没有正确构建我的 属性 DicePool 的 get/set 功能,但我不确定如何从 DicePool{set} 内部调用我的 2 参数 AddDice 函数,或者即使那是我应该采取的方法。

假设列表应该是私有的,我是否遗漏了一些东西来将新的 object 永久添加到列表中?

编辑添加:或者,创建一个 ManyDice object 会更好吗?但是如何从 OneDie object 构建 this.Sides 和 this.Roll?

这是我的代码,适用于将 objects(骰子)添加到列表(dicepool)。

class ManyDice
{
    private List<OneDie> _dicePool = new List<OneDie>();

   //What I think I might have to do:
   public List<OneDie> DicePool
    {
        get 
        { 
            return this._dicePool; 
        }
        set 
        {
            //???????????? how do I call AddDice, when I need 2 parameters for it?
        }
        
    }


    public void AddDie(int number, int sides)
    {

        for (int i = 0; i < number; i++)
        {
            this.dicePool.Add(new OneDie(sides));

        }
    }
}
class OneDie
{
    private int _sides, _rolledValue;

    public int Sides
    {
        get
        {
            return this._sides;
        }
        set
        {
            this._sides = value;
        }
    }
    public int RollValue
    {
        get
        {
            return this._rolledValue;
        }
        set
        {
            this._rolledValue = value;
            RollIt(value);
        }
    }
    public OneDie()
    {

    }
    public OneDie(int sides)
    {
            this.Sides = sides;
            this.RollValue = sides;
    }

    private int RollIt (int sides)
    {
        Random random = new Random((int)DateTime.Now.Ticks);
        return random.Next(1, (sides + 1));
    }

}
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Let's roll some dice!");
        Console.WriteLine("Please enter the number of dice you want to roll in the following format:");
        Console.WriteLine("xdy, where \"x\" is the number of dice you want and \"y\" is how many sides they have.");
        Console.WriteLine("Example: 2d6 is 2 6-sided dice. Perfect for playing Catan! (or Monopoly)");
        Console.WriteLine("Please limit your dice to d4, d6, d8, d10, d12, d20");

        Console.WriteLine("To add a die, type \"add xdy\" to add x number of y sided dice.");
        Console.WriteLine("To remove a die, type \"remove xdy.\"  to remove x number of y sided dice.");
        Console.WriteLine("Type \"dice\" to see a list of all the dice in the pile.");
        Console.WriteLine("Type \"roll\" to roll all the dice and see the results!");
        Console.WriteLine("Type \"clear\" to clear all the dice and start agin!");
        Console.WriteLine("Type \"exit\" to exit program\n");
        PlayDice();
        Console.ReadKey();
    }


    static void PlayDice() 
    { 
        do 
        {
            string[] xDy = null;
            int numberOfDice = 1;
            int numberOfSides=1;
            Console.WriteLine("\nEnter your command:");
            string option = Console.ReadLine();
            option = option.ToLower().Trim();
            string[] words = option.Split(' ');
            string command = words[0];
            //CheckCommand(command);
            if (words.Length > 1)
            {
            xDy = words[1].Split('d');
            numberOfDice = int.Parse(xDy[0]);
            numberOfSides = int.Parse(xDy[1]);
            }
            ManyDice die = new ManyDice();

            if (command == "exit") 
            {
                Console.WriteLine("Thank you, play again, soon!");
                break;
            }
            else if (command == "add") 
            {
                //numberOfSides=CheckDice(numberOfSides);
                
                die.AddDie(numberOfDice, numberOfSides);
                Console.WriteLine("You have {0}ed {1} {2}-sided dice.", command, numberOfDice, numberOfSides);
            }
            else if (command == "remove")
            {
                Console.WriteLine("You have {0}d {1} {2}-sided dice.", command, numberOfDice, numberOfSides);
            }
            else if (command == "dice")
            {
                Console.WriteLine("These are your dice:");
                die.Display();
            }
            else if (command == "roll")
            {
                Console.WriteLine("Here is your roll:");
            }
            else if (command == "clear")
            {
                Console.WriteLine("All dice have been cleared.");
            }
        } while (true);            
    }
    static int CheckDice(int sides)
    {
        List<int> check = new List<int> {4,6,8,10,12,20};
        while (!check.Contains(sides))
        {
            Console.WriteLine("{0}-sided dice are not available.\nPlease enter 4,6,8,10,12 or 20");
            sides = int.Parse(Console.ReadLine());                   
        }
           return sides;            
    }
    static string CheckCommand(string instructions)
    {
        List<string> check = new List<string> { "add", "remove", "dice", "roll","clear", "exit" };
        while (!check.Contains(instructions))
        {
            Console.WriteLine("Command not recognized.\nPlease enter \"add\", \"remove\", \"dice\", \"roll\",\"clear\", or \"exit\"");
            instructions = Console.ReadLine();
        }
        return instructions;
    }

    
}

基于评论和更新问题的新答案:

ManyDice die = new ManyDice(); 正在擦除您程序中每个循环的骰子列表。它用 class 的新实例替换您的变量,用新列表和所有。

只需在循环开始前移动该行:

行前 do {

然后每次迭代都将使用相同的 ManyDice 实例,并且将共享变量 die,而不会覆盖它。

旧答案:据我所知,您的程序只运行一次。然后你需要再次启动它以放入另一个骰子。您的主要功能只要求输入一次。每当您再次启动程序时,程序中使用的所有内存都会被清除。除非我遗漏了什么,这就是为什么您的列表会继续重置的原因。下次您尝试添加骰子时,您实际上 运行 是一个全新的程序。所以它不知道之前的运行。

一种解决方案是说(伪代码)

While (running) {
     // what you have now

     if (option == “done”) running = false;

    if (option == “roll”) // roll all dice. 
}

这将一直提示用户输入命令,直到他们输入完成。它仍然是同一个程序,因此您不会丢失之前命令的数据。

根据评论更新:您在每次迭代中重新创建 ManyDice 实例,有效地从头开始。将实例保存在 while 循环之外,然后重新使用它。

提示:

您的滚动可能应该由 manyDice.RollAll() 完成并且也许应该 return 一个 RollResults 列表。