欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt實現(xiàn)簡單五子棋小游戲

 更新時間:2020年08月28日 13:35:34   作者:Tjmies  
這篇文章主要為大家詳細(xì)介紹了Qt實現(xiàn)簡單五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

C++代碼簡單實現(xiàn)五子棋功能,主要是分為窗口繪圖的顯示,橫、縱、斜三個方面計算的功能代碼實現(xiàn),即能連續(xù)出現(xiàn)5個相同棋子就為贏。在這里就簡單講解一下這三個方面的功能實現(xiàn)(主要是通過QT實現(xiàn))。

下圖為游戲主窗口頁面:

第一步:窗口繪圖的實現(xiàn)(QPaintEvent繪圖事件 和 QMouseEvent鼠標(biāo)事件)

①鼠標(biāo)事件(這里我的是mouseDoubleClickEvent()雙擊事件)

void GamePage::mouseDoubleClickEvent(QMouseEvent *event)//鼠標(biāo)雙擊事件
{
 m_dx = event->x();
 m_dy = event->y();
 //避免亂點時存入坐標(biāo) 需添加:標(biāo)志符--》game狀態(tài) 坐標(biāo)的界限(點)
 if(m_dx < POINT_X_MAX && m_dy < POINT_Y_MAX && m_bRunState == true)
 {
 //如果點在交叉點周圍則設(shè)置點在交叉點上(判斷點位置)
 QPointF newPoint(gainPointPosition(QPointF(m_dx,m_dy)));
 
 if(!m_VectorRedPoint.contains(newPoint) &&    
  !m_VectorBlackPoint.contains(newPoint))//判斷點是否已經(jīng)存在
 {
  if(m_iFlagWho == 0)//紅棋
  {
  m_VectorRedPoint.append(newPoint);
  m_iFlagWho = 1;
  }
  else//黑棋
  {
  m_VectorBlackPoint.append(newPoint);
  m_iFlagWho = 0;
  }
 }
 
 }
}

在這里窗口網(wǎng)格圖是通過直接繪畫以及鼠標(biāo)雙擊選擇坐標(biāo)來存儲棋子和繪畫棋子,因此對點進行了一個設(shè)置位置函數(shù)以便處于兩線之間的交接處,代碼如下:

QPointF GamePage::gainPointPosition(QPointF srcPoint)//返回一個處于格子兩線交接處的坐標(biāo)點
{
 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)之間則設(shè)置點坐標(biāo)點為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)之間則設(shè)置點坐標(biāo)點為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;
}

②繪圖事件( 主要是網(wǎng)格圖、黑棋、紅棋的繪畫 )

棋子坐標(biāo)的存儲主要是通過QVector容器來實現(xiàn),并對容器進行迭代循環(huán)繪圖,實現(xiàn)代碼如下:

void GamePage::paintEvent(QPaintEvent *event)//繪畫事件
{
 QPainter *pater = new QPainter(this);
 pater->begin(this);
 //網(wǎng)格圖
 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<QPointF>::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<QPointF>::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();
 
}

第二步:輸贏的計算

上圖列出了計算的關(guān)系規(guī)律,下面就用代碼分別實現(xiàn)三個不同方向的計算:

①橫向

bool GamePage::checkXPointF(QVector<QPointF> vector) //檢查X軸方向的
{
 int num_L= 1;
 int num_R = 1;
 QVector<QPointF>::iterator iter;
 QVector<QPointF>::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"<<tmp;
   if((*itertmp).x() - tmp.x() == k*50)
   {
   num_L ++;
   }
  }
  //qDebug()<<"count:"<<num;
  if(num_L == k+1)//尋找過程中找到幾個點相連
  {
   if(num_L == 5)
   {
   return true;
   }
  }
  else
  {
   break;
  }
  }
 
  for(int k = 1;k < 5;k++)//右方向的查找
  {
  for(itertmp = vector.begin();itertmp != vector.end();itertmp++)
  {
   qDebug()<<*itertmp<<"X compare"<<tmp;
   if((*itertmp).x() - tmp.x() == -k*50)
   {
   num_R ++;
   }
  }
  //qDebug()<<"count:"<<num;
  if(num_R == k+1)//尋找過程中找到幾個點相連
  {
  if(num_R == 5)
  {
   return true;
  }
  }
  else
  {
  break;
  }
 }
 if(num_R + num_L == 5+1)//5+1 因為左右方向都是從1開始計算 重復(fù)了原點tmp坐標(biāo)
 {
  return true;
 }
 else
 {
  num_R = 1;
  num_L = 1;
 
 }
 }
 return false;
}

②縱向(與橫向同理)

