将对象项添加到数组会产生错误的结果

时间:2018-04-29 06:52:14

标签: c# visual-studio debugging

目前正在开发基础RPG系统,我遇到了一个方法错误。该方法旨在将(代码中的类)和可选金额添加到玩家库存(一个Item []数组)。

这是项目类的代码:

public class Item

{
    public string Name;
    public int quantity;
    public int maxstack;

    public int[] stats = new int[5];

    public Item(string name, int Amount = 1, int MaxStack = 10, int ATK = 0, 
    int DEF = 0, int MAT = 0, int MDF = 0, int SPD = 0)
    {
        Name = name;
        quantity = Amount;
        maxstack = MaxStack;
        stats[0] = ATK;
        stats[1] = DEF;
        stats[2] = MAT;
        stats[3] = MDF;
        stats[4] = SPD;
    }
}

关键变量是“数量”和“maxstack。”

现在,在向玩家广告资源添加项目时会出现问题,这些变量是关于这些变量的。 将库添加到库存时,该方法使用 Array.IndexOf();

搜索库存中的空槽和同一项的任何堆栈。

这是 AddItem()方法的代码:

public void AddItem(Item item, int Amount = 1)
{
    for (int i = Amount; i > 0; i--)
    {
        int ItemIndex = Array.IndexOf(inv, item); // Searches for a matching item
        int EmptySlot = Array.IndexOf(inv, null); // Searches for an empty slot

        ItemCheck:
        if (ItemIndex != -1) // ItemIndex will equal -1 if no matching item was found
        {
            if (inv[ItemIndex].quantity >= inv[ItemIndex].maxstack) // Is the quantity/stack of the found item equal to its maximum stackable value?
            {
                ItemIndex = Array.IndexOf(inv, item, ItemIndex + 1); // If yes, search for another index.
                goto ItemCheck;
            } else {
            inv[ItemIndex].quantity++; // If the stack hasn't reached its max, increase it by one.
            }
        }
        else
        {
            inv[EmptySlot] = item; // If no matching item was found, use an empty slot to create a new stack.
            inv[EmptySlot].quantity = 1;
        }
    }
}

现在,假设我创建一个名为“stick”的项目,它最多只能堆叠3.当运行 AddItem(stick,3)并列出每个堆栈的数量时,控制台返回

Stick x1
Stick x1

任何人都可以帮助我吗?为什么我的代码将堆栈重新调整为1?

修改

添加1,2或3根棍子会返回正确的数量,但只有在堆叠达到最大值时才添加更多的棍子会导致错误的结果。

修改

添加6支装可返回2个堆叠,每个堆叠3个。添加7支装可返回3个堆叠,每个堆叠1件。

2 个答案:

答案 0 :(得分:3)

这里最大的问题是您使用该项目存储数量......但该项目在您的广告资源中的多个位置使用。因此,当您将数量更改回1时,您将为清单中项目所在的每个位置更改它。

即,您没有该项目的副本,您多次拥有相同的对象。

你可以用很多方法解决这个问题,但也许你应该创建一个名为InventorySlot的新类并将数量放在那里。

public class InventorySlot
{
   public Item Item {get; set;}
   public int Quantity {get; set;}
}

现在你的玩家库存是一系列的InventorySlots ......就像这样 鉴于你的播放器中有这样的东西......

 public InventorySlot[] inv = new InventorySlot[5];

然后

public void AddItem(Item item, int amount = 1)
{
    var slot = inv.FirstOrDefault(s => s?.Item == item && s.Quantity < item.maxstack);
    if (slot != null)
    {
        slot.Quantity++;
    }
    else
    {
        slot = inv.FirstOrDefault(s => s == null);
        if (slot != null)
        {
            slot.Item = item;
            slot.Quantity = 1;
        }
    }
}

答案 1 :(得分:1)

我不明白你为什么要尝试将一个项目添加到一个数组中,因为这是一个列表!
您只需使用List<T>即可提供AddRemoveRemoveAtInsertIndexOf等方法。 如果那时你想得到一个数组,你可以打电话给yourList.ToArray()

  • Here是使用某些值初始化List<string>的示例。
  • Here是从List<T>删除项目的示例。

看看这个例子:

List<Item> yourList = new List<Item>(); //Create an empty list
/* Or
 * List<Item> youtList = new List<Item>()
 * {
 *     new Item(),
 *     new Item() //etc
 * }
 */
yourList.Add(new Item()); //Add an item 
yourList.Insert(0, new Item()); //Insert an item to the 0 index
yourList.Remove(yourItem); //Remove an item directly
yourList.RemoveAt(0); //Remove an item by its index in the list
Item[] yourArray = yourList.ToArray(); //Convert the list List<T> to an array T[]

查看List<T> docuentation有任何疑问。

如果由于任何特定原因需要使用数组,请告诉我,我将编辑此答案。