低配版五子棋

五子棋

五子棋是一个比较简单的经典小游戏,使用QT制作五子棋的需要用到绘图事件处理函数paintEvent(QPaintEvent *event)和鼠标事件处理函数mousePressEvent(QMouseEvent *e)

过程如下:

  • 绘制棋盘
  • 绘制棋子
  • 棋盘初始化
  • 点击鼠标获取棋子窗口落点位置
  • 将棋子落点位置转换为棋盘行列线位置
  • 下棋子(重绘棋盘)
  • 判断输赢

头文件:fivechesswidget.h

#ifndef FIVECHESSWIDGET_H
#define FIVECHESSWIDGET_H

#include <QWidget>
#include<QString>
//QLabel 类代表标签,它是一个用于显示文本或图像的窗口部件。
#include<QLabel>
#include<QRect>
#include<QPoint>
#include<QMouseEvent>
#include<QPaintEvent>
#include<QPainter>
#include<QMessageBox>

class FiveChessWidget : public QWidget
{
    Q_OBJECT
public:
    QLabel*label;
    QString str;
    QRect rect;
    QPoint x_y_pos;

    //0为空,1为白棋,2为黑棋
    int chessboard[18][18];
    int x0 = 60;//第一个交叉点的横坐标
    int y0 = 60;//第一个交叉点的纵坐标
    int width = 40;//棋盘格子宽度
    int c_r = 20;//棋子半径

    bool iswhite = 1;//先下白棋

public:
    explicit FiveChessWidget(QWidget *parent = 0);
    ~FiveChessWidget();

protected:
    virtual void paintEvent(QPaintEvent *event);//绘图事件
    virtual void mousePressEvent(QMouseEvent *e);//点击鼠标事件
    void play_chess(int i,int j);//下棋子
    void judge_chess(int i,int j);//判断棋子
    void scan_chessboard(int i,int j,int color);//扫描棋盘
    void judge_win(int num,int color);//判断输赢
    void clean_chessboard();//清空棋盘
};

#endif // FIVECHESSWIDGET_H:

fivechesswidget.cpp

#include "fivechesswidget.h"

/******构造函数初始化对象******/
FiveChessWidget::FiveChessWidget(QWidget *parent)
    : QWidget(parent)
{

    setFixedSize(800,800);//设置固定的窗口大小
    setWindowTitle("低配版五子棋");//窗口标题
    label = new QLabel;
    label->setParent(this);
    clean_chessboard();

}
FiveChessWidget::~FiveChessWidget()
{

}
/******清空棋盘******/
void FiveChessWidget::clean_chessboard()
{

    for(int i = 0;i<18;i++)
    {
        for(int j = 0;j<18;j++)
        {
            chessboard[i][j]=0;
        }
    }
}

/******绘制棋盘和棋子******/
void FiveChessWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);//创建QPainter对象

    //设置画笔
    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(2);
    pen.setColor(Qt::darkGray);
    painter.setPen(pen);
    //设置画刷
    QBrush brush;

    //画矩形
    painter.drawRect(30,30,740,740);
    painter.drawRect(60,60,680,680);

    //painter.drawPoint(100,100);画一个点
    //QPoint是QT中表示点的坐标类,用整型值表示某个点的坐标
    //画列线
    for(int i = 100; i < 730; i+=40)
    {
        painter.drawLine(QPoint(i,60),QPoint(i,740));
    }
    //画横线
    for(int j =100 ;j < 730; j+=40)
    {
        painter.drawLine(QPoint(60,j),QPoint(740,j));
    }
    //画棋子
    for(int i = 0; i<18;i++)
    {
        for(int j = 0;j<18;j++)
        {
            if(chessboard[i][j]==1)
            {
                pen.setStyle(Qt::SolidLine);
                pen.setWidth(2);
                pen.setColor(Qt::white);
                painter.setPen(pen);
                brush.setColor(Qt::white);
                brush.setStyle(Qt::SolidPattern);
                painter.setBrush(brush);
                painter.drawEllipse(x0+i*width-c_r,y0+j*width-c_r,2*c_r,2*c_r);//画白棋
            }
            else if(chessboard[i][j]==2)
            {
                pen.setStyle(Qt::SolidLine);
                pen.setWidth(2);
                pen.setColor(Qt::darkGray);
                painter.setPen(pen);
                brush.setColor(Qt::darkGray);
                brush.setStyle(Qt::SolidPattern);
                painter.setBrush(brush);
                painter.drawEllipse(x0+i*width-c_r,y0+j*width-c_r,2*c_r,2*c_r);//画黑棋
            }
        }
    }
}

