关联:NEU 东北大学
本篇将大致描述基础思路,后续会添加相应的演示视频和整个工程文件
首先我将大致描述一下我的创作进度
1.先完成棋盘的绘制(QT仅绘制棋盘)
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #includeQT_END_NAMESPACE #define CHESS_ROWS 6//列 #define CHESS_COLUMES 6//行 #define RECT_WIDTH 100//宽 #define RECT_HEIGHT 100//长 class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *); int num; private: void DrawChessboard(); void DrawItems(); void DrawItemWithMouse(); void DrawChessAtPoint(QPainter& painter,QPoint& pt); }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include#include #include #include int p_chess[CHESS_ROWS][CHESS_COLUMES]; int i=1; bool black_turn=false; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { resize((CHESS_COLUMES + 0.5)*RECT_WIDTH ,(CHESS_ROWS + 0.5)*RECT_HEIGHT); this->setWindowTitle("黑白棋 请点击以开始游戏"); //------------ } MainWindow::~MainWindow() { } void MainWindow::paintEvent(QPaintEvent *e) { DrawChessboard(); //画棋盘 DrawItems(); //画棋子 DrawItemWithMouse(); //画鼠标(当前方的棋子形状) update(); } void MainWindow::DrawChessboard() { QPainter painter(this); painter.setRenderHint(QPainter::HighQualityAntialiasing, true);//渲染提示,前一个参数属于枚举类型确定渲染的方式,后一个bool形参表示代表是否渲染 painter.setBrush(Qt::darkYellow);//设置画笔方式,画笔决定形状的填充方式 painter.setPen(QPen(QColor(Qt::black),2));//设置pen,pen决定线条轮廓和文本颜色 //第一个参数用来构造参数 for(int i = 0;i x() ) / RECT_WIDTH); pt.setY( (e->y() ) / RECT_HEIGHT); if(i%2+1==1){ if(!p_chess[pt.rx()][pt.ry()]){ black_turn=!black_turn; i++; p_chess[pt.rx()][pt.ry()]=1; // Sleep(500); } }else if((i % 2 + 1) == 2){ if(!p_chess[pt.rx()][pt.ry()]){ p_chess[pt.rx()][pt.ry()]=2; i++; black_turn=!black_turn; // Sleep(500); } // Sleep(1000); } if(black_turn){ this->setWindowTitle("请黑棋落子"); }else{ this->setWindowTitle("该白棋落子了"); } }
以上内容不涉及人机对弈,不涉及任何游戏规则,可适配于五子棋,黑白棋,围棋等
2.原先棋盘的绘制额外加上判断胜负,及人机对弈
仅改变
void MainWindow::mousePressEvent(QMouseEvent *e)函数
void MainWindow::DrawItemWithMouse()
{
QPainter painter(this);
painter.setPen(QPen(QColor(Qt::transparent)));
if ((i % 2 + 1) == 1)
{
painter.setBrush(Qt::black);
}
else
{
painter.setBrush(Qt::white);
}
painter.drawEllipse(mapFromGlobal(QCursor::pos()),RECT_WIDTH / 2,RECT_HEIGHT / 2);
}
void MainWindow::mousePressEvent(QMouseEvent *e)
{
QPoint pt;
pt.setX( (e->x() ) / RECT_WIDTH);
pt.setY( (e->y() ) / RECT_HEIGHT);
if(i%2+1==1){
if(!p_chess[pt.rx()][pt.ry()]){
black_turn=!black_turn;
i++;
p_chess[pt.rx()][pt.ry()]=1;
// Sleep(500);
}
}else if((i % 2 + 1) == 2){
//_____________________________________________
computer_player(2);//2是代表需要将p_chess中对应的值改为2,设置该参数可以使游戏ai可以指定执黑还是执白
//函数其中需要改变p_chess的值
//_________________________________________________-
i++;
black_turn=!black_turn;
// Sleep(500);
// Sleep(1000);
}
if(black_turn){
this->setWindowTitle("请黑棋落子");
}else{
this->setWindowTitle("该白棋落子了");
}
//________________________________________________________________
if(judge_end()){//每步棋下完之后判断是否本局结束
win_or_not()//根据规则判断谁输谁赢,并显示结果。
}
//___________________________________________________________
}
添加的函数不予实现
3.棋类ai的实现
先贴一下两个网址
1.介绍计算机博弈的相关知识
象棋巫师 - 象棋百科全书 (xqbase.com)https://www.xqbase.com/index.htm
2.某位大佬介绍黑白棋ai的文章
concluding2007-Bai.pdf (ustc.edu.cn)http://home.ustc.edu.cn/~baj/publications/concluding2007-Bai.pdf
很遗憾,水平有限未得到真传,仅实现了部分
主要是运用了minmax算法和alpha-bet剪枝,在6*6的黑白棋中,搜索到7层会是在保证不出现长时间停顿下的最大层数。
累了,想看之后滴滴我
项目文件
链接:https://pan.baidu.com/s/15ZEflEVbujFhKi1Bv6t5pw?pwd=vws5
提取码:vws5



