Android棋类游戏:五福

我最近在Android电子市场发表了一个人机对弈游戏:五福。这是我小时候常玩的一个游戏。

 

我采用了Minimax算法。这个算法实现起来相当直接。难点在于怎样快速地找出最佳走法,也就是怎样才能尽可能先评估最佳走法,以及如何优化评估函数(evaluation function)。

 

计算一步棋可能需要很长的时间,所以我们不能主线程做计算。我采用了AsyncTask类。AsyncTask类的通常用法是在doInBackground()函数中进行耗时的运算,然后在onPostExecute()中,把结果通知相应的活动(activity)。问题在于当onPostExecute()被调用时,那个活动有可能已经被杀掉了。例如Android会在屏幕改变方向时杀掉并重建正在显示的活动。如果你在此时调用活动的函数,程序就会死机。

 

为此,我采用了如下方法。写一个名为WufuApplication的类并继承Application类。当活动的onResume()函数被调用时,把该活动注册到WufuApplication。当onPause()被调用时,把给活动从WufuApplication中注销。在计算完成,即AsyncTask类的onPostExecute()函数被调用时,调用WufuApplication的一个函数。如果当时有注册的活动,该函数直接把计算结果传给该活动。否则,先把结果记录下来。该活动的onResume()函数会在注册完后检查WufuApplication中是否存有计算结果。如果有,就取得该结果并做出相应的动作。这样我们就不用担心在AsyncTask类进行计算时,活动被重建的情况了。

 

另一个问题是如何模拟一个一个的提子。如果同时提掉所有应提的子,玩家就可能不知道哪些子被提了。我写了一个实现了Runnable接口的名为MoveAnimator的类,并利用android.os.Handler类。MoveAnimator维护一个简单的状态机。该状态机有4个状态:等待、运行、暂停和完成。初始状态为等待。当MoveAnimator的play()函数被调用时,把当前状态改为运行,并调用如下函数:

 

m_handler.removeCallbacks(this);

m_handler.postDelayed(this,INTERVAL); // Add MoveAnimator to the message queue.

 

其中,m_handler为android.os.Handler的一个实例。

在MoveAnimator的run()方法中,如果当前状态为运行,并且还有未完成的步,我们就模拟该步。如果还有未完成的步,就继续调用postDelayed()在消息队列中放入一个新的请求。

当相关的活动的onPause()被调用时,调用MoveAnimator的onPause()方法,以把当前状态设置为暂停。当相关的活动的onResume()被调用时,调用MoveAnimator的onResume ()方法,以把当前状态恢复为运行。这样在屏幕切换方向后,还能继续提子。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值