| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
 本帖最后由 Stubborn 于 2021-11-30 16:33 编辑  
 
如果你想写一个五子棋游戏,又不想写界面代码,那么你可以拿走这篇代码,去实现你的五子棋游戏。 
 
- 你需要实现电脑的落子算法(博弈树搜索算法),让你的程序更聪明
 - 实现电脑落子算法应该是实现电脑下一步棋子落子在哪里
 - 你应该完善的代码位于PWidget类中的Ai_move函数
 - PWidget中的record属性,存放的是当前棋盘的额落子数据,建议你应该根据这个数据,初始化你的数据结构或者博弈树。
 - 在使用record前,请确认列表存放的点,和UI界面中的点的相对位置,以便更好的实现你的搜索算法。
 - 保存好图片,请确认图片的相关路径(在PWidget类中的pice属性修改图片路径),避免报错
 
 
  
 
黑白棋子图片 
 
 
 
 
 
 
- # -*- coding: utf-8 -*-
 
  
- # Form implementation generated from reading ui file '011.ui'
 
 - #
 
 - # Created by: PyQt5 UI code generator 5.15.6
 
 - #
 
 - # WARNING: Any manual changes made to this file will be lost when pyuic5 is
 
 - # run again.  Do not edit this file unless you know what you are doing.
 
  
 
- from PyQt5.QtGui import QPainter, QPen, QColor, QPixmap, QFont
 
 - from PyQt5.QtCore import Qt, QPoint, QSize, QRect, QMetaObject, QCoreApplication
 
 - from PyQt5.QtWidgets import (
 
 -     QMessageBox, QComboBox, QLabel, QWidget, QPushButton, QTextEdit, QMenuBar, QStatusBar, QMainWindow,
 
 - )
 
  
 
- class LaBel(QLabel):
 
 -     def __init__(self, parent):
 
 -         super().__init__(parent)
 
 -         self.setMouseTracking(True)
 
  
-     def enterEvent(self, e):
 
 -         e.ignore()
 
  
 
- class Ui_MainWindow(object):
 
 -     def setupUi(self, MainWindow):
 
 -         MainWindow.setObjectName("MainWindow")
 
 -         MainWindow.resize(1000, 550)
 
 -         MainWindow.setMinimumSize(QSize(1000, 550))
 
 -         MainWindow.setMaximumSize(QSize(1000, 550))
 
 -         self.centralwidget = QWidget(MainWindow)
 
 -         self.centralwidget.setObjectName("centralwidget")
 
 -         # TODO 复选框
 
 -         self.SelectComboBox = QComboBox(self.centralwidget)
 
 -         self.SelectComboBox.setGeometry(QRect(890, 210, 90, 23))
 
 -         self.SelectComboBox.setObjectName('SelectComboBox')
 
 -         self.SelectComboBox.addItems(['执黑先手', '执白后手'])
 
  
-         self.AlgorithmComboBox = QComboBox(self.centralwidget)
 
 -         self.AlgorithmComboBox.setGeometry(QRect(890, 240, 90, 23))
 
 -         self.AlgorithmComboBox.setObjectName('AlgorithmComboBox')
 
 -         self.AlgorithmComboBox.addItems(['算法选择-未装载', 'MaxMin', 'Alpha-Beta', 'MCTS'])
 
 -         # TODO 按钮
 
 -         self.AgoButton = QPushButton(self.centralwidget)
 
 -         self.AgoButton.setGeometry(QRect(890, 90, 90, 23))
 
 -         self.AgoButton.setObjectName("AgoButton")
 
  
-         self.NewGameButton = QPushButton(self.centralwidget)
 
 -         self.NewGameButton.setGeometry(QRect(890, 10, 90, 23))
 
 -         self.NewGameButton.setObjectName("NewGameButton")
 
  
-         self.AfterButton = QPushButton(self.centralwidget)
 
 -         self.AfterButton.setGeometry(QRect(890, 130, 90, 23))
 
 -         self.AfterButton.setObjectName("AfterButton")
 
  
-         self.FirstButton = QPushButton(self.centralwidget)
 
 -         self.FirstButton.setGeometry(QRect(890, 50, 90, 23))
 
 -         self.FirstButton.setObjectName("FirstButton")
 
  
-         self.EndButton = QPushButton(self.centralwidget)
 
 -         self.EndButton.setGeometry(QRect(890, 170, 90, 23))
 
 -         self.EndButton.setObjectName("EndButton")
 
  
