基于PYQT5的N皇后问题可视化编程源代码

大家好!本文为大家提供了一种基于搜索求N皇后问题所有解的个数的方法,并用PyQt5实现了一个简单的交互界面。

基于PYQT5的N皇后问题可视化编程源代码_第1张图片

import sys
import random
import time
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QHBoxLayout,QVBoxLayout,QMessageBox,QMainWindow,QCheckBox,QLabel,QLineEdit,QComboBox,QDesktopWidget
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtCore import Qt

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

        self.Num_Queens=4
        self.If_Draw=1
        self.Draw_Flag=0
        self.all_results=dict()
        self.one_result=[]

    def initUI(self):
        #选择皇后数量
        self.label_numberbox=QLabel('皇后数量:' , self)
        NumberBox=QComboBox(self)
        NumberBox.addItem('4')
        NumberBox.addItem('6')
        NumberBox.addItem('8')
        NumberBox.addItem('10')
        NumberBox.addItem('12')
        NumberBox.addItem('14')
        NumberBox.addItem('16')
        self.label_numberbox.move(440,20)
        self.label_numberbox.resize(60,20)
        NumberBox.move(500,20)
        NumberBox.resize(40,20)
        NumberBox.activated.connect(self.Input_Num_Queens)

        #是否绘图
        self.label_ifdraw=QLabel('是否绘图:',self)
        Ifdraw=QComboBox(self)
        Ifdraw.addItem('是')
        Ifdraw.addItem('否')
        self.label_ifdraw.move(440,60)
        self.label_ifdraw.resize(60, 20)
        Ifdraw.move(500,60)
        Ifdraw.resize(40, 20)
        Ifdraw.activated.connect(self.Input_If_Draw)

        #耗时
        self.label_time1=QLabel('搜索耗时:',self)
        self.label_time2 = QLabel(self)
        self.label_time1.move(440, 100)
        self.label_time2.move(500, 100)

        #开始与停止搜索
        StartButton=QPushButton('开始搜索',self)
        StopButton=QPushButton('停止搜索',self)
        StartButton.clicked.connect(self.Start)
        StopButton.clicked.connect(self.Stop)
        StartButton.move(420,140)
        StopButton.move(510,140)

        # 随机输出一种解
        OutputButton = QPushButton('随机输出一种解', self)
        OutputButton.pressed.connect(self.Output_Solution)
        OutputButton.move(420,180)
        OutputButton.resize(165,20)

        self.setGeometry(150,150,600,410)
        self.setWindowTitle('N-皇后问题')
        self.show()

    def paintEvent(self, e):
        if self.Draw_Flag == 0:
            self.Draw_Board()
        else:
            self.Draw_Chess()

    def Input_Num_Queens(self,Num):
        self.Num_Queens=(Num+2)*2
        self.If_Draw = 1
        self.Draw_Flag = 0
        self.all_results = dict()
        self.one_result = []
        self.label_time2.setText('')
        self.update()

    def Input_If_Draw(self,Num):
         self.If_Draw=1 if Num==0 else 0

    def Start(self):
        self.Draw_Flag = 1

        def Get_All_Results(num):
            all_results = []
            current_board = []
            Get_All_Results_Impl(current_board,all_results)
            return all_results

        def Get_All_Results_Impl(current_board, all_results):
            NextX = len(current_board)
            for NextY in range(self.Num_Queens):
                Conflict = False
                #遍历下一行可摆的位置
                for i in range(NextX):
                    if NextY == current_board[i] or NextY == current_board[i] + NextX - i or NextY == current_board[i] - NextX + i:
                        Conflict = True
                        break
                #判断是否与之前的棋子冲突
                if Conflict == False:
                    new_board = current_board.copy()
                    new_board.append(NextY)
                    if len(new_board) == self.Num_Queens:
                        all_results.append(new_board.copy())
                        if self.If_Draw == 1:
                            self.one_result=new_board.copy()
                            self.repaint()
                    else:
                        Get_All_Results_Impl(new_board, all_results)

        time_begin=time.time()
        self.all_results=Get_All_Results(self.Num_Queens)
        time_end=time.time()

        Time_cost = round(time_end - time_begin , 5)
        Time_cost = str(Time_cost)
        self.label_time2.setText((Time_cost)+'s')
        self.label_time2.adjustSize()

        Num_results=len(self.all_results)

        self.Draw_Flag = 0

        QMessageBox.information(self, '结果', '共有'+str(Num_results)+'种解')

    def Stop(self):
        self.close()

    def Draw_Board(self):
        qp = QPainter()
        qp.begin(self)

        pen = QPen(Qt.black, 2, Qt.SolidLine)
        qp.setPen(pen)
        qp.drawLine(5, 5, 405, 5)
        qp.drawLine(5, 5, 5, 405)
        qp.drawLine(5, 405, 405, 405)
        qp.drawLine(405, 5, 405, 405)

        delta=int(400/self.Num_Queens)
        k=1
        A=1
        for i in range(self.Num_Queens):
            for j in range(self.Num_Queens):
                if k % 2 == A % 2:
                    qp.setBrush(QColor(128,128,128))
                    qp.drawRect(int(5 + i * delta), int(5 + j * delta), delta, delta)
                else:
                    qp.setBrush(QColor(255, 255, 255))
                    qp.drawRect(int(5 + i * delta), int(5 + j * delta), delta, delta)
                k+=1
            A+=1

        qp.end()

    def Draw_Chess(self):
        delta=int(400/self.Num_Queens)

        qp=QPainter()

        qp.begin(self)

        pen = QPen(Qt.black, 2, Qt.SolidLine)
        qp.setPen(pen)
        qp.drawLine(5, 5, 405, 5)
        qp.drawLine(5, 5, 5, 405)
        qp.drawLine(5, 405, 405, 405)
        qp.drawLine(405, 5, 405, 405)

        k = 1
        A = 1
        for i in range(self.Num_Queens):
            for j in range(self.Num_Queens):
                if k % 2 == A % 2:
                    qp.setBrush(QColor(128, 128, 128))
                    qp.drawRect(int(5 + i * delta), int(5 + j * delta), delta, delta)
                else:
                    qp.setBrush(QColor(255, 255, 255))
                    qp.drawRect(int(5 + i * delta), int(5 + j * delta), delta, delta)
                k += 1
            A += 1

        qp.setBrush(QColor(255,0,0))
        for i in range(self.Num_Queens):
            x=5+delta*i
            y=5+delta*(self.one_result[i])
            A=int(x+0.1*delta)
            B=int(y+0.1*delta)
            C=int(0.8*delta)
            D=int(0.8*delta)
            qp.drawEllipse(A,B,C,D)

        qp.end()

    def Output_Solution(self):
        if len(self.all_results)==0:
            QMessageBox.information(self, '提示', '尚未开始搜索')
        else:
            self.Draw_Flag = 1
            t = int(len(self.all_results)*random.random())
            self.one_result = self.all_results[t]
            self.repaint()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '提示',
                                     "确定退出?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Window()
    sys.exit(app.exec_())



你可能感兴趣的:(N皇后问题,python)