开发工具: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;
}
}