上篇已经实现了点选后给予显示,本篇就开始讲解如何往数独中填入数字。这里使用的是在数独右边区域展示1-9数字,选择数字后自动填入。
那这1-9数字也得画出来,那就需要第3块画布了。添加标签如下(当然这里的边框是不需要的,等画完这块区域后可以去掉)。
<div id="divC"><canvas id="canC" width="60" height="540" style="border: 2px green solid;"></canvas></div>
并将展示的1-9数字区域,固定在数独右侧。css样式如下。
#divC {position:absolute;left : 50%;margin:0 300px;
}
准备好后,就可以开始绘制了。先获取一个存储了数字1-9的数组。
function getAllNumArr(min, max){//获取1-9数字数组let arrA = [];for(let i = min, j = 0; i <= max; i++,j++){arrA[j] = i;//1-9顺序数组}return arrA;
}
然后竖向按顺序绘制1-9数字,并将底色设置成斑马线,好区分每个格子。
function drawAllNum(pen, w, h){//竖向绘制1-9数字pen.font = "30px 微软雅黑";pen.textAlign = "center";let arrA = getAllNumArr(1, 9);for(let i = 0; i < arrA.length; i++){if(i%2 == 0){pen.fillStyle = "rgba(0, 0, 255, 0.1)";} else {pen.fillStyle = "rgba(255, 255, 0, 0.1)";}pen.fillRect(0, h/9*i, w, h/9);pen.fillStyle = "blueviolet";pen.fillText(arrA[i]+"", w/2, h/9*i+h/9/3*2);}
}
调用函数,完成绘制。
let penC = canC.getContext('2d');
drawAllNum(penC, w/9, h);
运行代码,效果如下。
此时已经显示好了待输入的数字,但每次点击在不可编辑块时,这些数字也在,可能误导玩家。可以控制下,只有选择的是可编辑区才显示画布C,否则就不显示。
这就需要在画布B的点击事件中添加代码(省略代码是之前写过的)。
//点击选中方块==>操作画布B
let penB = canB.getContext('2d');
let lastXY = [];//记录上次点击的方块
let penC = canC.getContext('2d');
let myFlag = false;//C区有没有图。true有图,false无图
canB.onclick = function (e) {//清除上次绘制的方块...//绘制本次选中的块...//绘制或清除C区if(arr[blockj][blocki] == 0 && !myFlag){//选中框能修改时,C区绘制1-9数字drawAllNum(penC, w/9, h);myFlag = true;} else if(arr[blockj][blocki] != 0){//清理C区penC.clearRect(0, 0, w/9, h);myFlag = false;}
}
运行效果如下。
现在就可以开始实现将数字填入格子中了。数字填入后可以要能修改的,并且清除数字填入新数字时,选择底色块不能受影响。那就用到了第4块画布,当然同第1/2块一样重叠起来。
先添加标签,变更如下(这里需要注意的是,画布B有关联的点击事件,所以标签需要放在画布A和画布D的下面。画布C区域不受影响,放哪都可以)。
<div id="div1"><div id="divA"><canvas id="canA" width="540" height="540"></canvas></div><div id="divD"><canvas id="canD" width="540" height="540"></canvas></div><div id="divB"><canvas id="canB" width="540" height="540"></canvas></div><div id="divC"><canvas id="canC" width="60" height="540"></canvas></div></div>
画布D的CSS样式,与第1/2块画布一样。
#divA,#divB,#divD {...
}
最后添加代码实现点击画布D的数字填入选择的格子中。
//点击选中右侧数字方块==>点击画布C,操作画布D
let penD = canD.getContext('2d');
canC.onclick = function (e) {if(lastXY.length != 0){//需要选中方块let myi = lastXY[1];let myj = lastXY[0];if(arr[myi][myj] == 0){//数组该值等于0才能填入新值//绘制本次选中的块var e = event || window.event;let blocki = Math.floor(e.offsetX/(w/9));let blockj = Math.floor(e.offsetY/(h/9));penD.clearRect(w/9*lastXY[0], h/9*lastXY[1], w/9, h/9);penD.font = "30px 微软雅黑";penD.textAlign = "center";penD.fillStyle = "blueviolet";penD.fillText(blockj+1+"", w/9*myj+w/9/2, h/9*myi+h/9/3*2);}}
}
完成后,运行效果如下。
到这里,其实就相当于可以开始玩数独了,但每次数独变化需要手动改代码中的数组,那这里就需要能自动生成一个数独了。
下一篇就讲一个最简单的算法。有兴趣或者有想法的也可以自己完成这个数独生成的算法。