我有一个GameState
个对象。它包含玩家,玩家的手和牌中的牌,玩家资源的状态和位置等等。几乎所有东西都与至少一个其他东西相关 - 卡片知道它们在哪个手中,资源知道它们属于哪个玩家,等等。
我想创建一个系统,告诉玩家两个GameState
之间的区别。它将比较状态并回来“如果你做了这个动作,这些事情就会改变”。最简单的方法是复制GameState
并将操作应用于副本,然后将副本与原始副本进行比较。
我已经查看了浅层和深层复制的一些实现,但我可以快速预见一个对象属于两个不同对象的问题。一个例子是一些玩家代币;玩家有一个他们所有的所有代币的列表(例如,玩家可以评估他们都在哪里),并且代币所在的空间有一个包含在其上的所有代币的列表(例如,如果空间会受到可能影响其上所有令牌的影响)。如果我进行深度复制,则播放器和空间将引用同一令牌的两个不同副本;如果我做一个浅拷贝,那么一切都将指向原始GameState
中存在的对象。我不能选择一方总是浅薄而另一方总是很深,因为可能会从棋盘上移除令牌并且没有空间,或者令牌将与玩家分离并且稍后由另一个获取。甚至可能存在使用时针对玩家的牌,因此如果它是针对用户的,那将是循环参考。
基本上,我想做这三个图中的第一个,但我无法弄清楚如何避免第二和第三种情况。
我怀疑通常没有简单的方法可以做到这一点,但我想我也可以问。
我在Unity3D中使用C#,以防这很重要。
答案 0 :(得分:0)
作为克隆的捷径,您可能会从序列化中获得一些好处。我经常使用JSON.NET(NewtonSoft)来执行类似的操作,只要您的对象不是太复杂,您通常可以使用基本的“序列化然后反序列化”过程。顺便说一下,JSON.NET可以很好地处理循环引用等。
我认为您面临的更大挑战是向用户展示“将会发生什么”信息。
答案 1 :(得分:0)
几个月前,我为奥赛罗的国际象棋比赛写了一个简单的AI。我需要将每次移动的不同游戏状态传递给我的评估函数。我所做的只是“克隆”计算所需的基本数据,并将“克隆数据”传递给其他函数。在函数内部,我做的事情或多或少与您的建议相同,即模拟每个州的每次移动的结果。
我认为自己定义“克隆”策略是不可避免的。但是,您只能从原始GameState
实例中提取有用数据。当然,球员的名字并不重要,对吗?