验证中...
语言: JavaScript
分类: 游戏开发
最后更新于 2018-05-17 11:48
数独小游戏页面
原始数据 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>数独游戏</title>
<style>
#demo-table tr td{
font-size: 40px;
border: 1px solid #ebebeb;
height: 100px;
width: 10%;
}
#demo-table{
border: 1px solid #ebebeb;
text-align: center;
border-spacing: 0;
border-collapse: collapse;
width: 100%;
}
.repeat{
color: red;
}
.check{
background-color: yellow;
/*color: blue;*/
}
.pass{
color:green;
}
.background{
background-color: #aaaaaa;
}
</style>
</head>
<body>
<div>
<table id="demo-table">
</table>
<div style="margin-top: 5px;text-align: center">
<select id="level" style="height: 80px;width: 80px;" onchange="changeLevel();">
<option value="1">初级</option>
<option value="2">中级</option>
<option value="3">高级</option>
</select>
<input style="height: 80px;width: 80px;" type="button" value="下一关" onclick="initTable();">
<input style="height: 80px;width: 80px;" type="button" value="提交" onclick="confirmTable();">
<div>
<h3>玩法规则</h3>
<ul>
<li>数独每行、每列及每宫填入数字1-9且不能重复。</li>
</ul>
</div>
</div>
</div>
</body>
<script>
window.onload = function () {
initTable();
};
var _ceilSize = 3;//每个小九宫格的边长
var _size = _ceilSize * _ceilSize;//整个表格的边长
var _shudu = [];//用来放入表格中的数据
var _num = [];//源数组
for (var i = 0;i<_size;i++){
_num[i] = i+1;
}
var _time = 0;//生成数据的次数
var _table = document.getElementById("demo-table");
var _eles = [];//用来存放每个td的背景颜色,true 为默认,false 为灰色
var _repeat = "repeat";//有重复数据的class名称
var _check = "check";//查看数据的class名称
var _pass = "pass";//填入的数据可以通过验证的class名称
var _background = "background";//背景颜色为灰色的class名称
//初始化表格
function initTable() {
initShudu();
var str = "";
for (var i = 0;i<_size;i++){
str += "<tr style='color: #000000;'>";
for (var j = 0;j<_size;j++){
if(_shudu[i][j]){
str += "<td style='font-weight: bold;' onclick='changeColor("+ i +"," + j +");'>";
str += _shudu[i][j];
str += "</td>";
}else {
str +="<td onclick='changeData("+ i +"," + j +");'></td>"
}
}
str += "</tr>";
}
_table.innerHTML = str;
//让相邻九宫格的背景颜色不同
var count = Math.floor((_ceilSize - 1) / 2);
for (var i = 0;i<_ceilSize;i++){
if(i%2 == 0){
for (var j = _ceilSize;j<_ceilSize + _ceilSize;j++){
for (var k = _ceilSize * i;k<_ceilSize + _ceilSize * i;k++){
var ele = _table.getElementsByTagName("tr")[k].getElementsByTagName("td")[j];
ele.classList.add(_background);
}
}
}else {
for (var k = _ceilSize * i;k<_ceilSize + _ceilSize * i;k++){
for (var l = 0;l<count + 1;l++){
for (var j = (_ceilSize + _ceilSize) * l;j<_ceilSize + (_ceilSize + _ceilSize) * l;j++){
var ele = _table.getElementsByTagName("tr")[k].getElementsByTagName("td")[j];
ele.classList.add(_background);
}
}
}
}
}
}
//初始化数独
function initShudu() {
generateShudu();
installLevel();
}
//生成一个二维数组,来存放数据
function generateShuZhu() {
for (var i = 0;i<_size;i++){
_shudu[i] = [];
_eles[i] = [];
for (var j = 0;j<_size;j++){
_shudu[i][j] = 0;
_eles[i][j] = true;
}
}
}
//生成数独
function generateShudu() {
generateShuZhu();
for (var i = 0;i<_size;i++){
var backCount = 0;//用来记录回退的次数
for (var j = 0;j<_size;j++){
var num = generateNum();
//如果返回值为0,则代表卡住,这一行须全部重置,初始化time,并且倒退到前一行的最后一列
if(num == 0){
//当回退次数达到一定次数后,判定为死循环,重新生成新数独
if(backCount == _size * _ceilSize){
generateShuZhu();
i = -1;
_time = 0;
break;
}
backCount++;
for (var k = 0;k<j;k++){
_shudu[i][k] = 0;
}
j = -1;
_time = 0;
continue;
}
if(isCorrect(num,i,j)){//填充成功
_shudu[i][j] = num;
_time = 0;//初始化time,为下次填充做准备
}else {//继续填充
_time++;//次数增加1
j--;//继续填充当前格
}
}
}
}
//设置数独的等级
function installLevel() {
var level = document.getElementById("level").value;
if(1 == level){//等级为初级,留_size * (_ceilSize + _ceilSize - 1)个空格
for (var i = 0;i<_size;i++){
for (var j = 0;j<_ceilSize + _ceilSize - 1;j++){
var k = generateNum() - 1;
var l = generateNum() - 1;
if(_shudu[k][l]){
_shudu[k][l] = "";
}else {
j--;
}
}
}
}else if(2 == level){//等级为中级,留_size * (_size - _ceilSize)个空格
for (var i = 0;i<_size;i++){
for (var j = 0;j<_size - _ceilSize;j++){
var k = generateNum() - 1;
var l = generateNum() - 1;
if(_shudu[k][l]){
_shudu[k][l] = "";
}else {
j--;
}
}
}
}else {//等级为高级,留(_size + 1) * (_ceilSize + _ceilSize)个空格
for (var i = 0;i<_size + 1;i++){
for (var j = 0;j<_ceilSize + _ceilSize;j++){
var k = generateNum() - 1;
var l = generateNum() - 1;
if(_shudu[k][l]){
_shudu[k][l] = "";
}else {
j--;
}
}
}
}
}
//生成数字
function generateNum() {
//所有数字都不能填充进去,表明该位置已经卡住,则返回0,由主程序处理
if(_size == _time){
return 0;
}
//生成随机数字,该数字是源数组的下标,该下标对应的数字为随机数字
var index = parseInt(Math.random() * (_size - _time));
//把该数字与源数组倒数第_time个数字互换,这样不会取到重复的数字
var temp = _num[index];
_num[index] = _num[_size - _time - 1];
_num[_size - _time - 1] = temp;
return temp;
}
//检查行是否符合要求
function checkRow(num,row,col) {
for (var i = 0;i<_size;i++){
if(i == col){
continue;
}else if(_shudu[row][i] == num){
return false;
}
}
return true;
}
//检查列是否符合要求
function checkCol(num,row,col) {
for (var i = 0;i<_size;i++){
if(i == row){
continue;
}else if(_shudu[i][col] == num){
return false;
}
}
return true;
}
//检查_ceilSize * _ceilSize区域是否符合要求
function checkNear(num,row,col) {
var startRow = Math.floor(row / _ceilSize) * _ceilSize;
var startCol = Math.floor(col / _ceilSize) * _ceilSize;
for (var i = startRow;i<startRow + _ceilSize;i++){
for (var j = startCol;j<startCol + _ceilSize;j++){
if(i == row && j == col){
continue;
}else if(_shudu[i][j] == num){
return false;
}
}
}
return true;
}
//是否满足行、列和_ceilSize * _ceilSize区域不重复的要求
function isCorrect(num,row,col) {
return checkRow(num,row,col) && checkCol(num,row,col) && checkNear(num,row,col);
}
//改变等级时,初始化表格
function changeLevel() {
initTable();
}
//填入数字
function changeData(i,j) {
//获取当前点击的元素
var ele = _table.getElementsByTagName("tr")[i].getElementsByTagName("td")[j];
//如果当前td有数据,则删除数据
if(ele.innerHTML){
ele.innerHTML = "";
_shudu[i][j] = "";
if(ele.classList.contains(_check)){
ele.classList.remove(_check);//清除检查class
if(!_eles[i][j]){//如果背景色不是默认色,则加上灰背景色class
ele.classList.add(_background);
}
}
return;
}
var num = window.prompt("请填入数字");
if(num > 0 && num <= _size){
_shudu[i][j] = num;
for (var k = 0;k<_size;k++){
for (var l = 0;l<_size;l++){
if(k == i && l == j){
continue;
}
if(num == _shudu[k][l]){
//获取和填入数字一样的一个td
var ele2 = _table.getElementsByTagName("tr")[k].getElementsByTagName("td")[l];
//判断当前这个数字是否是检查状态
if(ele2.classList.contains(_check)){//是
//判断当前点击的td背景色
if(ele.classList.contains(_background)){//是灰色
ele.classList.remove(_background);//移除背景色class
_eles[i][j] = false;//设置当前点击的td背景色为false
}
ele.classList.add(_check);//添加检查class
}
break;
}
}
}
}else if(num == "" || num == null || num == undefined){
return;
}else {
alert("按规定填入数字:1~" + _size);
return;
}
ele.innerHTML = num;
//验证填入的数据是否符合规范
if(isCorrect(num,i,j)){
//如果含有重复class,则移除
if(ele.classList.contains(_repeat)){
ele.classList.remove(_repeat);
}
//添加通过class
ele.classList.add(_pass);
}else {
//如果含有通过class,则移除
if(ele.classList.contains(_pass)){
ele.classList.remove(_pass);
}
//添加重复class
ele.classList.add(_repeat);
}
}
//改变同数字的背景色
function changeColor(i,j) {
var ele = _table.getElementsByTagName("tr")[i].getElementsByTagName("td")[j];
var num = _shudu[i][j];
var flag = true;//改变同数字的背景色
if(ele.classList.contains(_check)){
flag = false;//还原同数字的背景色
}
for (var k = 0;k<_size;k++){
for (var l = 0;l<_size;l++){
if(num == _shudu[k][l]){
ele = _table.getElementsByTagName("tr")[k].getElementsByTagName("td")[l];
if(flag){
if(ele.classList.contains(_background)){//如果有背景色是灰色
_eles[k][l] = false;//设置当前背景色是灰色
ele.classList.remove(_background);//移除背景色class
}
ele.classList.add(_check);//添加检查class
}else {
if(!_eles[k][l]){//当前背景色是灰色
ele.classList.add(_background);//添加背景色class
}
ele.classList.remove(_check);//移除检查class
}
}
}
}
}
//检查表格数据是否填入完整,是否符合规范
function checkTable() {
for (var i = 0;i<_size;i++){
for (var j = 0;j<_size;j++){
if(!isCorrect(_shudu[i][j],i,j)){
return false;
}
}
}
return true;
}
function confirmTable() {
if(checkTable()){
alert("恭喜你!数字填入正确!");
}else {
alert("不要灰心,你离成功已经很接近了,加油!");
}
}
</script>
</html>

评论列表( 0 )

你可以在登录后,发表评论

搜索帮助