Qt实现五子棋

QT实现五子棋


有点bug 但是能运行
每次点击右边会出现提示图标,表示是黑方落子还是白方并计时,
不过不知道为什么点的次数多了 就不出现提示了 然后过一会又有了
![Alt] 在这里插入图片描述

代码片.

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QBrush>
#include <QMouseEvent>
#include <QPen>
#include <QDebug>
#include <QMessageBox>
#include <QTime>
#include <QMainWindow>
#include <QTimer>
#include <QDateTime>
#include <QDesktopWidget>
#include <QApplication>
#include <QCoreApplication>
#include <QEventLoop>
#include <QProcess>
#include <QString>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

       ui->label_2->hide();
   // resize(640, 640);
    memset(a, 0, 15 * 15 * sizeof(int));
    player = 0;
    ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat);
    ui->lcdNumber->display(QDateTime::currentDateTime().toString("000"));
    ui->lcdNumber_2->setSegmentStyle(QLCDNumber::Flat);
    ui->lcdNumber_2->display(QDateTime::currentDateTime().toString("000"));
    timer1=new QTimer(this);
    connect(timer1,&QTimer::timeout,this,&Widget::handle_timeout);
    timer1->start(1000);
    timer2=new QTimer(this);
    connect(timer2,&QTimer::timeout,this,&Widget::handle_timeout);
    timer2->start(1000);



}

Widget::~Widget()
{
    delete ui;
}

 void Widget::handle_timeout()
{

    if(flag%2==0){
        for(sec=numb1;sec>0;sec--)
        {
            ui->lcdNumber->display(QDateTime::currentDateTime().toString(QString::number(sec)));
               Delay_MSec(1000);
               if(flag%2==1){
                   numb1=sec;
                   break;
               }
               if(sec<=0)
                    QMessageBox::information(this, "Win", "White Win", QMessageBox::Ok);
        }
       // timer1->stop();
    }
    else if(flag%2==1)
    {
        for(sec=numb2;sec>0;sec--)
        {
            ui->lcdNumber_2->display(QDateTime::currentDateTime().toString(QString::number(sec)));
               Delay_MSec(1000);
               if(flag%2==0) {
                   numb2=sec;
                   break;}
               if(sec<=0)
                    QMessageBox::information(this, "Win", "Black Win", QMessageBox::Ok);
        }
       // timer2->stop();
    }

}
void Widget::Delay_MSec(unsigned int msec)
{
    QTime _Timer=QTime::currentTime().addMSecs(msec);
    while(QTime::currentTime()<_Timer)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}
