蛙蛙推荐:动手做个网页游戏-五子棋
声明:
五子棋的算法和思路是来源自园友二十四画生的一个帖子,地址如下,在此感谢。
http://www.cnblogs.com/esshs/archive/2005/04/01/129824.html
我只是在算法上稍加改进,并从c#代码移植到javascript和html上。
摘要:
五子棋是中国的传统休闲益智小游戏,规则不是太复杂,我们可以通过写一个五子棋来锻炼编码的思路和风格,提高基本功能力。上次花很大功夫写的正则解析引擎也是这个目的,但关注度比较低,希望这个小五子棋游戏能得到稍微多一些的关注,这次也没有用高深的技术,熟悉html,javascript和jquery就可以了。
思路
首先从高层进行设计,分成棋盘界面类,棋子管理类,AI类,五子棋规则类,界面帮助类等几个模块,模块间要有明确的分层关系,高层模块调用低层模块,模块之间的调用关系也要明确,降低耦合,模块对外暴露的接口在同一个抽象层次上,
StoneRule主要负责检查当前棋局的状态,是否出现了某方赢棋,黑子出现禁手,平局等状态,ChessboardState枚举表示棋局的各种状态。 由于正规五子棋的禁手规则判断比较复杂,我这里判断三三禁手,四四禁手和长连禁手规则比较简单,只要形成两个或者两个以上的活三,活四就算禁手,不考虑太深层次的规则,如看起来是活三,其实对方可以堵的情况。所以也许和正规的规则有些出入,但一般选手使用是不影响的。
StoneAI可以根据当前棋局和电脑的颜色来自动计算出电脑下一步该走哪儿,内部有一个Check方法来给棋盘上每一个没下子的空位进行评分,评分最高的就是电脑要走的下一步棋的位置。评分这个规则在二十四画生的博客里有介绍,大概意思就是假设这个空位放上电脑方的棋子后,电脑方连成的最大棋子数是多少,连成的棋子越多,评分越高,这属于进攻措施。然后再假如电脑不在这个空位放子的话,对方放子的话,对方连成的最大棋子数是多少,连成的棋子数越高,评分越高,这属于防守措施。 我在评分的时候加了改进,如果放子后连成3个,需要两边都有空位才给加分,否则两边已经堵上了,即使电脑走了这个子也不可能连成五个,而连成4个子的话,至少要有一边有空位,否则最终也连不成5个。
Chessboard表示一个棋盘,主要是UI表现层,有画棋盘,在某点上画棋子,移除某点上的棋子(撤销或悔棋),重置等操作,这些都是用jquery操作Dom完成的。
UIHelper是界面辅助类,比如向用户显示信息,捕捉用户的开始游戏按钮和棋盘的点击事件等。
StoneManager类是整体的驱动类,由它来操控协调其它的类一起工作,init()用来初始化棋盘,Start()开始一个新的回合,以及处理人下子和电脑自动下子。
从上面可以看出每个类都有自己明确的职责,而且调用关系也很明显。
流程
开局:浏览器打开的时候执行StoneManager.Init()去初始化棋局和绘制棋盘, 用户点击开始游戏按钮后,进行开始状态,默认是人先手,电脑后手,先手永远是黑子,这是既定规则,开始后棋盘要Reset,把已有的棋子清空。
人落子:人点击棋盘后,UIHelper类会捕捉到,并执行StoneManager的PersonDownStone方法,人落完子后,检查棋局状态,是否赢棋或者出现禁手,平局等。然后是电脑落子,StoneManager会调用StoneAI类去询问下一步该在哪儿落子,然后去落子,落完子后也要重新检查棋盘状态。
赢棋:当检查棋盘出现某方赢棋后,StoneManager会调用UIHelper通知用户某方赢棋,并调用Chessboard.Reset重新开局。
以下是游戏的在线演示,欢迎大家试用,点击下面的“运行代码”按钮。
有人说有360浏览器和TT浏览器打不开,我提供了一个本地压缩包下载:fivestones.zip