数独是一项快乐的益智游戏,起源于18世纪瑞士的一种数学游戏。解答者需要运用纸、笔进行演算,需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。

  本次分享讲展示如何利用Django来直观方便地破解数独。

  首先新建两个模板来展示页面,一个是index.html,方便用户输入数独,此数独可以来自其他网站;一个是answer.html,用于展示用户输入的数独的答案。

  index.html的代码如下:

<html>

<head>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'App/mystyle.css' %}" />
</head> <body background="{% static 'App/mountain.jpg' %}">
<center><h1>Solve A Sudoku</h1></center>
<form action="/answer/" method="get">
<table class="sd" border="0" align="center" cellspacing="1" cellpadding="1">
<tr>
<td class="xx"><input id="1" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="2" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="3" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="4" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="5" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="6" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="7" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="8" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="9" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="10" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="11" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="12" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="13" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="14" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="15" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="16" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="17" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="18" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="19" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="20" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="21" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="22" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="23" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="24" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="25" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="26" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="27" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="top"><input id="28" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="29" class="big" name="grid" maxlength="1"></td>
<td class="topr"><input id="30" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="31" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="32" class="big" name="grid" maxlength="1"></td>
<td class="topr"><input id="33" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="34" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="35" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="36" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="37" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="38" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="39" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="40" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="41" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="42" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="43" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="44" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="45" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="46" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="47" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="48" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="49" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="50" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="51" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="52" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="53" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="54" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="top"><input id="55" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="56" class="big" name="grid" maxlength="1"></td>
<td class="topr"><input id="57" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="58" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="59" class="big" name="grid" maxlength="1"></td>
<td class="topr"><input id="60" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="61" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="52" class="big" name="grid" maxlength="1"></td>
<td class="top"><input id="63" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="64" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="65" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="66" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="67" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="68" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="69" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="70" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="71" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="72" class="big" name="grid" maxlength="1"></td>
</tr>
<tr>
<td class="xx"><input id="73" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="74" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="75" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="76" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="77" class="big" name="grid" maxlength="1"></td>
<td class="rr"><input id="78" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="79" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="80" class="big" name="grid" maxlength="1"></td>
<td class="xx"><input id="81" class="big" name="grid" maxlength="1"></td>
</tr>
</table>
<br>
<center>
<button type="reset" value="Reset">Reset</button>
<input type="submit" value="Show Anwser">
</center>
</form>
</body> </html>

  answer.html的代码如下:

<html>

<head>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'App/mystyle.css' %}" />
</head> <body background="{% static 'App/sky.jpg' %}">
<center><h1>{{info}}</h1>
{% ifequal info 'The solution is found:'%}
<script>
var mat = {{grid|safe}};
var mat_orig = {{grid_orig|safe}};
var i,j;
document.write('<table class="sd" border="0" align="center" cellspacing="1" cellpadding="1">');
for(i=0;i<9;i++){
document.write('<tr>');
if (i != 3 && i != 6){
for(j=0;j<9;j++){
if(j ==2 || j ==5){
if(mat[i][j] == mat_orig[i][j]){
document.write('<td class="rr"><font color="blue" size="5">'+mat[i][j]+'</font</td>');
}
else{
document.write('<td class="rr">'+mat[i][j]+'</td>');
}
}
else{
if(mat[i][j] == mat_orig[i][j]){
document.write('<td class="xx"><font color="blue" size="5">'+mat[i][j]+'</font</td>');
}
else{
document.write('<td class="xx">'+mat[i][j]+'</td>');
}
}
}
}
else{
for(j=0;j<9;j++){
if(j ==2 || j ==5){
if(mat[i][j] == mat_orig[i][j]){
document.write('<td class="topr"><font color="blue" size="5">'+mat[i][j]+'</font</td>');
}
else{
document.write('<td class="topr">'+mat[i][j]+'</td>');
}
}
else{
if(mat[i][j] == mat_orig[i][j]){
document.write('<td class="top"><font color="blue" size="5">'+mat[i][j]+'</font</td>');
}
else{
document.write('<td class="top">'+mat[i][j]+'</td>');
}
}
}
}
document.write('</tr>');
}
</script>
{% endifequal %}
<button onclick="window.location.href='http://localhost:8000/index'">Return</button>
<br><br>
</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;
}

  在views.py中,获取从前端index.html输入的数字信息,并进行数独的破解,再将破解后的答案输出到answer.html.其中,views.py的代码如下:

