【问题标题】:Adding object item to array giving wrong results将对象项添加到数组会给出错误的结果
【发布时间】:2018-04-29 06:52:13
【问题描述】:

目前正在开发一个基本的 RPG 系统,但我遇到了一个方法错误。该方法旨在添加一个 item(代码中的类)和一个可选数量到玩家库存(一个 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 个物品。

【问题讨论】:

  • 那么,什么是inv?
  • 我会大胆猜测并说它可能不起作用,因为Array.IndexOf 在数组中找不到与您传递给函数的任何Item 对象的值相等的项.
  • 盯着goto ......你知道SO人们希望我们对新人很好......但有时我觉得这很有挑战性:)
  • @KeithNicholas 对于goto 导致不良代码流的原因,最好提供一个建设性的信息性理由;我们知道,但不是每个人都知道。
  • 哦,我知道....我知道问题所在。

标签: c# visual-studio debugging


【解决方案1】:

这里最大的问题是您使用该物品来存储数量......但是该物品在您的库存中的多个位置使用。因此,当您将数量改回 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;
        }
    }
}

【讨论】:

  • 完全没有考虑数量会如何改变全局项目的价值。谢谢!
  • 现在函数似乎在这行抛出错误: var slot = inv.FirstOrDefault(s => s.Item == item && s.Quantity
  • 哦,是的.....我会调整的,现在有一个?在 s 之后标记,这意味着如果 s 为 null,它不会尝试获取 Item,它只会评估为 null
【解决方案2】:

我不明白您为什么要尝试将项目添加到数组中,因为它是一个列表!
你可以简单地使用List&lt;T&gt;,它提供了AddRemoveRemoveAtInsertIndexOf等方法。
如果你想得到一个数组,你可以打电话给yourList.ToArray()

  • Here 是使用一些值初始化 List&lt;string&gt; 的示例。
  • Here 是从 List&lt;T&gt; 中删除项目的示例。

看这个例子:

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&lt;T&gt; docuentation

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

【讨论】:

    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多