九宮格數獨遊戲
一個九宮格數獨遊戲,以下是思路和html文件,由於水平有限沒有使用什麼比較高級的語法,都是一些基礎的東西,所以代碼比較長。
邏輯思路
1.生成數獨遊戲
思路是把數獨理解成一個二維數組,只要每次遊戲開始隨機生成一個符合九宮格規則的9*9二維數組即可。(如果不隨機就可以記答案,遊戲就沒意思了)
1.1輸入原型數組,這個數組要符合規則
1.2打亂這個數組生成答案數組:使用能保持數組符合規則的打亂方式。比如我用的是1-3,4-6,7-9列以豎排爲單位先各自內部打亂,再1-3,4-6,7-9,三個豎排爲單位換位置,行的打亂方式也是同理。這種打亂方式可以讓原數組的一個位置的數,可能出現在答案數組的任何一個位置,同時每次變換後,數組都符合九宮格規則
2.網頁顯示
兩個問題:一是如何確定顯示哪些已知數,二是以何種方式顯示在網頁中
2.1選已知數:其實可以理解爲隨機的選一些位置(數獨遊戲的已知數位置是可以變得),並將位置對應的答案數組中的數顯示出來。這裏我使用了9*9的控制數組,控制數組打亂後,凡是爲1的位置,對應答案數組的數就要顯示
2.1.1生成控制數組
例
[0,1,0,0]
[0,1,0,1]
[1,0,1,0]
[0,0,0,1]
這隻一個4*4的例子而已,可以根據難度的需要調節1的數量
2.1.2打亂控制數組生成實際控制數組(目的是使已知數顯示位置隨機,且不會集聚)
使用1.2的打亂方式,只要初始控制數組每個單元格都有1,這個方式就不會出現1的位置聚在一起的情況。
2.2顯示方式
2.2.1框架
我使用了在表格(table)中嵌套文本框的形式,這樣的好處是後面容易獲取填寫的數據參與正誤判斷,且表格容易實現九宮格的效果,我無需添加許多css樣式。
2.2.2已知數顯示
控制數組爲1的位置對應的表格位置內的文本框,value值設爲對應答案數組值的,同時將這個文本框設爲只讀,這樣文本框可以顯示固定的已知值,玩家不能修改那個單元格
3.輸入控制
限制只能輸入一個數字1-9
實現:先正則表達式限制數字以外的東西,一旦輸入onkeyup調用函數將value刷回爲空
然後將輸入數字parseInt,若爲0,刷回空字符,若大於9,則%10取餘
4.正誤判斷
我使用getelementId等方法,獲取文本框的value,然後生成一個玩家數組,和答案數組進行是否相等的方式比較
具體實現:兩個for循環,以及正誤控制變量k,初始化爲0,如果有一個位置數不相等,將k賦值爲1,若循環結束後,k爲1,則顯示答錯了,若k仍爲0則顯示恭喜答對了
5.答案顯示
功能:這個功能是按下一個按鈕後,所有文本框會顯示答案,原理是調用onclick激活一個函數,用兩個for循環,將9*9的答案刷如文本框的value
6.一些提升體驗的功能
6.1再來一題功能,按鈕onclick調用重新加載網頁的函數
6.2難度選擇功能,使用隱藏部分div,來實現四宮格和九宮格的各自出現
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>數獨遊戲</title>
<style type="text/css">
/*1.格式,使用類選擇器(對應class)*/
/*1.1文本框格式*/
.wbk{
width:50px;
height:50px;
text-align:center;/*格式是把style="width:50px; height:50px;text-align:center"內的東西移出來*/
}
/*1.2div格式*/
.divgs{
width:500px;
height:600px;
background-color: rgba(0,0,0,0.1);/*前三位表示顏色,最後一位表示透明度*/
margin:0 auto;/*設置margin,第一個參數表示頂部的距離爲0,而第二個auto表示的是自動,即自動根據網頁來居中。*/
}
/*1.3table格式*/
.tablegs{
width:200px;
height:200px;
background-color: rgba(0,255,0,0.1);/*前三位表示顏色,最後一位表示透明度*/
margin:0 auto;/*設置margin,第一個參數表示頂部的距離爲0,而第二個auto表示的是自動,即自動根據網頁來居中。*/
}
/*1.4按鈕格式*/
.angs{
width:100px;
height:50px;
background-color: rgba(0,0,255,0.1);/*前三位表示顏色,最後一位表示透明度*/
margin:220 auto;/*設置margin,第一個參數表示頂部的距離爲0,而第二個auto表示的是自動,即自動根據網頁來居中。*/
}
/*1.4表格一個的格式*/
.xgs{
background-color: rgba(255,0,0,0.1);/*前三位表示顏色,最後一位表示透明度*/
}
/*2.屬性選擇器*/
/*用name爲屬性*/
input[name="c1"]
{
background-color: rgba(255,255,51,1);;
}
</style>
<!--js代碼-->
<script language="javascript">
//1.弄亂數組函數
//1.1隨機數生成:生成0-2範圍內的整數
function suiji2(){
var a=0;
a=parseInt(Math.random()*10000);
var b=0;
b=a%3;
return b;
}
//1.2小九宮格內縱向打亂:橫向9個不動,縱向0-2,3-5,6-8內部序號互換
function zongmix2(shuzu2,x){//x負責調控0-2,3-5,6-8,第一個九宮格x爲0,第二個x爲3,第三個x爲6,橫向的y同理
var sj=0;
sj=suiji2();
var zhongzhuan=new Array();
zhongzhuan=shuzu2[sj+x];
shuzu2[sj+x]=shuzu2[((sj+1)%3)+x];
shuzu2[((sj+1)%3)+x]=zhongzhuan;
}
function quanzongmix2(shuzu2){
zongmix2(shuzu2,0);
zongmix2(shuzu2,3);
zongmix2(shuzu2,6);
}
//1.3九大格縱向打亂:橫向9個不動,0-2與3-5與6-8,3行爲單位互換
function dazongmix2(shuzu2){
var sj=0;
sj=suiji2();
var dagesj=(sj*3);//大格之間行距爲3,dagesui的值爲0,3,6
var zhongzhuan=new Array();;
for (i=0;i<3;i++){
zhongzhuan=shuzu2[dagesj+i];
shuzu2[dagesj+i]=shuzu2[(dagesj+3+i)%9];
shuzu2[(dagesj+3+i)%9]=zhongzhuan;
}
}
//1.4小九宮格內橫向打亂:縱向9個不動,橫向0-2,3-5,6-8內部序號互換
function hengmix2(shuzu2,y)
{
var sj=0;
sj=suiji2();
var zz=0;
for (i=0;i<9;i++)
{
zz=shuzu2[i][sj+y];
shuzu2[i][sj+y]=shuzu2[i][((sj+1)%3)+y];
shuzu2[i][((sj+1)%3)+y]=zz;
}
}
function quanhengmix2(shuzu2){
hengmix2(shuzu2,0);
zongmix2(shuzu2,3);
zongmix2(shuzu2,6);
}
//1.5九大格橫向打亂
function dahengmix2(shuzu2)
{
var sj=0;
sj=suiji2();
var dagesj=(sj*3);//大格之間行距爲3,dagesui的值爲0,3,6
var zz=0;
for (j=0;j<3;j++)
{
for (i=0;i<9;i++)
{
zz=shuzu2[i][dagesj+j];
shuzu2[i][dagesj+j]=shuzu2[i][(dagesj+3+j)%9];
shuzu2[i][(dagesj+3+j)%9]=zz;
}
}
}
//1.5多次打亂
function hunhe2(shuzu2)
{
for (k=0;k<15;k++)//這裏不能用i
{
quanzongmix2(shuzu2);
dazongmix2(shuzu2);
quanhengmix2(shuzu2);
dahengmix2(shuzu2);
}
}
//2.答案數組生成
//2.1生成數獨表原型數組
var shuzu2 = new Array();
shuzu2[0] = new Array();
shuzu2[0]=[1,2,3,4,5,6,7,8,9];
shuzu2[1] = new Array();
shuzu2[1]=[4,5,6,7,8,9,1,2,3];
shuzu2[2] = new Array();
shuzu2[2]=[7,8,9,1,2,3,4,5,6];
shuzu2[3] = new Array();
shuzu2[3]=[2,3,1,5,6,4,8,9,7];
shuzu2[4] = new Array();
shuzu2[4]=[5,6,4,8,9,7,2,3,1];
shuzu2[5] = new Array();
shuzu2[5]=[8,9,7,2,3,1,5,6,4];
shuzu2[6] = new Array();
shuzu2[6]=[3,1,2,6,4,5,9,7,8];
shuzu2[7] = new Array();
shuzu2[7]=[6,4,5,9,7,8,3,1,2];
shuzu2[8] = new Array();
shuzu2[8]=[9,7,8,3,1,2,6,4,5];
//2.2原型數組打亂生成答案數組
hunhe2(shuzu2);
//3.顯示控制xk2數組(用於控制哪些位置顯示已知數)
//3.1生成原型控制數組(數字1的多少即可調節難度)
var xk2 = new Array();
xk2[0] = new Array();
xk2[0]=[1,0,0,1,0,1,0,1,0];
xk2[1] = new Array();
xk2[1]=[0,0,1,0,1,0,1,0,0];
xk2[2] = new Array();
xk2[2]=[0,1,0,0,0,0,0,0,1];
xk2[3] = new Array();
xk2[3]=[1,0,0,1,1,0,0,0,1];
xk2[4] = new Array();
xk2[4]=[0,1,1,1,0,0,1,0,0];
xk2[5] = new Array();
xk2[5]=[1,0,0,1,0,0,0,1,1];
xk2[6] = new Array();
xk2[6]=[0,0,1,0,1,1,0,1,0];
xk2[7] = new Array();
xk2[7]=[1,1,1,0,0,1,0,1,0];
xk2[8] = new Array();
xk2[8]=[1,0,0,1,0,0,1,0,0];
//3.2打亂生成實際控制數組
hunhe2(xk2);
//4.顯示xs2在網頁中的已知數導入(原理:控制數組爲1的點對應答案數組點的數據顯示出來)
//4.1合成id號(字符串拼接函數)
function hcid2(x, y) {
var idhao2="txtnine"+x+y;
return idhao2;
}
//4.2已知數導入以及對應文本框只讀鎖定
function xs2()
{
window.onload=function()//onload可以使得js可以在網頁打開時就將表格內含的值改變
{
for (i=0;i<9;i++)
{
for (j=0;j<9;j++)
{
if (xk2[i][j]==1)
{
var str=hcid2(i,j);
document.getElementById(str).value=shuzu2[i][j];
document.getElementById(str).readOnly = true;//readOnly爲true則這個文本框只讀
}
}
}
};
}
xs2();
//5.提取數字正確判斷分析(暫時先使用與標準答案是否相同的算法,因爲數組小,到時候正式九宮格可能要用,數字不重複且範圍內,且相加和爲45)
//5.1文本框填入數字提取函數
function ds2(shuzi){
//第一種方法
var temp=document.getElementById(shuzi).value; //注意引號內的內容應該是文本框的id而不能是name
return temp;
}
//5.2與正確答案比較函數
var zw2=0;//正誤控制變量初始化
function zhengwu2(tianxie2)
{
zw2=0;//函數每次運行前初始化,這樣第二次做題纔有意義
for (i=0;i<9;i++)
{
for (j=0;j<9;j++)
{
if (tianxie2[i][j]!=shuzu2[i][j])
{
zw2=1; //若有不同正誤控制變量賦值爲1
}
}
}
}
//5.3答題者填入答案初始化
var tianxie2 = new Array();
for (i=0;i<9;i++)
{
tianxie2[i] = new Array(9);
}
//5.4答題者填入答案填入
function yiqi2()
{
for (i=0;i<9;i++)
{
for (j=0;j<9;j++)
{
var zhanshiid2=hcid2(i, j);
tianxie2[i][j]=ds2(zhanshiid2);
}
}
}
//5.5第五部分函數整體激活函數
function panduan2(){
yiqi2();
zhengwu2(tianxie2);
if(zw2==1)
{
alert("填錯了");
}
else
{
alert("恭喜全對");
}
}
//6.文本框輸入控制函數(由於知識有限實現控制輸入的方式比較低級)
function kongzi2(idcode)
{
//獲取該id對應的object
var temp=document.getElementById(idcode);//id的i大寫
//不準輸入數字以外的數
temp.value=temp.value.replace(/[^\d]/g,'');//js正則語法:/正則表達式主體/修飾符(可選)
//輸入數字控制
a=parseInt(temp.value);
//不準輸入0
if(a==0){
temp.value = '';
}
//只能輸入一位數,且後輸的數會取代前輸的數
if(a>9){
temp.value = a%10;
}
}
//不使用object.onkeyup,100X100更簡單,但在9宮格比較麻煩
//7.答案顯示函數(點擊按鈕後答案出現在文本框內)
function daan2()
{
for (i=0;i<9;i++)
{
for (j=0;j<9;j++)
{
var str=hcid2(i,j);
document.getElementById(str).value=shuzu2[i][j];
}
}
alert("答案可能不唯一,這只是一種答案");
}
//8.新的一題(同過頁面刷新實現)
function xinti2()
{
alert("代碼編寫者:周宇森");
location.reload();
}
</script>
</head>
<!--html代碼-->
<body>
<!--1.困難模式-->
<div class="divgs" id="sigongge">
<div style="text-align:center"><!--div居中-->
<p>困難模式</p>
<p>規則:根據已給的數字,將所有空格填上數字,要求每行每列以及九個小九宮格內都要有1-9</p>
</div>
<form name="form1" id="form2" method="post">
<table border="1" class="tablegs"><!--使用表格達到理想的視覺效果,在表格中嵌套文本框以達到響應的效果-->
<!--onkeyup當用戶釋放鍵盤按鈕時執行Javascript代碼:-->
<!--table對象可以動態創建,但是我暫時對代碼實現不太懂-->
<!--第一行-->
<tr>
<th><input type="text" name="c1" id="txtnine00" class="wbk" onkeyup="kongzi2('txtnine00')"></th>
<th><input type="text" name="c1" id="txtnine01" class="wbk" onkeyup="kongzi2('txtnine01')"></th>
<th><input type="text" name="c1" id="txtnine02" class="wbk" onkeyup="kongzi2('txtnine02')"></th>
<th><input type="text" id="txtnine03" class="wbk" onkeyup="kongzi2('txtnine03')"></th>
<th><input type="text" id="txtnine04" class="wbk" onkeyup="kongzi2('txtnine04')"></th>
<th><input type="text" id="txtnine05" class="wbk" onkeyup="kongzi2('txtnine05')"></th>
<th><input type="text" name="c1" id="txtnine06" class="wbk" onkeyup="kongzi2('txtnine06')"></th>
<th><input type="text" name="c1" id="txtnine07" class="wbk" onkeyup="kongzi2('txtnine07')"></th>
<th><input type="text" name="c1" id="txtnine08" class="wbk" onkeyup="kongzi2('txtnine08')"></th>
</tr>
<!--第二行-->
<tr>
<th><input type="text" name="c1" id="txtnine10" class="wbk" onkeyup="kongzi2('txtnine10')"></th>
<th><input type="text" name="c1" id="txtnine11" class="wbk" onkeyup="kongzi2('txtnine11')"></th>
<th><input type="text" name="c1" id="txtnine12" class="wbk" onkeyup="kongzi2('txtnine12')"></th>
<th><input type="text" id="txtnine13" class="wbk" onkeyup="kongzi2('txtnine13')"></th>
<th><input type="text" id="txtnine14" class="wbk" onkeyup="kongzi2('txtnine14')"></th>
<th><input type="text" id="txtnine15" class="wbk" onkeyup="kongzi2('txtnine15')"></th>
<th><input type="text" name="c1" name="c1" id="txtnine16" class="wbk" onkeyup="kongzi2('txtnine16')"></th>
<th><input type="text" name="c1" id="txtnine17" class="wbk" onkeyup="kongzi2('txtnine17')"></th>
<th><input type="text" name="c1" id="txtnine18" class="wbk" onkeyup="kongzi2('txtnine18')"></th>
</tr>
<!--第三行-->
<tr>
<th><input type="text" name="c1" id="txtnine20" class="wbk" onkeyup="kongzi2('txtnine20')"></th>
<th><input type="text" name="c1" id="txtnine21" class="wbk" onkeyup="kongzi2('txtnine21')"></th>
<th><input type="text" name="c1" id="txtnine22" class="wbk" onkeyup="kongzi2('txtnine22')"></th>
<th><input type="text" id="txtnine23" class="wbk" onkeyup="kongzi2('txtnine23')"></th>
<th><input type="text" id="txtnine24" class="wbk" onkeyup="kongzi2('txtnine24')"></th>
<th><input type="text" id="txtnine25" class="wbk" onkeyup="kongzi2('txtnine25')"></th>
<th><input type="text" name="c1" id="txtnine26" class="wbk" onkeyup="kongzi2('txtnine26')"></th>
<th><input type="text" name="c1" id="txtnine27" class="wbk" onkeyup="kongzi2('txtnine27')"></th>
<th><input type="text" name="c1" id="txtnine28" class="wbk" onkeyup="kongzi2('txtnine28')"></th>
</tr>
<!--第四行-->
<tr>
<th><input type="text" id="txtnine30" class="wbk" onkeyup="kongzi2('txtnine30')"></th>
<th><input type="text" id="txtnine31" class="wbk" onkeyup="kongzi2('txtnine31')"></th>
<th><input type="text" id="txtnine32" class="wbk" onkeyup="kongzi2('txtnine32')"></th>
<th><input type="text" name="c1" id="txtnine33" class="wbk" onkeyup="kongzi2('txtnine33')"></th>
<th><input type="text" name="c1" id="txtnine34" class="wbk" onkeyup="kongzi2('txtnine34')"></th>
<th><input type="text" name="c1" id="txtnine35" class="wbk" onkeyup="kongzi2('txtnine35')"></th>
<th><input type="text" id="txtnine36" class="wbk" onkeyup="kongzi2('txtnine36')"></th>
<th><input type="text" id="txtnine37" class="wbk" onkeyup="kongzi2('txtnine37')"></th>
<th><input type="text" id="txtnine38" class="wbk" onkeyup="kongzi2('txtnine38')"></th>
</tr>
<!--第五行-->
<tr>
<th><input type="text" id="txtnine40" class="wbk" onkeyup="kongzi2('txtnine40')"></th>
<th><input type="text" id="txtnine41" class="wbk" onkeyup="kongzi2('txtnine41')"></th>
<th><input type="text" id="txtnine42" class="wbk" onkeyup="kongzi2('txtnine42')"></th>
<th><input type="text" name="c1" id="txtnine43" class="wbk" onkeyup="kongzi2('txtnine43')"></th>
<th><input type="text" name="c1" id="txtnine44" class="wbk" onkeyup="kongzi2('txtnine44')"></th>
<th><input type="text" name="c1" id="txtnine45" class="wbk" onkeyup="kongzi2('txtnine45')"></th>
<th><input type="text" id="txtnine46" class="wbk" onkeyup="kongzi2('txtnine46')"></th>
<th><input type="text" id="txtnine47" class="wbk" onkeyup="kongzi2('txtnine47')"></th>
<th><input type="text" id="txtnine48" class="wbk" onkeyup="kongzi2('txtnine48')"></th>
</tr>
<!--第六行-->
<tr>
<th><input type="text" id="txtnine50" class="wbk" onkeyup="kongzi2('txtnine50')"></th>
<th><input type="text" id="txtnine51" class="wbk" onkeyup="kongzi2('txtnine51')"></th>
<th><input type="text" id="txtnine52" class="wbk" onkeyup="kongzi2('txtnine52')"></th>
<th><input type="text" name="c1" id="txtnine53" class="wbk" onkeyup="kongzi2('txtnine53')"></th>
<th><input type="text" name="c1" id="txtnine54" class="wbk" onkeyup="kongzi2('txtnine54')"></th>
<th><input type="text" name="c1" id="txtnine55" class="wbk" onkeyup="kongzi2('txtnine55')"></th>
<th><input type="text" id="txtnine56" class="wbk" onkeyup="kongzi2('txtnine56')"></th>
<th><input type="text" id="txtnine57" class="wbk" onkeyup="kongzi2('txtnine57')"></th>
<th><input type="text" id="txtnine58" class="wbk" onkeyup="kongzi2('txtnine58')"></th>
</tr>
<!--第七行-->
<tr>
<th><input type="text" name="c1" id="txtnine60" class="wbk" onkeyup="kongzi2('txtnine60')"></th>
<th><input type="text" name="c1" id="txtnine61" class="wbk" onkeyup="kongzi2('txtnine61')"></th>
<th><input type="text" name="c1" id="txtnine62" class="wbk" onkeyup="kongzi2('txtnine62')"></th>
<th><input type="text" id="txtnine63" class="wbk" onkeyup="kongzi2('txtnine63')"></th>
<th><input type="text" id="txtnine64" class="wbk" onkeyup="kongzi2('txtnine64')"></th>
<th><input type="text" id="txtnine65" class="wbk" onkeyup="kongzi2('txtnine65')"></th>
<th><input type="text" name="c1" id="txtnine66" class="wbk" onkeyup="kongzi2('txtnine66')"></th>
<th><input type="text" name="c1" id="txtnine67" class="wbk" onkeyup="kongzi2('txtnine67')"></th>
<th><input type="text" name="c1" id="txtnine68" class="wbk" onkeyup="kongzi2('txtnine68')"></th>
</tr>
<!--第八行-->
<tr>
<th><input type="text" name="c1" id="txtnine70" class="wbk" onkeyup="kongzi2('txtnine70')"></th>
<th><input type="text" name="c1" id="txtnine71" class="wbk" onkeyup="kongzi2('txtnine71')"></th>
<th><input type="text" name="c1" id="txtnine72" class="wbk" onkeyup="kongzi2('txtnine72')"></th>
<th><input type="text" id="txtnine73" class="wbk" onkeyup="kongzi2('txtnine73')"></th>
<th><input type="text" id="txtnine74" class="wbk" onkeyup="kongzi2('txtnine74')"></th>
<th><input type="text" id="txtnine75" class="wbk" onkeyup="kongzi2('txtnine75')"></th>
<th><input type="text" name="c1" id="txtnine76" class="wbk" onkeyup="kongzi2('txtnine76')"></th>
<th><input type="text" name="c1" id="txtnine77" class="wbk" onkeyup="kongzi2('txtnine77')"></th>
<th><input type="text" name="c1" id="txtnine78" class="wbk" onkeyup="kongzi2('txtnine78')"></th>
</tr>
<!--第九行-->
<tr>
<th><input type="text" name="c1" id="txtnine80" class="wbk" onkeyup="kongzi2('txtnine80')"></th>
<th><input type="text" name="c1" id="txtnine81" class="wbk" onkeyup="kongzi2('txtnine81')"></th>
<th><input type="text" name="c1" id="txtnine82" class="wbk" onkeyup="kongzi2('txtnine82')"></th>
<th><input type="text" id="txtnine83" class="wbk" onkeyup="kongzi2('txtnine83')"></th>
<th><input type="text" id="txtnine84" class="wbk" onkeyup="kongzi2('txtnine84')"></th>
<th><input type="text" id="txtnine85" class="wbk" onkeyup="kongzi2('txtnine85')"></th>
<th><input type="text" name="c1" id="txtnine86" class="wbk" onkeyup="kongzi2('txtnine86')"></th>
<th><input type="text" name="c1" id="txtnine87" class="wbk" onkeyup="kongzi2('txtnine87')"></th>
<th><input type="text" name="c1" id="txtnine88" class="wbk" onkeyup="kongzi2('txtnine88')"></th>
</tr>
</table>
<div style="text-align:center"><!--div居中-->
<input type="button" value="點擊提交" onclick="panduan2()" class="angs" ><!--絕對位置雖然會方便,但是手機上會出錯-->
</div>
<div style="text-align:center">
<input type="button" value="顯示答案" onclick="daan2()" class="angs" >
</div>
<div style="text-align:center">
<input type="button" value="新的一題" onclick="xinti2()" class="angs" >
</div>
</form>
</div>
</body>
</html>
<!--
易錯點
1.雙引號裏面就只能用單引號
2.
3.for循環用的變量小心,連續兩個for循環,或者for循環中嵌套了包含for循環的函數,就不能都用i了,要用i,j,k
-->