失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > QT实现五子棋小游戏

QT实现五子棋小游戏

时间:2021-06-24 06:28:26

相关推荐

QT实现五子棋小游戏

学习QT的过程中,为了加深自己的一些基础操作,也为了想装x,就自己写了一个五子棋小游戏,目前界面没写完整,游戏主题部分可以玩。

五子棋游戏主要的操作有三个。

第一:

void MainWindow::paintEvent(QPaintEvent *) //使用绘图事件时需要添加时间函数在h文件下面{QPainter p(this);//创建Qpainter类型并指定绘图背景QPen pen; //创建画笔,用于设置绘图的线的粗细颜色和一些风格QBrush brush;pen.setWidth(4); //制定宽度p.setPen(pen); //告诉p用画笔来画图p.drawPixmap(0,0,this->width(),this->height(),QPixmap(":/new/prefix1/5c8a2a67967b8.jpg")); //设置窗口背景]grand_x=width()/25;//记录横向每一格子的宽度,,分25格子grand_y=height()/15; //记录纵向每一格子宽度start_x=grand_x; //记录期盼绘制横向起始坐标start_y=grand_y; //记录期盼纵向起始坐标for(int i=0;i<= 23;i++) //循环绘制竖线{p.drawLine(start_x+i*grand_x,start_y,start_x+i*grand_x,13*start_y+grand_y); //起始坐标加上每一次循环后格子de宽度}for(int i=0;i<=13;i++) //横线{p.drawLine(start_x,start_y+i*grand_y,23*grand_x+start_x,start_y+i*grand_y);}brush.setStyle(Qt::SolidPattern);if(chess_x>=0&&click_x<24&&chess_y>=0&&chess_y<14) //绘制下子标记点{brush.setColor(Qt::white);p.setBrush(brush);p.drawEllipse((start_x+grand_x*chess_x)-7,(start_y+grand_y*chess_y)-7, 14, 14);}/*绘制棋子 */for(int i=0;i<=23;i++)for(int j=0;j<=13;j++){if((game->gameMapVec[i][j]==1)) //绘制棋子{p.setPen(QColor(Qt::black));//画黑点p.setBrush(QBrush(Qt::black));point_x=(start_x+grand_x*i)-15;point_y=(start_y+grand_y*j)-15;p.drawEllipse(point_x,point_y,33,33);// p.end();/*第一个参数是x坐标,第二个是圆的y坐标注意:这里的xy不是指圆心坐标,而是指圆点起点坐标,从屏幕左上角(0.0)算起第三个参数是圆点宽度第四个是高度可以根据三四各参数来绘制椭圆或者圆*/}if((game->gameMapVec[i][j]==-1)) //绘制棋子{p.setPen(QColor(Qt::white));//画白点p.setBrush(QBrush(Qt::white));point_x=(start_x+grand_x*i)-15;point_y=(start_y+grand_y*j)-15;p.drawEllipse(point_x,point_y,33,33);}}}

上述函数实现的功能就是绘制棋盘,棋子,和下棋标记。

当鼠标移动时,坐标会跟着移动,判断鼠标当前坐标,动态绘制除下棋标记,当鼠标出发按压事件后,在此处绘制一个棋子。

第二:

void MainWindow::mouseMoveEvent(QMouseEvent *event) //鼠标按压事件{int x=event->x(); //定义变量来获取鼠标每次按下后的坐标值int y=event->y();if(x>=start_x/2&&x<=start_x+23.5*grand_x&&y>=start_y/2&&y<=start_y*13.5+grand_y) //保证棋子落在棋盘内部,在外部的无效{chess_x=(x-start_x/2)/(grand_x); //保证鼠标点击区域的坐标是十字线,(未优化)chess_y=(y-start_y/2)/(grand_y);//qDebug() << chess_x<< chess_y;update();//更新整个界面,(为显示新的棋子的图像)}else{chess_x=-1; //棋盘的坐标,为了防止出错,初始化-1chess_y=-1;}}

上述代码实现了如下功能:

1,捕获鼠标移动时的坐标,并判断是否在棋盘内。

2,若果在棋盘内,就同过处理,让鼠标在某一个棋盘十字附近的时候,让坐标直接等于棋盘的格子相应的坐标。比如左上角第一个就是(0,0),这样,棋盘在我们眼里相当于一个二维数组。具体处理过程,程序里面有注释。

第三:

int gamemode::Jude_win(){int situ_1[5][5]= {{1,1,1,1,1}, {0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};int situ_2[5][5]= {{1,0,0,0,0},{1,0,0,0,0},{1,0,0,0,0},{1,0,0,0,0},{1,0,0,0,0}};int situ_3[5][5]= {{1,0,0,0,0},{0,1,0,0,0},{0,0,1,0,0},{0,0,0,1,0},{0,0,0,0,1}};int situ_4[5][5]= {{0,0,0,0,1},{0,0,0,1,0},{0,0,1,0,0},{0,1,0,0,0},{1,0,0,0,0}};int situ_5[5][5]= {{0,0,0,0,1},{0,0,0,0,1},{0,0,0,0,1},{0,0,0,0,1},{0,0,0,0,1}};int situ_6[5][5]= {{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{1,1,1,1,1}};for(int i=0;i<=19;i++)for(int j=0;j<=9;j++){int cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_1[x][y]*gameMapVec[i+x][j+y]; //if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_2[x][y]*gameMapVec[i+x][j+y];if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_3[x][y]*gameMapVec[i+x][j+y];if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_4[x][y]*gameMapVec[i+x][j+y];if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_5[x][y]*gameMapVec[i+x][j+y];if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;for(int x=0;x<=4;x++)for(int y=0;y<=4;y++){cnt=cnt+situ_6[x][y]*gameMapVec[i+x][j+y];if(cnt==5){return 1;}if(cnt==-5){return -1;}}cnt=0;}return 0;}

上述代码是用来判断输赢的。学过图像处理的都知道卷积操作。五子连珠就是相当于用一个5x5的模板去扫描整个棋盘。

在这之前,我用和一个二维数组保存下棋的情况。初始化数组为0.(没有棋子),当触发鼠标按压事件的的时候,如果黑色,标记为1,白色为-1.那么用上述六中情况可以包括所有五子连一起的情况。

ps:刚开始用了四中情况。米子一样的四个模板。但是这样,边界就扫描不到。

人机对战还没有加进去。

如果有大佬愿意一起开发,可以给它加一个开始页面,加人机挑战,甚至可以写如tcp协议,局域网玩。

源码上传至csnd,注释很详细,欢迎下载相互学习。

如果觉得《QT实现五子棋小游戏》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。