/******点击鼠标获取棋子坐标******/
void FiveChessWidget::mousePressEvent(QMouseEvent *e)
{
    int i,j;
    if(e->button()==Qt::LeftButton)
    {
        x_y_pos = e->pos();
        for(i = 0;i < 18;i++)
        {
            for(j = 0;j<18;j++)
            {
                rect = QRect(x0+i*width-c_r,y0+j*width-c_r,2*c_r,2*c_r);
                if(rect.contains(x_y_pos))
                {
                    if(chessboard[i][j]==0)
                    {
                        play_chess(i,j);
                        label->move(590,10);
                        label->resize(180,20);
                        str.sprintf("当前棋子坐标:(%d,%d)",(x0+i*width),(y0+j*width));
                        //label->setText("("+QString::number(x0+i*width)+","+QString::number(y0+j*width)+")");
                        label->setText(str);
                    }
                }
            }
        }
    }
}

/******下棋子******/
void FiveChessWidget::play_chess(int i, int j)
{
    if(iswhite)
    {
        chessboard[i][j] = 1;
    }
    else
    {
        chessboard[i][j] = 2;
    }
    iswhite = !iswhite;
    this->update();
    judge_chess(i,j);
}

/******判断棋子******/
void FiveChessWidget::judge_chess(int i, int j)
{
    if(chessboard[i][j]==0)//判断是否为空
        return;
    if(chessboard[i][j]==1)//是否为白棋
        scan_chessboard(i,j,1);
    if(chessboard[i][j]==2)//是否为黑棋
        scan_chessboard(i,j,2);
}

/******扫描棋盘******/
void FiveChessWidget::scan_chessboard(int i, int j,int color)
{
    int row;//行
    int col;//列
    int chessnums=0;//棋子数量
    int direction;//扫描方向
    for(direction=0;direction<4;direction++)
    {
        switch (direction) {
        case 0://行扫描
        {
            for(row=i,col=j;(chessboard[row][col-1]==color)&&(col>=0);chessnums++,col--);
            for(row=i,col=j;(chessboard[row][col+1]==color)&&(col<18);chessnums++,col++);
            judge_win(chessnums+1,color);
            chessnums=0;
            break;
        }
        case 1://列扫描
        {
            for(row=i,col=j;(chessboard[row-1][col]==color)&&(row>=0);chessnums++,row--);
            for(row=i,col=j;(chessboard[row+1][col]==color)&&(row<18);chessnums++,row++);
            judge_win(chessnums+1,color);
            chessnums=0;
            break;
        }
        case 2://左对角线
        {
            for(row=i,col=j;(chessboard[row-1][col-1]==color)&&(row>=0);chessnums++,row--,col--);
            for(row=i,col=j;(chessboard[row+1][col+1]==color)&&(row<18);chessnums++,row++,col++);
            judge_win(chessnums+1,color);
            chessnums=0;
            break;
        }
        case 3://右对角线
        {
            for(row=i,col=j;(chessboard[row-1][col+1]==color)&&(row>=0);chessnums++,row--,col++);
            for(row=i,col=j;(chessboard[row+1][col-1]==color)&&(row<18);chessnums++,row++,col--);
            judge_win(chessnums+1,color);
            chessnums=0;
            break;
        }
        default:
            break;
        }
    }
}

/******判断输赢******/
void FiveChessWidget::judge_win(int num,int color)
{
    if(num==5)
    {
        if(color==1)
        {
            QMessageBox::question(this,QString("结束"),QString("白棋获胜"),"确认");
            clean_chessboard();
            this->update();//重绘棋盘

        }
        if(color==2)
        {
            QMessageBox::question(this,QString("结束"),QString("黑棋获胜"),"确认");
            clean_chessboard();
            this->update();//重绘棋盘
        }
    }
    else
      return;
}

main.cpp

#include "fivechesswidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    FiveChessWidget w;
    w.show();

    return a.exec();//消息循环
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值