Qt五子棋小项目

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

随着嵌入式课程的逐渐深入,Qt的使用日益频繁,所以在此锻炼自己使用Qt的能力,所以在此我开始了我的第一个Qt小项目。


提示:以下是本篇文章正文内容,下面案例可供参考

一、五子棋项目的总体介绍

五子棋在我们的印象中只停留在手机游戏,以及日常生活中的休闲玩意,也可谓无人不知、无人不晓。因为其难度对于新手来说也不算太难,所以我选择五子棋来作为我Qt的第一个小项目。
接下来介绍总体过程:
首先,我们创建一个Qt项目,在Qt的起始模板中我们会构建两个事件函数,一个为绘画事件(paintEvent(QPaintEvent *)),另一个为鼠标点击事件(mousePressEvent(QMouseEvent *event))。在绘画事件中我们会调用QPainter对象来分别绘画棋盘和下的棋子。在鼠标点击事件中,我们会监听鼠标点击事件,并以此来判断并确定鼠标点击的位置来确定下子的位置。接下来详细介绍。

二、具体步骤

1.鼠标点击事件

在这一事件中我们需要监听鼠标点击的位置来确定下子位置,与此同时还需要判断是否会有两次点击在同一位置并作出反应对此我的方法是:通过构建一个QPoint类型的一维数组来记录棋子的位置以便在绘画事件中绘画棋子;构建一个二维数组来判断该点下的使白棋还是黑棋,于此同时在下棋的同时我们还应该时刻关注棋盘棋子的分布,以判断是否有哪一方赢得比赛。具体请看:

	//此处为构建二维数组用到的参数的宏定义
	#define Space  20          //棋盘间隔
	#define broad_length   32  //棋盘长度
	#define broad_width    40  //棋盘宽度
	//定义的记录棋子位置的数组
	QPoint point[5000];
	int length=0;			//记录一维数组的长度
	//定义的判断位置处的棋子颜色,并初始化为零
	int flag_arr[broad_length*Space][broad_width*Space]={0};

我用来记录黑棋的方式是将二维数组相应的值设置为 1 ,记录白棋设置相应的值为 2。

void MyWidget::mousePressEvent(QMouseEvent *event){
    int x=event->x()%20;	//用来判断该点距离两线交点的水平距离
    int y=event->y()%20;	//用来判断该点距离两线交点的垂直距离
    if(x<=radius)			//如果该距离小于设定的棋子半径
        pos_x=event->x()-x; //取该点的水平坐标
    else if(x>=Space-radius)//如果该距离小于对另一个点的距离
        pos_x=event->x()+Space-x;//取另一点的水平坐标
    if(y<=radius)			//同上
        pos_y=event->y()-y;
    else if(y>=Space-radius)
        pos_y=event->y()+Space-y;
//    qDebug()<<"pos_x = "<<pos_x<<"  "<<"pos_y = "<<pos_y;             //打印点击的坐标
    if(flag_arr[pos_x][pos_y]==0){		//判断该点是否已被下子
        point[length++]=QPoint(pos_x,pos_y);//将为被下子的位置纳入我们设定的一维数组中
        if(length%2==0)
            flag_arr[pos_x][pos_y]=1;	//偶数次下为黑棋
        else flag_arr[pos_x][pos_y]=2;	//奇数次下为白棋
    }
    else qDebug()<<"此处已被下子!";		//如果此处已被下棋,则打印出该字段
    judge_to_win(point[length-1],level);		//该处为判断赢的函数(下面会有说明)  水平方向
    judge_to_win(point[length-1],vertical);		//垂直方向
    judge_to_win(point[length-1],oblique_left);	//斜向左方向
    judge_to_win(point[length-1],oblique_rigth);//斜向右方向
}

在这里我默认的就是黑棋先下,当然我们也可以选择让白棋先下,不过再次我就不在赘述了,因为其方法是一样的,不过我们也可以通过宏定义来做。
接下来我们开始解释如何判断赢的函数,具体请看:

void MyWidget::judge_to_win(QPoint &add,int dir){
    int x=add.rx();					//获取当前点的横向坐标
    int y=add.ry();					//获取纵向坐标
    int flag=flag_arr[x][y];		//获取该处的标志,是黑棋还是白棋
    int num_level=1;				//默认一颗棋子在该处
    switch(dir){
        case 1:						//纵向判断
            y+=Space;				//获取纵向的下一颗棋子	
            while(flag_arr[x][y]==flag)//判断下一颗棋子是否与当前下的棋子类型一致
            {
                num_level++;		//一致,则数量加一
                y+=Space;			//在获取下一颗棋子
                if(num_level>=5){	//数量大于等于5,则说明一方已经到达胜利
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
            y=add.ry()-Space;				//判断该棋子另一方向的棋子
            while(flag_arr[x][y]==flag){	//判断该棋子另一方向的棋子是否与当前所下的棋子一致
                num_level++;				//一致,则数量加一
                y-=Space;					//再判断下一颗
                if(num_level>=5){			//同上
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
        break;
        case 2:			//其下的带码与上方的代码并无二处,只是判断的方向不同罢了
            x+=Space;
            while(flag_arr[x][y]==flag)
            {
                num_level++;
                x+=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
            x=add.rx()-Space;
            while(flag_arr[x][y]==flag){
                num_level++;
                x-=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
        break;
        case 3:
            x+=Space;
            y+=Space;
            while(flag_arr[x][y]==flag)
            {
                num_level++;
                x+=Space;
                y+=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
            x=add.rx()-Space;
            y=add.ry()-Space;
            while(flag_arr[x][y]==flag){
                num_level++;
                x-=Space;
                y-=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
        break;
        case 4:
            x+=Space;
            y-=Space;
            while(flag_arr[x][y]==flag)
            {
                num_level++;
                x+=Space;
                y-=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
            x=add.rx()-Space;
            y=add.ry()+Space;
            while(flag_arr[x][y]==flag){
                num_level++;
                x-=Space;
                y+=Space;
                if(num_level>=5){
                    if(flag==1)
                        qDebug()<<"black win!";
                    if(flag==2)
                        qDebug()<<"white win!";
                }
            }
        break;
    }
}

以上的代码可能会有写篇幅较长,但是其原理却很简单,应该每个人都可以掌握。如果看到这里有更好的方法,欢迎赐教。

2.绘画事件

在这一事件中我们需要绘制棋盘,同时也需要将储存鼠标点击的位置的一维数组的棋子一一绘制,并区分该子是黑棋还是白棋。看代码:

	QPainter painter(this); //在创建的窗口创建painter对象,如果没有this,那么你所绘画的对象将不会出现在你所创建的窗口内,即会另外创建一个窗口
    QBrush brush;			//定义brush对象用来设置填充属性
    for(int i=0;i<length;i++){   //依次遍历存储棋子坐标的数组
        if(i%2==0)		
            brush.setColor(Qt::black);//偶数则用黑色填充
        else brush.setColor(Qt::white);//奇数则用白色填充
        brush.setStyle(Qt::SolidPattern);//设置填充形式
        painter.setBrush(brush);//设置painter对象的brush对象
        painter.drawEllipse(point[i],radius,radius);//开始画圆,半径为radius
    }

总结

以上就是今天要讲的内容,本文仅仅简单介绍了五子棋项目的简单实现,当然我们也可以设置菜单,来实现五子棋游戏的开始与结束,悔棋的功能,今天的分享就到这里,如果有错误或者有补充的地方,欢迎指正。谢谢!如需源码,请私信!

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值