import json
from django.http import HttpResponse
from django.shortcuts import render_to_response def index(request):
return render_to_response('index.html') #Read a Sudoku puzzle from the web page
def readAPuzzle(lst):
grid=[]
for i in range(9):
grid.append(lst[9*i:9*(i+1)]) return grid #Obtain a list of free cells from the puzzle
def getFreeCellList(grid):
freeCellList=[]
for i in range(9):
for j in range(9):
if grid[i][j] == 0:
freeCellList.append([i,j]) return freeCellList #Search for a solution
def search(grid):
freeCellList=getFreeCellList(grid)
numberOfFreeCells=len(freeCellList)
if numberOfFreeCells == 0:
return True k=0 #Start from the first free cell while True:
i=freeCellList[k][0]
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 += 1
elif grid[i][j] < 9:
#Fill the free cell with the next possible value
grid[i][j] += 1
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 -= 1 #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] += 1 return True #A solution is found #Check whether grid[i][j] is valid in the grid
def isValid(i,j,grid):
#Check whether grid[i][j] is valid at the i's row
for column in range(9):
if column != j and grid[i][column] == grid[i][j]:
return False #Check whether grid[i][j] is valid at the j's column
for row in range(9):
if row != i and grid[row][j] == grid[i][j]:
return False #Check whether grid[i][j] is valid at the 3-by-3 box
for row in range((i//3)*3,(i//3)*3+3):
for col in range((j//3)*3,(j//3)*3+3):
if row != i and col != j and 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
def isValidGrid(grid):
for i in range(9):
for j in range(9):
if grid[i][j] not in range(10) or (grid[i][j] in range(1,10) and not isValid(i,j,grid)):
return False
return True def answer(request):
#Get input from the index.html page
get_lst = request.REQUEST.getlist("grid")
#original grid to store the input numbers, replace empty string with 0
grid_orig = readAPuzzle(lst = [int(_) if _ else 0 for _ in get_lst])
#the grid that store a answer with latter processing
grid = readAPuzzle(lst = [int(_) if _ else 0 for _ in get_lst]) #information to output
info = ""
if not isValidGrid(grid):
info = "Invalid input"
elif search(grid):
info = "The solution is found:"
else:
info = "No solution!"
return render_to_response('answer.html',{'grid_orig':json.dumps(grid_orig),'grid':json.dumps(grid),'info':info})

  启动该Django项目的服务,在浏览器中输入'localhost:8000/index',页面如下:

![用户输入界面](http://img.blog.csdn.net/20180110165712092?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

  我们在http://www.sudoku-cn.com/中随便找一个难度为‘高级+’的数独游戏,将其输入到index.html页面中,如下:

![数独游戏](http://img.blog.csdn.net/20180110170203295?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

  按下"Show Answer"按钮,不用1秒,答案就出来了,如下所示:

![显示答案](http://img.blog.csdn.net/20180110170341981?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

  在该页面中,按下"Return"按钮可回到原先的输入页面。
  怎么样?这样的数独破解程序是不是酷酷的?欢迎访问该项目的Github地址:https://github.com/percent4/Sudoku-Solver .
  本次分享到此结束,欢迎大家交流~~

Django之破解数独的更多相关文章

  1. JavaScript之破解数独(附详细代码)

      在上一篇分享中,我们用Python和Django来破解数独,这对不熟悉Python和Django的人来说是非常不友好的.这次,笔者只用HTML和JavaScript写了破解数独的程序,对于熟悉前端 ...

  2. C++ 完美破解九宫格(数独)游戏

    看到CSDN上有位大神用C#写了一个破解数独的程序(点击打开链接),不过我对C#也不懂,比较喜欢C++,就用标准C++也写了一个,希望各位喜欢.三纯程序,纯控制台程序,纯各人爱好,纯算法程序,无win ...

  3. 数独GUI程序项目实现

    数独GUI程序项目实现 导语:最近玩上了数独这个游戏,但是找到的几个PC端数独游戏都有点老了...我就想自己做一个数独小游戏,也是一个不错的选择. 前期我在网上简单地查看了一些数独游戏的界面,代码.好 ...

  4. 阿里CBU技术面试小结

    一个执着于技术的公众号 前言 今天给大家分享一篇胡文兴同学阿里CBU技术面试的自我总结,希望通过本篇文章也让正在准备求职面试的你有所帮助. 本篇文章已经征得原作者同意转载至本公众号,并且征得他的同意标 ...

  5. 数独破解c++代码

    数独破解c++代码 #include <iostream> #include <cstring> #include <cstdio> #include <st ...

  6. codevs 2924 数独挑战

    2924 数独挑战 http://codevs.cn/problem/2924/ 题目描述 Description "芬兰数学家因卡拉,花费3个月时间设计出了世界上迄今难度最大的数独游戏,而 ...

  7. django xadmin 外键

    style_fields = {'db栏位名称': "fk-ajax"} 实体关系: Account (*)-->(1) user 表单控件: 下拉框 美化用了selecti ...

  8. django xadmin 插件(3) 列表视图新增自定义按钮

    效果图: 编辑按钮是默认的list_editable属性对应的插件(xadmin.plugins.editable) 放大按钮对应的是自定义插件. 自定义按钮源码: xplugin.py(保证能够直接 ...

  9. 数独挑战(codevs 2924)

    2924 数独挑战  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description “芬兰数学家因卡拉,花费3 ...

随机推荐

  1. Scrum冲刺阶段1

    各个成员在 Alpha 阶段认领的任务 人员 任务 何承华 美化设计 部分后端设计 陈宇 后端设计 丁培辉 美化设计 部分后端设计 温志铭 前端设计 杨宇潇 服务器搭建 张主强 前端设计 明日各个成员 ...

  2. 【对比分析四】position的absolute与fixed共同点与不同点

    共同点: (1) 改变行内元素的呈现方式,display被置为block: (2) 让元素脱离普通流,不占据空间: (3) 默认会覆盖到非定位元素上 不同点: absolute的”根元素“是可以设置的 ...

  3. Linux(以centos7为例)下自动挂载NTFS硬盘

    Linux(以centos7为例)下自动挂载NTFS硬盘 作者:子敬叔叔 编写时间:2017年5月3日星期三 需求:     为了熟悉Linux的使用,在自己的笔记本上新安装一个centos7, 但我 ...

  4. EF6学习笔记(六) 创建复杂的数据模型

    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇原文地址:Creating a More Complex Data Model 本篇讲的比较碎,很多内容本人 ...

  5. kaldi的TIMIT实例二

    ============================================================================ MonoPhone Training & ...

  6. Linux下的redis的持久化,主从同步及哨兵

    redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失, 为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久 ...

  7. web API简介(二):客户端储存之document.cookie API

    概述 前篇:web API简介(一):API,Ajax和Fetch 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据.document.cook ...

  8. Swift5 语言指南(二) 版本兼容性

    本书描述了Swift 5,它是Xcode 10.2中包含的Swift的默认版本.您可以使用Xcode 10.2构建以Swift 5,Swift 4.2或Swift 4编写的目标. 当您使用Xcode ...

  9. spring boot 通过controller跳转到指定 html 页面问题以及请求静态资源问题

    1. 项目结构 2. pom文件配置 重点是红色框内的依赖 3. application配置文件 4. controller 注意使用@Controller注解: @RestController 等价 ...

  10. ASP.NET Core中自定义路由约束

    路由约束 ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值.可选和约束. 约束的使用方法是在属性路由上添加指定的约束名,用法如下: // 单个使用 [R ...