Example #1
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 #2
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 #3
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()