本项目是使用java技术+自创“假设下子”算法开发的人机大战四子棋游戏客户端。java
具体项目,以及原创PSD,设计文档,在文件末尾的百度云链接。算法
组名:CST数组
组长:陈飞良(C):架构
组员:布局
沈珂 (S):网站
谭明航 (T):this
本程序的代码实现思想由三人共同讨论得出,其中组员沈珂的“假设下子”思想尤其精妙,让代码实现更为简单,在这基础上,组员谭明航 ,心思缜密,考虑到各类特殊状况,让整个更加智能。组长陈飞良则负责在他们的基础上设计算法进行完善。spa
游戏的总体界面由三人共同讨论,组长陈飞良使用PS制做而成。设计
Ⅰ.游戏的整体布局与架构由组长陈飞良完成。htm
Ⅱ.本游戏的核心是电脑的下子方法,共有七步
①假设该子为电脑子,判断能连成四子(由谭明航实现)
②假设该子为玩家子,判断看是否存在,玩家4子相连,即不算此位置玩家将四子的状况,有则拦截(由谭明航实现)
③排除垫脚石的状态, 若是此位置上一位置是玩家子,玩家子可成四子,则该位置优先级为-9(由沈珂实现)
④排除连子最多,可是到顶端也没法组成4个连子的(由谭明航实现)
⑤若是电脑放一子下一步 电脑能同时造成2种方法成四子 ,则设置max_x[x] = 4,即优先级为 4。(由陈飞良实现)
⑥若是玩家放一子下一步玩家能同时造成2种方法成四子则拦截 ,则设置max_x[x] = 10,即优先级为 10(由陈飞良实现)
⑦普通攻击,假设电脑按照优先级前后(在max_x中有各列优先级),同级则随机落子。(由沈珂实现)
本程序共设计了一个6个类,主要说下3个类
其中有位置类,即Position类。而且Position类中有一个整型标志成员Label_Status.
Label_Status = 0 表示空 .
Label_Status = 1 表示玩家子.
Label_Status = 2 表示电脑子.
Game类为主类,放了布局的各个控件,以及,玩家和电脑的移动方法等。
MainPanel类为主面板
在设计主界面初始化时先将每一个格子放下表明玩家子和电脑子的Label成员.同时设置为不可见,而且Label_Status = 0 . 即该位置为空
实现方法:使相应位置的玩家Label或者电脑Label可见,同时更改标志。
玩家的下子:经过监听键盘和鼠标进行相应的移动,得到玩家下子的位置
电脑的下子是整个程序的核心,基本是遵循人的思惟
设置一个_y[]数组每一个元素初始化为-1,表示该列无可下位置
遍历某一列的每一行( x : 0-- 6),找到能下子的那一行,即该子的y坐标
找到后位置赋值给_y[],即 _y[x] = y’;
固然此处的y坐标对应的位置应该为115 + 100 * y
同时x坐标对应的位置为375 + 100 * x
(这个位置由棋盘大小,和布局时埋子的方式决定)
定义了一个max_x存储每一列(x : 0 --- 7)所下位置各方向可成最大连子,每一个元素初始化为-10(只是取一个小于0的数能够随意取,可是要方便后期的优先级设置,能够为-7 -8 等)
使用三次Math.max可求出
max_x[r] = Math.max(Math.max(you, you_xia), Math.max(xia, you_shang));
①假设该子为电脑子,判断能连成四子
this.pos[x][y].setLabel_Status(2);
遍历查找,成立,则落子,直接宣布比赛结果。
若是不能够,标志恢复
this.pos[x][y].setLabel_Status(0);
如下各类状况同理
②假设该子为玩家子,判断看是否存在,玩家4子相连,即不算此位置玩家将四子的状况,有则拦截
③排除垫脚石的状态, 若是此位置上一位置是玩家子,玩家子可成四子,则该位置优先级为-9
把该位置的max_x[x] = -9; (前期max_x元素初始化为-10)即除非没地方下,才下此处
④排除连子最多,可是到顶端也没法组成4个连子的
max_x[x] = 0; 优先级比通常的小,但比垫脚石高
⑤若是电脑放一子下一步 电脑能同时造成2种方法成四子 ,则设置max_x[x] = 10,即优先级为 4
⑥若是玩家放一子下一步玩家能同时造成2种方法成四子则拦截 ,则设置max_x[x] = 10,即优先级为 10
⑦普通攻击,假设电脑下子后,连子最多的位置(在max_x中有各列最大)随机落子。(前面的垫脚石类的状况,能够改变max_x中的值来改变优先级)
若是是2--4列 max_x += 0.5 ; 同等优先级,中间再优先一点,且不会跨级。
可建立一个数组a,把max_x数据赋值过去,而后利用Arrays.Sort方法排序最后去a最后一个元素,即为a的最大值,即max_x最大值
具体代码编写顺序以下:
因为以前照着网上的例子敲过人与人对战的五子棋,因此完成的效率很是的高,在老师说公布题目以后,咱们组便开了的个会,把基本的算法定下了。组员沈珂的“假设下子”思想,对咱们的代码实现做用很是之大,在这第一次会议中便肯定了7个主要的方法,同时在一周后,便写出了1.0版。而后一路的查漏补缺。
本程序曾与两个网站的游戏进行对垒
(1)一个是 http://www.4399.com/flash/48470_1.htm ,这个网站算法有个优势就是懂得占据中间位置,比过以后,便决定在咱们2--4列的优先级+0.5,使其在能造成一样多连子数的时候,比其余位置优先,尽可能占据中间位置,可是其余位置比下此位置连子多时,仍然会下那个连子更多的位置。因为这个网站没有写垫脚石的算法,因此咱们改完以后的胜率是80%左右。
(2)第二个是 http://www.7k7k.com/swf/50447.htm ,这个网站的优势是能主动造成双三,比过以后,咱们便在咱们程序中加了两个方法:
可是,这个网站的方法还有一个方法即是,在下一个子以后成三子,咱们被迫去拦截,同时还给他本身垫脚,此时咱们必输。
同时,咱们程序没有写防止本身给对方垫脚,使其成双三的算法:
因此,在完善后,咱们的胜率只能在50--60%之间徘徊。
本程序的”假设下子”思想是采用枚举的方法优势在于不须要考虑具体状况,如:
在方法6中,能够拦截的状况有:
...........等等。即只要符合下一子,能有两种方法成四子就拦,并不须要考虑具体状况,由电脑“假设下子”去枚举,代码效率很是的高,与其余组的程序对比,基本以能够20行代码发挥200行代码的做用。