不可变的游戏对象,基本的函数式编程问题 [英] Immutable game object, basic functional programming question

查看:95
本文介绍了不可变的游戏对象,基本的函数式编程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力学习更多,从功能编程中吸取教训,以及不变性对于并发性的好处等等。



<作为一种思维练习,我想象一个简单的游戏,在这种游戏中,马里奥esq类型的角色可以跑向敌人并向他射击......

然后我尝试着想象这是使用不可变对象在功能上编写的。



这提出了一些让我困惑的问题(作为一个命令式OO程序员)。
$ b $如果我的小家伙在位置x10,y100向右移动1个单位,我是否使用他的旧值重新实例化了他的x值(例如x11,y100)+1? b
$ b 2)(如果我的第一个假设是正确的)
如果我的输入线程移动小个子右边1个单位,我的敌人AI线程射击小家伙和敌人-Ai线程解决之前输入线程然后我的家伙将失去健康,然后在输入线程解决,获得回来,并向右移动...



这是否意味着我无法解雇我的线程?
当我得到两个线程操作的结果时,我是否需要发送线程来完成它们的工作,然后同步地将新线程同步()还是有一个简单的功能解决方案?

这是一个稍微不同的线程问题,而不是我每天都面对的问题。
通常我必须决定是否关心线程解决的顺序。在上述情况下,我在技术上不在乎他是否受到伤害或先行动。但是我确实在乎实例化过程中的竞争条件是否会导致一个线程数据完全丢失。

3)(如果我的第一个假设是正确的话,请再次实例化)一个对象(例如马里奥家伙)有一个可怕的开销,这使得它成为一个非常严肃的/重要的设计决策?



编辑
对于这种额外的编辑,抱歉,我不是这里关于后续问题的良好做法...... 4)如果不变性是我应该努力争取的,甚至跳过实例化已经改变的新对象的新版本......并且如果我每次都实例化我的人他的动作(只有一个不同的位置),如果他是可变的,我不会有完全相同的问题吗?尽可能多地引用他在某个时间点上的东西实际上是在看旧的价值观?我越深入地了解这一点,我的头脑就越兴奋,因为生成具有不同值的同一事物的新版本就像是可变性,通过黑客攻击。 :¬?



我想我的问题是:应如何这项工作? (更新)//简化游戏循环更新或嘀嗒声,以及如何才能改变他的位置?

 方法
{
if(Keyboard.IsDown(Key.Right)
guy = new Guy(guy){location = new Point(guy.Location.x +1,guy.Location.y )};
}

令人困惑的是:上面的代码意味着这个人是可变的! (即使他的财产不是)



4.5)这完全可能与一个完全不可改变的人吗?

谢谢,



J。

解决方案


1)如果我的小家伙在位置
x10,y100右移1个单位,我只需
使用旧的
值重新实例化他,并将+1位置给他的x位置
(例如x11,y100)?

好吧,不一定。你可以实例化一次这个家伙,并在比赛中改变自己的位置。您可以 用代理模拟这一点。这个人是一个代理人,AI也是这样,渲染线程也是这样,用户也是这样。



当AI向这个人发送消息时,当用户按下箭头键发送另一个消息等。

 让guyAgent(家伙,职位,健康)= 
let message = receiveMessages()
let(newPosition,newHealth)= process(messages)
sendMessage(renderer,(guy,newPosition,newHealth))
guyAgent(guy,newPosition, newHealth)

Everything现在是不可变的(实际上,代理的dipatch队列确实有一些4)如果不变性是我b $ b应该争取的,甚至是跳过
环的东西实例化已变更的
对象的新版本...并且如果我
每次移动
(仅限于不同位置)时实例化我的人,请不要
我有完全一样的问题a如果他是可变的,那么我就是


好的。使用可变值进行循环,并使用不可变循环进行循环是等同的。



编辑:


  1. 对于代理商, wiki 总是有帮助的。

  2. Luca Bolognese有一个 F#执行代理。 本书(虽然以人工智能应用程序为目标(而不是从软件工程角度来看)非常出色。


I'm in the process of trying to 'learn more of' and 'learn lessons from' functional programming and the idea of immutability being good for concurrency, etc.

As a thought exercise I imagined a simple game where Mario-esq type character can run and jump around with enemies that shoot at him...

Then I tried to imagine this being written functionally using immutable objects.

This raised some questions that puzzled me (being an Imperative OO programmer).

1) If my little guy at position x10,y100 moves right 1 unit do I just re-instantiate him using his old values with a +1 to his x position (e.g x11,y100)?

2) (If my first assumption is correct) If my input thread moves little guy right 1 unit and my enemy AI thread shoots little guy and enemy-ai-thread resolves before input-thread then my guy will loose health, then upon input thread resolving, gain it back and move right ...

Does this mean I can't fire-&-forget my threads even with immutability? Do I need to send my threads off to do their thing then new()up little guy synchronously when I have the results of both threaded operations? or is there a simple 'functional' solution?

This is a slightly different threading problem than I face on a day to day basis. Usually I have to decide if I care about what order threads resolve in or not. Where as in the above case I technically don't care if he takes damage or moves first. But I do care if race conditions during instantiation cause one threads data to be totally lost.

3) (Again if my first assumption is correct) Does constantly instantiating new instances of an object (e.g Mario guy) have a horrible overhead that makes it a very serious/important design decision ?

EDIT Sorry for this additional edit, I wasn't what good practice is on here about follow up questions...

4) If immutability is something I should strive for and even jump though hoops of instantiating new versions of objects that have changed...And If I instantiate my guy every time he moves (only with a different position) don't I have exactly the same problems as I would if he was mutable? in as much that something that referenced him at one point in time is actually looking at old values?.. The more I dig into this the more my head's spinning as generating new versions of the same thing with differing values just seems like mutability, via hack. :¬?

I guess my question is: How should this work? and how is it beneficial over just mutating his position?

for(ever)//simplified game-loop update or "tick" method
{
   if(Keyboard.IsDown(Key.Right)
      guy = new Guy(guy){location = new Point(guy.Location.x +1, guy.Location.y)};
}

Also confusing is: The above code means that guy is mutable!(even if his properties are not)

4.5) Is that at all possible with a totally immutable guy?

Thanks,

J.

解决方案

1) If my little guy at position x10,y100 moves right 1 unit do I just re-instantiate him using his old values with a +1 to his x position (e.g x11,y100)?

Well, not necessarily. You could instantiate the guy once, and change its position during play. You may model this with agents. The guy is an agent, so is the AI, so is the render thread, so is the user.

When the AI shoots the guy, it sends it a message, when the user presses an arrow key that sends another message and so on.

 let guyAgent (guy, position, health) =
     let messages = receiveMessages()
     let (newPosition, newHealth) = process(messages)
     sendMessage(renderer, (guy, newPosition, newHealth))
     guyAgent (guy, newPosition, newHealth)

"Everything" is immutable now (actually, under the hood the agent's dipatch queue does have some mutable state probably).

4) If immutability is something I should strive for and even jump though hoops of instantiating new versions of objects that have changed...And If I instantiate my guy every time he moves (only with a different position) don't I have exactly the same problems as I would if he was mutable?

Well, yes. Looping with mutable values and recurring with immutable ones is equivalent.

Edit:

  1. For agents, the wiki is always helpful.
  2. Luca Bolognese has an F# implementation of agents.
  3. This book (called by some The Intelligent Agent Book), though targeting the AI applications (instead of having a SW engineering point of view) is excellent.

这篇关于不可变的游戏对象,基本的函数式编程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