Django之破解数独
数独是一项快乐的益智游戏,起源于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之破解数独的更多相关文章
- JavaScript之破解数独(附详细代码)
在上一篇分享中,我们用Python和Django来破解数独,这对不熟悉Python和Django的人来说是非常不友好的.这次,笔者只用HTML和JavaScript写了破解数独的程序,对于熟悉前端 ...
- C++ 完美破解九宫格(数独)游戏
看到CSDN上有位大神用C#写了一个破解数独的程序(点击打开链接),不过我对C#也不懂,比较喜欢C++,就用标准C++也写了一个,希望各位喜欢.三纯程序,纯控制台程序,纯各人爱好,纯算法程序,无win ...
- 数独GUI程序项目实现
数独GUI程序项目实现 导语:最近玩上了数独这个游戏,但是找到的几个PC端数独游戏都有点老了...我就想自己做一个数独小游戏,也是一个不错的选择. 前期我在网上简单地查看了一些数独游戏的界面,代码.好 ...
- 阿里CBU技术面试小结
一个执着于技术的公众号 前言 今天给大家分享一篇胡文兴同学阿里CBU技术面试的自我总结,希望通过本篇文章也让正在准备求职面试的你有所帮助. 本篇文章已经征得原作者同意转载至本公众号,并且征得他的同意标 ...
- 数独破解c++代码
数独破解c++代码 #include <iostream> #include <cstring> #include <cstdio> #include <st ...
- codevs 2924 数独挑战
2924 数独挑战 http://codevs.cn/problem/2924/ 题目描述 Description "芬兰数学家因卡拉,花费3个月时间设计出了世界上迄今难度最大的数独游戏,而 ...
- django xadmin 外键
style_fields = {'db栏位名称': "fk-ajax"} 实体关系: Account (*)-->(1) user 表单控件: 下拉框 美化用了selecti ...
- django xadmin 插件(3) 列表视图新增自定义按钮
效果图: 编辑按钮是默认的list_editable属性对应的插件(xadmin.plugins.editable) 放大按钮对应的是自定义插件. 自定义按钮源码: xplugin.py(保证能够直接 ...
- 数独挑战(codevs 2924)
2924 数独挑战 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description “芬兰数学家因卡拉,花费3 ...
随机推荐
- Servlet执行流程和生命周期
Servlet执行流程 Get方式请求HelloServlet ---> <a href="servlet/HelloServlet"> ↓ 服务器在配置文档中查 ...
- JavaScript:原生模拟$.ajax以及jsonp
现实项目中,常常会用到请求,但是在考虑低版本的浏览器时,promise相关的axios,fetch这类第三方库的支持率就不那么好了,再考虑到最大的一个问题,跨域,更是让人头痛,虽然也有fetch-js ...
- Linux 下查看我们的不速之客
我们通过下面这个命令,可以查看 VPS 上还有谁在登陆: w 输出类似下列信息: 23:20:00 up 960 days, 4:29, 2 user, load average: 0.05, 0.0 ...
- NAT 模式下虚拟机安装的centos7 ping主机显示connect: Network is unreachable
在虚拟机下安装的centos7使用的网络是NAT模式,安装成功后ping主机地址显示 Network is unreachable 解决方案: 1)使用ifconfig命令查看网卡信息 2)进入/et ...
- 无网情况下linux安装django
创建虚拟环境~/project/hanqin/django> virtualenv monitor2~/project/hanqin/django/monitor2> cd bin~/pr ...
- Cura - CuraEngine - 架构分析
参考: https://blog.csdn.net/justdoithai/article/details/52746094
- utf-8转gb2312
近日在对一个json串进行转码时,显示中文乱码,原因是json串编码方式为utf-8,而我程序在windows上采用的是多字节编码方式,即采用gb2312编码.这里就存在一个utf-8到gb2312的 ...
- Linux下的redis的持久化,主从同步及哨兵
redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失, 为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久 ...
- Akka-Cluster(3)- ClusterClient, 集群客户端
上篇我们介绍了distributed pub/sub消息传递机制.这是在同一个集群内的消息共享机制:发布者(publisher)和订阅者(subscriber)都在同一个集群的节点上,所有节点上的Di ...
- 音视频编解码——YUV视频格式详解
一.YUV 介绍 YUV是一种颜色编码方方式,通常由彩色摄像机进行取像,然后把取得的彩色图像信号经过分色.分别放大校正后得到RGB,再经过矩阵变换得到亮度信号Y和两个色差信号B-Y(即U).R-Y(即 ...