在找实习面试的时候,有一位面试官问过我一个非常有意思的面试题,如何设计一个连连看游戏。
作为一个学习计算机的学生,可能先要做的是去理解问题,在这个过程中可以尽情地去问面试官问题,沟通可能比写好代码更重要。
下面是我问面试官的几个问题:
1、连连看游戏的规则是什么?
面试官给我打开了一个手机应用,解释了一下。其中最重要的是如何判断两个图形能否相消。(两个同样的图用线相连,连线拐的弯不能超过两个)
2、最多有多少张图?
一般练练看游戏是20*20或者30*30,所以图片最多大概在1000张左右。
3、如果两个图能够消除,是直接把两个图消除?还是找到最短路径后,把路径画出来,然后再消除?
最短路径的问题可以之后考虑,先考虑简单的,直接消除两个图。
4、连连看游戏是否存在死锁状态?是否需要解除死锁状态?
在玩连连看游戏的时候,如果图片是随机摆放的,可能会碰到死锁状态。因为死锁状态很影响用户体验,所以需要解决。
搞清楚了问题之后,我们就可以分析和解决问题了。先写一个连连看游戏的程序伪代码。
initGame();//生成游戏初始化状态while(!isGameOver()){//如果游戏没有结束if(isDeadlock()){//如果出现死锁情况unlock();//解除死锁}waitClick();//等待用户点击游戏中的图curClick=getCurrentClick();//得到当前输入if(isLegalInput(curClick)&&preClick==null){//如果当前是合法输入,并且是第一次点击preClick=curClick;curClick=null;}if(preClick!=null&&curClick!=null){//如果已经点了两个图if(findPath(preClick,curClick)){//如果两个图之间存在一条连线remove(preClick,curClick);//消除这两个图preClick=null;curClick=null;//还原状态}else{preClick=curClick;curClick=null;//要被连得图变成最近一次点击的图}}}生成游戏初始状态。我们先假设有25张不同的图,连连看游戏的大小是20*20,那么我们在25张图中有放回的随机抽样200次即可,然后再把这200张图复制一遍,变成400张图。最后,我们需要把这400张图随机地放到一个20*20的二维空间中。
游戏结束的条件就是所有的图片都被连线并且消除了,我们可以通过加入一个变量existPictureNum,来记录当前网格中存在的图片数量,当existPictureNum为0时,所有图片都已经消除,游戏也就结束了。实现就是下面加粗的代码。
最直观的想法是遍历一下网格,碰到一个图时,看看该图是否能够和另一个图进行连线。找到一个可以连线的图,就不是死锁状态;否则,是死锁状态。