一、頁面展示
(1)頁面中的空格爲input,方便輸入數據,數據通過使用Vue實現雙向動態綁定
(2)任意填入數據
(3)點擊【解密】,即解出數獨答案(當然我這裏是讓程序計算出一種結果便結束的
二、代碼展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>數獨</title>
<script type="text/javascript" src="../Import/vue.js"></script> <!--在上-->
<link rel="stylesheet" href="../Import/element-ui-index.css">
<script type="text/javascript" src="../Import/element-ui-index.js"></script>
<style>
li {
list-style: none;
}
.el-input__inner {
border-radius: 0;
}
</style>
</head>
<body>
<div id="app">
<ul>
<h2 style="margin-left: 155px">數獨解密</h2>
<li v-for="(value,i) in items.length">
<span v-for="(item,j) in items[i]" @click="changeNum(i,j)">
<el-input class="ano" v-model="items[i][j]" maxlength="1"
style="width: 45px;font-size: 20px;text-align: center;cursor: pointer"></el-input>
</span>
</li>
</ul>
<el-button size="medium" style="margin-left: 300px" @click="reset">重置</el-button>
<el-button size="medium" type="primary" @click="decode">解密</el-button>
</div>
</body>
<script>
new Vue({
el: '#app',
data() {
return {
items: [["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", ""]],
sign: false,
}
},
mounted() {
let all_div = document.querySelectorAll('.ano');
for (let i = 0; i < 9; i++) {
all_div[i * 9].style.borderLeft = "1px solid black";
all_div[i * 9 + 2].style.borderRight = "1px solid black";
all_div[i * 9 + 5].style.borderRight = "1px solid black";
all_div[i * 9 + 8].style.borderRight = "1px solid black";
all_div[i].style.borderTop = "1px solid black";
all_div[i + 9 * 3].style.borderTop = "1px solid black";
all_div[i + 9 * 6].style.borderTop = "1px solid black";
all_div[i + 9 * 8].style.borderBottom = "1px solid black";
}
},
methods: {
changeNum(i, j) {
console.log(i, j);
console.log(typeof this.items[i][j]);
},
reset() {
this.sign = false;
for (let i = 0;i < 9;i++){
for (let j = 0;j < 9;j++){
this.items[i].splice(j, 1, ""); //刪除第行第j 個元素,再賦值""
}
}
},
//一行裏面1-9
//一列裏面1-9
//一個九宮格里面1-9
check(n, key) { // 判斷key填入n格時是否滿足條件,n代表第幾個格子
for (let ii = 0; ii < 9; ii++) { // j爲n豎座標 判斷n所在行是否合法
let jj = parseInt(n / 9);
if (this.items[jj][ii] == key)
return false;
}
for (let ii = 0; ii < 9; ii++) { // j爲n橫座標 判斷n所在列是否合法
let jj = n % 9;
if (this.items[ii][jj] == key)
return false;
}
let y = parseInt(parseInt(n / 9) / 3) * 3;
let x = parseInt((n % 9) / 3) * 3;
for (let ii = y; ii < y + 3; ii++)//判斷n所在的小九宮格是否合法
for (let jj = x; jj < x + 3; jj++)
if (this.items[ii][jj] == key)
return false;
return true;
},
dfs(n) { // 所有的都符合,退出搜索,n代表格子數,共81個格子,0~80
if (n > 80) {
this.sign = true;
return;
}
if (this.items[parseInt(n / 9)][n % 9] != "")
this.dfs(n + 1);
else { // 否則對當前位一次填入1~9進行測試
for (let ii = 1; ii <= 9; ii++) {
if (this.check(n, ii)) {
this.items[parseInt(n / 9)].splice([n % 9],1,ii);
this.dfs(n + 1);
if (this.sign)// 返回時如果構造成功,則直接退出
return;
// 繼續搜索,後續位也填1~9測試,直到最後一位,通過的話置true
// 如果構造不成功,還原當前位
this.items[parseInt(n / 9)].splice([n % 9],1,"");
//this.items[parseInt(n / 9)][n % 9] = "";
}
}
}
},
decode() {
console.log(this.items);
console.log("解密");
this.dfs(0); //從第0格開始填
console.log(this.items);
this.items = JSON.parse(JSON.stringify(this.items));
}
}
})
</script>
</html>
三、爬坑
(1)在頁面中直接通過input輸入的數據類型爲String
原因:
我一開始寫匹配的時候,寫的 === 便成了第一個坑,因爲我實際上往數組裏面存的數據是Number型,而 === 判斷 1 != "1"。
check(n, key) {
for (let ii = 0; ii < 9; ii++) {
let jj = parseInt(n / 9);
if (this.items[jj][ii] == key) /*這個位置 here*/
return false;
}
for (let ii = 0; ii < 9; ii++) {
let jj = n % 9;
if (this.items[ii][jj] == key) /*這個位置 here*/
return false;
}
let y = parseInt(parseInt(n / 9) / 3) * 3;
let x = parseInt((n % 9) / 3) * 3;
for (let ii = y; ii < y + 3; ii++)
for (let jj = x; jj < x + 3; jj++)
if (this.items[ii][jj] == key) /*這個位置 here*/
return false;
return true;
},
(2)Vue數組中數值變化頁面不渲染問題
解出數獨值之後,數組雖然已發生變化,但是頁面未發生渲染 數據動態綁定竟然失效!
原因:
由於JavaScript的限制,Vue不能檢測以下變動的數組:
1. 利用索引值直接設置一個項時,如vm.items[indexOfItem] = newValue;
this.items[parseInt(n / 9)][n % 9] = ii; //本代碼中出問題的地方
this.items[parseInt(n / 9)][n % 9] = "";
2. 修改數組的長度時,如vm.items.lenngth = newLength;
爲了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue
相同的效果,同時也將觸發狀態更新:
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
爲了解決第二類問題,你可以使用 splice
:
example1.items.splice(newLength)
其他相關Vue無法渲染的問題參考如下:Vue數組中對象屬性變化頁面不渲染問題
解決方法1:
decode() {
console.log(this.items);
console.log("解密");
this.dfs(0);
console.log(this.items);
this.items = JSON.parse(JSON.stringify(this.items)); //解決方法:直接重新賦值
}
解決方法2:使用splice方法
this.items[parseInt(n / 9)].splice(n % 9, 1, ii); //將出現問題的兩句代碼替換爲splice
this.items[parseInt(n / 9)].splice(n % 9, 1, "");
(3)JavaScript 除法 會保留小數點
解決:
爬坑長經驗!!