井字棋游戏:任意一方先走,占据一个格子,只要某一方先在井字中画成一条直线就算赢。

首先在Qt Creator 中创建我们需要的项目,代码如下

widget.h文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QGridLayout;
class QLabel;
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    //初始化界面布局
    void initUi();

    //重写事件过滤器
    bool eventFilter(QObject *, QEvent *);

    //计算
    bool calculate(QList<int>,int);

    //判断是否已经选择
    inline bool isSelected(int);


private:

    //网格布局
    QGridLayout* gridLayout;

    //声明9个格子
    QLabel* label1;
    QLabel* label2;
    QLabel* label3;
    QLabel* label4;
    QLabel* label5;
    QLabel* label6;
    QLabel* label7;
    QLabel* label8;
    QLabel* label9;

    //接收选中的数字
    int num;

    //判断是红方还是蓝方(自增,奇数为红,偶数为蓝)
    int isRed;

    //保存红方选中的数字列表
    QList<int> redList;
    //保存蓝方选中的数字列表
    QList<int> blueList;

};
#endif // WIDGET_H

widget.cpp 文件

#include "widget.h"
#include <QLabel>
#include <QGridLayout>
#include <QEvent>
#include <QDebug>
#include <QMessageBox>
#include <QString>
#include <QPushButton>
#include <QApplication>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    //判断是红方还是蓝方(自增,奇数为红,偶数为蓝)
    isRed = 1;

    //设置窗口标题
    setWindowTitle(QStringLiteral("井字棋游戏"));

    //设置主窗口最小大小
    setMinimumSize(740, 700);

    //初始化界面布局
    initUi();

    //给每个格子添加事件过滤
    label1->installEventFilter(this);
    label2->installEventFilter(this);
    label3->installEventFilter(this);
    label4->installEventFilter(this);
    label5->installEventFilter(this);
    label6->installEventFilter(this);
    label7->installEventFilter(this);
    label8->installEventFilter(this);
    label9->installEventFilter(this);

}

//初始化界面布局
void Widget::initUi(){

    //初始化
    label1 = new QLabel("1");
    label1->setText("1");
    label2 = new QLabel("2");
    label3 = new QLabel("3");
    label4 = new QLabel("4");
    label5 = new QLabel("5");
    label6 = new QLabel("6");
    label7 = new QLabel("7");
    label8 = new QLabel("8");
    label9 = new QLabel("9");

    gridLayout = new QGridLayout(this);

    //网格间隙为0
    gridLayout->setVerticalSpacing(0);
    gridLayout->setHorizontalSpacing(0);


    //设置水平居中
    label1->setAlignment(Qt::AlignCenter);
    label2->setAlignment(Qt::AlignCenter);
    label3->setAlignment(Qt::AlignCenter);
    label4->setAlignment(Qt::AlignCenter);
    label5->setAlignment(Qt::AlignCenter);
    label6->setAlignment(Qt::AlignCenter);
    label7->setAlignment(Qt::AlignCenter);
    label8->setAlignment(Qt::AlignCenter);
    label9->setAlignment(Qt::AlignCenter);

    //设置边框
    label1->setFrameStyle(QFrame::Box);
    label2->setFrameStyle(QFrame::Box);
    label3->setFrameStyle(QFrame::Box);
    label4->setFrameStyle(QFrame::Box);
    label5->setFrameStyle(QFrame::Box);
    label6->setFrameStyle(QFrame::Box);
    label7->setFrameStyle(QFrame::Box);
    label8->setFrameStyle(QFrame::Box);
    label9->setFrameStyle(QFrame::Box);


    // 添加到网格布局中
    gridLayout->addWidget(label1,0,0);
    gridLayout->addWidget(label2,0,1);
    gridLayout->addWidget(label3,0,2);
    gridLayout->addWidget(label4,1,0);
    gridLayout->addWidget(label5,1,1);
    gridLayout->addWidget(label6,1,2);
    gridLayout->addWidget(label7,2,0);
    gridLayout->addWidget(label8,2,1);
    gridLayout->addWidget(label9,2,2);


}

