debugging 将对象项添加到数组中,结果错误

2nc8po8w  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(147)

我目前在一个基本的RPG系统上工作,我遇到了一个方法的错误。这个方法的目的是添加一个item(代码中的类)和一个可选的数量到玩家的库存(一个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;
    }
}

关键变量是“数量”和“最大堆栈”。
现在,问题来了,当添加一个物品到玩家的物品栏,关于这些变量。该方法,当添加一个物品到物品栏时,搜索在物品栏中的一个空的位置和任何堆栈的相同物品使用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个项目。

wh6knrhe

wh6knrhe1#

这里最大的问题是您使用料号来储存数量...但是料号在库存中的多个地方使用。因此,当您将数量变更回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;
        }
    }
}
jvidinwx

jvidinwx2#

我不明白为什么需要向数组中添加项,因为标准库已经提供了List<T>,它定义了AddRemoveRemoveAtInsertIndexOf等方法。
示例:

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 by reference
yourList.RemoveAt(0); // Remove an item by its position in the list
Item[] yourArray = yourList.ToArray(); // Create an array with the elements in the list

请参阅docs

相关问题