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;    //棋盘的坐标,为了防止出错,初始化-1
       chess_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,注释很详细,欢迎下载相互学习。

  • 17
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lobmo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值