Qt实现简单五子棋小游戏
C++代码简单实现五子棋功能,主要是分为窗口绘图的显示,横、纵、斜三个方面计算的功能代码实现,即能连续出现5个相同棋子就为赢。在这里就简单讲解一下这三个方面的功能实现(主要是通过QT实现)。
下图为游戏主窗口页面:
第一步:窗口绘图的实现(QPaintEvent绘图事件和QMouseEvent鼠标事件)
①鼠标事件(这里我的是mouseDoubleClickEvent()双击事件)
voidGamePage::mouseDoubleClickEvent(QMouseEvent*event)//鼠标双击事件 { m_dx=event->x(); m_dy=event->y(); //避免乱点时存入坐标需添加:标志符--》game状态坐标的界限(点) if(m_dx在这里窗口网格图是通过直接绘画以及鼠标双击选择坐标来存储棋子和绘画棋子,因此对点进行了一个设置位置函数以便处于两线之间的交接处,代码如下:
QPointFGamePage::gainPointPosition(QPointFsrcPoint)//返回一个处于格子两线交接处的坐标点 { QPointFtmp; for(inti=0;i<12;i++) { if(srcPoint.x()>=50*i&&srcPoint.x()<=(50*i+25))//X判断 { tmp.setX(50*i);//如果处于50*i~50*i+25)之间则设置点坐标点为50*i } elseif(srcPoint.x()>=(50*i+25)&&srcPoint.x()<=50*(i+1)) { tmp.setX(50*(i+1));//如果处于50*i+25~50*(i+1)之间则设置点坐标点为50*(i+1) } if(srcPoint.y()>=50*i&&srcPoint.y()<=(50*i+25))//Y判断 { tmp.setY(50*i);//同上 } elseif(srcPoint.y()>=(50*i+25)&&srcPoint.y()<=50*(i+1)) { tmp.setY(50*(i+1));//同上 } } returntmp; }②绘图事件(主要是网格图、黑棋、红棋的绘画)
棋子坐标的存储主要是通过QVector容器来实现,并对容器进行迭代循环绘图,实现代码如下:
voidGamePage::paintEvent(QPaintEvent*event)//绘画事件 { QPainter*pater=newQPainter(this); pater->begin(this); //网格图 pater->setPen(Qt::black); for(inti=0;i<=12;i++) { pater->drawLine(0,50*i,600,50*i); pater->drawLine(50*i,0,50*i,600); } //红色棋绘画 QVector::iteratoriter; for(iter=m_VectorRedPoint.begin();iter!=m_VectorRedPoint.end();iter++) { pater->setBrush(QBrush(Qt::red,Qt::SolidPattern)); pater->setPen(Qt::red); pater->drawEllipse(*iter,15,15); } //黑色棋绘画 QVector ::iteratoriter1; for(iter1=m_VectorBlackPoint.begin();iter1!=m_VectorBlackPoint.end();iter1++) { pater->setBrush(QBrush(Qt::black,Qt::SolidPattern)); pater->setPen(Qt::black); pater->drawEllipse(*iter1,15,15); } pater->end(); update(); } 第二步:输赢的计算
上图列出了计算的关系规律,下面就用代码分别实现三个不同方向的计算:
①横向
boolGamePage::checkXPointF(QVectorvector)//检查X轴方向的 { intnum_L=1; intnum_R=1; QVector ::iteratoriter; QVector ::iteratoritertmp; for(iter=vector.begin();iter!=vector.end();iter++) { QPointFtmp=*iter; for(intk=1;k<5;k++)//左方向的查找 { for(itertmp=vector.begin();itertmp!=vector.end();itertmp++) { qDebug()<<*itertmp<<"Xcompare"< ②纵向(与横向同理)
boolGamePage::checkYPointF(QVectorvector) { qDebug()<<"enterY***************"; intnum_U=1; intnum_D=1; QVector ::iteratoriter; QVector ::iteratoritertmp; for(iter=vector.begin();iter!=vector.end();iter++) { QPointFtmp=*iter; for(intk=1;k<5;k++)//上 { for(itertmp=vector.begin();itertmp!=vector.end();itertmp++) { qDebug()<<*itertmp<<"Ycompare"< ③斜向(从上图可知,以坐标系为例,分为四个象限的计算和计数来判断是否达到要求)
intGamePage::findSeriesPointF(boolflag,QPointFtmp,QVectorvector) { boolflag_iter=false; intforward_count=1;//一象限的数量 intreverse_count=1; intforward_count2=1; intreverse_count2=1; QVector ::iteratoriter=vector.begin(); while(iter!=vector.end()) { qDebug()<<*iter<<"compare"< 以上横、纵、斜三个方向的运算都是通过最简单的算法是实现,易于理解。
④定时器实现红黑旗的定时检查功能
voidGamePage::slotCheckWhetherWin()//定时器检查是否输赢功能 { m_pVerVector.clear(); m_pVerVectorB.clear(); m_pHerVector.clear(); m_pHerVectorB.clear(); QVector::iteratoriterRed; for(iterRed=m_VectorRedPoint.begin();iterRed!=m_VectorRedPoint.end();iterRed++) { qDebug()<<*iterRed; } QVector tmpRed=m_VectorRedPoint; //红棋判断 if(m_VectorRedPoint.size()>=5) { for(iterRed=m_VectorRedPoint.begin();iterRed!=m_VectorRedPoint.end();iterRed++) { QPointFtmp=*iterRed;//获取第一个点 qDebug()<<"tmp:"< ::iteratoritertmp; for(itertmp=tmpRed.begin();itertmp!=tmpRed.end();itertmp++) { qDebug()<<"tmpRed:"<<*itertmp; //横向连续5个点 if((*itertmp).y()-tmp.y()>=-0.000001&&(*itertmp).y()-tmp.y()<=0.000001)//先判断y是同一坐标 { m_pHerVector.append(*itertmp); } //纵向连续5个点 if((*itertmp).x()-tmp.x()>=-0.000001&&(*itertmp).x()-tmp.x()<=0.000001)//先判断y是同一坐标 { m_pVerVector.append(*itertmp); } } //对容器进行操作 if(checkXPointF(m_pHerVector)||checkYPointF(m_pVerVector)) { QMessageBox::warning(nullptr,"warning","红方XY赢了!"); m_ptimer->stop(); return; } else { m_pHerVector.clear();//清空 m_pVerVector.clear();//清空 count=0; } //其他都是斜向 if(findSeriesPointF(true,tmp,m_VectorRedPoint)==5) { QMessageBox::warning(nullptr,"warning","红方斜线赢了!"); m_ptimer->stop(); return; } } } //黑棋判断 QVector ::iteratoriterBlack; QVector tmpBlack=m_VectorBlackPoint; if(m_VectorBlackPoint.size()>=5) { for(iterBlack=m_VectorBlackPoint.begin();iterBlack!=m_VectorBlackPoint.end();iterBlack++) { QPointFtmp=*iterBlack;//获取第一个点 qDebug()<<"tmp:"< ::iteratoritertmp; for(itertmp=tmpBlack.begin();itertmp!=tmpBlack.end();itertmp++)//正向 { qDebug()<<"tmpRed:"<<*itertmp; //横向连续5个点 if((*itertmp).y()-tmp.y()>=-0.000001&&(*itertmp).y()-tmp.y()<=0.000001)//先判断y是同一坐标 { m_pHerVectorB.append(*itertmp); } //纵向连续5个点 if((*itertmp).x()-tmp.x()>=-0.000001&&(*itertmp).x()-tmp.x()<=0.000001)//先判断y是同一坐标 { m_pVerVectorB.append(*itertmp); } } //对容器进行操作 if(checkXPointF(m_pHerVectorB)||checkYPointF(m_pVerVectorB)) { QMessageBox::warning(nullptr,"warning","黑方XY赢了!"); m_ptimer->stop(); return; } else { m_pHerVectorB.clear();//清空 m_pVerVectorB.clear();//清空 count=0; } //其他都是斜向 if(findSeriesPointF(true,tmp,m_VectorBlackPoint)==5) { QMessageBox::warning(nullptr,"warning","黑方斜线赢了!"); m_ptimer->stop(); return; } } } } 以上就是实现简单的五子棋功能,初步实现一些简单的计算功能,能正常运行小游戏,没花太多时间进行检查,可能会存在一些bug,还请见谅,希望对初学者有所帮助。
更多有趣的经典小游戏实现专题,分享给大家:
C++经典小游戏汇总
python经典小游戏汇总
python俄罗斯方块游戏集合
JavaScript经典游戏玩不停
javascript经典小游戏汇总
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。