void Widget::paintEvent(QPaintEvent *)
{
    gridW = width()/19;  //窗口宽度分18份
    gridH = height()/19; //窗口高度分18份
    //棋盘起点坐标
    startX = gridW;
    startY = gridH;
    QPainter p(this);
    //背景图
    p.drawPixmap(0,0, width(),height(),QPixmap(":/new/prefix1/C:/tupian/image/board1.jpg"));
    p.setRenderHint(QPainter::Antialiasing, true);

    int i, j;
    for (i = 0; i < 16; i++)
    {
        p.drawLine(startX, startY + i * gridH, startX+15*gridW, startY + i * gridH);
        p.drawLine(startX + i * gridW, startY, startX + i * gridW, startY+15*gridH);
    }

    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    for (i = 0; i < 15; i++)
    {
        for (j = 0; j < 15; j++)
        {
            if (a[i][j] == 1)
            {
                p.drawPixmap(startX+i*gridW, startY+j*gridH,
                             gridW, gridH,
                   QPixmap(":/new/prefix1/C:/tupian/image/white.png")
                   );
                ui->label->hide();
                ui->label_2->show();

                /*brush.setColor(Qt::black);
                p.setBrush(brush);
                p.drawEllipse(QPoint((i + 1) * 40, (j + 1) * 40), 15, 15);*/
            }
            else if (a[i][j] == 2)
            {
                p.drawPixmap(startX+i*gridW, startY+j*gridH,
                       gridW, gridH,
                       QPixmap(":/new/prefix1/C:/tupian/image/black.png")
                       );
                ui->label->show();
                    ui->label_2->hide();

                /*brush.setColor(Qt::white);
                p.setBrush(brush);
                p.drawEllipse(QPoint((i + 1) * 40, (j + 1) * 40), 15, 15);*/
            }
        }
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *e)
{
    int x, y;

     flag++;
    if(e->x() >= startX && e->x() < startX+15*gridW && e->y() >= startY && e->y() < startY+15*gridH)
    {
        x = (e->x() - startX) / gridW;
        y = (e->y() - startY) / gridH;
        if (!a[x][y])
        {
            a[x][y] = player++ % 2 + 1;
        }
        if(iswin(x, y))
        {
            update();
            setEnabled(false);
            if(flag%2==1)
                 QMessageBox::information(this, "Win", "Black Win", QMessageBox::Ok);
            else
                 QMessageBox::information(this, "Win", "White Win", QMessageBox::Ok);
         
        }
    }
    update();
}

int Widget::iswin(int x, int y)
{
     return f1(x, y) || f2(x, y) || f3(x, y) || f4(x ,y);
}

int Widget::f1(int x, int y)
{
    int i;
    for (i = 0; i < 5; i++)
    {
        if(y - i >= 0 &&
           y + 4 - i <= 0xF &&
           a[x][y - i] == a[x][y + 1 - i] &&
           a[x][y - i] == a[x][y + 2 - i] &&
           a[x][y - i] == a[x][y + 3 - i] &&
           a[x][y - i] == a[x][y + 4 - i])
        return 1;
    }
    return 0;
}

int Widget::f2(int x, int y)
{
    int i;
    for (i = 0; i < 5; i++)
    {
        if(x - i >= 0 &&
           x + 4 - i <= 0xF &&
           a[x - i][y] == a[x + 1 - i][y] &&
           a[x - i][y] == a[x + 2 - i][y] &&
           a[x - i][y] == a[x + 3 - i][y] &&
           a[x - i][y] == a[x + 4 - i][y])
           return 1;
    }
    return 0;
}

int Widget::f3(int x, int y)
{
    int i;
    for (i = 0; i < 5; i++)
    {
        if(x - i >= 0 &&
           y - i >= 0 &&
           x + 4 - i <= 0xF &&
           y + 4 - i <= 0xF &&
           a[x - i][y - i] == a[x + 1 - i][y + 1 - i] &&
           a[x - i][y - i] == a[x + 2 - i][y + 2 - i] &&
           a[x - i][y - i] == a[x + 3 - i][y + 3 - i] &&
           a[x - i][y - i] == a[x + 4 - i][y + 4 - i])
           return 1;
    }
    return 0;
}

int Widget::f4(int x, int y)
{
    int i;
    for (i = 0; i < 5; i++)
    {
        if(x + i <= 0xF &&
           y - i >= 0 &&
           x - 4 + i >= 0 &&
           y + 4 - i <= 0xF &&
           a[x + i][y - i] == a[x - 1 + i][y + 1 - i] &&
           a[x + i][y - i] == a[x - 2 + i][y + 2 - i] &&
           a[x + i][y - i] == a[x - 3 + i][y + 3 - i] &&
           a[x + i][y - i] == a[x - 4 + i][y + 4 - i])
           return 1;
    }
    return 0;
}

void Widget::on_pushButtonOver_clicked()
{
    this->close();
}


/*-------main.cpp----------------------------*/
#include

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
/*---------widget.h-----------*/
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void paintEvent(QPaintEvent *event);
   void mouseReleaseEvent(QMouseEvent *event);
   QTimer *timer1,*timer2;
   void handle_timeout(void);
   void Delay_MSec(unsigned int msec);
   int flag=3;
   int sec=0;
   int numb1=900;
   int numb2=900;
   int player;

private slots:
   void on_pushButtonOver_clicked();

private:
    Ui::Widget *ui;
    int a [15][15];

    int iswin(int,int);
    int f1(int,int);
    int f2(int,int);
    int f3(int,int);
    int f4(int,int);
    int gridW;  //棋盘水平方向一个格子的宽度
    int gridH;  //棋盘水平方向一个格子的高度
    int startX; //棋盘起点x坐标
    int startY; //棋盘起点y坐标

    int chessX=-1, chessY=-1; //棋盘下标



};
#endif // WIDGET_H




