六子棋界面开发实例

开发工具:Qt 5.7.0

项目名称:六子棋界面

首次开发并没有使用UI,纯代码实现

实现效果:

1.选择先手后手,鼠标拖动单击落子

2.悔棋(支持一轮悔棋,可修改支持多轮)

3.暂停

4.终止、清除棋盘

5.定时

6.人机对战(ai比较笨)

MainWindow头文件:

#pragma once
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//#define int             BOOL;
//#define unsigned char   BYTE;
//#include "define.h"

//**********UI部分************
#include <QMainWindow>
#include <QLayout>
#include <QPushButton>
#include <QRadioButton>
#include <QButtonGroup>
#include <QMessageBox>
#include <QPixmap>
#include <QSplashScreen>
#include <QPainter>
#include <QLabel>
#include <QTimer>
#include <QTime>
#include <QMouseEvent>
#include <QLCDNumber>
#include <QMouseEvent>
#include <QString>
//#include <QPalette>


//**********AI部分************
#include <stdio.h>
#include <string>
#include <iostream>
#include <list>
#include <memory.h>
#include <ctime>
#include <cstdlib>
using namespace std;

#define GRID_NUM 19          //棋盘的行数
#define GRID_COUNT 361       //棋盘总的格子数
#define BLACK  1             //黑棋
#define WHITE  7             //白棋
#define NOSTONE 0            //没有棋子



//#define Cbwitch 19

//*****************************

//class QLabelPush;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int YesNO=0;
    int FirstSecon=0;
    int Clickstep=0;
    int Huiqi[500][2]={0};
    int rx=0,ry=0;
    int Chesstate=1;  //1为黑子 2为白子
    //void paintEvent(QPaintEvent *event);
    //void mousePressEvent(QMouseEvent *mouseEvent);//下棋动作
    //void mouseMoveEvent(QMouseEvent *event);     //鼠标移动捕捉
    //friend class Label;
private slots:
    void StopBtnClick();
    void EndBtnClick();
    void OutBtnCliked();
    void GoBtnCliked();
    void FirstSecond();

    //计时模块
    void showTime();      //显示当前时间

private:

    //总控制区域
    QVBoxLayout *ImformationLayout;    //竖状布局  
    QPushButton *First;
    QPushButton *Second;
    QGridLayout *CtrlLayout;
    QPushButton *StopBtn;
    QPushButton *GoBtn;
    QPushButton *EndBtn;
    QPushButton *OutBtn;
    QPixmap pixmap1;
    //信息控制区域
    QGridLayout *InforLayout;
    QLabel *Score;
    QRadioButton *FirstBtn;
    QRadioButton *SecondBtn;
    QButtonGroup *DifficultyBtn;
    //棋盘区域
    QGridLayout *ChessLayout;
    QPainter *painter;
    QLabel *ChessBD;   //尝试在QLabel上绘制棋盘
    QPixmap pixmap;
    QPixmap pixmap2;
   // void PainterChess(int x,int y);
  //  QPainter *painter;
    //绘图


    //计时模块
    QVBoxLayout *TimeLayout;
    QTimer *timer;
    QLCDNumber *lcd1;
    QLCDNumber *lcd2;
    QLabel *USER1;
    QLabel *USER2;
    int hour1,hour2;
    int minute1,minute2;
    int second1,second2;
    int clickPosRow=0,clickPosCol=0;   //存放捕捉到的鼠标的位置
    //QPoint dragPosition;
    //bool showColon;
protected:
    void paintEvent(QPaintEvent *event);       //绘图函数
    void mouseMoveEvent(QMouseEvent *event);   //鼠标监听函数
    void mouseReleaseEvent(QMouseEvent *event);    //落子函数
    //void mousePressEvent(QMouseEvent *event);
};

