qt实现五子棋(一)
第二大步是创建主界面将绘制界面和界面元素的初始化分开逻辑更为清晰。所谓界面是指frame、背景、标题、界面大小等内容;界面元素是指例如为combox添加item等。在主界面中核心问题是,处理鼠标事件确保当前棋子落在准确位置,并提示用户角色切换;还有就是判断游戏胜利。
使用QPainter画界面背景,在ui设计师中添加frame和界面元素部件,通过样式表对按钮进行美化;使用gridLayout添加棋盘widget;设置窗口title;设置”五子棋“标题;设置显示黑棋、白棋;ui设计师中 界面如下,看代码时找对应关系。
这块逻辑没有写好,实际的程序应该没有这部分。还是应该把初始化分解为两个动作比较合适。
首先配置按钮音效,清空(初始化)棋盘,设置角色,连接鼠标信号(棋盘)与刷新界面函数,刷新界面函数将保存坐标信息到二维数组中,以此二维数组为参数调用棋盘类提供的刷新棋盘的方法,从而使得界面得到刷新。同时应该切换角色,为落子添加配音。判断玩家是否胜利。一旦有玩家胜利, 弹出对话框,恭喜玩家。
思路:红绿线代表双层循环,红线代表内存循环,绿线代表外层循环。因此在遍历时将按照从上到下从左到右的顺序遍历。因此若每个棋子当作”五子连珠“的首棋子,那就只需检测四个方向的”五子连珠“,如图蓝线所示。一旦检测到有”五子连珠“立马停止遍历,返回胜利玩家。
单击退出游戏或者”X“时,将提示是否退出,点是即刻退出,点否则不退出。
1.可以在此基础上自己编写算法,做一个“人机对战模式”;
2.可以在此基础上结合网口编程,实现公网对战。
main
#include "chessform.h"
#include "chessplate.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
chessForm w;
w.show();
// chessPlate e;
// e.show();
return a.exec();
}
chessForm.h
#ifndef CHESSFORM_H
#define CHESSFORM_H
#include
#include "chessplate.h"
#include
#include
namespace Ui {
class chessForm;
}
class chessForm : public QWidget
{
Q_OBJECT
public:
explicit chessForm(QWidget *parent = nullptr);
~chessForm();
protected:
void paintEvent(QPaintEvent *);
void closeEvent(QCloseEvent *);
private:
Ui::chessForm *ui;
chessPlate * myPlate;
chessPlate::ChessType currentRole;
int formChessData[15][15];
int black_cnt = 0,white_cnt = 0;
void Init();
void showRole(const QString whiteFileName,const QString blackFileName);
void setRole(chessPlate::ChessType currentRole);//设置谁先下
void setChessInit();
bool isGot(int i,int j);
public slots:
void doProcessStartGame();
void doProcessExitGame();
void doProcessFrushPlate(int p,int q );
};
#endif // CHESSFORM_H
chessForm.cpp
#include "chessform.h"
#include "ui_chessform.h"
chessForm::chessForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::chessForm)
{
ui->setupUi(this);
Init();//初始化主界面
// this->setWindowIcon(QIcon(":/res/中文.png"));
connect(ui->openGameBtn,&QPushButton::clicked,this,&chessForm::doProcessStartGame);
connect(ui->exitBtn,&QPushButton::clicked,this,&chessForm::doProcessExitGame);
}
chessForm::~chessForm()
{
delete ui;
}
void chessForm::paintEvent(QPaintEvent *)
{
//绘制主界面背景
QPainter painter(this);
painter.drawPixmap(0,0,this->width(),this->height(),QPixmap(":/res/back.jpg"));
}
void chessForm::closeEvent(QCloseEvent *event)
{
if(QMessageBox::Yes==QMessageBox::information(this,"提示","是否退出",QMessageBox::Yes,QMessageBox::No))
{
event->accept();
}
else
{
event->ignore();
}
}
void chessForm::Init()
{
//申请棋盘类空间
myPlate = new chessPlate();
//把棋盘放在主界面的容器中
ui->gridLayout->addWidget(myPlate);
//设置Title、图标
this->setWindowTitle("五子棋");
//设置标题字
ui->titleLab->setPixmap(QPixmap(":/res/title.png"));
//添加争先选择部件
QStringList list;
list.clear();
list.append("白子先");
list.append("黑子先");
ui->comboBox->addItems(list);
//显示白棋、黑棋行走标识
showRole(":/res/white.png",":/res/black.png");
}
void chessForm::showRole(const QString whiteFileName, const QString blackFileName)
{
ui->whiteLab->setPixmap(QPixmap(whiteFileName));
ui->whiteLab->setScaledContents(true);
ui->blackLab->setPixmap(QPixmap(blackFileName));
ui->blackLab->setScaledContents(true);
}
void chessForm::setRole(chessPlate::ChessType Role)
{
currentRole = Role;
if(Role == chessPlate::Black)
{
ui->blackLab->setVisible(true);
ui->whiteLab->setVisible(false);
}
else
{
ui->blackLab->setVisible(false);
ui->whiteLab->setVisible(true);
}
}
void chessForm::setChessInit()
{
for (int i=0;i<15 ;i++ ) {
for (int j = 0;j<15 ;j++ ) {
formChessData[i][j]=chessPlate::Empty;
}
}
myPlate->setChessStatus(formChessData);
white_cnt=0;
black_cnt=0;
ui->lcdNumBlack->display(black_cnt);
ui->lcdNumWhite->display(white_cnt);
}
bool chessForm::isGot(int i, int j)
{
//扫面方式决定了,这种判断方式
chessPlate::ChessType a;
a= chessPlate::ChessType(formChessData[i][j]);
if(i>10)//向右判断
{
//不向右判断
}
else
{
qDebug()<<"111111";
if(formChessData[i+1][j]==a&&formChessData[i+2][j]==a&&formChessData[i+3][j]==a&&formChessData[i+4][j]==a)
{return true;}
}
if(j>10)//向下判断
{
//不向下判断
}
else
{
if(formChessData[i][j+1]==a&&formChessData[i][j+2]==a&&formChessData[i][j+3]==a&&formChessData[i][j+4]==a)
{return true;}
}
if(j>10||i>10)//向斜下判断
{
//不向斜下判断
}
else
{
if(formChessData[i+1][j+1]==a&&formChessData[i+2][j+2]==a&&formChessData[i+3][j+3]==a&&formChessData[i+4][j+4]==a)
{return true;}
}
if(j<4||i>10)
{
//不向斜上判断
}
else
{
if(formChessData[i+1][j-1]==a&&formChessData[i+2][j-2]==a&&formChessData[i+3][j-3]==a&&formChessData[i+4][j-4]==a)
{return true;}
}
return false;
}
void chessForm::doProcessStartGame()
{
QSound *sound = new QSound(":/res/startSound.wav",this);
//播放开始音效
sound->play();
//设置循环次数 -1代表无线
sound->setLoops(3);
//界面初始化
if(ui->comboBox->currentText().contains("白"))
{
setRole(chessPlate::White);
}
else
{
setRole(chessPlate::Black);
}
//棋盘初始化
setChessInit();
//可以开始下棋,连接信号槽
connect(myPlate,&chessPlate::mousePosSend,this,&chessForm::doProcessFrushPlate);
}
void chessForm::doProcessExitGame()
{
this->close();
}
void chessForm::doProcessFrushPlate(int p, int q)
{
QSound *gameSound = new QSound(":/res/gamesound.wav",this);
//判断能否下子
if(formChessData[p][q]==chessPlate::Empty)
{
//可以下子 下哪一个子
if(currentRole==chessPlate::Black)
{
formChessData[p][q]=chessPlate::Black;
black_cnt++;
currentRole = chessPlate::White;
}
else
{
formChessData[p][q] = chessPlate::White;
white_cnt++;
currentRole = chessPlate::Black;
}
myPlate->setChessStatus(formChessData);
gameSound->play();
ui->lcdNumBlack->display(black_cnt);
ui->lcdNumWhite->display(white_cnt);
//判断是否胜利
int i=0,j=0;
for (i=0;i<15 ;i++ ) {
for (j=0;j<15 ;j++ ) {
if(formChessData[i][j]==0)
{}
else
{
if(isGot(i,j))//这个棋子是否构成成功棋形判断函数
{break;}
}
}
if(j!=15)
{break;}
}
if((i!=15)&&formChessData[p][q] == chessPlate::White)
{
QMessageBox::information(this,"提示","恭喜白棋胜利!",QMessageBox::Ok);
setChessInit();
showRole(":/res/white.png",":/res/black.png");
disconnect(myPlate,&chessPlate::mousePosSend,this,&chessForm::doProcessFrushPlate);
}
else if((i!=15)&&formChessData[p][q] == chessPlate::Black)
{
QMessageBox::information(this,"提示","恭喜黑棋胜利!",QMessageBox::Ok);
setChessInit();
showRole(":/res/white.png",":/res/black.png");
disconnect(myPlate,&chessPlate::mousePosSend,this,&chessForm::doProcessFrushPlate);
}
else
{}
}
else
{}
}