以下是基于Qt实现五子棋的代码: mainwindow.h ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QPushButton> #include <QLabel> #include <QMouseEvent> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); protected: void paintEvent(QPaintEvent *event); void mousePressEvent(QMouseEvent *event); private: enum {ROW = 15, COL = 15}; // 棋盘行列数 enum {WIDTH = 40, HEIGHT = 40}; // 棋子大小 QPushButton *startButton; // 开始按钮 QPushButton *backButton; // 悔棋按钮 QPushButton *exitButton; // 退出按钮 QLabel *turnLabel; // 提示当前轮到哪个玩家 QLabel *blackCountLabel; // 黑方棋子数 QLabel *whiteCountLabel; // 白方棋子数 QPoint mousePos; // 鼠标点击位置 int board[ROW][COL] = {0}; // 棋盘,0表示空,1表示黑,2表示白 int turn = 1; // 当前轮到哪个玩家,1表示黑,2表示白 int blackCount = 0; // 黑方棋子数 int whiteCount = 0; // 白方棋子数 bool isGameOver = false; // 是否结束游戏 void initUI(); // 初始化UI void startGame(); // 开始游戏 void drawBoard(QPainter &painter); // 绘制棋盘 void drawPiece(QPainter &painter, int row, int col); // 绘制棋子 bool checkWin(int row, int col); // 检查是否胜利 void gameOver(); // 游戏结束 void reset(); // 重置游戏 }; #endif // MAINWINDOW_H ``` mainwindow.cpp ```cpp #include "mainwindow.h" #include <QPainter> #include <QMessageBox> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { initUI(); } MainWindow::~MainWindow() { } void MainWindow::initUI() { setFixedSize(620, 620); startButton = new QPushButton("开始游戏", this); startButton->setGeometry(500, 50, 100, 40); connect(startButton, &QPushButton::clicked, this, &MainWindow::startGame); backButton = new QPushButton("悔棋", this); backButton->setGeometry(500, 130, 100, 40); backButton->setEnabled(false); connect(backButton, &QPushButton::clicked, [=]() { if (!isGameOver) { // 游戏未结束才能悔棋 board[mousePos.x()][mousePos.y()] = 0; // 当前位置清空 turn = turn == 1 ? 2 : 1; // 切换玩家 backButton->setEnabled(false); // 禁用悔棋按钮 update(); // 重新绘制 } }); exitButton = new QPushButton("退出游戏", this); exitButton->setGeometry(500, 210, 100, 40); connect(exitButton, &QPushButton::clicked, [=]() { if (QMessageBox::Yes == QMessageBox::question(this, "提示", "确定要退出吗?")) { qApp->quit(); } }); turnLabel = new QLabel("当前轮到黑方下棋", this); turnLabel->setGeometry(500, 300); blackCountLabel = new QLabel("黑方棋子数:0", this); blackCountLabel->setGeometry(500, 350); whiteCountLabel = new QLabel("白方棋子数:0", this); whiteCountLabel->setGeometry(500, 400); } void MainWindow::startGame() { reset(); // 重置游戏 startButton->setEnabled(false); // 开始游戏后禁用开始按钮 } void MainWindow::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); drawBoard(painter); // 绘制棋盘 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if (board[i][j] != 0) { drawPiece(painter, i, j); // 绘制棋子 } } } } void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { // 左键点击 int x = event->x(); int y = event->y(); if (x >= 20 && x <= 580 && y >= 20 && y <= 580) { // 在棋盘内点击 int row = (y - 20) / HEIGHT; int col = (x - 20) / WIDTH; if (board[row][col] == 0) { // 当前位置没有棋子 board[row][col] = turn; // 下棋 if (checkWin(row, col)) { // 检查是否胜利 gameOver(); } else { turn = turn == 1 ? 2 : 1; // 切换玩家 backButton->setEnabled(true); // 开启悔棋按钮 } update(); // 重新绘制 } } } } void MainWindow::drawBoard(QPainter &painter) { painter.setPen(QPen(Qt::black, 2)); for (int i = 0; i < ROW; i++) { painter.drawLine(20, 20 + i * HEIGHT, 20 + (ROW - 1) * WIDTH, 20 + i * HEIGHT); painter.drawLine(20 + i * WIDTH, 20, 20 + i * WIDTH, 20 + (COL - 1) * HEIGHT); } } void MainWindow::drawPiece(QPainter &painter, int row, int col) { if (board[row][col] == 1) { // 黑方棋子 painter.setBrush(QBrush(Qt::black)); } else if (board[row][col] == 2) { // 白方棋子 painter.setBrush(QBrush(Qt::white)); } painter.drawEllipse(QPoint(col * WIDTH + 20, row * HEIGHT + 20), WIDTH / 2, HEIGHT / 2); } bool MainWindow::checkWin(int row, int col) { int i, j, k, count; // 横向 count = 1; for (i = col - 1; i >= 0; i--) { // 向左 if (board[row][i] == turn) { count++; } else { break; } } for (i = col + 1; i < COL; i++) { // 向右 if (board[row][i] == turn) { count++; } else { break; } } if (count >= 5) { return true; } // 纵向 count = 1; for (i = row - 1; i >= 0; i--) { // 向上 if (board[i][col] == turn) { count++; } else { break; } } for (i = row + 1; i < ROW; i++) { // 向下 if (board[i][col] == turn) { count++; } else { break; } } if (count >= 5) { return true; } // 斜向(左上到右下) count = 1; for (i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { // 向左上 if (board[i][j] == turn) { count++; } else { break; } } for (i = row + 1, j = col + 1; i < ROW && j < COL; i++, j++) { // 向右下 if (board[i][j] == turn) { count++; } else { break; } } if (count >= 5) { return true; } // 斜向(左下到右上) count = 1; for (i = row + 1, j = col - 1; i < ROW && j >= 0; i++, j--) { // 向左下 if (board[i][j] == turn) { count++; } else { break; } } for (i = row - 1, j = col + 1; i >= 0 && j < COL; i--, j++) { // 向右上 if (board[i][j] == turn) { count++; } else { break; } } if (count >= 5) { return true; } return false; } void MainWindow::gameOver() { isGameOver = true; backButton->setEnabled(false); // 禁用悔棋按钮 QString message = turn == 1 ? "黑方胜利!" : "白方胜利!"; QMessageBox::information(this, "游戏结束", message); startButton->setEnabled(true); // 开启开始按钮 } void MainWindow::reset() { memset(board, 0, sizeof(board)); // 清空棋盘 turn = 1; // 黑方先手 blackCount = 0; whiteCount = 0; isGameOver = false; backButton->setEnabled(false); // 禁用悔棋按钮 update(); // 重新绘制 } ``` 在.pro文件中添加: ```pro QT += widgets ``` 编译运行即可看到五子棋界面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值