构造函数:

 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
 {
     memset(cb, 0, sizeof(char)* GRID_NUM * GRID_NUM);
     //计时区域
    /* QPalette p=palette();      //设置背景

     p.setColor(QPalette::Window,Qt::black);
     setPalette(p);
     setWindowFlags(Qt::FramelessWindowHint);
     setWindowOpacity(0.5);
     QTimer *timer =new QTimer(this);
     connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));
     timer->start(1000);
     showTime();
     resize(150,60);
     showColon =true;
     */
     USER1 =new QLabel(tr("玩家1"));
     USER2 =new QLabel(tr("玩家2"));
     TimeLayout =new QVBoxLayout;
     timer =new QTimer(this);
     lcd1 =new QLCDNumber;
     lcd2 =new QLCDNumber;
     lcd1->setDigitCount(10);                   //设置LCD显示的位数
     lcd2->setDigitCount(10);
     //lcd1->setMode(QLCDNumber::Dec);            //设置显示模式为10进制
     //lcd2->setMode(QLCDNumber::Dec);            //设置显示模式为10进制
     //lcd1->setSegmentStyle(QLCDNumber::Flat);   //设置显示方式
     //lcd2->setSegmentStyle(QLCDNumber::Flat);
     hour1=0,hour2=0,minute1=0,minute2=0,second1=0,second2=0;
     timer->setInterval(1000);                  //设置定时器多少毫秒发送一个timeout信号
     //timer->start();
     lcd1->display("00:00:00");
     lcd2->display("00:00:00");
     TimeLayout->addWidget(USER1,0);
     TimeLayout->addWidget(lcd1,1);
     TimeLayout->addWidget(USER2,2);
     TimeLayout->addWidget(lcd2,3);

     //总控制区域
     CtrlLayout =new QGridLayout;
     StopBtn =new QPushButton(tr("暂停"));      //初始化按钮
     GoBtn =new QPushButton(tr("Star"));
     EndBtn =new QPushButton(tr("终止"));
     OutBtn =new QPushButton(tr("悔棋"));
     First =new QPushButton(tr("先手"));
     Second =new QPushButton(tr("后手"));

     CtrlLayout->addWidget(StopBtn,0,1);       //向区域内添加部件
     CtrlLayout->addWidget(GoBtn,0,0);
     CtrlLayout->addWidget(OutBtn,1,1);
     CtrlLayout->addWidget(EndBtn,1,0);
     //信息控制区域
     InforLayout =new QGridLayout;
     DifficultyBtn =new QButtonGroup(this);
     FirstBtn =new QRadioButton(tr("后手"));
     SecondBtn =new QRadioButton(tr("先手"));
     DifficultyBtn->addButton(FirstBtn);
     DifficultyBtn->addButton(SecondBtn);
     DifficultyBtn->setId(FirstBtn,0);
     DifficultyBtn->setId(SecondBtn,1);
     InforLayout->addWidget(FirstBtn,0,0);
     InforLayout->addWidget(SecondBtn,0,1);
     //FirstBtn->setChecked(true);
     //棋盘区域
     ChessLayout =new QGridLayout;
     ChessBD =new QLabel;
     painter =new QPainter;
     //QPixmap pixmap("ChessBoard.png");
    //QPixmap pixmap2("Chessb.png");
    // ChessBD->setPixmap(pixmap);
     /*painter->begin(this);
     for(int i=0;i<GRID_NUM;i++)
         for(int j=0;j<GRID_NUM;j++)
         {
             if(chessboard[i][j]==1)
             {
                 //ChessBD->drawFrame(painter->drawPixmap(i*40,j*40,30,30,pixmap2));
             }
             if(chessboard[i][j]==2)
             {
                 painter->drawPixmap(i*40,j*40,30,30,pixmap2);
             }
         }
     painter->end();
     */
     ChessBD->setFixedSize(750,750);
     ChessBD->update();
     ChessLayout->addWidget(ChessBD);
     QVBoxLayout *ImformationLayout =new QVBoxLayout;
     ImformationLayout->addLayout(TimeLayout,0);
     ImformationLayout->addLayout(InforLayout,2);
     ImformationLayout->addLayout(CtrlLayout,1);
     QGridLayout *mainLayout =new QGridLayout;
     mainLayout->addLayout(ChessLayout,0,0);
     mainLayout->addLayout(ImformationLayout,0,1);
     QWidget *widget = new QWidget(this);
     widget->setLayout(mainLayout);
    /* QPixmap pixmap1("BlackGround.png");
     QPalette palette();
     palette.setBrush(QPalette::Background,QBrush(pixmap1));
     widget->setPalette(palette);
     */
     this->setCentralWidget(widget);
  //   Sleep(1000);     //休眠等待程序启动画面
     connect(StopBtn,SIGNAL(clicked()),this,SLOT(StopBtnClick()));
     connect(EndBtn,SIGNAL(clicked()),this,SLOT(EndBtnClick()));
     connect(OutBtn,SIGNAL(clicked()),this,SLOT(OutBtnCliked()));
     connect(GoBtn,SIGNAL(clicked()),this,SLOT(GoBtnCliked()));
     connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));
     connect(FirstBtn,SIGNAL(clicked()),this,SLOT(FirstSecond()));
     connect(SecondBtn,SIGNAL(clicked()),this,SLOT(FirstSecond()));
 }


棋盘采用划线函数实现:

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(0,0,width(),height(),QPixmap("blcjaiffa.png"));
    painter.setRenderHint(QPainter::Antialiasing,true);  //抗锯齿
    for(int i=0;i<GRID_NUM;i++)
    {
        painter.drawLine(30+40 * i, 750,30 +40 * i,30);
        painter.drawLine(30,30+40 * i,750,30+40 * i);
//        painter.drawLine(kBoardMargin, kBoardMargin + kBlockSize * i, size().width() - kBoardMargin, kBoardMargin + kBlockSize * i);
    }
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    brush.setColor(Qt::black);
    painter.setBrush(brush);
    painter.drawEllipse(34 +40* 9 - 10, 34 + 40 *9 - 10, 5 * 2, 5 * 2);
    for (int i = 0; i < 19; i++)
        for (int j = 0; j < 19; j++)
        {
            if (cb[i][j] == 1)
            {
                brush.setColor(Qt::white);
                painter.setBrush(brush);
                painter.drawEllipse(30 +40* j - 10, 30 + 40 * i - 10, 10 * 2, 10 * 2);
            }
            else if (cb[i][j] == 7)
            {
                brush.setColor(Qt::black);
                painter.setBrush(brush);
                painter.drawEllipse(30 +40* j - 10, 30 + 40 * i - 10, 10 * 2, 10 * 2);
            }

        }
}

