logo资料库

Qt实现简单五子棋小游戏.pdf

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
Qt实现简单五子棋小游戏 实现简单五子棋小游戏 C++代码简单实现五子棋功能,主要是分为窗口绘图的显示,横、纵、斜三个方面计算的功能代码实现,即能连续出现5个相 同棋子就为赢。在这里就简单讲解一下这三个方面的功能实现(主要是通过QT实现)。 下图为游戏主窗口页面: 游戏主窗口页面: 第一步:窗口绘图的实现(QPaintEvent绘图事件 和 QMouseEvent鼠标事件) 第一步: ①鼠标事件(这里我的是mouseDoubleClickEvent()双击事件) void GamePage::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击事件 { m_dx = event->x(); m_dy = event->y(); //避免乱点时存入坐标 需添加:标志符--》game状态 坐标的界限(点) if(m_dx < POINT_X_MAX && m_dy < POINT_Y_MAX && m_bRunState == true) { //如果点在交叉点周围则设置点在交叉点上(判断点位置) QPointF newPoint(gainPointPosition(QPointF(m_dx,m_dy))); if(!m_VectorRedPoint.contains(newPoint) && !m_VectorBlackPoint.contains(newPoint))//判断点是否已经存在 { if(m_iFlagWho == 0)//红棋 { m_VectorRedPoint.append(newPoint); m_iFlagWho = 1; } else//黑棋 { m_VectorBlackPoint.append(newPoint); m_iFlagWho = 0; } } } } 在这里窗口网格图是通过直接绘画以及鼠标双击选择坐标来存储棋子和绘画棋子,因此对点进行了一个设置位置函数以便处于 两线之间的交接处,代码如下: QPointF GamePage::gainPointPosition(QPointF srcPoint)//返回一个处于格子两线交接处的坐标点 { QPointF tmp; for(int i = 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 } else if (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);//同上 } else if (srcPoint.y() >= (50*i + 25) && srcPoint.y() <= 50*(i+1)) { tmp.setY(50*(i+1));//同上 } } return tmp; } ②绘图事件( 主要是网格图、黑棋、红棋的绘画 ) 棋子坐标的存储主要是通过QVector容器来实现,并对容器进行迭代循环绘图,实现代码如下: void GamePage::paintEvent(QPaintEvent *event)//绘画事件 { QPainter *pater = new QPainter(this); pater->begin(this); //网格图 pater->setPen(Qt::black); for(int i = 0;i <= 12;i++) { pater->drawLine(0,50*i,600,50*i); pater->drawLine(50*i,0,50*i,600); } //红色棋绘画 QVector::iterator iter; 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::iterator iter1; 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(); } 第二步: 第二步:输赢的计算
上图列出了计算的关系规律,下面就用代码分别实现三个不同方向的计算: ①横向 bool GamePage::checkXPointF(QVector vector) //检查X轴方向的 { int num_L= 1; int num_R = 1; QVector::iterator iter; QVector::iterator itertmp; for(iter = vector.begin();iter != vector.end();iter++) { QPointF tmp = *iter; for(int k = 1;k < 5;k++)//左方向的查找 { for(itertmp = vector.begin();itertmp != vector.end();itertmp++) { qDebug()<<*itertmp<<"X compare"<
if(num_R == 5) { return true; } } else { break; } } if(num_R + num_L == 5+1)//5+1 因为左右方向都是从1开始计算 重复了原点tmp坐标 { return true; } else { num_R = 1; num_L = 1; } } return false; } ②纵向(与横向同理) bool GamePage::checkYPointF(QVector vector) { qDebug()<<"enter Y***************"; int num_U = 1; int num_D = 1; QVector::iterator iter; QVector::iterator itertmp; for(iter = vector.begin();iter != vector.end();iter++) { QPointF tmp = *iter; for(int k = 1;k < 5;k++)//上 { for(itertmp = vector.begin();itertmp != vector.end();itertmp++) { qDebug()<<*itertmp<<"Y compare"<
{ return true; } }else{break;} } if(num_D + num_U == 5 + 1)//减去一个 { return true; } else { num_D = 1; num_U= 1; } } return false; } ③斜向(从上图可知,以坐标系为例,分为四个象限的计算和计数来判断是否达到要求) int GamePage::findSeriesPointF(bool flag, QPointF tmp, QVector vector) { bool flag_iter = false; int forward_count = 1;//一象限的数量 int reverse_count = 1; int forward_count2 = 1; int reverse_count2 = 1; QVector::iterator iter= vector.begin(); while(iter != vector.end()) { qDebug()<<*iter<<"compare"<
{ reverse_count=2; flag_iter = true; } break; case 2: if((*iter).x() - tmp.x() == -50*reverse_count && (*iter).y() - tmp.y() == 50*reverse_count) { reverse_count++; flag_iter = true; } break; case 3: if((*iter).x() - tmp.x() == -50*reverse_count && (*iter).y() - tmp.y() == 50*reverse_count) { reverse_count++; flag_iter = true; } break; case 4: if((*iter).x() - tmp.x() == -50*reverse_count && (*iter).y() - tmp.y() == 50*reverse_count) { reverse_count++; flag_iter = true; } break; } qDebug()<
case 1: if((*iter).x() - tmp.x() == 50 && (*iter).y() - tmp.y() == 50) { reverse_count2++; flag_iter = true; } break; case 2: if((*iter).x() - tmp.x() == 50*reverse_count2 && (*iter).y() - tmp.y() == 50*reverse_count2) { reverse_count2++; flag_iter = true; } break; case 3: if((*iter).x() - tmp.x() == 50*reverse_count2 && (*iter).y() - tmp.y() == 50*reverse_count2) { reverse_count2++; flag_iter = true; } break; case 4: if((*iter).x() - tmp.x() == 50*reverse_count2 && (*iter).y() - tmp.y() == 50*reverse_count2) { reverse_count2++; flag_iter = true; } break; } qDebug()<::iterator iterRed; 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++) {
QPointF tmp = *iterRed;//获取第一个点 qDebug()<<"tmp:"<::iterator itertmp; 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::iterator iterBlack; QVector tmpBlack = m_VectorBlackPoint; if(m_VectorBlackPoint.size() >= 5) { for(iterBlack = m_VectorBlackPoint.begin();iterBlack != m_VectorBlackPoint.end();iterBlack++) { QPointF tmp = *iterBlack;//获取第一个点 qDebug()<<"tmp:"<::iterator itertmp; 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); } }
分享到:
收藏