//重写事件过滤器
bool Widget::eventFilter(QObject* obj, QEvent* ev){
    //判断是不是 鼠标点击事件
    if(ev->type() == QEvent::MouseButtonPress){

        //设置背景色
        QPalette p;
        //奇数为红,偶数为蓝
        if(isRed % 2 == 1){
            p.setColor(QPalette::Window,Qt::red);
        }else{
            p.setColor(QPalette::Window,Qt::blue);
        }

        if(obj == label1){
            num = 1;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label1->setAutoFillBackground(true);
            label1->setPalette(p);
        }
        if(obj == label2){
            num = 2;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label2->setAutoFillBackground(true);
            label2->setPalette(p);
        }
        if(obj == label3){
            num = 3;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label3->setAutoFillBackground(true);
            label3->setPalette(p);
        }
        if(obj == label4){
            num = 4;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label4->setAutoFillBackground(true);
            label4->setPalette(p);
        }
        if(obj == label5){
            num = 5;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label5->setAutoFillBackground(true);
            label5->setPalette(p);
        }
        if(obj == label6){
            num = 6;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label6->setAutoFillBackground(true);
            label6->setPalette(p);
        }
        if(obj == label7){
            num = 7;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label7->setAutoFillBackground(true);
            label7->setPalette(p);
        }
        if(obj == label8){
            num = 8;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label8->setAutoFillBackground(true);
            label8->setPalette(p);
        }
        if(obj == label9){
            num = 9;
            bool isOK = isSelected(num);
            if(isOK){
                return QWidget::eventFilter(obj,ev);
            }
            label9->setAutoFillBackground(true);
            label9->setPalette(p);
        }


        //下一步谁走
        if(isRed % 2 == 1){
            //把红方选中的保存到redList中
            redList << num;
            qDebug() << "redList = " << redList;
            //判断谁赢
            bool boolR = calculate(redList,blueList.size()+redList.size());
            if(boolR){
                if(QMessageBox::Ok == QMessageBox::information(this,"success",QStringLiteral("红方赢了               "))){
                    //设置程序的退出码
                    qApp->exit(122);
                }
            }
        }else{
            //把蓝方选中的保存到redList中
            blueList << num;
            qDebug() << "blueList = " << blueList;
            //判断谁赢
            bool boolR = calculate(blueList,blueList.size()+redList.size());
            if(boolR){
                if(QMessageBox::Ok == QMessageBox::information(this,"success",QStringLiteral("蓝方赢了               "))){
                    qApp->exit(122);
                }
            }
        }
        //自增,对方走
        isRed++;
        qDebug() << "isRed =  "  << isRed;
    }
    return QWidget::eventFilter(obj,ev);
}

//计算
bool Widget::calculate(QList<int> list,int size){

    //3个数字才能组成一组(这个条件有没有不影响)
    if(list.size() > 2){

        //判断list中是否包含该数字
        bool b1 = list.contains(1);
        bool b2 = list.contains(2);
        bool b3 = list.contains(3);
        bool b4 = list.contains(4);
        bool b5 = list.contains(5);
        bool b6 = list.contains(6);
        bool b7 = list.contains(7);
        bool b8 = list.contains(8);
        bool b9 = list.contains(9);

        //组成一条线的组合
        if(b1 & b2 & b3){
            return true;
        }
        if(b4 & b5 & b6){
            return true;
        }
        if(b7 & b8 & b9){
            return true;
        }
        if(b1 & b4 & b7){
            return true;
        }
        if(b2 & b5 & b8){
            return true;
        }
        if(b3 & b6 & b9){
            return true;
        }
        if(b3 & b5 & b7){
            return true;
        }
        if(b1 & b5 & b9){
            return true;
        }

        //判断是否平局
        if(size == 9){
            QMessageBox::information(this,"success",QStringLiteral("该游戏平局               "));
            qApp->exit(122);
            return false;
        }

    }
    return false;
}

//判断是否已经选择
bool Widget::isSelected(int num){

    //判断当前是哪一方
    if(isRed % 2 == 1){
        //红方

        //判断是否选中对方已有的
        if(blueList.contains(num)){
            QMessageBox::warning(this,"warning",QStringLiteral("已经被对方选中!!!蓝               "));
            return true;
        }
        //判断是否重复选中
        if(redList.contains(num)){
            QMessageBox::warning(this,"warning",QStringLiteral("不能选中自身已有               "));
            return true;
        }
    }else{
        //蓝方

        //判断是否选中对方已有的
        if(redList.contains(num)){
            QMessageBox::warning(this,"warning",QStringLiteral("已经被对方选中!!!红               "));
            return true;
        }
        //判断是否重复选中
        if(blueList.contains(num)){
            QMessageBox::warning(this,"warning",QStringLiteral("不能选中自身已有               "));
            return true;
        }
    }
    return false;
}

Widget::~Widget(){}

main.cpp 文件

#include "widget.h"
#include <QApplication>
#include <QProcess>

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

    //接收并判断退出码
    int code = a.exec();
    if(code == 122){
        //使用 startDetached () 函数打开外部进程时,外部进程启动后,不会随主程序的退出而退出
        //参数:需要启动的应用程序的文件路径
        QProcess::startDetached(qApp->applicationFilePath());
        return 0;
    }

    return code;
}

感觉写的很繁琐,希望能简化一下,接受建议