鼠标move函数和鼠标release函数:

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
  //  this->setMouseTracking(TRUE);   //设置窗体追踪鼠标
    int x=event->x();   //获取鼠标位置
    int y=event->y();
    int len=0;
    //非棋盘区域不能落子
    if(x>30 && x<750 && y>30 && y<750)  //确定棋盘位置
      {
       int col = x / 40;
       int row = y / 40;
       int leftTopPosX = 30 + 40 * col;
       int leftTopPosY = 30 + 40 * row;
       // 根据距离算出合适的点击位置,一共四个点,根据半径距离选最近的
       clickPosRow = -1; // 初始化最终的值
       clickPosCol = -1;
       //int len = 0; // 计算完后取整就可以了

       // 确定一个误差在范围内的点,且只可能确定一个出来
       len = sqrt((x - leftTopPosX) * (x - leftTopPosX) + (y - leftTopPosY) * (y - leftTopPosY));
       if (len < 10)
       {
           clickPosRow = row;
           clickPosCol = col;
       }
             len = sqrt((x - leftTopPosX - 40) * (x - leftTopPosX - 40) + (y - leftTopPosY) * (y - leftTopPosY));
             if (len < 10)
             {
                 clickPosRow = row;
                 clickPosCol = col + 1;
             }
             len = sqrt((x - leftTopPosX) * (x - leftTopPosX) + (y - leftTopPosY - 40) * (y - leftTopPosY - 40));
             if (len < 10)
             {
                 clickPosRow = row + 1;
                 clickPosCol = col;
             }
             len = sqrt((x - leftTopPosX - 40) * (x - leftTopPosX - 40) + (y - leftTopPosY - 40) * (y - leftTopPosY - 40));
             if (len < 10)
             {
                 clickPosRow = row + 1;
                 clickPosCol = col + 1;
             }
         }
         // 存了坐标后也要重绘
    this->update();

}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(YesNO==1)
    {
        if(cb[clickPosRow][clickPosCol]==0)
          {
            if(FirstSecon==0)
            {
                if(step==0)
                {
                  cb[clickPosRow][clickPosCol]=7;
                  step++;
                  if( cb[clickPosRow][clickPosCol]==0)
                  {
                     step--;
                  }
                  else
                  {
                    Huiqi[++Huiqi[0][0]][0]=clickPosRow;
                    Huiqi[++Huiqi[0][1]][1]=clickPosCol;
                    SearchAGoodMove(cb,FirstSecon==0?1:7);
                    step+=2;
                  }
                }
               else
                {
                  cb[clickPosRow][clickPosCol]=7;
                  Clickstep++;
                  step++;
                  if( cb[clickPosRow][clickPosCol]==0)
                  {
                     step--;
                     Clickstep--;
                  }
                  else
                  {
                      Huiqi[++Huiqi[0][0]][0]=clickPosRow;
                      Huiqi[++Huiqi[0][1]][1]=clickPosCol;
                  }
                }
            }
            if(FirstSecon==1)
            {
               cb[clickPosRow][clickPosCol]=1;
               Clickstep++;
               step++;
               if( cb[clickPosRow][clickPosCol]==0)
               {
                  step--;
                  Clickstep--;
               }
               else
               {
                   Huiqi[++Huiqi[0][0]][0]=clickPosRow;
                   Huiqi[++Huiqi[0][1]][1]=clickPosCol;
               }
            }
            if(Clickstep==2)
            {
                Clickstep=0;
                Chesstate=1;
                //此处调用电脑走子
                for(int i=0;i<19;i++) //缓存,悔棋用
                {
                    for(int j=0;j<19;j++)
                    {
                        cb1[i][j]=cb[i][j];
                    }
                }
                SearchAGoodMove(cb,FirstSecon==0?1:7);
                step+=2;
                Chesstate=2;
            }
            this->update();
          }

    }
    else
    {
         QMessageBox::information(this, "提示", "请先选择先手后手,再单击start");
    }
    int m=JudgeWin();
    if(m!=0)
         {
            QMessageBox::information(this,"提示", "结束");
            timer->stop();
            second1=0;
            minute1=0;
            hour1=0;
             second2=0;
             minute2=0;hour2=0;
            lcd1->display("00:00:00");
            lcd2->display("00:00:00");
            memset(cb, 0, sizeof(char)* GRID_NUM * GRID_NUM);
            this->update();
            step=0;
            Clickstep=0;YesNO=0;
            }
}





  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值