-         # TODO 标签横竖轴
 
 -         font = QFont()
 
 -         font.setFamily("Arial")
 
 -         font.setPointSize(12)
 
 -         font.setBold(True)
 
 -         font.setWeight(75)
 
 -         self.y_axis = []
 
 -         for i in range(1, 16):
 
 -             lable = QLabel(self.centralwidget)
 
 -             lable.setGeometry(QRect(330, -4 + i * 30, 50, 12))
 
 -             lable.setFont(font)
 
 -             self.y_axis.append((str(i), lable))
 
  
-         self.x_axis = []
 
 -         for i, a in zip(range(1, 16), 'ABCDEFGHIJKLMNO'):
 
 -             lable = QLabel(self.centralwidget)
 
 -             lable.setGeometry(QRect(344 + i * 30, 495, 50, 12))
 
 -             lable.setFont(font)
 
 -             self.x_axis.append((a, lable))
 
  
-         # TODO 按钮接口
 
 -         MainWindow.setCentralWidget(self.centralwidget)
 
 -         self.menubar =QMenuBar(MainWindow)
 
 -         self.menubar.setGeometry(QRect(0, 0, 1000, 23))
 
 -         self.menubar.setObjectName("menubar")
 
 -         MainWindow.setMenuBar(self.menubar)
 
 -         self.statusbar = QStatusBar(MainWindow)
 
 -         self.statusbar.setObjectName("statusbar")
 
 -         MainWindow.setStatusBar(self.statusbar)
 
  
-         self.retranslateUi(MainWindow)
 
 -         self.NewGameButton.clicked.connect(MainWindow.newgame)  # type: ignore
 
 -         self.FirstButton.clicked.connect(MainWindow.first)  # type: ignore
 
 -         self.AgoButton.clicked.connect(MainWindow.ago)  # type: ignore
 
 -         self.AfterButton.clicked.connect(MainWindow.after)  # type: ignore
 
 -         self.EndButton.clicked.connect(MainWindow.end)  # type: ignore
 
 -         QMetaObject.connectSlotsByName(MainWindow)
 
  
-     def retranslateUi(self, MainWindow):
 
 -         _translate = QCoreApplication.translate
 
 -         MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
 
 -         self.AgoButton.setText(_translate("MainWindow", "前一步"))
 
 -         self.NewGameButton.setText(_translate("MainWindow", "新游戏"))
 
 -         self.AfterButton.setText(_translate("MainWindow", "后一步"))
 
 -         self.FirstButton.setText(_translate("MainWindow", "首步"))
 
 -         self.EndButton.setText(_translate("MainWindow", "末步"))
 
 -         for val, obj in self.y_axis:
 
 -             obj.setText(_translate("MainWindow", val))
 
 -         for val, obj in self.x_axis:
 
 -             obj.setText(_translate("MainWindow", val))
 
  
 
- class CornerWidget(QWidget):
 
  
-     def __init__(self, parent):
 
 -         """跟随鼠标移动的特殊标记"""
 
 -         super().__init__(parent=parent)
 
 -         self.setFixedSize(30, 30)
 
  
-     def paintEvent(self, e):
 
 -         qp = QPainter()
 
 -         qp.begin(self)
 
 -         pen = QPen(Qt.red, 3, Qt.SolidLine)
 
 -         qp.setPen(pen)
 
 -         qp.drawLine(0, 8, 0, 0)
 
 -         qp.drawLine(0, 0, 8, 0)
 
 -         qp.drawLine(22, 0, 28, 0)
 
 -         qp.drawLine(28, 0, 28, 8)
 
 -         qp.drawLine(28, 22, 28, 28)
 
 -         qp.drawLine(28, 28, 20, 28)
 
 -         qp.drawLine(8, 28, 0, 28)
 
 -         qp.drawLine(0, 28, 0, 22)
 
  
 
- class PWidget(QWidget):
 
  
-     def __init__(self, parent=None, *args, **kwargs):
 
 -         """
 
 -         init_ui :: 初始化界面函数
 
 -         last_pos :: 初始点位,记录位置是否发生变化
 
 -         PLAYER :: Ai  W白子,B黑子 ,黑先手
 
 -         GAME :: 是否开始游戏,如果开始游戏,mousePressEvent可以进行落子触发
 
 -         black :: 黑棋子
 
 -         white :: 白棋子
 
 -         record :: 落子记录
 
 -         pix_record :: 存放棋子,QLabel对象
 
 -         tmp :: 临时存放,主要用与进退步数临时数据,QLabel对象
 
 -         """
 
 -         super().__init__(parent, *args, **kwargs)
 
 -         # TODO 消息框
 
 -         self.TextEdit = QTextEdit(parent)
 
 -         self.TextEdit.setGeometry(QRect(0, 0, 321, 501))
 
 -         self.TextEdit.setObjectName("TextEdit")
 
  
