LifeGame
LifeGame
首先本文起因于野比的《生命游戏和细胞自动机的学习笔记》http://www.cnblogs.com/conmajia/archive/2012/05/31/life-game-note.html
问野比要源码后并没有达到本人想要的结果,于是想自己实现一个世界,一个生命规则。
游戏源码已上传,文章末尾。
人工智能就算了,虽然本人也很有热情,但是其中没有涉及任何人工智能相关。
倒是有以下几个方面需要普及一下:
普及知识
D20规则
维基百科传送门:http://zh.wikipedia.org/wiki/D20%E8%A6%8F%E5%89%87
D20规则影响了我很多,有时甚至涉及到现实。
这东西不能细说,有兴趣的可以去奇幻修士会:http://www.tdsgame.org/
生命游戏
维基百科传送门:http://zh.wikipedia.org/wiki/%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F
说起生命游戏,以前在emacs中确实打开过这个游戏。
程序介绍
首先,程序没有完成。
因为这个东西不是一个Demo。
程序都是本人一点一点敲出来的,趁着周末。到周一才发现,完全不能从此状态中脱离,这严重影响了心情和工作。所以决定在此将程序发布出来。
实现目标
- 细胞有属性:
暂时只使用基本的力量、敏捷、智力,属性影响细胞各个方面;
- 细胞有动作:
细胞大多时间在漫步(Wander),但是在有其他细胞攻击自身时,细胞会出于本能的进行反击,由于没有智商(能力),经常会看到两个细胞致死不休的相互攻击。当然细胞也会在周围有其他细胞时主动出击,或者细胞懒得动(休息);
- 细胞有视野:
细胞所谓的周围(视野)已经不局限与周围8个方格,而是由于时间(白天还是黑夜),自身属性(敏捷影响视野)去决定。例如下面是一个视野为3的细胞。
- 细胞有能力:
可以理解为智商。但是感觉更像是游戏中的技能。例如说细胞在攻击时发现击中要害更致命,那么它以后攻击的时候都会向要害攻击(学会【击中要害】)。
这里为了让游戏更有意思,对思考类能力做了特殊处理,比如说细胞学会了【谋而后动】,那么它会在每次行动前,考虑自身、对手、周围细胞等各个因素,然后做一个判断,决定这次应该做什么。学会【走为上策】细胞会在自己自身不利情况逃跑。更甚者学会【知己知彼】还会考虑对手情况。
- 细胞有状态:
标准的如战斗中、逃跑、濒死,战斗状态如被拌摔等(与能力有关)
程序中
不记得哪里看过,与程序员谈话很舒服,因为说两句就扯回程序了。
前面说了那么多,不谈程序,确实感觉有点不适应。
能力中使用位运算
首先在设计状态的时候使用了位运算判断,这也是一个很经典的学习案例:
给一个地址:http://blog.csdn.net/masefee/article/details/5258432
还有就是在应用程序开发中权限问题也可以解决:http://www.cnblogs.com/toby/archive/2011/10/23/2221863.html
我为了给每个技能增加【稀有度】,提出一个能力最大值的概念,其实我承认很大程度上是因为我发现智力有点废柴。
每个能力并不全是只有一个1(二进制),如上例中的【击中要害】二进制就有3个1。
/*
这里需要说明一下,本身是没有能力类型的(如上面的共计类型),但是发现由于攻击类的能力稀有度低(原本的【奋力一击】是0x00000001【击中要害】是0x01000002),很多细胞同时拥有【奋力一击】和【击中要害】,所以提出了能力类型这个概念,同一个能力类型每个细胞只能拥有两个(不排除给一些思考类能力增加判断替换能力的功能)。
*/
当你获得一个新技能的时候,剩余能力值(能力最大值减去已有能力值)不足,则无法获得该技能,这样保证了高智力细胞的优势。
判断能力值的方法来源经典的判断整数二进制中1的个数,也算学有所用。其实完全可以写一个类的,这我知道,而且在能力中暴露出来的问题(比如说通过0x00000001获得【奋力一击】这个能力的名字),也让我考虑将能力封装一个类。但是这都是后话。
判断视野
这真是经验不足了。
虽然很喜欢游戏,但是对于游戏编程还是没有过多接触。
本来很简单的一个问题,但是实现的时候还是出了不少问题,最后写下如下代码:
public static List<Point> Within(this Point p, int distance) { List<Point> lstResult = new List<Point>(); Func<int, List<Point>> func = dis => { List<Point> lst = new List<Point>(); foreach (var item in Enumerable.Range(1, dis)) { if (item != dis) { lst.Add(p + new Size(item, dis - Math.Abs(item))); lst.Add(p + new Size(item, -(dis - Math.Abs(item)))); lst.Add(p + new Size(-item, dis - Math.Abs(item))); lst.Add(p + new Size(-item, -(dis - Math.Abs(item)))); } else { lst.Add(p + new Size(item, dis - Math.Abs(item))); lst.Add(p + new Size(-item, dis - Math.Abs(item))); lst.Add(p + new Size(dis - Math.Abs(item), item)); lst.Add(p + new Size(dis - Math.Abs(item), -item)); } } return lst; }; foreach (var item in Enumerable.Range(1, distance)) { lstResult.AddRange(func(item)); } return lstResult; }
//把那个func提出来本来以为这里想递归……
哪位大侠帮忙改一下吧。我也感觉看不下去。
写在后面
正如前面所说,程序没有写完。
既要追求简单,又想在简单中创造不简单,还是得花费不少时间的。
现在很难再像以前专注于某一个爱好。
我一直都说。
对我来说,选择爱好作为工作是一件痛苦的事情。这让我分不清是在工作还是在游戏。
附上源码:https://files.cnblogs.com/nanqi/LifeGame.zip
欢迎交流讨论
秋秋:贰柒伍零玖陆玖陆柒
最后,之所以晚上写博客,是因为写这东西太费时间了。