自己写数独游戏

本人对数独游戏比较感兴趣,闲暇之余会玩上几局。但是发现app广告弹出实在是太频繁了,于是想着何不自己动手写一个呢。

一个完整的数独游戏大致有这几个部分:

  • 界面,能够互动,让用户看到数独题目,填写数字。并且能够实时判断所填数字是否正确。
  • 出题,能够随机出题。虽然也可以通过预存题目的方式完成游戏,但是这样做题目有限,不能一直玩下去。能做到随机出题才更有趣。游戏必须能够先随机生成一局满足数独条件的组合,即横、竖、九宫格里面的数字为1~9且不重复。
  • 难度,能够让用户选择难度。同一局,根据挖洞的数量不同,难度也不相同。当然,挖洞后还必须保证解是唯一的。否则,用户无法顺利填空。
界面

界面的部分,我是用Cocos Creator来完成的。这是一款很不错的小游戏编辑软件。用来做小游戏方便快捷。效果如下,


主界面
游戏界面

用户可以选择难度,然后游戏会根据所选择的难度随机生成一局。用户先选择空的格子,再点选下面的1~9数字,这样就可以把数字填进去了。系统会立刻判断填的数字是否正确。如果填错,就会记录填错1次。用户可以再选择其他数字。我设计的这款游戏并不像其他游戏那样一局只能错3次。那些游戏限制错误次数主要是为了用户充值。我记录也只是让用户知道自己解一局的错误次数。

出题

数独游戏的出题思路有3种:

  1. 收集网上已有的数独题目,存储在游戏中。或是通过闯关的方式1关1局,或是在存好的题库中随机选择一局。这个方法的优点是出题逻辑简单,缺点是要么游戏内存会比较大,要么就是题目太少,容易重复。

  2. 在方法1 的基础上,通过轮换数字位子的方式再多创造新的题目。这样一来,一局可以延伸出9!的新局来。具体来说,就是以一个存在的棋局为基础,把所有1所在的位置替换成2,2所在的位子替换成3,依次替换。在这种方式下,还是可以保证横、竖、九宫格里面的数字是不重复。当然,也可以把所有1替换成6,所有2替换9之类的。只要保证是9个数字的轮换即可。通过变量来解释就是把a,b,c,d,e,f,g,h,i这9个变量放到棋局中并且满足横、竖、九宫格里面不重复。再把1~9赋值到这9个变量中。但是这样的方式所产生的新局从本质上还是一样的。如果被发现了这个规律,只要每次找到轮换的方式即可快速解题。也没有意思了。

  3. 通过解题的方式创造新题。这个方法的思路是,先在棋局中随机位置填1~9。然后通过解题的算法把剩余的空都填上。并且,在解题算法中也加入随机顺序的解答。这样一来,就能够得到真正随机的棋局了。我自己在游戏中选择的是第三种方式出题。

难度

在出好题之后,需要通过挖洞的方式(在完整的棋局中把某些数字去掉)来实现不同的难度。简单难度挖掉40个空,普通难度挖掉45个空,困难难度挖掉50个空。虽然每一级只相差5个空,但是每多挖掉1个空,其计算难度都会倍增。

为了保证挖洞后,解唯一(每一个空只有1个可能的数字)。在每次挖完后,还需要再通过解题算法验证。只要有一个空不是唯一解,就需要重新再挖。

出题+挖洞的计算都是在用户开始新的一局的时候运行的。为了保证用户体验,最多挖到50个洞。我目前的算法如果是要挖55个洞还保证唯一解,就需要几分钟才能完成了。但是如果是50个洞,则可以在1秒钟之内完成。也许有更好的挖洞算法,不过即使是50个洞的难度,对我来说要解题已经很难了。自己玩,难度也算足够了。


解题代码:
solve_sudo(target){
        var temp = this.copy_sudo(target);
        if(temp[0][0]==0){
            this.try_fill(0,0,temp);
        }
        else{
            var next_cords = this.get_next(0,0,temp);
            this.try_fill(next_cords[0],next_cords[1],temp);
        }
        return temp;
    },
try_fill(x,y,target){
        if (target[x][y] == 0){     
            var list = [1,2,3,4,5,6,7,8,9]
            list = this.shuffleSelf(list);  
            for (var i =0;i<9;i++){
                var num = list[i];
                if(this.check(x,y,num,target)){
                    target[x][y] = num;
                    var next_cords = this.get_next(x,y,target);
                    if(next_cords[0]==-1){
                        return true;
                    }
                    else{
                        var end = this.try_fill(next_cords[0],next_cords[1],target);
                        if(end==undefined){
                            target[x][y] = 0;
                        }
                        else{
                            return true;
                        }
                    }
                }
            }
        }
    },
 get_next(x,y,target){
        for (var j=y+1;j<9;j++){
            if(target[x][j]==0){
                return [x,j];
            }
        }

        for(var i=x+1;i<9;i++){
            for(var j=0;j<9;j++){
                
                if(target[i][j]==0){
                    return [i,j];
                }
            }
        }
        
        return [-1,-1];

    },

现在这个游戏已经在IOS的app store上发布了。感兴趣的朋友可以下载玩玩。免费无广告,纯粹个人兴趣。搜索 简洁数独 即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。