数独求解

#-*-coding:utf-8-*-
import sys,copy
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class sudokuSolver(QMainWindow):
    def __init__(self,parent=None):
        super(sudokuSolver,self).__init__(parent)
        self.board=[]
        self.isEnd=False#数独是否已经有解
        
        self.file=QAction(QIcon('icon/open.png'),'File',self)
        self.connect(self.file,SIGNAL('triggered()'),self.readFile)
        self.fileBar = self.addToolBar('File')
        self.fileBar.addAction(self.file)

        self.begin=QAction(QIcon('icon/begin.png'),'Begin',self)
        self.connect(self.begin,SIGNAL('triggered()'),self.solve)
        self.beginBar = self.addToolBar('Begin')
        self.beginBar.addAction(self.begin)
        
        
        self.table=QTableWidget(9,9)
        self.table.verticalHeader().setVisible(False)
        self.table.horizontalHeader().setVisible(False)
        self.table.setEditTriggers(QTableWidget.NoEditTriggers)
        self.table.setAlternatingRowColors(True)
        for i in range(9):
            self.table.setColumnWidth(i,30)
        for i in range(9):
            self.table.setRowHeight(i,30)
        
        self.setWindowTitle('sudokuSolver')
        self.setCentralWidget(self.table)
        self.setFixedSize(300,330)
        self.setWindowIcon(QIcon('icon/3.png'))

    def readFile(self):
        fileName=QFileDialog.getOpenFileName(self,self.tr("Open File"),QString(),self.tr("Text Files(*.txt)"))
        f=open(fileName,'r')
        aLine=f.readline()
        while aLine:
            aLine=aLine.replace('\n','')
            self.board.append(aLine.split(' '))
            aLine=f.readline()
        #draw board
        for i in range(9):
            for j in range(9):
                if self.board[i][j]!='.':
                    newItem=QTableWidgetItem(self.board[i][j])
                    self.table.setItem(i,j,newItem)

    def solve(self):
        print(self.board)
        self.sudoku(0,self.board)

    def sudoku(self,num,board):
        if self.isEnd:
            return
        if num>80:
            print(board)
            #draw board
            for i in range(9):
                for j in range(9):
                    newItem=QTableWidgetItem(board[i][j])
                    self.table.setItem(i,j,newItem)
            self.isEnd=True
            return
        i=num/9
        j=num%9
        if board[i][j] == '.':
            for t in ['1','2','3','4','5','6','7','8','9']:
                isOk=True
                #检查行
                for k in range(9):
                    if board[i][k]==t:
                        isOk=False
                        break
                #检查列
                for k in range(9):
                    if board[k][j]==t:
                        isOk=False
                        break
                
                #检查方块
                x=0
                y=0
                if i<=2:
                    x=2
                elif i<=5:
                    x=5
                elif i<=8:
                    x=8
                if j<=2:
                    y=2
                elif j<=5:
                    y=5
                elif j<=8:
                    y=8

                for m in range(3):
                    for n in range(3):
                        if board[x][y]==t:
                            isOk=False
                        y=y-1
                    x=x-1
                    y=y+3
                
                if isOk:
                    nState=copy.deepcopy(board)
                    nState[i][j]=t
                    newNum=num+1
                    self.sudoku(newNum,nState)
        else:
            newNum=num+1
            self.sudoku(newNum,board)


def main():
    app=QApplication(sys.argv)
    demo=sudokuSolver()
    demo.show()
    app.exec_()
    
if __name__=='__main__':
    main()
    
    
        
        
        

结果截图:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值