2016-04-22 39 views
2

我正在進行一段文字冒險,當玩家輸入「拿起鐵劍」或其他任何東西時,我需要能夠將JSON陣列中的鐵劍拿出來放在保存的房間內。如何編輯C#中的json文件?

{ 
Rooms: [ 
    { 
     id: "PizzaShop1", 
     name: "Pizza Shop", 
     description: "in a nice warm pizza shop that smells of garlic.", 
     items: [ 
      { 
       id: "HawaiianPizza1", 
       name: "Hawaiian Pizza", 
       description: "a pizza topped with ham and pineapple", 
       strengthMod: 0, 
       toughnessMod: 0 
      }, 
      { 
       id: "MeatloversPizza1", 
       name: "Meatlovers Pizza", 
       description: "a pizza topped with lots of meat", 
       strengthMod: 0, 
       toughnessMod: 0 
      } 
     ], 
     entities: [ 
      { 
       name: "Pizza Chef", 
       description: "an italian man", 
       friendly: true 
      }, 
      { 
       name: "Mouse", 
       description: "a pesky mouse", 
       friendly: false 
      } 
     ], 
     northExit: "", 
     southExit: "Road1", 
     eastExit: "", 
     westExit: "" 
    },  
    { 
     id: "Road1", 
     name: "Road", 
     description: "on a town road", 
     items: [ 
      { 
       id: "IronSword1", 
       name: "Iron Sword", 
       description: "a battered but usable sword", 
       strengthMod: 2, 
       toughnessMod: 0 
      } 
     ], 
     entities: [], 
     northExit: "PizzaShop1", 
     southExit: "", 
     eastExit: "", 
     westExit: "" 
    } 
] 
} 

這裏是我的C#代碼:

   else if (s.Contains(" pick up ")) 
      { 
       String newJson = ""; 
       s = s.Replace(" the ", " "); 
       s = s.Replace(" pick ", " "); 
       s = s.Replace(" up ", " "); 
       String[] Words = s.Split(' '); 
       foreach (String word in Words) 
       { 
        if (word != Words[1]) 
        { 
         Words[1] = Words[1] + " " + word; 
         Words[1] = Words[1].Replace(" ", " "); 
         Words[1] = Words[1].Trim(); 
        } 
       } 
       using (StreamReader sr = new StreamReader("TAPResources/map.json")) 
       { 
        String json = sr.ReadToEnd(); 
        dynamic array = JsonConvert.DeserializeObject(json); 
        foreach (var rooms in array["Rooms"]) 
        { 
         foreach (var item in rooms["items"]) 
         { 
          String itm = (String)item["name"]; 
          PrintMessage("Words: " + Words[1]); 
          PrintMessage("Item Name: " + itm.ToLower()); 
          if (Words[1] == itm.ToLower()) 
          { 
           rooms["items"].Remove(item); 
          } 
         } 
        } 
        newJson = (String)JsonConvert.SerializeObject(array); 
       } 
       File.WriteAllText("TAPResources/map.json", newJson); 
      } 

行:

rooms["items"].Remove(item); 

給出了一個錯誤,因爲我不能編輯循環內的數組。通常我會通過將值添加到另一個數組來解決此問題,然後遍歷該數組以從初始數組中刪除,但我不知道如何爲該變量類型創建數組。

+0

的可能的複製[讀取並解析在C#JSON文件(http://stackoverflow.com/questions/13297563/read-and-parse-a-json-file-in-c-sharp) – Mostafiz

+0

不是重複的,我已經閱讀過它,它根本沒有幫助我。 – Towja

+0

你將不得不對'JsonConvert.SerializeObject(array);'的結果做一些事情,比如把它寫回你的json文件。 –

回答

0

確定,所以在這裏我們去,理想地,建議使用良好定義的對象(類)的情況下使用動態對象是較慢的處理,任何如何:

動態數組= GetRooms();

foreach (var rooms in array["Rooms"]) 
    { 
     List<object> list = new List<object>(); 
     foreach (var item in rooms["items"]) 
     { 
      string itm = (string) item["name"]; 
      if (!"hawaiian pizza".Equals(itm.ToLower())) 
      { 
       list.Add(item); 
      } 
     } 
     //u can use this 
     //from rooms in array["Rooms"] select rooms where (true something) 
     //or what I did case I'm lazy 
     //Newtonsoft.Json.Linq.JToken transfor or you can use linq to dow whatever 
     rooms["items"] = JsonConvert.DeserializeObject<JToken>(JsonConvert.SerializeObject(list.ToArray())); 
    } 
    Console.Write(JsonConvert.SerializeObject(array)); 
0

您可能想要添加代表遊戲,房間和物品的類,然後在遊戲進行時將它們保存在內存中。當他們保存遊戲時,您可以將其序列化回JSON。使用對象更容易,而不是嘗試循環遍歷整個文檔室和每個項目以找到一個項目並將其刪除。

public class Item 
{ 
    public string id { get; set; } 
    public string name { get; set; } 
    public string description { get; set; } 
    public int strengthMod { get; set; } 
    public int toughnessMod { get; set; } 
} 

public class Room 
{ 
    public string id { get; set; } 
    public string name { get; set; } 
    public string description { get; set; } 
    public List<Item> items { get; set; } 
    public List<object> entities { get; set; } 
    public string northExit { get; set; } 
    public string southExit { get; set; } 
    public string eastExit { get; set; } 
    public string westExit { get; set; } 
} 

public class Game 
{ 
    public List<Room> Rooms { get; set; } 
} 

然後你就可以反序列化JSON成一個遊戲對象是這樣的::

var game = JsonConvert.DeserializeObject<Game>(json); 

然後,如果你想刪除

我會根據您的JSON文件提出以下類來自「Road1」房間的劍比循環動態物體更簡潔:

//Find room by id and remove item by id 
game.Rooms.Single(room => room.id == "Road1") 
    .items.RemoveAll(item => item.id == "Iron Sword"); 

//Turn the game object back into a Json string 
var json = JsonConvert.SerializeObject(game); 

//now write json string back to storage... 

這給您在運行時帶來更大的靈活性。例如,在飛行中添加新房間變得非常簡單:

var room = new Room 
     { 
      id = "new room", 
      name = "very cool room", 
      description = "A very cool room that was added on the fly", 
      items = new List<Item> 
         { 
          new Item 
           { 
           id = "another sword", 
           description = "Another battered sword" 
           //etc... 
           } 
          } 
      //etc... 
     } 

game.Rooms.Add(room); 

希望這有助於您。

+0

謝謝堆,但我真的不明白什麼 'game.Rooms.Single(room => room.id ==「Road1」) .items.RemoveAll(item => item.id ==「Iron Sword」); '在做 – Towja

+0

這是一個Linq聲明。將遊戲視爲文檔。它有一個所有房間的清單,每個房間都有一個物品清單。第一部分:game.room.Single(房間=>房間。id =「Road1」)是說在遊戲中找到具有「Road1」id第二部分的單人房間.items.RemoveAll(item => item.id ==「Iron Sword」)是說找到物品在我們剛剛尋找的房間裏,用「鐵劍」的標識去掉它。 Linq是處理集合的強大語法。如果你用C#編寫代碼,你將會想要學習它。複製並粘貼代碼並與其一起玩。 – cnaegle

+0

謝謝堆!我對C#還很陌生。 – Towja