bool GamePage::checkYPointF(QVector<QPointF> vector)
{
 qDebug()<<"enter Y***************";
 int num_U = 1;
  int num_D = 1;
 QVector<QPointF>::iterator iter;
 QVector<QPointF>::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"<<tmp;
   if((*itertmp).y() - tmp.y() == k*50)
   {
   num_U ++;
   }
  }
  qDebug()<<"num_U:"<<num_U;
  if(num_U == k+1)//尋找過程中找到幾個點相連
  {
   if(num_U == 5)
   {
   return true;
   }
  }else{break;}
  }
  for(int k = 1;k < 5;k++)//下
  {
  for(itertmp = vector.begin();itertmp != vector.end();itertmp++)
  {
   qDebug()<<*itertmp<<"Y compare"<<tmp;
   if((*itertmp).y() - tmp.y() == -k*50)
   {
   num_D ++;
   }
 
  }
  qDebug()<<"num_D:"<<num_D;
  if(num_D == k+1)//尋找過程中找到幾個點相連
  {
  if(num_D == 5)
  {
   return true;
  }
  }else{break;}
 }
 if(num_D + num_U == 5 + 1)//減去一個
 {
  return true;
 }
 else
 {
  num_D = 1;
  num_U= 1;
 }
 }
 
 return false;
}

③斜向(從上圖可知,以坐標(biāo)系為例,分為四個象限的計算和計數(shù)來判斷是否達到要求)

