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()
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
class GoBang(QWidget): def __init__(self): super().__init__() self.env = Env.OthelloEnv() self.initUI() self.i = 0 self.Q = test.Q def initUI(self): self.chessboard = ChessBoard() # 棋盘类 palette1 = QPalette() # 设置棋盘背景 palette1.setBrush(self.backgroundRole(), QtGui.QBrush(QtGui.QPixmap('img/1.jpg'))) self.setPalette(palette1) # self.setStyleSheet("board-image:url(img/chessboard.jpg)") # 不知道这为什么不行 self.setCursor(Qt.PointingHandCursor) # 鼠标变成手指形状 self.resize(WIDTH, HEIGHT) # 固定大小 540*540 self.setMinimumSize(QtCore.QSize(WIDTH, HEIGHT)) self.setMaximumSize(QtCore.QSize(WIDTH, HEIGHT)) self.setWindowTitle("黑白棋") # 窗口名称 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(4096)] # 新建棋子标签,准备在棋盘上绘制棋子 for piece in self.pieces: piece.setVisible(True) # 图片可视 piece.setScaledContents(True) # 图片大小根据标签大小可变 self.mouse_point.raise_() # 鼠标始终在最上层 self.ai_down = True # AI已下棋,主要是为了加锁,当值是False的时候说明AI正在思考,这时候玩家鼠标点击失效,要忽略掉 mousePressEvent self.draw(3, 3) self.draw(3, 4) self.draw(4, 4) self.draw(4, 3) 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 print_win(self, d, r, color): if d: print('finish!') if r * color: win = 'black' else: win = 'white' QMessageBox.information(self, 'Finish', 'Game over! ' + win + ' win!') 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: # 棋子落在棋盘上,排除边缘 st = [] st = Env.judge(self.chessboard.lineboard(), self.piece_now) k = i * 8 + j if self.chessboard.get_xy_on_logic_state( i, j) == EMPTY and k in st: # 棋子落在空白处 if len(st) != 0: self.draw(i, j) self.env.state = self.chessboard.lineboard() s, r, d = self.env._step([self.piece_now * -1, k]) self.drawState(s) print('s:', s) self.print_win(d, r, self.piece_now * -1) self.ai_down = False # AI_action = self.random_policy(s, self.piece_now) # AI_action = Value_based.mid_policy(s, self.piece_now) AI_action = test.make_epsilon_greedy_policy( self.Q, s, self.piece_now, 0.1) if AI_action == [0, 0]: self.piece_now = self.piece_now * -1 self.ai_down = True else: s, r, d = self.env._step(AI_action) self.drawState(s) print('s:', s) self.print_win(d, r, self.piece_now) self.piece_now = self.piece_now * -1 self.ai_down = True else: self.piece_now = self.piece_now * -1 self.ai_down = False # AI_action = self.random_policy(s, self.piece_now) # AI_action = Value_based.mid_policy(s, self.piece_now) AI_action = test.make_epsilon_greedy_policy( self.Q, self.env.state, self.piece_now, 0.1) if AI_action == [0, 0]: self.piece_now = self.piece_now * -1 self.ai_down = True else: s, r, d = self.env._step(AI_action) self.drawState(s) print('s:', s) self.print_win(d, r, self.piece_now) self.piece_now = self.piece_now * -1 self.ai_down = True if self.piece_now == BLACK: self.mouse_point.setPixmap(self.black) else: self.mouse_point.setPixmap(self.white) # self.ai_down = False # board = self.chessboard.board() # liner_board = self.chessboard.lineboard() # self.AI = AI(board) # 新建线程对象,传入棋盘参数 # self.AI.finishSignal.connect(self.AI_draw()) # 结束线程,传出参数 # self.AI.start() # run def random_policy(self, state, flag): st = Env.judge(state, flag) l = len(st) if l == 0: return [0, 0] else: p = random.randint(0, l - 1) return [flag, st[p]] def drawState(self, state): print(self.i) self.i = self.i + 1 for i in range(0, 8): for j in range(0, 8): if state[8 * i + j] == -1: self.drawAll(i, j, -1) print(state[8 * i + j], end=" ") elif state[8 * i + j] == 1: self.drawAll(i, j, 1) print(state[8 * i + j], end=" ") else: print(state[8 * i + j], end=" ") continue print() print() 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.step += 1 # 步数+1 def drawAll(self, i, j, color): x, y = self.coordinate_transform_map2pixel(i, j) if color == BLACK: self.pieces[self.step].setPixmap(self.black) # 放置黑色棋子 self.chessboard.draw_xy(i, j, BLACK) else: self.pieces[self.step].setPixmap(self.white) # 放置白色棋子 self.chessboard.draw_xy(i, j, WHITE) self.pieces[self.step].setGeometry(x, y, PIECE, PIECE) # 画出棋子 self.step += 1 # 步数+1 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 + 0.5) * GRID - PIECE / 2, MARGIN + ( i + 0.5) * GRID - PIECE / 2 def coordinate_transform_pixel2map(self, x, y): # 从 UI 上的绘制坐标到 chessMap 里的逻辑坐标的转换 i, j = int(math.floor( (y - MARGIN) / GRID)), int(math.floor((x - MARGIN) / GRID)) # 有MAGIN, 排除边缘位置导致 i,j 越界 if i < 0 or i >= 8 or j < 0 or j >= 8: return None, None else: return i, j
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
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)
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)