分析
- 有两种对弈模式:人人对战和人机对战
- 采用Qt实现界面
- 棋盘大小为19x19
- 黑白任一方先连成5个棋子形成的直线,则该方赢对方输
设计
该设计有三个模块:
- 棋盘(棋子)模块
主要负责棋盘棋子的绘画 - 判断模块
记录当前结果 - 显示模块
主要刷新棋盘,输出提示信息
类实现
棋盘(棋子)类
方法:
public: void drawPlate(QPainter&); //在主窗口绘画棋盘 void drawChess(QPainter&); //在主窗口绘画棋子 void clearChess(); //清理棋子
属性:
public: const int SIZE=19; //棋盘的大小19x19 const int WIDTH=40; //格子之间的距离 int chess[SIZE][SIZE]; //记录棋子 int player=1; //默认黑棋先下,记录该谁下
判断类
方法
public: Judge(ChessBoard*); //构造函数,将实时的对弈情况传输到Judge类 bool isWin(int x,int y); //判断下在x,y的输赢 int Win1(int x,int y); //判断输赢的第一种情况 int Win2(int x,int y); //判断输赢的第二种情况 ... int Win4(int x,int y); //判断输赢的第四种情况
属性:
private: int chess[19][19]; //保存构造函数传过来的实施对弈情况
模式类——人人对弈类、人机对弈类
我们发现人人对弈和人机对弈的棋盘棋子的绘画不变,我们将在显示类中直接画好,我们只接收棋子的对弈情况。
人人对弈:
方法
public: void peopleDown(ChessBoard*); //人人对战下法,包含判断类
人机对弈:
方法
public: void computerDown(ChessBoard*); //人机对战下法,包含判断类 int getLine(QPoint,int i,int j); //判断在i方向(一个棋子有8个方向)上棋子的值,j表示坐标相对值 int Evaluate(QPoint); //估值算法,计算每种棋型的权重 int bestValue(int *x,int *y); //遍历棋盘,得到最大估值的坐标 void comFirst(ChessBoard*); //电脑先下
显示类
方法
public: void paintEvent(QPaintEvent*); //画图事件,绘制棋盘棋子 void mousePressEvent(QMouseEvent*); //监听鼠标点击事件 private slots: //槽函数 void on_conboBox_activated(const QString & arg1); //模式选择处理 void on_comFirstButton_clicked(); //电脑先下按钮事件处理 void on_restartButton_clicked(); //重新开始按钮事件处理
属性:
public: int flag=1; //选择对战模式,默认为人人对战 1为人人对战,2为人机对战
效果图
总结
看的出,界面比较丑,而且功能简单,不过最关键的是五子棋的判断输赢和人机对弈的估值,这是开发过程中最复杂的,需要对五子棋的各种棋型进行估值。由于没有用到深层思考算法,只是判断棋盘最大估值落子,所以智商比较低(简直就是弱智),只能思考一层。如果有机会,将试试深层思考算法和网络对战。