-         self.init_ui()
 
 -         self.last_pos = (-1, -1)
 
 -         self.piece = {
 
 -             "B": QPixmap('img/black.png'),
 
 -             "W": QPixmap('img/white.png')
 
 -         }
 
 -         self.PLAYER = "W"
 
 -         self.Ai = "B"
 
 -         self.GAME = False
 
 -         self.record = []
 
 -         self.record_tmp = []
 
 -         self.pix_record = []
 
 -         self.pix_tmp = []
 
  
-     def init_ui(self):
 
 -         # TODO 开启鼠标位置的追踪。并在鼠标位置移动时,使用特殊符号标记当前的位置
 
 -         self.setMouseTracking(True)
 
 -         self.corner = CornerWidget(self)
 
 -         self.corner.repaint()
 
 -         self.corner.hide()
 
  
-     def draw(self, x, y, p):
 
 -         """绘制棋子及其数字"""
 
 -         # TODO 绘制棋子
 
 -         label = LaBel(self)
 
 -         label.setVisible(True)
 
 -         label.setScaledContents(True)
 
 -         label.setPixmap(self.piece[p])
 
 -         label.setGeometry(15 + 30 * x, 15 + 30 * y, 30, 30)
 
 -         # TODO 数字字体设置
 
 -         font = QFont()
 
 -         font.setFamily("Arial")
 
 -         font.setPointSize(12)
 
 -         font.setBold(True)
 
 -         font.setWeight(75)
 
 -         # TODO 绘制数字
 
 -         num = LaBel(self)
 
 -         num.setGeometry(QRect(15 + 30 * x, 15 + 30 * y, 30, 30))
 
 -         num.setFont(font)
 
 -         num.setVisible(True)
 
 -         num.setScaledContents(True)
 
 -         if p == "W":
 
 -             num.setStyleSheet("color: black")
 
 -         else:
 
 -             num.setStyleSheet("color: white")
 
 -         num.setAlignment(Qt.AlignCenter)
 
 -         num.setNum(len(self.record))
 
 -         num.setGeometry(15 + 30 * x, 15 + 30 * y, 30, 30)
 
 -         # TODO 存储对象
 
 -         self.pix_record.append([label, num])
 
  
-     def Ai_move(self):
 
 -         """AI移动"""
 
 -         # TODO 这里实现你的AI移动函数, 可以传递 self.record 给你的算法,计算出当前五子棋下一步的着落点
 
 -         #      我这里个人建议给你,是通过self.record来构建你的数据结构或者博弈树进行搜索最佳着落点,可以不用管前端的任何操作。
 
 -         #        当然你可以通过自己的想法给界面添加功能
 
 -         # TODO ===================================
 
 -         from random import randint
 
 -         x, y = randint(0, 14), randint(0, 14)
 
 -         while x + y * 15 in self.record:
 
 -             x, y = randint(0, 14), randint(0, 14)
 
 -         # TODO 如果需要想界面输入提示信息
 
 -         self.TextEdit.append(f"电脑落子在<{x}-{y}>\n")
 
 -         # TODO  =================================
 
 -         # TODO 如果当前是白棋落子
 
 -         if len(self.record) % 2:
 
 -             self.draw(x, y, 'W')
 
 -         # TODO 如果当前是黑棋落子
 
 -         else:
 
 -             self.draw(x, y, 'B')
 
 -         self.record.append(x + y * 15)
 
  
-     def paintEvent(self, e):
 
 -         """绘制棋盘"""
 
 -         qp = QPainter()
 
 -         qp.begin(self)
 
 -         qp.fillRect(self.rect(), QColor("green"))
 
  
-         qp.drawRect(self.rect())
 
 -         qp.setBackground(QColor("green"))
 
 -         qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))
 
 -         # TODO 绘制纵横线
 
 -         for i in range(15):
 
 -             qp.drawLine(QPoint(30, 30 + 30 * i), QPoint(450, 30 + 30 * i))
 
 -         for i in range(15):
 
 -             qp.drawLine(QPoint(30 + 30 * i, 30), QPoint(30 + 30 * i, 450))
 
 -         # TODO 绘制棋盘中心的黑点
 
 -         qp.setBrush(QColor(0, 0, 0))
 
 -         key_points = [(3, 3), (11, 3), (3, 11), (11, 11), (7, 7)]
 
 -         for t in key_points:
 
 -             qp.drawEllipse(QPoint(30 + 30 * t[0], 30 + 30 * t[1]), 5, 5)
 
  
