Example #1
0
class GoBang(QWidget):
    backSignal = QtCore.pyqtSignal()  # 返回信号,用来和主界面连接

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):  # UI初始化

        self.chessboard = ChessBoard()  # 棋盘类,详见chessboard.py

        palette1 = QPalette()  # 设置棋盘背景
        palette1.setBrush(self.backgroundRole(),
                          QtGui.QBrush(QtGui.QPixmap('source/游戏界面1.png')))
        self.setPalette(palette1)

        # self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        self.sound_piece = QSound("sound/move.wav")  # 加载落子音效
        self.sound_win = QSound("sound/win.wav")  # 加载胜利音效
        self.sound_defeated = QSound("sound/defeated.wav")  # 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 画布大小,设为固定值,不允许缩放
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        self.setWindowIcon(QIcon('source/icon.ico'))  # 窗口图标

        # 所有按钮的图标和布局
        self.backBtn = MyButton.MyButton('source/返回按钮_hover.png',
                                         'source/返回按钮_normal.png',
                                         'source/返回按钮_press.png',
                                         parent=self)
        self.backBtn.move(610, 80)

        self.startBtn = MyButton.MyButton('source/开始按钮_hover.png',
                                          'source/开始按钮_normal.png',
                                          'source/开始按钮_press.png',
                                          parent=self)
        self.startBtn.move(610, 180)

        self.returnBtn = MyButton.MyButton('source/悔棋按钮_hover.png',
                                           'source/悔棋按钮_normal.png',
                                           'source/悔棋按钮_press.png',
                                           parent=self)
        self.returnBtn.move(610, 400)

        self.loseBtn = MyButton.MyButton('source/认输按钮_hover.png',
                                         'source/认输按钮_normal.png',
                                         'source/认输按钮_press.png',
                                         parent=self)
        self.loseBtn.move(610, 500)

        #绑定按钮
        self.backBtn.clicked.connect(self.goBack)
        self.startBtn.clicked.connect(self.restart)
        self.loseBtn.clicked.connect(self.lose)
        self.returnBtn.clicked.connect(self.returnOneStep)

        # self.gameStatu = []

        self.black = QPixmap('source/black.png')  # 黑白棋子
        self.white = QPixmap('source/white.png')

        self.piece_now = BLACK  # 黑棋先行
        self.my_turn = True  # 玩家先行
        self.step = 0  # 步数
        self.x, self.y = 1000, 1000

        # self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        # self.mouse_point.setScaledContents(True)
        # self.mouse_point.setPixmap(self.black)  # 加载黑棋
        # self.mouse_point.setGeometry(270, 270, PIECE, PIECE)
        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  # 图片大小根据标签大小可变

        self.ai_down = True  # AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        self.show()

    # 返回键设计,回到主菜单
    def goBack(self):
        self.backSignal.emit()
        self.close()

    def closeEvent(self, a0: QtGui.QCloseEvent):
        self.backSignal.emit()

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    # def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
    #     # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
    #     self.mouse_point.move(e.x() - 16, e.y() - 16)

    def mousePressEvent(self, e):  # 玩家下棋
        if e.button() == Qt.LeftButton and self.ai_down == True:
            x, y = e.x(), e.y()  # 鼠标坐标
            i, j = self.coordinate_transform_pixel2map(x, y)  # 对应棋盘坐标
            if not i is None and not j is None:  # 棋子落在棋盘上,排除边缘
                if self.chessboard.get_xy_on_logic_state(
                        i, j) == EMPTY:  # 棋子落在空白处
                    self.draw(i, j)  # 玩家棋子绘制

                    # ----------------------------------------------------------------------
                    # 这里要对接双人落子,我准备偷个懒,直接把ui的全部代码粘到另一个文件里,修改落子代码实现双人对战。对接的同学有好的传参方式也可以直接修改这份代码。
                    # ----------------------------------------------------------------------

                    self.ai_down = False
                    board = self.chessboard.board()
                    self.AI = AI(board)  # 新建线程对象,传入棋盘参数
                    self.AI.finishSignal.connect(self.AI_draw)  # 结束线程,传出参数
                    self.AI.start()  # run

    # ----------------------------------------------------------------------

    # 以下部分和AI落子相关,对接的同学请注意
    # ----------------------------------------------------------------------

    def AI_draw(self, i, j):
        if self.step != 0:
            self.draw(i, j)  # AI
            self.x, self.y = self.coordinate_transform_map2pixel(i, j)
        self.ai_down = True
        self.update()

    def drawLines(self, qp):  # 指示AI当前下的棋子
        if self.step != 0:
            pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
            qp.setPen(pen)
            qp.drawLine(self.x - 5, self.y - 5, self.x + 3, self.y + 3)
            qp.drawLine(self.x + 3, self.y, self.x + 3, self.y + 3)
            qp.drawLine(self.x, self.y + 3, self.x + 3, self.y + 3)

    # 落子代码
    def draw(self, i, j):
        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.piece_now == BLACK:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
            self.piece_now = WHITE
            self.chessboard.draw_xy(i, j, BLACK)
        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.piece_now = BLACK
            self.chessboard.draw_xy(i, j, WHITE)

        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        self.sound_piece.play()  # 落子音效
        self.step += 1  # 步数+1

        winner = self.chessboard.anyone_win(i, j)  # 判断输赢
        if winner != EMPTY:
            # self.mouse_point.clear()
            self.gameover(winner)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGINXL + j * GRID - PIECE / 2, MARGINY + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round(
            (y - MARGINY) / GRID)), int(round((x - MARGINXL) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= 15 or j < 0 or j >= 15:
            return None, None
        else:
            return i, j

    # 这块代码后期还可以再改,用图片做出来应该会更好看
    def gameover(self, winner):
        if winner == BLACK:
            self.sound_win.play()
            reply = QMessageBox.question(self, 'You Win!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        else:
            self.sound_defeated.play()
            reply = QMessageBox.question(self, 'You Lost!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)

        if reply == QMessageBox.Yes:  # 复位
            self.piece_now = BLACK
            self.mouse_point.setPixmap(self.black)
            self.step = 0
            for piece in self.pieces:
                piece.clear()
            self.chessboard.reset()
            self.update()
        else:
            self.close()

    # 认输功能键,不知道为什么卡的厉害。人机对战的认输还没写
    def lose(self):
        # if self.gameStatu == False:
        #     return
        if self.piece_now == BLACK:
            self.gameover(WHITE)
        # elif self.turnChessColor == "white":
        #     self.lbl = QLabel(self)
        #     self.lbl.setPixmap(QPixmap("source/黑棋胜利.png"))
        #     self.lbl.move(150,150)
        #     self.lbl.show()
        else:
            return

    # 重开,这个问题有点大,重新绘图我没实现。目前是把数组清空了,图没变(在上面重新画棋盘也太蠢了吧,刷新界面会比较好但是我没写出来:/)
    def restart(self):
        for i in range(15):
            for j in range(15):
                x, y = self.coordinate_transform_map2pixel(i, j)
                self.chessboard.draw_xy(i, j, EMPTY)
                self.pieces[self.step].setGeometry(x, y, 100, 100)
        # if self.lbl != None:
        #     self.lbl.close()
        self.chessboard.reset
        # self.close
        # ex = GoBang()

    # 这个理论上要做悔棋功能,看看写代码的同学是怎么实现的。
    def returnOneStep(self):
        return
Example #2
0
class GoBang(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.chessboard = ChessBoard()  # 棋盘类

        palette1 = QPalette()  # 设置棋盘背景
        palette1.setBrush(self.backgroundRole(),
                          QtGui.QBrush(QtGui.QPixmap('img/chessboard.jpg')))
        self.setPalette(palette1)
        # self.setStyleSheet("board-image:url(img/chessboard.jpg)")  # 不知道这为什么不行
        self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        self.sound_piece = QSound("sound/luozi.wav")  # 加载落子音效
        self.sound_win = QSound("sound/win.wav")  # 加载胜利音效
        self.sound_defeated = QSound("sound/defeated.wav")  # 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 固定大小 540*540
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        self.setWindowIcon(QIcon('img/black.png'))  # 窗口图标

        # self.lb1 = QLabel('            ', self)
        # self.lb1.move(20, 10)

        self.black = QPixmap('img/black.png')
        self.white = QPixmap('img/white.png')

        self.piece_now = BLACK  # 黑棋先行
        self.my_turn = True  # 玩家先行
        self.step = 0  # 步数
        self.x, self.y = 1000, 1000

        self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        self.mouse_point.setScaledContents(True)
        self.mouse_point.setPixmap(self.black)  # 加载黑棋
        self.mouse_point.setGeometry(270, 270, PIECE, PIECE)
        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  # 图片大小根据标签大小可变

        self.mouse_point.raise_()  # 鼠标始终在最上层
        self.ai_down = True  # AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        self.show()

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
        # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
        self.mouse_point.move(e.x() - 16, e.y() - 16)

    def mousePressEvent(self, e):  # 玩家下棋
        if e.button() == Qt.LeftButton and self.ai_down == True:
            x, y = e.x(), e.y()  # 鼠标坐标
            i, j = self.coordinate_transform_pixel2map(x, y)  # 对应棋盘坐标
            if not i is None and not j is None:  # 棋子落在棋盘上,排除边缘
                if self.chessboard.get_xy_on_logic_state(
                        i, j) == EMPTY:  # 棋子落在空白处
                    self.draw(i, j)
                    self.ai_down = False
                    board = self.chessboard.board()
                    self.AI = AI(board)  # 新建线程对象,传入棋盘参数
                    self.AI.finishSignal.connect(self.AI_draw)  # 结束线程,传出参数
                    self.AI.start()  # run

    def AI_draw(self, i, j):
        if self.step != 0:
            self.draw(i, j)  # AI
            self.x, self.y = self.coordinate_transform_map2pixel(i, j)
        self.ai_down = True
        self.update()

    def draw(self, i, j):
        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.piece_now == BLACK:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
            self.piece_now = WHITE
            self.chessboard.draw_xy(i, j, BLACK)
        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.piece_now = BLACK
            self.chessboard.draw_xy(i, j, WHITE)

        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        self.sound_piece.play()  # 落子音效
        self.step += 1  # 步数+1

        winner = self.chessboard.anyone_win(i, j)  # 判断输赢
        if winner != EMPTY:
            self.mouse_point.clear()
            self.gameover(winner)

    def drawLines(self, qp):  # 指示AI当前下的棋子
        if self.step != 0:
            pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
            qp.setPen(pen)
            qp.drawLine(self.x - 5, self.y - 5, self.x + 3, self.y + 3)
            qp.drawLine(self.x + 3, self.y, self.x + 3, self.y + 3)
            qp.drawLine(self.x, self.y + 3, self.x + 3, self.y + 3)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGIN + j * GRID - PIECE / 2, MARGIN + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round((y - MARGIN) / GRID)), int(round((x - MARGIN) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= 15 or j < 0 or j >= 15:
            return None, None
        else:
            return i, j

    def gameover(self, winner):
        if winner == BLACK:
            self.sound_win.play()
            reply = QMessageBox.question(self, 'You Win!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        else:
            self.sound_defeated.play()
            reply = QMessageBox.question(self, 'You Lost!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)

        if reply == QMessageBox.Yes:  # 复位
            self.piece_now = BLACK
            self.mouse_point.setPixmap(self.black)
            self.step = 0
            for piece in self.pieces:
                piece.clear()
            self.chessboard.reset()
            self.update()
        else:
            self.close()
Example #3
0
class GoBang(QWidget):
    backSignal = QtCore.pyqtSignal()  # 返回信号,用来和主界面连接

    def __init__(self):
        super().__init__()
        self.initUI()
        self.c = self.init_clent()


    def init_clent(self): # 客户端初始化
        # 创建 socket 对象
        c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 获取服务器ip地址 应该由界面输入 在这里直接用主机地址代替
        # host = input('please input the server IP address : ')
        host = socket.gethostname()
        # 设置端口号
        port = 9999
        # 连接服务,指定主机和端口
        c.connect((host, port))
        t1 = threading.Thread(target=self.client_recv)
        t1.start()
        return c

    def client_recv(self):
        '''接收数据'''
        while True:
            try:
                data = self.c.recv(1024).decode()
                str_list = data.split(' ')
                x, y = int(str_list[0]), int(str_list[1])
                print('xy')
                self.draw(x, y)
                self.ai_down = True  # 解锁 允许鼠标点击下棋
            except:
                pass



    def initUI(self):  # UI初始化

        self.chessboard = ChessBoard()  # 棋盘类,详见chessboard.py

        palette1 = QPalette()  # 设置棋盘背景
        palette1.setBrush(self.backgroundRole(), QtGui.QBrush(QtGui.QPixmap('source/游戏界面1.png')))
        self.setPalette(palette1)

        # self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        self.sound_piece = QSound("sound/move.wav")  # 加载落子音效
        self.sound_win = QSound("sound/win.wav")  # 加载胜利音效
        self.sound_defeated = QSound("sound/defeated.wav")  # 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 画布大小,设为固定值,不允许缩放
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        self.setWindowIcon(QIcon('source/icon.ico'))  # 窗口图标

        # 所有按钮的图标和布局
        self.backBtn = MyButton.MyButton('source/返回按钮_hover.png',
                                         'source/返回按钮_normal.png',
                                         'source/返回按钮_press.png',
                                         parent=self)
        self.backBtn.move(610, 80)

        self.startBtn = MyButton.MyButton('source/开始按钮_hover.png',
                                          'source/开始按钮_normal.png',
                                          'source/开始按钮_press.png',
                                          parent=self)
        self.startBtn.move(610, 180)

        self.returnBtn = MyButton.MyButton('source/悔棋按钮_hover.png',
                                           'source/悔棋按钮_normal.png',
                                           'source/悔棋按钮_press.png',
                                           parent=self)
        self.returnBtn.move(610, 400)

        self.loseBtn = MyButton.MyButton('source/认输按钮_hover.png',
                                         'source/认输按钮_normal.png',
                                         'source/认输按钮_press.png',
                                         parent=self)
        self.loseBtn.move(610, 500)

        # 绑定按钮
        self.backBtn.clicked.connect(self.goBack)
        self.startBtn.clicked.connect(self.restart)
        self.loseBtn.clicked.connect(self.lose)
        self.returnBtn.clicked.connect(self.returnOneStep)

        # self.gameStatu = []

        self.black = QPixmap('source/black.png')  # 黑白棋子
        self.white = QPixmap('source/white.png')

        self.piece_now = BLACK  # 黑棋先行



        self.step = 0  # 步数
        self.x, self.y = 1000, 1000



        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  # 图片大小根据标签大小可变

        # self.mouse_point.raise_()  # 鼠标始终在最上层
        self.ai_down = True  # 主要是为了加锁,当值是False的时候在等待对方下棋,这时候己方鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        self.show()

    # 返回键设计,回到主菜单
    def goBack(self):
        self.backSignal.emit()
        self.close()

    def closeEvent(self, a0: QtGui.QCloseEvent):
        self.backSignal.emit()

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    # def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
    #     # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
    #     self.mouse_point.move(e.x() - 16, e.y() - 16)

    def mousePressEvent(self, e):  # 玩家1下棋

        if e.button() == Qt.LeftButton and self.ai_down:
            x, y = e.x(), e.y()  # 鼠标坐标
            i, j = self.coordinate_transform_pixel2map(x, y)  # 对应棋盘坐标
            if not i is None and not j is None:  # 棋子落在棋盘上,排除边缘
                if self.chessboard.get_xy_on_logic_state(i, j) == EMPTY:  # 棋子落在空白处
                    t1 = (str(i), ' ', str(j))
                    t2 = ''.join(t1)
                    # 发送棋子坐标到服务器
                    self.c.send(t2.encode('utf-8'))
                    self.draw(i, j)
                    self.ai_down = False # 加锁 避免鼠标再点击


    def drawLines(self, qp):  # 绘制lines
        if self.step != 0:
            pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
            qp.setPen(pen)
            qp.drawLine(self.x - 5, self.y - 5, self.x + 3, self.y + 3)
            qp.drawLine(self.x + 3, self.y, self.x + 3, self.y + 3)
            qp.drawLine(self.x, self.y + 3, self.x + 3, self.y + 3)

    # 落子代码
    def draw(self, i, j):

        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.piece_now == BLACK:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
            self.piece_now = WHITE
            self.chessboard.draw_xy(i, j, BLACK)
        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.piece_now = BLACK
            self.chessboard.draw_xy(i, j, WHITE)

        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        self.sound_piece.play()  # 落子音效
        self.step += 1  # 步数+1

        winner = self.chessboard.anyone_win(i, j)  # 判断输赢
        if winner != EMPTY:
            # self.mouse_point.clear()
            self.gameover(winner)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGINXL + j * GRID - PIECE / 2, MARGINY + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round((y - MARGINY) / GRID)), int(round((x - MARGINXL) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= 15 or j < 0 or j >= 15:
            return None, None
        else:
            return i, j

    # 这块代码后期还可以再改,用图片做出来应该会更好看
    def gameover(self, winner):
        if winner == BLACK:
            self.sound_win.play()
            reply = QMessageBox.question(self, 'You Win!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        else:
            self.sound_defeated.play()
            reply = QMessageBox.question(self, 'You Lost!', 'Continue?',
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:  # 复位
            self.piece_now = BLACK
            self.mouse_point.setPixmap(self.black)
            self.step = 0
            for piece in self.pieces:
                piece.clear()
            self.chessboard.reset()
            self.update()
        else:
            self.close()

    # 认输功能键,不知道为什么卡的厉害。人机对战的认输还没写
    def lose(self):
        # if self.gameStatu == False:
        #     return
        if self.piece_now == BLACK:
            self.gameover(WHITE)
        # elif self.turnChessColor == "white":
        #     self.lbl = QLabel(self)
        #     self.lbl.setPixmap(QPixmap("source/黑棋胜利.png"))
        #     self.lbl.move(150,150)
        #     self.lbl.show()
        else:
            return

    # 重开,这个问题有点大,重新绘图我没实现。目前是把数组清空了,图没变(在上面重新画棋盘也太蠢了吧,刷新界面会比较好但是我没写出来:/)
    def restart(self):
        for i in range(15):
            for j in range(15):
                x, y = self.coordinate_transform_map2pixel(i, j)
                self.chessboard.draw_xy(i, j, EMPTY)
                self.pieces[self.step].setGeometry(x, y, 100, 100)
        # if self.lbl != None:
        #     self.lbl.close()
        self.chessboard.reset
        # self.close
        # ex = GoBang()

    # 这个理论上要做悔棋功能,看看写代码的同学是怎么实现的。
    def returnOneStep(self):
        return
Example #4
0
class GoBang(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.chessboard = ChessBoard()  # 棋盘类
        self.chess_manual = ""

        palette1 = QPalette()  # 设置棋盘背景
        pix = QtGui.QPixmap('board_' + str(N_LINE) + '.jpg')
        pix = pix.scaled(WIDTH, HEIGHT)
        palette1.setBrush(self.backgroundRole(), QtGui.QBrush(pix))
        self.setPalette(palette1)

        self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        #self.sound_piece = QSound("sound/luozi.wav")# 加载落子音效
        # self.sound_win = QSound("sound/win.wav")# 加载胜利音效
        # self.sound_defeated = QSound("sound/defeated.wav")# 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 固定大小 540*540
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        self.setWindowIcon(QIcon('black.png'))  # 窗口图标

        # self.lb1 = QLabel('			', self)
        # self.lb1.move(20, 10)

        self.black = QPixmap('black.png')
        self.white = QPixmap('white.png')

        self.is_black_do = True  # 黑棋回合先行
        self.Going_over = True
        self.step = 0  # 步数
        self.x, self.y = 1000, 1000

        self.who = QLabel('Black Player is Going...', self)
        self.who.resize(WIDTH, MARGIN)
        self.who.move(0, 0)
        self.who.setAlignment(Qt.AlignHCenter)
        self.who.setFont(QFont("Roman times", MARGIN / 3, QFont.Bold))

        # choose the Mode pvp,pve,eve
        text, ok = QInputDialog.getText(
            self, 'The Black Player',
            'Choose the Black Player\n0 for Human\n1 for AI_1\n2 for AI_2\n3 for AI_3\n4 for AI_MCTS'
        )
        black_text = 0
        white_text = 0
        if not ok:
            sys.exit()
        while (1):
            if ok:
                if text == "0":
                    black_text = 0
                    break
                elif text == "1":
                    black_text = 1
                    break
                elif text == "2":
                    black_text = 2
                    break
                elif text == "3":
                    black_text = 3
                    break
                elif text == "4":
                    black_text = 4
                    break
                else:
                    text, ok = QInputDialog.getText(
                        self, 'The Black Player',
                        'Illegal Input!\n0 for Human\n1 for AI_1\n2 for AI_2\n3 for AI_3\n4 for AI_MCTS'
                    )

        self.setWindowIcon(QIcon('white.png'))
        text, ok = QInputDialog.getText(
            self, 'The White Player',
            'Choose the White Player\n0 for Human\n1 for AI_1\n2 for AI_2\n3 for AI_3\n4 for AI_MCTS'
        )

        if not ok:
            sys.exit()
        while (1):
            if ok:
                if text == "0":
                    white_text = 0
                    break
                elif text == "1":
                    white_text = 1
                    break
                elif text == "2":
                    white_text = 2
                    break
                elif text == "3":
                    white_text = 3
                    break
                elif text == "4":
                    white_text = 4
                    break
                else:
                    text, ok = QInputDialog.getText(
                        self, 'The White Player',
                        'Illegal Input!\n0 for Human\n1 for AI_1\n2 for AI_2\n3 for AI_3\n4 for AI_MCTS'
                    )

        self.player_black = ChoiceOfPlayer(self.chessboard, black_text, True,
                                           self)
        self.player_white = ChoiceOfPlayer(self.chessboard, white_text, False,
                                           self)
        self.black_text = black_text
        self.white_text = white_text
        # text, ok = QInputDialog.getText(self, 'Mode Select', '1 for PvsP\n2 for PvsAI\n3 for AIvAI\n4 for Random vs AI\n5 for Random vs Random')
        # Mode = 0
        # while(1):
        # 	if ok:
        # 		if text == "1":
        # 			Mode = 1
        # 			break
        # 		elif text == "2":
        # 			Mode = 2
        # 			break
        # 		elif text == "3":
        # 			Mode = 3
        # 			break
        # 		elif text == "4":
        # 			Mode = 4
        # 			break
        # 		elif text == "5":
        # 			Mode = 5
        # 			break
        # 		else:
        # 			text, ok = QInputDialog.getText(self, 'Mode Select', 'Illegal input\n1 for pvp\n2 for pve\n3 for eve')

        # if Mode == 1:
        # 	self.player_black = ChoiceOfPlayer(self.chessboard,0,True,self)

        # 	self.player_white = ChoiceOfPlayer(self.chessboard,0,False,self)

        # elif Mode == 3:
        # 	self.player_black = ChoiceOfPlayer(self.chessboard,1,True,self)
        # 	self.player_white = ChoiceOfPlayer(self.chessboard,1,False,self)
        # elif Mode == 5:
        # 	self.player_black = ChoiceOfPlayer(self.chessboard,2,True,self)
        # 	self.player_white = ChoiceOfPlayer(self.chessboard,2,False,self)
        # elif Mode == 2:
        # 	human_color, ok = QInputDialog.getText(self, 'Color Select', '1 for black\n2 for white')
        # 	while(1):
        # 		if ok:
        # 			if human_color == "1":
        # 				self.player_black = ChoiceOfPlayer(self.chessboard,0,True,self)
        # 				self.player_white = ChoiceOfPlayer(self.chessboard,1,False,self)
        # 				break;
        # 			elif human_color == "2":
        # 				self.player_white = ChoiceOfPlayer(self.chessboard,0,False,self)
        # 				self.player_black = ChoiceOfPlayer(self.chessboard,1,True,self)
        # 				break;
        # 			else:
        # 				human_color, ok = QInputDialog.getText(self, 'Color Select', 'Illegal input\n1 for black\n2 for white')
        # else Mode == 4:

        self.setWindowIcon(QIcon('black.png'))
        self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        self.mouse_point.setScaledContents(True)
        self.mouse_point.setPixmap(self.black)  #加载黑棋
        self.mouse_point.setGeometry(270, 270, PIECE, PIECE)
        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  #图片大小根据标签大小可变

        self.mouse_point.raise_()  # 鼠标始终在最上层
        #self.ai_down = True# AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        print('Choose Over')
        self.show()
        self.game()

    def game(self):

        if (1):
            self.player_black.is_black = True
            self.player_white.is_black = True
            #if self.is_black_do == True and self.Going_over == True:
            if (1):
                print('black')
                self.Going_over = False
                self.player_black.board = self.chessboard
                #self.player_black.is_black = True
                self.player_black.finishSignal.connect(self.AI_draw)
                if self.step < 2:
                    self.player_black.start()

            #if self.is_black_do == False and self.Going_over == True:
            if (1):
                print('white')
                self.Going_over = False
                self.player_white.board = self.chessboard
                #self.player_white.is_black = False
                self.player_white.finishSignal.connect(self.AI_draw)
                if self.step < 2:
                    self.player_white.start()

    def AI_draw(self, i, j):
        if self.step != -1:
            self.draw(i, j)  # AI
            self.x_t, self.y_t = self.coordinate_transform_map2pixel(i, j)

        self.update()

    def draw(self, i, j):
        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.is_black_do == True:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
            self.is_black_do = False
            self.chessboard.draw_xy(i, j, BLACK)
            self.who.setText('WHITE Player is Going...')
        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.is_black_do = True
            self.chessboard.draw_xy(i, j, WHITE)
            self.who.setText('BLACK Player is Going...')

        print(self.step)
        #b,w = self.chessboard.value_judge()
        #b,w = self.chessboard.value_judge_2(i,j)
        #print('B_value:' + str(b) + '\n' + 'W_value:' + str(w) + '\n')
        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        #self.sound_piece.play()# 落子音效
        self.step += 1  # 步数+1
        self.chess_manual = self.chess_manual + str(i) + ',' + str(j) + '|'

        winner = self.chessboard.anyone_win(i, j)  # 判断输赢
        self.Going_over = True
        if winner != EMPTY:
            self.mouse_point.clear()
            tmp, black, white = self.chessboard.get_board_item()
            print("BLACK num: " + str(len(black)))
            print("WHITE num: " + str(len(white)))

            self.player_black.is_black = False
            self.player_white.is_black = True
            self.gameover(winner)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGIN + j * GRID - PIECE / 2, MARGIN + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round((y - MARGIN) / GRID)), int(round((x - MARGIN) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= N_LINE or j < 0 or j >= N_LINE:
            return None, None
        else:
            return i, j

    def gameover(self, winner):

        fo = open(
            'Manual/' + str(self.black_text) + 'vs' + str(self.white_text) +
            '_' + str(time.time()) + '.chess', 'w')
        fo.write('BOARD_SIZE:' + str(N_LINE))
        fo.write('BLACK Player: ' + str(self.black_text) + '\n')
        fo.write('WHITE Player: ' + str(self.white_text) + '\n')
        fo.write('Winner: ' + str(winner) + '\n')
        fo.write(str(self.chess_manual))
        fo.close()

        if winner == BLACK:
            # self.sound_win.play()
            reply = QMessageBox.question(self, 'BLACK Win!',
                                         'BLACK Win! Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        elif winner == WHITE:
            # self.sound_defeated.play()
            reply = QMessageBox.question(self, 'WHITE Win!',
                                         'WHITE Win! Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        else:
            reply = QMessageBox.question(self, 'Tie', 'Tie! Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        if reply == QMessageBox.Yes:  # 复位
            self.is_black_do = True
            self.mouse_point.setPixmap(self.black)
            self.step = 0
            for piece in self.pieces:
                piece.clear()
            self.chessboard.reset()
            self.player_black.is_black = True
            self.player_white.is_black = True
            self.chess_manual = ""
            self.who.setText('BLACK Player is Going...')
            self.update()
        else:
            self.close()

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
        # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
        self.mouse_point.move(e.x() - PIECE * 0.5, e.y() - PIECE * 0.5)

    # def mousePressEvent(self, e):# 玩家下棋
    #	 if e.button() == Qt.LeftButton and self.ai_down == True:
    #		 x, y = e.x(), e.y()# 鼠标坐标
    #		 i, j = self.coordinate_transform_pixel2map(x, y)# 对应棋盘坐标
    #		 if not i is None and not j is None:# 棋子落在棋盘上,排除边缘
    #			 if self.chessboard.get_xy_on_logic_state(i, j) == EMPTY:# 棋子落在空白处
    #				 self.draw(i, j)
    #				 #self.ai_down = False
    #				 board = self.chessboard.board()
    #				 # self.AI = AI(board)# 新建线程对象,传入棋盘参数
    #				 # self.AI.finishSignal.connect(self.AI_draw)# 结束线程,传出参数
    #				 # self.AI.start()# run

    def mousePressEvent(self, e):
        self.x = e.x()
        self.y = e.y()
        self.Going = False

    def drawLines(self, qp):  # 指示AI当前下的棋子
        if self.step != 0:
            pen = QtGui.QPen(QtCore.Qt.red, 10, QtCore.Qt.SolidLine)
            qp.setPen(pen)

            qp.drawLine(self.x_t - 60, self.y_t - 60, self.x_t + 3,
                        self.y_t + 3)
            qp.drawLine(self.x_t + 13, self.y_t, self.x_t + 13, self.y_t + 13)
            qp.drawLine(self.x_t, self.y_t + 13, self.x_t + 13, self.y_t + 13)
Example #5
0
class GoBang(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.chessboard = ChessBoard()  # 棋盘类

        palette1 = QPalette()  # 设置棋盘背景
        palette1.setBrush(self.backgroundRole(),
                          QtGui.QBrush(QtGui.QPixmap('img/chessboard.jpg')))
        self.setPalette(palette1)
        # self.setStyleSheet("board-image:url(img/chessboard.jpg)")  # 不知道这为什么不行
        self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        self.sound_piece = QSound("sound/luozi.wav")  # 加载落子音效
        self.sound_win = QSound("sound/win.wav")  # 加载胜利音效
        self.sound_defeated = QSound("sound/defeated.wav")  # 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 固定大小 540*540
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        self.setWindowIcon(QIcon('img/black.png'))  # 窗口图标

        # self.lb1 = QLabel('            ', self)
        # self.lb1.move(20, 10)

        self.black = QPixmap('img/black.png')
        self.white = QPixmap('img/white.png')

        self.piece_now = BLACK  # 黑棋先行
        # self.my_turn = False  # 玩家先行
        self.step = 0  # 步数
        self.x, self.y = 1000, 1000

        self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        self.mouse_point.setScaledContents(True)
        # self.mouse_point.setPixmap(self.black)  # 加载黑棋
        self.mouse_point.setGeometry(270, 270, PIECE, PIECE)
        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  # 图片大小根据标签大小可变
        #gkh for weight reading##########
        f = open('./data/blackweight', 'r')
        line = f.readline()
        while line:
            blackweight_list.append(float(line[0:-1]))
            line = f.readline()
        f.close()
        f = open('./data/whiteweight', 'r')
        line = f.readline()
        while line:
            whiteweight_list.append(float(line[0:-1]))
            line = f.readline()
        f.close()
        print(blackweight_list, whiteweight_list)
        ###############
        #print(weight_list)
        self.mouse_point.raise_()  # 鼠标始终在最上层
        self.ai_down = True  # AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        self.show()
        # 玩家选择是否先手
        self.two_ai_train = QMessageBox.question(
            self, 'Let\'s play a game!', '是否使用ai互相训练呢?',
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        #gkh : realize two ai train
        if self.two_ai_train == QMessageBox.Yes:
            self.AItrain()
        ##########
        else:
            # 玩家选择是否先手
            self.my_turn = QMessageBox.question(
                self, 'Let\'s play a game!', '是否选择先手?',
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if self.my_turn == QMessageBox.No:
                # self.mouse_point.setPixmap(self.white)  # 加载白棋

                #################
                self.ai_down = False
                board = self.chessboard.board()
                ##########gkh : AI get the list
                self.AI = AI(board, 1)  # 新建线程对象,传入棋盘参数
                print('AI 0')
                self.AI.finishSignal.connect(self.AI_draw)  # 结束线程,传出参数
                self.AI.start()  # run

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    #gkh: AI train
    def AItrain(self):
        print('ai start')
        #while True:
        board = self.chessboard.board()
        self.piece_now = BLACK
        self.black_ai_down = False
        self.BLACKAI = BLACKAI(board, 1)
        self.BLACKAI.finishSignal.connect(self.BLACKAI_draw)
        self.BLACKAI.start()
        self.BLACKAI.wait()
        print('end black')

    def whiteAItrain(self):
        self.piece_now = WHITE
        print('start white')
        board = self.chessboard.board()
        self.WHITEAI = AI(board, 2)
        self.WHITEAI.finishSignal.connect(self.WHITEAI_draw)
        self.WHITEAI.start()
        self.WHITEAI.wait()

    #############
    # def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
    #     # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
    #     self.mouse_point.move(e.x() - 16, e.y() - 16)

    def mousePressEvent(self, e):  # 玩家下棋
        if e.button() == Qt.LeftButton and self.ai_down == True:
            print("press")
            x, y = e.x(), e.y()  # 鼠标坐标
            i, j = self.coordinate_transform_pixel2map(x, y)  # 对应棋盘坐标
            if not i is None and not j is None:  # 棋子落在棋盘上,排除边缘
                if self.chessboard.get_xy_on_logic_state(
                        i, j) == EMPTY:  # 棋子落在空白处
                    endgame = self.draw(i, j)
                    if endgame == False:
                        return
                    self.ai_down = False
                    board = self.chessboard.board()
                    # if self.piece_now == WHITE: # 玩家先手黑棋 已下完
                    #     self.AI = AI(board,2)  # 新建线程对象,传入棋盘参数
                    # else:
                    #     self.AI = AI(board,1) # 玩家后手,AI先手
                    #     print('AI , 3')
                    ########gkh change
                    if self.my_turn == QMessageBox.No:
                        self.AI = AI(board, 1)
                        print('AI, 123')
                    else:
                        self.AI = AI(board, 2)
                    ##############
                    self.AI.finishSignal.connect(self.AI_draw)  # 结束线程,传出参数
                    self.AI.start()  # run

    ####gkh ai train
    def BLACKAI_draw(self, i, j):
        # if self.step != 0:
        notendgame = self.draw(i, j)  # AI
        if notendgame == False:
            return
        self.x, self.y = self.coordinate_transform_map2pixel(i, j)
        self.update()
        self.whiteAItrain()

    def WHITEAI_draw(self, i, j):
        # if self.step != 0:
        notendgame = self.draw(i, j)  # AI
        if notendgame == False:
            return
        self.x, self.y = self.coordinate_transform_map2pixel(i, j)
        self.update()
        self.AItrain()

    def AI_draw(self, i, j):
        # if self.step != 0:
        notendgame = self.draw(i, j)  # AI

        self.x, self.y = self.coordinate_transform_map2pixel(i, j)
        self.ai_down = True
        self.update()

        return notendgame

    #######################
    def draw(self, i, j):
        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.piece_now == BLACK:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子

            self.piece_now = WHITE
            self.chessboard.draw_xy(i, j, BLACK)

        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.piece_now = BLACK
            self.chessboard.draw_xy(i, j, WHITE)

        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        self.sound_piece.play()  # 落子音效
        self.step += 1  # 步数+1

        #gkh: check if there is rule breaker
        rulerbreak = False
        # if self.piece_now == WHITE:
        #     rulerbreak = self.chessboard.breakrule(i, j)
        #     if (rulerbreak == True):
        #         self.gameover(2)
        if rulerbreak == False:
            #gkh :modify end at this place
            winner = self.chessboard.anyone_win(i, j)  # 判断输赢
            if winner != EMPTY:
                self.mouse_point.clear()
                self.gameover(winner)
                return False
        return True

    def drawLines(self, qp):  # 指示AI当前下的棋子
        # if self.step != 0:
        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
        qp.setPen(pen)
        qp.drawLine(self.x - 5, self.y - 5, self.x + 3, self.y + 3)
        qp.drawLine(self.x + 3, self.y, self.x + 3, self.y + 3)
        qp.drawLine(self.x, self.y + 3, self.x + 3, self.y + 3)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGIN + j * GRID - PIECE / 2, MARGIN + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round((y - MARGIN) / GRID)), int(round((x - MARGIN) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= 15 or j < 0 or j >= 15:
            return None, None
        else:
            return i, j

    def gameover(self, winner):
        global now_value, last_value
        ######gkh: game over update
        f = open('./data/blackweight', 'w')
        for i in range(len(blackweight_list)):
            f.write(str(blackweight_list[i]) + '\n')
        f.close()
        f = open('./data/whiteweight', 'w')
        for i in range(len(whiteweight_list)):
            f.write(str(whiteweight_list[i]) + '\n')
        f.close()
        ###################
        if winner == BLACK:
            # self.sound_win.play()
            # reply = QMessageBox.question(self, 'Black Win!', 'Continue?',
            #                              QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            #######gkh wei xiabi xunlian jia
            difference = get_difference(discount)
            now_value = -50
            if difference != 0:
                learning_weight(learning_rate, difference, 2)
        else:
            # self.sound_defeated.play()
            # reply = QMessageBox.question(self, 'Black Lost!', 'Continue?',
            #                              QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            difference = get_difference(discount)
            now_value = 50
            if difference != 0:
                learning_weight(learning_rate, difference, 2)
        # if reply == QMessageBox.Yes:  # 复位
        self.piece_now = BLACK
        ###########gkh init

        now_value = 0
        last_value = 0
        # self.mouse_point.setPixmap(self.black)
        self.step = 0
        for piece in self.pieces:
            piece.clear()
        self.chessboard.reset()
        self.update()
        self.ai_down = True
        self.BLACKAI.quit()
        self.WHITEAI.quit()
        self.AItrain()
class display_manual(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.chessboard = ChessBoard()  # 棋盘类
        self.chess_manual = []
        self.Going = False
        palette1 = QPalette()  # 设置棋盘背景
        pix = QtGui.QPixmap('board_' + str(N_LINE) + '.jpg')
        pix = pix.scaled(WIDTH, HEIGHT)
        palette1.setBrush(self.backgroundRole(), QtGui.QBrush(pix))
        self.setPalette(palette1)
        # self.setStyleSheet("board-image:url(img/chessboard.jpg)")# 不知道这为什么不行
        self.setCursor(Qt.PointingHandCursor)  # 鼠标变成手指形状
        #self.sound_piece = QSound("sound/luozi.wav")# 加载落子音效
        # self.sound_win = QSound("sound/win.wav")# 加载胜利音效
        # self.sound_defeated = QSound("sound/defeated.wav")# 加载失败音效

        self.resize(WIDTH, HEIGHT)  # 固定大小 540*540
        self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT))
        self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT))

        self.setWindowTitle("GoBang")  # 窗口名称
        # self.setWindowIcon(QIcon('img/black.png'))# 窗口图标

        # self.lb1 = QLabel('			', self)
        # self.lb1.move(20, 10)

        self.black = QPixmap('black.png')
        self.white = QPixmap('white.png')

        self.is_black_do = True  # 黑棋回合先行

        self.step = 0  # 步数
        self.x, self.y = 1000, 1000

        self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        self.mouse_point.setScaledContents(True)
        self.mouse_point.setPixmap(self.black)  #加载黑棋
        self.mouse_point.setGeometry(270, 270, PIECE, PIECE)
        self.pieces = [LaBel(self) for i in range(225)]  # 新建棋子标签,准备在棋盘上绘制棋子
        for piece in self.pieces:
            piece.setVisible(True)  # 图片可视
            piece.setScaledContents(True)  #图片大小根据标签大小可变

        self.mouse_point.raise_()  # 鼠标始终在最上层
        #self.ai_down = True# AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent

        self.setMouseTracking(True)
        self.show()
        self.display_it()

    def display_it(self):
        openfile_name, file_type = QFileDialog.getOpenFileName(
            self, '选择文件', '', 'chess_manual(*.chess)')

        print(openfile_name)
        fo = open(openfile_name, 'r')
        fo.readline()
        fo.readline()
        fo.readline()
        string = fo.readline()
        step_list = []
        flag_1 = False
        flag_2 = False
        x = 0
        y = 0
        flag_1 = True
        sub_str = string.split("|")
        for sub_sub in sub_str:
            if sub_sub == "":
                break
            num_pair = sub_sub.split(',')
            x = int(num_pair[0])
            y = int(num_pair[1])
            step_list.append([x, y])

        print(step_list)
        fo.close()
        # for l in step_list:
        # 	self.AI_draw(l[0],l[1])

        self.display_player = DisplayPlayer(step_list, self)
        self.display_player.finishSignal.connect(self.AI_draw)
        self.display_player.start()

    def AI_draw(self, i, j):
        if self.step != -1:
            self.draw(i, j)  # AI
            self.x_t, self.y_t = self.coordinate_transform_map2pixel(i, j)

        self.update()
        print('update')

    def draw(self, i, j):
        x, y = self.coordinate_transform_map2pixel(i, j)

        if self.is_black_do == True:
            self.pieces[self.step].setPixmap(self.black)  # 放置黑色棋子
            self.is_black_do = False
            self.chessboard.draw_xy(i, j, BLACK)
        else:
            self.pieces[self.step].setPixmap(self.white)  # 放置白色棋子
            self.is_black_do = True
            self.chessboard.draw_xy(i, j, WHITE)

        print(self.step)
        self.pieces[self.step].setGeometry(x, y, PIECE, PIECE)  # 画出棋子
        #self.sound_piece.play()# 落子音效
        self.step += 1  # 步数+1
        self.chess_manual.append([i, j])

        winner = self.chessboard.anyone_win(i, j)  # 判断输赢
        self.Going_over = True
        if winner != EMPTY:
            self.mouse_point.clear()
            tmp, black, white = self.chessboard.get_board_item()
            print("BLACK num: " + str(len(black)))
            print("WHITE num: " + str(len(white)))

            self.gameover(winner)

    def coordinate_transform_map2pixel(self, i, j):
        # 从 chessMap 里的逻辑坐标到 UI 上的绘制坐标的转换
        return MARGIN + j * GRID - PIECE / 2, MARGIN + i * GRID - PIECE / 2

    def coordinate_transform_pixel2map(self, x, y):
        # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换
        i, j = int(round((y - MARGIN) / GRID)), int(round((x - MARGIN) / GRID))
        # 有MAGIN, 排除边缘位置导致 i,j 越界
        if i < 0 or i >= N_LINE or j < 0 or j >= N_LINE:
            return None, None
        else:
            return i, j

    def gameover(self, winner):

        if winner == BLACK:
            # self.sound_win.play()
            reply = QMessageBox.question(self, 'BLACK Win!',
                                         'BLACK Win! Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)
        else:
            # self.sound_defeated.play()
            reply = QMessageBox.question(self, 'WHITE Win!',
                                         'WHITE Win! Continue?',
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.No)

        if reply == QMessageBox.Yes:  # 复位
            self.is_black_do = True
            self.mouse_point.setPixmap(self.black)
            self.step = 0
            for piece in self.pieces:
                piece.clear()
            self.chessboard.reset()
            self.update()
            self.display_it()
        else:
            self.close()

    def paintEvent(self, event):  # 画出指示箭头
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()

    def mouseMoveEvent(self, e):  # 黑色棋子随鼠标移动
        # self.lb1.setText(str(e.x()) + ' ' + str(e.y()))
        self.mouse_point.move(e.x() - PIECE * 0.5, e.y() - PIECE * 0.5)

    # def mousePressEvent(self, e):# 玩家下棋
    #	 if e.button() == Qt.LeftButton and self.ai_down == True:
    #		 x, y = e.x(), e.y()# 鼠标坐标
    #		 i, j = self.coordinate_transform_pixel2map(x, y)# 对应棋盘坐标
    #		 if not i is None and not j is None:# 棋子落在棋盘上,排除边缘
    #			 if self.chessboard.get_xy_on_logic_state(i, j) == EMPTY:# 棋子落在空白处
    #				 self.draw(i, j)
    #				 #self.ai_down = False
    #				 board = self.chessboard.board()
    #				 # self.AI = AI(board)# 新建线程对象,传入棋盘参数
    #				 # self.AI.finishSignal.connect(self.AI_draw)# 结束线程,传出参数
    #				 # self.AI.start()# run

    def mousePressEvent(self, e):
        self.Going = True

    def drawLines(self, qp):  # 指示AI当前下的棋子
        if self.step != 0:
            pen = QtGui.QPen(QtCore.Qt.green, 10, QtCore.Qt.SolidLine)
            qp.setPen(pen)

            qp.drawLine(self.x_t - 60, self.y_t - 60, self.x_t + 3,
                        self.y_t + 3)
            qp.drawLine(self.x_t + 13, self.y_t, self.x_t + 13, self.y_t + 13)
            qp.drawLine(self.x_t, self.y_t + 13, self.x_t + 13, self.y_t + 13)