zoukankan      html  css  js  c++  java
  • 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;
         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;
         30px;
        height: 30px;
        text-align: center;
        LINE-height: 30px;
    }
    td.rr {
        border-right: #443 2px solid;
        border-top: #999 1px solid;
         30px;
        height: 30px;
        text-align: center;
        LINE-height: 30px;
    }
    td.top {
        border-right: #999 1px solid;
        border-top: #443 2px solid;
         30px;
        height: 30px;
        text-align: center;
        LINE-height: 30px;
    }
    td.topr {
    	border-right: #443 2px solid;
        border-top: #443 2px solid;
         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 .   本次分享到此结束,欢迎大家交流~~
  • 相关阅读:
    Ajax基本案例详解之$.getjson的实现
    Ajax基本案例详解之$.getjson的实现
    Ajax传递json数据
    Ajax传递json数据
    Ajax基本案例详解之load的实现
    多节点日志数据 数据集成
    crontab 问题分析
    不留文档的某某离开后 审计服务器操作历史
    /cloudmonitor.log 主机监控
    网关会对开发者的接口非业务调用错误做统一处理
  • 原文地址:https://www.cnblogs.com/jclian91/p/8259665.html
Copyright © 2011-2022 走看看