使用es6制作简单数独游戏

最近心血来潮想制作一个数独游戏,说干咱就干。刚刚好前一阶段学习了es6,可以用这个项目来当做一个小练习。

    目前开发已经完成,由于只是基本功能,页面样式并不是很华丽,下面我们先开看看长什么样子。

alt

大概页面就长这个样子,页面有三个按钮,分别是检查,重玩,换题。

  1. 检查就是检查当你填满是否成功。
  2. 重玩就是放弃你所填的,重新开始本局游戏。
  3. 换题就是重新换个题目。

下面是游戏中截图。

alt;

alt;

最后这个图我比较偷懒。直接生成的,并没有自己填。

下面就来看看代码吧。

里面最重要的就数算法了吧。我使用是回溯法,废话不多说直接上代码。先来看一下生成数独的算法。大概就是把数独分成81格,从1-81分别生成,没生成一个格都要去判断一下每一行,每一列,每一宫是否满足规则。如果不满足则回溯。下面是生成数独的方法。

//生成数独
const makeArray=(arr, n)=>{

        if(n == 81) {
            return arr;
        }

        let x = Math.floor(n / 9);
        let y = n % 9;

        if(arr[x][y] == 0) { let index = 0; let arrn = makeRandomArray(9); for(let i = 0; i < arrn.length; i++) { arr[x][y] = arrn[i]; if(checkArrayByIndex(arr, x, y)) { let endArr = makeArray(arr, n + 1); if(!checkArrayHasZero(arr)) return endArr; } } arr[x][y] = 0; //回溯  } else { makeArray(arr, n + 1); } return arr; }

 

当生成完数组之后,就可以生成游戏所用的数独,其实则是隐藏其中的格子。

//对二维数组进行随机n位置0
const resetZeroByArray=(arr,n)=>{

    let k=0;

    while(k<n){

        let ranNum=randomNumber(81);

        let x = Math.floor((ranNum-1) / 9);

        let y = ranNum % 9; if(arr[x][y]!=0){ arr[x][y]=0; k++; } } return arr; }

 

最后则是当玩家填完数组之后再去验证这个数独是否满足规则。

//判断二维数组是否是完整数独
    checkSudoArray(arr){                

        let sign=true;

        //检查数组中是否含有0,如果有0立刻返回false
        if(checkArrayHasZero(arr))return false;

        //对每一行每一列每一宫进行检查
        for(let i=0;i<9;i++){

            let rowSign=checkedRow(arr,i);
            let colSign=checkedCol(arr,i); let gongSign=checkedGongByNum(arr,i+1); if(!(rowSign&&colSign&&gongSign)){ sign=false; }; } return sign; } //根据坐标检查九宫格 const checkArrayByIndex = (arr, x, y) => { let signRow = false; let signCol = false; let signGong = false; //检查行 signRow = checkedRow(arr, x); //检查列 signCol = checkedCol(arr, y); //检查宫 signGong = checkedGongByIndex(arr, x, y); if(signRow && signCol && signGong) { return true; } else { return false; } }

 

这样算法大概就介绍完了。接下来来看看页面。页面我是把二维数组直接放在父模板中,然后先去初始化然后根据这个数组去生成grid。

<div class="sudoMain" >
              <Row class="numRow" type="flex" v-for="(row,i) in arr" justify="center">            
                <i-col class="numCol" v-for="(cell,j) in row" :data-x='i'  :data-y='j'><div class="spanDiv" @click="cellClick($event,i,j)">{{arr[i][j]==0?"":arr[i][j]}}</div></i-col>           
            </Row>    
</div>

 

一定要记得把每个坐标赋值到元素上,这样可以进行接下来的操作都很方便。接来下用户选择的数字面板单独写出来,通过点击事件进行隐藏或者显示。

selectClick(e,i,j){
            this.showSelectPop=false;
            this.arr[this.selectX][this.selectY]=(i-1)*3+j;                    
        }

 

介绍的大体差不多了,代码已经上传到github,如果想看源码的话可以直接上github下载。地址是:https://github.com/like2372/sudoVue.git

转载于:https://www.cnblogs.com/like2372/p/8329835.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值