-     def mouseMoveEvent(self, e):
 
 -         """
 
 -         根据鼠标轨迹,绘制特殊标记
 
 -         """
 
 -         # TODO 获取鼠标坐标, 此工作区域为{350, 0, 480, 480}
 
 -         mouse_x = e.windowPos().x()
 
 -         mouse_y = e.windowPos().y()
 
 -         # TODO 判断鼠标位置,如果在区域内{(350, 0)(830, 0)(350, 460)(830, 460)}
 
 -         if 365 < mouse_x < 815 and 15 < mouse_y < 445:
 
 -             game_x, game_y = int((mouse_x - 365) // 30), int((mouse_y - 15) // 30)
 
 -         else:
 
 -             game_x = -1
 
 -             game_y = -1
 
  
-         # TODO 如果发生变化
 
 -         change = False
 
 -         if game_x != self.last_pos[0] or game_y != self.last_pos[1]:
 
 -             change = True
 
 -         self.last_pos = (game_x, game_y)
 
 -         # TODO 如果发生变化根据鼠标位置的变化,绘制特殊标记
 
 -         if change and game_x != -1:
 
 -             self.setCursor(Qt.PointingHandCursor)
 
 -         if change and game_x == -1:
 
 -             self.setCursor(Qt.ArrowCursor)
 
 -         if change and game_x != -1:
 
 -             self.corner.move(15 + game_x * 30, 15 + game_y * 30)
 
 -             self.corner.show()
 
 -         if change and game_x == -1:
 
 -             self.corner.hide()
 
  
-     def mousePressEvent(self, e):
 
 -         """
 
 -         根据鼠标的动作,确定是否落子,并确定位置,绘制棋子
 
 -         """
 
 -         # TODO 点击后一步的时候,不是你落子判断
 
 -         if len(self.record) % 2 and self.PLAYER == 'B':
 
 -             QMessageBox.about(self, '温馨提示', '当前不是你落子,请点击下一步')
 
 -             return
 
 -         elif self.PLAYER == 'W':
 
 -             QMessageBox.about(self, '温馨提示', '当前不是你落子,请点击下一步')
 
 -             return
 
  
-         if e.button() == Qt.LeftButton and self.GAME:
 
 -             # 1. 首先判断按下了哪个格子
 
 -             mouse_x = e.windowPos().x()
 
 -             mouse_y = e.windowPos().y()
 
 -             # TODO 判断鼠标位置,如果在区域内{(350, 0)(830, 0)(350, 460)(830, 460)}
 
 -             if 365 < mouse_x < 815 and 15 < mouse_y < 445:
 
 -                 game_x, game_y = int((mouse_x - 365) // 30), int((mouse_y - 15) // 30)
 
 -             else:
 
 -                 return
 
 -             # TODO 玩家是否可以落子
 
 -             res = game_x + game_y * 15
 
 -             if res in self.record:
 
 -                 return
 
 -             # TODO 玩家落子
 
 -             self.record_tmp.clear()
 
 -             self.pix_tmp.clear()
 
 -             self.draw(game_x, game_y, self.PLAYER)
 
 -             self.record.append(res)
 
 -             # TODO 电脑落子
 
 -             self.Ai_move()
 
  
-         else:
 
 -             QMessageBox.about(self, '温馨提示', '请点击<新游戏>开始')
 
  
 
- class Gomoku(QMainWindow, Ui_MainWindow):
 
  
-     def __init__(self, parent=None, *args, **kwargs):
 
 -         super().__init__(parent, *args, **kwargs)
 
 -         self.debugging = False
 
 -         self.setupUi(self)
 
 -         self.setwidget()
 
  
-     def setwidget(self):
 
 -         self.widget = PWidget(self.centralwidget)
 
 -         self.widget.setGeometry(QRect(350, 0, 480, 480))
 
  
-     def newgame(self):
 
 -         """
 
 -         开始新的游戏
 
 -         :return: None
 
 -         """
 
 -         # TODO 游戏开始
 
 -         self.widget.GAME = True
 
 -         # TODO 清理数据
 
 -         self.widget.record.clear()
 
 -         self.widget.record_tmp.clear()
 
 -         # TODO 清理图像
 
 -         self.widget.pix_record += self.widget.pix_tmp
 
 -         for pix, num in self.widget.pix_record:
 
 -             pix.setPixmap(QPixmap(""))
 
 -             num.setPixmap(QPixmap(""))
 
 -         self.widget.pix_record.clear()
 
 -         self.widget.pix_tmp.clear()
 
 -         # TODO 获取选选择
 
 -         select = self.SelectComboBox.currentText()
 
 -         self.widget.PLAYER, self.widget.Ai = ["B", "W"] if select == "执黑先手" else ["W", "B"]
 
 -         if self.widget.Ai == "B":
 
 -             self.widget.Ai_move()
 
  
-     def first(self):
 
 -         """回到首步"""
 
 -         # TODO 回到首步前提是落子至少超过2个
 
 -         if len(self.widget.pix_record) >= 2:
 
 -             # TODO 开启调试模式
 
 -             self.debugging = True
 
 -             # TODO 对图像处理
 
 -             self.widget.pix_tmp = self.widget.pix_record[1:]
 
 -             self.widget.pix_record = [self.widget.pix_record[0], ]
 
 -             for pix, num in self.widget.pix_tmp:
 
 -                 pix.setVisible(False)
 
 -                 num.setVisible(False)
 
 -             # # TODO 对落点数据处理
 
 -             self.widget.record_tmp = self.widget.record[1:]
 
 -             self.widget.record = [self.widget.record[0], ]
 
 -             return
 
 -         QMessageBox.about(self, '温馨提示', '当前已经是第一步')
 
  
-     def ago(self):
 
 -         """前一步"""
 
 -         # TODO 如果还可以返回上一步
 
 -         if len(self.widget.pix_record) > 1:
 
 -                 # # TODO 对图像处理,对落点数据处理
 
 -                 pix, num = self.widget.pix_record.pop()
 
 -                 pix.setVisible(False)
 
 -                 num.setVisible(False)
 
 -                 self.widget.pix_tmp.insert(0, [pix, num])
 
 -                 self.widget.record_tmp.insert(0, self.widget.record.pop())
 
  
-                 # # TODO 第二轮
 
 -                 pix, num = self.widget.pix_record.pop()
 
 -                 pix.setVisible(False)
 
 -                 num.setVisible(False)
 
 -                 self.widget.pix_tmp.insert(0, [pix, num])
 
 -                 self.widget.record_tmp.insert(0, self.widget.record.pop())
 
 -                 return
 
 -         QMessageBox.about(self, '温馨提示', '当前已经是第一步')
 
  
-     def after(self):
 
 -         """后一步"""
 
 -         # TODO 如果图像临时数据还有数据,那么从临时数据’回档‘
 
 -         if self.widget.pix_tmp:
 
 -             # TODO 对图像处理
 
 -             pix, num = self.widget.pix_tmp.pop(0)
 
 -             pix.setVisible(True)
 
 -             num.setVisible(True)
 
 -             self.widget.pix_record.append([pix, num])
 
 -             # # TODO 对落点数据处理
 
 -             self.widget.record.append(self.widget.record_tmp.pop(0))
 
 -             return
 
 -         # TODO 如果图像临时数据没有数据,那么通过电脑计算下一步
 
 -         self.widget.Ai_move()
 
  
-     def end(self):
 
 -         """回到最后一步"""
 
 -         # # TODO 前提是临时数据还有数据,否则当前已经是最后一步
 
 -         if self.widget.pix_tmp:
 
 -             # TODO 对图像处理,显示图像
 
 -             while self.widget.pix_tmp:
 
 -                 pix, num = self.widget.pix_tmp.pop(0)
 
 -                 pix.setVisible(True)
 
 -                 num.setVisible(True)
 
 -                 self.widget.pix_record.append([pix, num])
 
 -             # # TODO 对落点数据处理
 
 -             self.widget.record += self.widget.record_tmp
 
 -             return
 
 -         QMessageBox.about(self, '温馨提示', '当前已经是最后一步')
 
  
 
- if __name__ == '__main__':
 
 -     import sys
 
 -     from PyQt5.QtWidgets import QApplication
 
  
-     app = QApplication(sys.argv)
 
  
-     game = Gomoku()
 
  
-     game.show()
 
  
-     sys.exit(app.exec_())
 
 
  复制代码 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |