zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    cs ip 通过jmp转移命令间接赋值。无法直接对其赋值。
    8086 cpu为什么要把段地址*16+偏移量形成物理地址呢?
    保护模式和实模式的区别
    计算机的内存是以字节为单位的, 这个认知很重要。
    计算机的内存是以字节为单位的。
    一个字 word 是16位, 一个字由两个字节组成 , 字节=byte ,一个字节8位, 位=bit 如果没有特殊说明kb 就是指 k*bit
    物理地址为20位 如10000H 用段地址*16+偏移地址表示
    深入学习Java线程池
    在线考试系统镜像构建、推送、部署
    容器 变成镜像提交到阿里云镜像仓库
  • 原文地址:https://www.cnblogs.com/like2372/p/8329835.html
Copyright © 2011-2022 走看看