2014-07-19 32 views
0

我有一個GameState對象。它包含諸如玩家,玩家手中和牌中的牌,玩家資源的狀態和位置等等。幾乎所有東西都至少與另一件事有關 - 卡片知道他們在哪手牌,資源知道他們屬於哪個球員,等等。如何正確複製一組對象而無需參考原件或複製多次引用的對象?

我想創建一個系統告訴玩家兩個GameState s之間的區別。它會比較各州並回來「如果你做了這個動作,這些事情就會改變」。最簡單的做法似乎是複製GameState並將動作應用於副本,然後將副本與原始副本進行比較。

我已經環顧了一些淺層和深層複製的實現,但我可以快速預見一個對象屬於兩個不同對象的問題。一個例子是一些玩家令牌;玩家有一個所有令牌的列表(例如,玩家可以盤點他們所在的位置),而令牌所在的空間上有所有令牌的列表(例如,如果空間受到影響所有令牌的東西的影響)。如果我進行深層複製,則玩家和空間將指同一令牌的兩個不同副本;如果我做一個淺拷貝,那麼所有的東西都會指向原始的GameState中存在的對象。我不能選擇一邊總是淺的,另一邊總是很深,因爲也許令牌將被從板上移開並且沒有空間,或者令牌將與玩家分離並且隨後被另一個拾起。在使用時甚至可能會有卡片針對玩家,所以如果它瞄準用戶,那將是一個循環引用。

基本上,我想做這三個圖中的第一個,但我無法弄清楚如何避免第二和第三種情況。

drawing of what I'd like to achieve compared to what I know how to do

我懷疑有沒有簡單的方法一般要做到這一點,但我想我還不如問。

我在Unity3D中使用C#,萬一這很重要。

+0

好像你必須自己定義克隆邏輯。另一個想法是創建兩個方法來讀取和寫入一個GameState對象到一個Stream。然後你可以編寫如下代碼:MemoryStream ms = ...;寫入(GateState,ms); GameState clone = Read(ms);如果你打算將GameState保存到磁盤,這些也會有用。 – Loathing

回答

0

作爲克隆的捷徑,您可能會從序列化中獲得一些里程碑。我經常使用JSON.NET(NewtonSoft)來執行類似的操作,只要你的對象不是太複雜,你通常可以通過基本的「序列化然後反序列化」過程來獲得。順便說一句,JSON.NET很好地處理循環引用等。

我認爲你的更大挑戰是要向用戶展示「將要發生的事情」信息。

0

幾個月前,我爲奧賽羅國際象棋遊戲寫了一個簡單的AI。我需要爲每次移動都通過不同的遊戲狀態來評估我的評估功能。我所做的只是「克隆」計算所需的基本數據,並將「克隆數據」傳遞給其他功能。在函數內部,我做了或多或少與您所建議的相同的事情,即模擬每種狀態下每次移動的結果。

我認爲自己定義一個「克隆」策略是不可避免的。但是,您只能從原始的GameState實例中提取有用的數據。球員的名字當然無所謂,對吧?