JavaScript之破解数独(附详细代码)
在上一篇分享中,我们用Python和Django来破解数独,这对不熟悉Python和Django的人来说是非常不友好的。这次,笔者只用HTML和JavaScript写了破解数独的程序,对于熟悉前端的人,这是十分友好的。
话不多说,直接上代码。
首页index.html的代码如下:
<html>
<head>
<link rel="stylesheet" type="text/css" href="mystyle.css" />
<script type="text/javascript" src="answer.js"></script>
</head>
<body background="mountain.jpg">
<center><h1>Solve A Sudoku</h1></center>
<table class="sd" border="0" align="center" cellspacing="1" cellpadding="1">
<tr>
<td class="xx"><input id="1" class="big" maxlength="1"></td>
<td class="xx"><input id="2" class="big" maxlength="1"></td>
<td class="rr"><input id="3" class="big" maxlength="1"></td>
<td class="xx"><input id="4" class="big" maxlength="1"></td>
<td class="xx"><input id="5" class="big" maxlength="1"></td>
<td class="rr"><input id="6" class="big" maxlength="1"></td>
<td class="xx"><input id="7" class="big" maxlength="1"></td>
<td class="xx"><input id="8" class="big" maxlength="1"></td>
<td class="xx"><input id="9" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="10" class="big" maxlength="1"></td>
<td class="xx"><input id="11" class="big" maxlength="1"></td>
<td class="rr"><input id="12" class="big" maxlength="1"></td>
<td class="xx"><input id="13" class="big" maxlength="1"></td>
<td class="xx"><input id="14" class="big" maxlength="1"></td>
<td class="rr"><input id="15" class="big" maxlength="1"></td>
<td class="xx"><input id="16" class="big" maxlength="1"></td>
<td class="xx"><input id="17" class="big" maxlength="1"></td>
<td class="xx"><input id="18" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="19" class="big" maxlength="1"></td>
<td class="xx"><input id="20" class="big" maxlength="1"></td>
<td class="rr"><input id="21" class="big" maxlength="1"></td>
<td class="xx"><input id="22" class="big" maxlength="1"></td>
<td class="xx"><input id="23" class="big" maxlength="1"></td>
<td class="rr"><input id="24" class="big" maxlength="1"></td>
<td class="xx"><input id="25" class="big" maxlength="1"></td>
<td class="xx"><input id="26" class="big" maxlength="1"></td>
<td class="xx"><input id="27" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="top"><input id="28" class="big" maxlength="1"></td>
<td class="top"><input id="29" class="big" maxlength="1"></td>
<td class="topr"><input id="30" class="big" maxlength="1"></td>
<td class="top"><input id="31" class="big" maxlength="1"></td>
<td class="top"><input id="32" class="big" maxlength="1"></td>
<td class="topr"><input id="33" class="big" maxlength="1"></td>
<td class="top"><input id="34" class="big" maxlength="1"></td>
<td class="top"><input id="35" class="big" maxlength="1"></td>
<td class="top"><input id="36" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="37" class="big" maxlength="1"></td>
<td class="xx"><input id="38" class="big" maxlength="1"></td>
<td class="rr"><input id="39" class="big" maxlength="1"></td>
<td class="xx"><input id="40" class="big" maxlength="1"></td>
<td class="xx"><input id="41" class="big" maxlength="1"></td>
<td class="rr"><input id="42" class="big" maxlength="1"></td>
<td class="xx"><input id="43" class="big" maxlength="1"></td>
<td class="xx"><input id="44" class="big" maxlength="1"></td>
<td class="xx"><input id="45" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="46" class="big" maxlength="1"></td>
<td class="xx"><input id="47" class="big" maxlength="1"></td>
<td class="rr"><input id="48" class="big" maxlength="1"></td>
<td class="xx"><input id="49" class="big" maxlength="1"></td>
<td class="xx"><input id="50" class="big" maxlength="1"></td>
<td class="rr"><input id="51" class="big" maxlength="1"></td>
<td class="xx"><input id="52" class="big" maxlength="1"></td>
<td class="xx"><input id="53" class="big" maxlength="1"></td>
<td class="xx"><input id="54" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="top"><input id="55" class="big" maxlength="1"></td>
<td class="top"><input id="56" class="big" maxlength="1"></td>
<td class="topr"><input id="57" class="big" maxlength="1"></td>
<td class="top"><input id="58" class="big" maxlength="1"></td>
<td class="top"><input id="59" class="big" maxlength="1"></td>
<td class="topr"><input id="60" class="big" maxlength="1"></td>
<td class="top"><input id="61" class="big" maxlength="1"></td>
<td class="top"><input id="52" class="big" maxlength="1"></td>
<td class="top"><input id="63" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="64" class="big" maxlength="1"></td>
<td class="xx"><input id="65" class="big" maxlength="1"></td>
<td class="rr"><input id="66" class="big" maxlength="1"></td>
<td class="xx"><input id="67" class="big" maxlength="1"></td>
<td class="xx"><input id="68" class="big" maxlength="1"></td>
<td class="rr"><input id="69" class="big" maxlength="1"></td>
<td class="xx"><input id="70" class="big" maxlength="1"></td>
<td class="xx"><input id="71" class="big" maxlength="1"></td>
<td class="xx"><input id="72" class="big" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="73" class="big" maxlength="1"></td>
<td class="xx"><input id="74" class="big" maxlength="1"></td>
<td class="rr"><input id="75" class="big" maxlength="1"></td>
<td class="xx"><input id="76" class="big" maxlength="1"></td>
<td class="xx"><input id="77" class="big" maxlength="1"></td>
<td class="rr"><input id="78" class="big" maxlength="1"></td>
<td class="xx"><input id="79" class="big" maxlength="1"></td>
<td class="xx"><input id="80" class="big" maxlength="1"></td>
<td class="xx"><input id="81" class="big" maxlength="1"></td>
</tr>
</table>
<br>
<center>
<button type="button" onclick="clc()">Clear</button>
<button type="button" onclick="get_answer()">Show Answer</button>
</center>
</body>
</html>
其使用的样式表mystyle.css的代码如下:
.sd {
table-layout: fixed;
border: #443 3px solid;
width: 355px;
height: 355px;
background-color: #fff;
vertical-align: middle;
border-collapse: collapse;
text-align: center;
}
.big {
FONT-SIZE: 25px;
border: none;
background-color: transparent;
WIDTH: 30px;
HEIGHT: 30px;
LINE-HEIGHT: 28px;
TEXT-ALIGN: center;
margin: 0px;
COLOR: #0000FF;
FONT-FAMILY: Verdana;
}
td.xx {
border-right: #999 1px solid;
border-top: #999 1px solid;
width: 30px;
height: 30px;
text-align: center;
LINE-height: 30px;
}
td.rr {
border-right: #443 2px solid;
border-top: #999 1px solid;
width: 30px;
height: 30px;
text-align: center;
LINE-height: 30px;
}
td.top {
border-right: #999 1px solid;
border-top: #443 2px solid;
width: 30px;
height: 30px;
text-align: center;
LINE-height: 30px;
}
td.topr {
border-right: #443 2px solid;
border-top: #443 2px solid;
width: 30px;
height: 30px;
text-align: center;
LINE-height: 30px;
}
其使用的JavaScript的代码(answer.js)如下:
//clear all the input
function clc(){
for(var i=0; i<81; i++){
document.getElementsByTagName("input")[i].value = "";
document.getElementsByTagName("input")[i].style.color = 'blue';
}
document.body.style.backgroundImage = "url(mountain.jpg)";
}
//press "show answer" button and show answer then
function get_answer(){
var bool = check_input();
if(bool){
var grid = readAPuzzle();
if(!isValidGrid(grid)){
alert("Invalid input, please try again!");
}
else{
if(search(grid)){
output_ans();
document.body.style.backgroundImage = "url(sky.jpg)";
}
else{
alert("Found no solution!");
}
}
}
}
//check if the input are valid
function check_input(){
var arr = new Array();
for(var i=0; i<81; i++){
arr[i] = Number(document.getElementsByTagName("input")[i].value);
if(isNaN(arr[i])){
alert('Input should be any number between 1 and 9 !');
return false
}
}
if(arr.every(function isZero(x){return x== 0})){
alert('There is no input!');
return false
}
return true
}
//read a puzzle from the web page
function readAPuzzle(){
var arr = new Array();
for(var i=0; i<81; i++){
arr[i] = Number(document.getElementsByTagName("input")[i].value);
}
var grid = new Array();
for(var i=0; i<9; i++){
grid[i] = new Array();
for(var j=0; j<9; j++){
grid[i][j] = 0;
}
}
for(var i=0; i<81; i++){
grid[Math.floor(i/9)][i%9] = arr[i];
}
return grid
}
//Obtain a list of free cells from the puzzle
function getFreeCellList(grid){
var freeCellList = new Array();
index = 0
for(var i=0; i<9; i++){
for(var j=0; j<9; j++){
if(grid[i][j] == 0){
freeCellList[index] = new Array(i,j);
index++;
}
}
}
return freeCellList
}
//Check whether grid[i][j] is valid in the grid
function isValid(i,j,grid){
//Check whether grid[i][j] is valid at the i's row
for(var column=0; column<9; column++){
if((column != j) && (grid[i][column] == grid[i][j])){
return false
}
}
//Check whether grid[i][j] is valid at the j's column
for(var row=0; row<9; row++){
if((row != i) && (grid[row][j] == grid[i][j])){
return false
}
}
//Check whether grid[i][j] is valid at the 3-by-3 box
for(var row=Math.floor(i/3)*3; row < Math.floor(i/3)*3+3; row++){
for(var col=Math.floor(j/3)*3; col < Math.floor(j/3)*3+3; col++){
if((row != i) && (col != j) && (grid[row][col] == grid[i][j])){
return false
}
}
}
return true //The current value at grid[i][j] is valid
}
//Check whether the fixed cells are valid in the grid
function isValidGrid(grid){
for(var i=0; i<9; i++){
for(var j=0; j<9; j++){
if((grid[i][j] < 0) || (grid[i][j] > 9) || ((grid[i][j] != 0) && (! isValid(i,j,grid)))){
return false
}
}
}
return true
}
//Search for a solution
function search(grid){
var freeCellList = getFreeCellList(grid);
var numberOfFreeCells = freeCellList.length;
if(numberOfFreeCells == 0){
return true
}
var k = 0; //Start from the first free cell
while(true){
var i = freeCellList[k][0];
var j = freeCellList[k][1];
if(grid[i][j] == 0){
grid[i][j] = 1;
}
if(isValid(i,j,grid)){
if(k+1 == numberOfFreeCells){
//no more free cells
return true //A solution is found
}
else{
//Move to the next free cell
k++;
}
}
else{
if(grid[i][j] < 9){
//Fill the free cell with the next possible value
grid[i][j]++;
}
else{
//grid[i][j] is 9,backtrack
while(grid[i][j] == 9){
if(k == 0){
return false //No possible value
}
grid[i][j] = 0; //Reset to free cell
k--; //Backtrack to the preceding free cell
i = freeCellList[k][0];
j = freeCellList[k][1];
}
//Fill the free cell with the next possible value
//search continues from this free cell at k
grid[i][j]++;
}
}
}
return true //A solution is found
}
//output the answer on the web page
function output_ans(){
var grid = readAPuzzle();
var grid_original = readAPuzzle();
if(search(grid)){
for(var i=0; i<81; i++){
if(grid[Math.floor(i/9)][i%9] != grid_original[Math.floor(i/9)][i%9]){
document.getElementsByTagName("input")[i].value = grid[Math.floor(i/9)][i%9];
document.getElementsByTagName("input")[i].style.color = 'black';
}
}
}
}
我们将对如何操作做一个简单的图解说明。
开始的页面如下:
![开始页面](http://img.blog.csdn.net/20180112170516897?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
首先,如果没有任何输入而直接点击“Show Answer”按钮,则会显示如下页面:
![没有任何输入而直接点击“Show Answer”按钮](http://img.blog.csdn.net/20180112170408140?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如何在表格中一旦输入非数字,则会显示如下页面:
![在表格中输入非数字](http://img.blog.csdn.net/20180112170704244?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
若在九宫格中输入的数字不符合规则,则会显示页面如下:
![在九宫格中输入的数字不符合规则](http://img.blog.csdn.net/20180112170822474?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当我们输入的数字符合规则时,就能得到正确的答案,比如,我们在http://www.cn.sudokupuzzle.org/上随便找一个“骨灰级”的数独并输入,页面如下:
![“骨灰级”的数独](http://img.blog.csdn.net/20180112171202339?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当我们按下“Show Answer”按钮时,显示的答案如下:
![显示答案](http://img.blog.csdn.net/20180112171309460?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当按下“Clear”按钮时,所有格子将会被清空,这样我们就能就行下一次破解啦~~
本次分享到此结束,欢迎大家交流~~
P.S.写这个项目主要是为了学习JavaScript,因为最近刚开始接触前端。欢迎大家访问这个项目的Github地址:https://github.com/percent4/Sudoku-Solver-JavaScript-Version .
JavaScript之破解数独(附详细代码)的更多相关文章
- Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例【附详细代码】
http://blog.csdn.net/xiefu5hh/article/details/51707529 Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例[附 ...
- LTMP手动编译安装以及全自动化部署实践(附详细代码)
大家使用LNMP架构,一般可以理解为Linux Shell为CentOS/RadHat/Fedora/Debian/Ubuntu/等平台安装LNMP(Nginx/MySQL /PHP),LNMPA(N ...
- Python——EM(期望极大算法)教学(附详细代码与注解)
今天,我们详细的讲一下EM算法. 前提准备 Jupyter notebook 或 Pycharm 火狐浏览器或谷歌浏览器 win7或win10电脑一台 网盘提取csv数据 需求分析 实现高斯混合模型的 ...
- 手把手教你用Python实现“坦克大战”,附详细代码!
小时候玩的“坦克大战”,你还记得吗? 满满的回忆 ! 今天,我们使用Python以及强大的第三方库来实现一个简单的坦克大战游戏. 整体效果 环境依赖 python3.7 pygame1.9.6 ...
- 15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码)
15分钟带你了解前端工程师必知的javascript设计模式(附详细思维导图和源码) 前言 设计模式是一个程序员进阶高级的必备技巧,也是评判一个工程师工作经验和能力的试金石.设计模式是程序员多年工作经 ...
- Ajax引擎:ajax请求步骤详细代码
说起AJAX,可能是很多同学在很多地方都看到过,各大招聘网站上对于WEB前端和PHP程序员的技能要求清单中也是必不可少的一项.但是,ajax请求步骤详细代码以及说明却比较少见到 什么是AJAX引擎? ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...
- Django之破解数独
数独是一项快乐的益智游戏,起源于18世纪瑞士的一种数学游戏.解答者需要运用纸.笔进行演算,需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫(3*3)内的 ...
- Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)
Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误) Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误) 升级到Truffle3.0 如果之前安装的是Truf ...
随机推荐
- Elasticsearch下安装ik分词器
安装ik分词器(必须安装maven) 上传相应jar包 解压到相应目录 unzip elasticsearch-analysis-ik-master.zip(zip包) cp -r elasticse ...
- ABP框架系列之四十二:(Object-To-Object-Mapping-对象映射)
Introduction It's a common to map a similar object to another object. It's also tedious and repeatin ...
- C++ MFC棋牌类小游戏day4
根据昨天的计划,今天开始做下面的内容. 1.鼠标点击事件 2.点击坐标进行处理.(坐标转换) 3.判断选中的位置是否有效. 4.确定选中的棋子,设置棋子的状态和棋子所在坐标的状态. 5.判断移动是否有 ...
- 让photoshop cc 支持 webp格式
下载WebP.8bi文件,看PS cc 是32位还是64位,找到对应的文件. brushes8.com-2017-11-03_08-29-21_654098.7z 把 WebP.8bi 复制到pho ...
- 在windows 下使用eclipse进行编译和烧写
eclipse IDE是一款开源的前端编程软件,它提供了编写,编译和调试ESP-IDF项目的图形集成开发环境. 首先在https://www.obeo.fr/en/eclipse-download?I ...
- IDEA运行android项目一直是同一个apk
1.IDEA运行android项目时不像eclipse和android studio那样直接运行,IDEA需要设置Artifacts,这样每次运行的时候它才能重新编译,以下附上步骤! 这样就可以了.
- pgsqls修改表字段长度
alter table T_RPACT_PROTO_EDIT_RECORD alter column remark type VARCHAR(1024); 需要注意type关键字
- nginx 502错误 upstream sent too big header while reading response header from upstream
原本的设置是 proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; 在这种配置下,使用fiddler进行抓包分 ...
- Visual Studio Code 写Python 代码
最近在博客园新闻里面看到微软发布的Visual Studio Code 挺好用的,现在在学习Python,查看官网发布的VSCode 是支持Python代码,自己试着安装用一下,下面是我的安装以及配置 ...
- [UWP]实现一个轻量级的应用内消息通知控件
在UWP应用开发中,我们常常有向用户发送一些提示性消息的需求.这种时候我们一般会选择MessageDialog.ContentDialog或者ToastNotification来完成功能. 但是,我们 ...