int GamePage::findSeriesPointF(bool flag, QPointF tmp, QVector<QPointF> vector)
{
 bool flag_iter = false;
 int forward_count = 1;//一象限的數(shù)量
 int reverse_count = 1;
 int forward_count2 = 1;
 int reverse_count2 = 1;
 QVector<QPointF>::iterator iter= vector.begin();
 
 while(iter != vector.end())
 {
  qDebug()<<*iter<<"compare"<<tmp;
  switch(forward_count)//一象限
  {
  case 1:
   if((*iter).x() - tmp.x() == 50 && (*iter).y() - tmp.y() == -50)
   {
   forward_count ++;
 
   flag_iter = true;
   }
   break;
  case 2:
   if((*iter).x() - tmp.x() == 50*forward_count && (*iter).y() - tmp.y() == -50*forward_count)
   {
   forward_count++;
   flag_iter = true;
   }
   break;
  case 3:
   if((*iter).x() - tmp.x() == 50*forward_count && (*iter).y() - tmp.y() == -50*forward_count)
   {
   forward_count++;
   flag_iter = true;
   }
   break;
  case 4:
   if((*iter).x() - tmp.x() == 50*forward_count && (*iter).y() - tmp.y() == -50*forward_count)
   {
   forward_count++;
   flag_iter = true;
   }
   break;
 
  }
  switch(reverse_count)//三象限
  {
  case 1:
   if((*iter).x() - tmp.x() == -50 && (*iter).y() - tmp.y() == 50)
   {
   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()<<forward_count<<"+"<<reverse_count;
  if(forward_count + reverse_count == 6)//未加上點本身
  {
  return 5;
 
  }
 
  switch(forward_count2)//2象限
  {
  case 1:
   if((*iter).x() - tmp.x() == -50 && (*iter).y() - tmp.y() == -50)
   {
   forward_count2++;
   flag_iter = true;
   }
   break;
  case 2:
   if((*iter).x() - tmp.x() == -50*forward_count2 && (*iter).y() - tmp.y() == -50*forward_count2)
   {
   forward_count2++;
   flag_iter = true;
   }
   break;
  case 3:
   if((*iter).x() - tmp.x() == -50*forward_count2 && (*iter).y() - tmp.y() == -50*forward_count2)
   {
   forward_count2++;
   flag_iter = true;
   }
   break;
  case 4:
   if((*iter).x() - tmp.x() == -50*forward_count2 && (*iter).y() - tmp.y() == -50*forward_count2)
   {
   forward_count2++;
   flag_iter = true;
   }
   break;
  }
 
  switch(reverse_count2)//4象限
  {
  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()<<forward_count2<<"+"<<reverse_count2;
  if(forward_count2 + reverse_count2 == 6)//未加上點本身
  {
  return 5;
  }
  if(flag_iter)
  {
   iter = vector.begin();//目的是返回首個點,重頭存貨在后 不錯過
   flag_iter = false;
  }
  else {
   iter++;
  }
 
 }
 
 return 0;
}

以上橫、縱、斜三個方向的運算都是通過最簡單的算法是實現(xiàn),易于理解。

④定時器實現(xiàn)紅黑旗的定時檢查功能

void GamePage::slotCheckWhetherWin()//定時器檢查是否輸贏功能
{
 m_pVerVector.clear();
 m_pVerVectorB.clear();
 m_pHerVector.clear();
 m_pHerVectorB.clear();
 
 QVector<QPointF>::iterator iterRed;
 for(iterRed = m_VectorRedPoint.begin();iterRed != m_VectorRedPoint.end();iterRed++)
 {
  qDebug()<<*iterRed;
 }
 QVector<QPointF> tmpRed = m_VectorRedPoint;
 //紅棋判斷
 if(m_VectorRedPoint.size() >= 5)
 {
  for(iterRed = m_VectorRedPoint.begin();iterRed != m_VectorRedPoint.end();iterRed++)
  {
 
  QPointF tmp = *iterRed;//獲取第一個點
  qDebug()<<"tmp:"<<tmp;
  QVector<QPointF>::iterator itertmp;
  for(itertmp = tmpRed.begin();itertmp != tmpRed.end();itertmp++)
  {
   qDebug()<<"tmpRed:"<<*itertmp;
   //橫向連續(xù)5個點
   if((*itertmp).y() - tmp.y() >= -0.000001 && (*itertmp).y() - tmp.y() <= 0.000001)//先判斷y是同一坐標(biāo)
   {
    m_pHerVector.append(*itertmp);
   }
   //縱向連續(xù)5個點
   if((*itertmp).x() - tmp.x() >= -0.000001 && (*itertmp).x() - tmp.x() <= 0.000001)//先判斷y是同一坐標(biāo)
   {
    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<QPointF>::iterator iterBlack;
 QVector<QPointF> tmpBlack = m_VectorBlackPoint;
 if(m_VectorBlackPoint.size() >= 5)
 {
  for(iterBlack = m_VectorBlackPoint.begin();iterBlack != m_VectorBlackPoint.end();iterBlack++)
  {
 
  QPointF tmp = *iterBlack;//獲取第一個點
  qDebug()<<"tmp:"<<tmp;
  QVector<QPointF>::iterator itertmp;
  for(itertmp = tmpBlack.begin();itertmp != tmpBlack.end();itertmp++)//正向
  {
   qDebug()<<"tmpRed:"<<*itertmp;
   //橫向連續(xù)5個點
   if((*itertmp).y() - tmp.y() >= -0.000001 && (*itertmp).y() - tmp.y() <= 0.000001)//先判斷y是同一坐標(biāo)
   {
    m_pHerVectorB.append(*itertmp);
   }
   //縱向連續(xù)5個點
   if((*itertmp).x() - tmp.x() >= -0.000001 && (*itertmp).x() - tmp.x() <= 0.000001)//先判斷y是同一坐標(biāo)
   {
    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;
  }
  }
 
 }
 
}

以上就是實現(xiàn)簡單的五子棋功能,初步實現(xiàn)一些簡單的計算功能,能正常運行小游戲,沒花太多時間進行檢查,可能會存在一些bug,還請見諒 ,希望對初學(xué)者有所幫助。

更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:

C++經(jīng)典小游戲匯總

python經(jīng)典小游戲匯總

python俄羅斯方塊游戲集合

JavaScript經(jīng)典游戲 玩不停

javascript經(jīng)典小游戲匯總

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言實現(xiàn)掃雷游戲(可以自動展開)

    C語言實現(xiàn)掃雷游戲(可以自動展開)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)掃雷游戲,可以自動展開,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C語言實現(xiàn)簡單的掃雷功能

    C語言實現(xiàn)簡單的掃雷功能

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單的掃雷功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++對象的淺復(fù)制和深復(fù)制詳解及簡單實例

    C++對象的淺復(fù)制和深復(fù)制詳解及簡單實例

    這篇文章主要介紹了C++對象的淺復(fù)制和深復(fù)制詳解及簡單實例的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • C/C++實現(xiàn)快速排序算法的兩種方式實例

    C/C++實現(xiàn)快速排序算法的兩種方式實例

    快速排序是一種采用分治思想,在實踐中通常運行較快一種排序算法,這篇文章主要給大家介紹了關(guān)于C/C++實現(xiàn)快速排序的兩種方式的相關(guān)資料,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下
    2021-08-08
  • VisualStudio2022 cmake配置opencv開發(fā)環(huán)境

    VisualStudio2022 cmake配置opencv開發(fā)環(huán)境

    本文主要介紹了VisualStudio2022 cmake配置opencv開發(fā)環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • C++編程異常處理中try和throw以及catch語句的用法

    C++編程異常處理中try和throw以及catch語句的用法

    這篇文章主要介紹了C++編程異常處理中try和throw以及catch語句的用法,包括對Catch塊的計算方式的介紹,需要的朋友可以參考下
    2016-01-01
  • 基于Qt OpenCV的圖像灰度化像素操作詳解

    基于Qt OpenCV的圖像灰度化像素操作詳解

    這篇文章主要為大家詳細(xì)介紹了基于Qt+OpenCV的圖像灰度化像素操作:最大值法、平均法、加權(quán)平均值法,感興趣的小伙伴可以了解一下
    2022-07-07
  • Qt實現(xiàn)Slider滑塊條組件的示例代碼

    Qt實現(xiàn)Slider滑塊條組件的示例代碼

    在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,本文主要介紹了Qt實現(xiàn)Slider滑塊條組件的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • C++中的memset用法詳解

    C++中的memset用法詳解

    memset是一個初始化函數(shù),作用是將某一塊內(nèi)存中的全部設(shè)置為指定的值,本文給大家介紹C++中的memset用法,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • C/C++ 多線程的學(xué)習(xí)心得總結(jié)

    C/C++ 多線程的學(xué)習(xí)心得總結(jié)

    本篇文章是對C/C++中多線程的學(xué)習(xí)心得總結(jié)進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評論