2015-09-29 69 views
-2

我目前在C#中創建了一個非常基本的遊戲,並且我創建了一個使用非常簡單的命令(Items.Add(id,amount))創建的庫存系統,您可以將項目添加到所述庫存。我想要做的,我目前的系統不能做的是能夠有效地「搜索」我的庫存數組,這是一個持有物品ID和物品數量的二維數組。我目前的系統是這樣的:重複搜索Integer數組

public static void add(int id, int amount) 
{ 
    for (int i = 0; i < Ship_Builder.Player.invCount; i++) 
    { 
     if (Ship_Builder.Player.inv[i, 0] == 0) 
     { 
      Ship_Builder.Player.inv[i, 0] = id; 
      Ship_Builder.Player.inv[i, 1] = amount; 
     } 
    } 

    Ship_Builder.Player.invCount++; 
} 

我希望它(在別的if)能夠搜索數組。我確實有這個:

else if (Ship_Builder.Player.inv[i, 0] == Ship_Builder.Player.inv[i + 1, 0]) 
{ 
    //Do 
} 

之前,但它沒有工作,我想它。 任何幫助將不勝感激,謝謝, 勞倫斯。

+10

爲什麼要使用數組,爲什麼不使用字典? –

+0

我在搜索這個問題的答案之前並沒有探索過Dictionary,我真的不想重新寫出我的所有子系統(依賴於庫存)是如何工作的...... –

+1

我不想重新編寫我的子系統真的瞭解你的「搜索」功能。你能否提供一些示例輸入/輸出? – BradleyDotNET

回答

0

由於意見建議,你應該使用Dictionary這樣的任務。但是如果你不得不使用一個二維數組,這是(我假設)在我們添加任何項目之前預先填充零,然後像你提出的if-else聲明不會做的伎倆。你需要做的是遍歷整個數組,首先尋找匹配的id,並且每次你的id s不匹配,你必須檢查你當前檢查的id是否等於0.如果是,那麼你已經遍歷了所有「插槽」,其中有一些項目沒有找到匹配,這意味着這個項目必須進入另一個空的插槽。

public static void add(int id, int amount) 
{ 
    for (int i = 0; i < Ship_Builder.Player.invCount; i++) 
    { 
     if (Ship_Builder.Player.inv[i, 0] != id) 
     { 
      if (Ship_Builder.Player.inv[i, 0] == 0) 
      { 
       Ship_Builder.Player.inv[i, 0] = id; 
       Ship_Builder.Player.inv[i, 1] = amount; 
       Ship_Builder.Player.invCount++; 

       continue; 
      } 
     } 
     else 
     { 
      Ship_Builder.Player.inv[i, 1] += amount; 

      continue; 
     } 
    } 
} 

警告!我的答案假設您在空槽中找到具有最小可能索引的新項目。此外,如果您要移除項目並將id設置爲零,那麼在您分配新項目之前,您必須首先遍歷整個數組以搜索匹配的索引。如果陣列很大,這可能在時間上非常昂貴。

+0

非常感謝您的答案,它返回了一個超出範圍的異常,但我現在正在工作 - 該數組已最大長度爲50,所以它應該沒問題。 –

0

有很多這裏發生了(並沒有足夠的細節來給除廣招任何答覆),但我怎麼會接近這樣的事情是開始使用對象面向設計,而不是依賴在數組中的索引位置。我定義是這樣的:

public class InventoryItem 
{ 
    public int Id { get; set; } 
    public int Amount { get; set; } 
    // Now I can add other useful properties here too 
    // ...like Name perhaps? 
} 

現在我會想辦法讓我的庫存Dictionary<int,InventoryItem>並添加東西,我的庫存可能是這個樣子:

public void Add(int id, int amount) 
{ 
    // assuming myInventory is our inventory 
    if (myInventory.ContainsKey(id)) { 
     myInventory[id].Amount += amount; 
    } 
    else { 
     myInventory[id] = new InventoryItem() 
     { 
      Id = id, 
      Amount = amount 
     }; 
    } 
} 

現在不是必要那你實際上使用了InventoryItem這個類,你可以堅持使用Dictonary<int,int>,但是你可能會發現,當你通過它的時候,你寧願有一些對象可以使用。然後可能有

你可以的所有對象的主字典,只是將它們添加到您的庫存,所以你最終的東西,如:

public void Add(InventoryItem item, int amount) 
{ 
    // assuming myInventory is our inventory 
    if (myInventory.ContainsKey(item.Id)) { 
     myInventory[item.Id].Amount += amount; 
    } 
    else { 
     myInventory[item.Id] = new InventoryItem(item) // assuming you added a 
                 // copy constructor, for example 
     { 
      Amount = amount 
     }; 
    } 
} 
+0

謝謝你的驚人答案,我可能會在以後使用字典,但現在我會堅持我目前的系統。 –

+0

我只會改變一個Enum的ID。會使代碼讀/寫更簡單,以說'myInventory [Inventory.Gold]'等。 –

0

根據速度性能要求(使用數組應該只比這略快),您可以跳過硬編碼值和數組。這有幾個半高級主題:

public abstract class InventoryItem 
// or interface 
{ 
    public abstract string Name { get; } 
    public int Count { get; set; } 
} 

public class InventoryGold : InventoryItem 
{ 
    public string Name { get { return "Gold" } } 
} 

public abstract class InventoryWeapon : InventoryItem { } 

public class OgreSlayingKnife : InventoryWeapon 
{ 
    public string Name { get { return "Ogre Slaying Knife"; } } 
    public int VersusOgres { get { return +9; } } 
} 

public UpdateCount<Item>(this ICollection<Item> instance, 
    int absoluteCount) 
{ 
    var item = instance.OfType<Item>().FirstOrDefault(); 

    if (item == null && absoluteCount > 0) 
    { 
    item = default(Item); 
    item.Count = absoluteCount; 
    instance.add(item); 
    } 
    else 
    { 
    if (absoluteCount > 0) 
     item.Count = absoluteCount; 
    else 
     instance.Remove(item); 
    } 
} 

// Probably should be a Hashset 
var inventory = new List<InventoryItem>(); 

inventory.UpdateCount<InventoryGold>(10); 

inventory.UpdateCount<OgreSlayingKnife(1)