Qt编写的黑白棋游戏 其中人机算法和落子有很大的问题 希望又人能帮忙解决一下

qq_39037901 2019-08-31 09:32:52
#include "report.h"
#include "ui_report.h"
#include <QLabel>
#include <QBitmap>
#include <QPainter>
#include <QImage>
#include <QWidget>
#include <QPixmap>
#include <QDebug>
#include <QMouseEvent>
#include <QTimer>
#include <QMessageBox>
#include <QSound>
Report::Report(QWidget *parent) :
QWidget(parent),
ui(new Ui::Report)
{
ui->setupUi(this);
this->setMouseTracking(true);
this->setFixedSize(1024,600);
//设置窗口图标 标题
this->setWindowIcon(QIcon(":/image/logo.png"));
this->setWindowTitle("Black&White Chess");
//Exit 退出游戏
connect(ui->Exit,&QPushButton::clicked,this,&QWidget::close);
//back 返回选择模式
connect(ui->back,&QPushButton::clicked,[=](){
emit this->back_mode();
});
ui->Black_Win->hide();
ui->White_Win->hide();
connect(&mTimer, &QTimer::timeout,this ,&Report::ReportPlay);
connect(&LeftTimer, &QTimer::timeout,[=]() mutable{
TimeNum--;
ui->time->display(TimeNum);
//倒计时结束
if(!TimeNum)
{
TimeNum = 16;
this->changePlayer();
}
});
connect(ui->Pause,&QPushButton::clicked,[=](){
flag++;
if(flag % 2 == 1)
{
LeftTimer.stop();
}
else
{
LeftTimer.start();
}
});

Start = QPoint(272, 60);//起点坐标
End = QPoint(752, 540);//终点坐标
L = (End.x() - Start.x())/8;
player = Black;
ui->white->hide();


NewChess();//刷新棋盘

}

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

void Report::paintEvent(QPaintEvent *event)
{
//定义一个画家
QPainter *painter = new QPainter(this);
//QPainter *painter2 = new QPainter(this);
//QPainter *painter3 = new QPainter(this);
QPixmap pix;
pix.load(":/image/222.jpg");
pix = pix.scaled(1024, 600);//修改图片尺寸
//画家画图
painter->drawPixmap(0,0,pix.width(),pix.height(),pix);
for(int i = 0;i<=8;i++)//画家画横线
{
painter->setPen(QPen(Qt::white,2));
painter->drawLine(272,60+60*i,752,60+60*i);
}
for(int j = 0;j<=8;j++)//画家画竖线
{
painter->setPen(QPen(Qt::white,2));
painter->drawLine(272+60*j,60,272+60*j,540);
}
int b_n = 0,w_n = 0;
for(int i=0;i<8;++i)
{
for(int j=0;j<8;++j)
{
if (chess[i][j]==Black)
{
painter->drawPixmap(Start.x()+j*L,Start.y()+i*L,L,L,QPixmap(":/image/b.png"));
//qDebug()<<"xxx"<<endl;
b_n+=1;
}
else if (chess[i][j]==White)
{
painter->drawPixmap(Start.x()+j*L,Start.y()+i*L,L,L,QPixmap(":/image/w.png"));
w_n+=1;
}
else if (chess[i][j]==Null)
{
painter->drawPixmap(Start.x()+j*L+5,Start.y()+i*L+5,L-10,L-10,QPixmap(":/image/kuang.png"));
}
}
}
connect(ui->Start,&QPushButton::clicked,[=](){
NewChess();
update();
});
//黑白棋子中显示当前黑白棋子数
ui->black_num->setText(QString::number(b_n));
ui->white_num->setText(QString::number(w_n));
if(b_n + w_n ==64)
{
LeftTimer.stop();
if(b_n > w_n)
{
ui->Black_Win->show();
}
else if(b_n > w_n)
{
ui->White_Win->show();
}
else if(b_n == w_n)
{
QMessageBox::information(this,"MESSAGE","GAMEOVER");
}
}
}

void Report::mousePressEvent(QMouseEvent *e)//鼠标单击 下棋
{
int row = 0, col = 0;
row = (e->y() - Start.y())/L;//行数
col = (e->x() - Start.x())/L;//列数
if(e->button() == Qt::LeftButton)//左键
{
p = e->globalPos() = this->frameGeometry().topLeft();
//qDebug()<<"x ="<<e->x()<<" y ="<<e->y()<<endl;
if(player == Black)
{
judgePlayer(row,col,Black,true);
changePlayer();
}
else if(player == White)
{
ReportPlay();
}
update();
}
}

void Report::NewChess()//刷新棋盘
{
TimeNum = 15;
ui->time->display(TimeNum);
if(LeftTimer.isActive() == false)
{
//定时器
this->LeftTimer.start(1000);
}
for(int i=0;i<8;++i)
{
for(int j=0;j<8;++j)
{
chess[i][j] = Null;
}
}
//为中间四个棋子赋初值
chess[3][3] = chess[4][4] = Black;
chess[3][4] = chess[4][3] = White;
}

void Report::changePlayer()//交换棋手
{
if(player == Black)
{
player = White;
TimeNum = 16;
ui->black->hide();
ui->white->show();
}
else if(player == White)
{
player = Black;
TimeNum = 16;
ui->white->hide();
ui->black->show();
this->mTimer.start(1000); //毫秒为单位
}
}

int Report::judgePlayer(int row, int col, Report::NowChess player, bool eatChess)//判断落子
{
//落子的八个方向
int tmp[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
int tmpX = row,tmpY = col; //临时保存棋子坐标位置
eatNum = 0;
for(int i = 0;i<8;i++)
{
tmpX = row; tmpY = col;
tmpX += tmp[i][0];
tmpY += tmp[i][1];
//落子处相邻为不同色可以落子
if(tmpX>=0&&tmpX<8&&tmpY>=0&&tmpY<8&&chess[row][col]==Null && (chess[tmpX][tmpY] != player)&& (chess[tmpX][tmpY] != Null))
{
tmpX += tmp[i][0];
tmpY += tmp[i][1];//向前走一步,开始判断该方向还有无自己棋子
while(tmpX <= 7 && tmpX >= 0 && tmpY <= 7 && tmpY >= 0)
{
if(chess[tmpX][tmpY] == Null)
{
break;//遇到空位跳出循环
}
if(chess[tmpX][tmpY] == player)//找到自己的棋子代表可以吃子
{
//能吃子则点击点标记为自己的棋子,update后是自己的棋子,否则点击处不能落子
if(eatChess == true)
{
chess[row][col] = player;
tmpX -= tmp[i][0];
tmpY -= tmp[i][1];//回退一步开始吃子
//没有回到开始的位置就继续执行
while((tmpX != row) || (tmpY != col))
{//没有回退到点击处则继续修改原有棋子状态
//若为true则为落子,修改为自己的棋子,如果为false则为测试,不用修改
chess[tmpX][tmpY] = player;
tmpX -= tmp[i][0];
tmpY -= tmp[i][1];//回退一格,继续
eatNum++; //吃子数累计
}
break;//跳出循环,结束该方向的判断
}
else if(eatChess == false)//机器人检测
{
tmpX -= tmp[i][0];
tmpY -= tmp[i][1];
//没有回到开始的位置就继续执行
while((tmpX != row) || (tmpY != col))
{//若为true则为落子,修改为自己的棋子,如果为false则为测试,不用修改
tmpX -= tmp[i][0];
tmpY -= tmp[i][1];//回退一格,继续
eatNum++; //吃子数累计
}
break;//跳出循环,结束该方向的判断
}
qDebug()<<"eatNum = "<<eatNum<<endl;
}
tmpX += tmp[i][0];
tmpY += tmp[i][1];
}
}
else if(chess[row][col] == Null)
{
return 0;
}
return eatNum;
}
}
void Report::ReportPlay()//机器人算法
{
this->mTimer.stop();//定时器停止,定时器的作用是防止计算机下子过快,做的一个1s的延时
int max = 0, num = 0;
//判断能落子的最大值
for(int i = 0; i<8; i++)
{
for(int j = 0; j<8; j++)
{
//判断能吃的位置

if( num = judgePlayer(i, j, White, false) > max)//寻找最多吃子的位置
{
max = num;
px = i;
py = j;//记录数组坐标
}
}
}
if(max == 0)//max=0,最多能吃0个子,也就是无法落子
{
changePlayer();
return;
}
else if(max > 0)
{
judgePlayer(px, py,White,true);
}
}



...全文
107 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Italink 2019-08-31
  • 打赏
  • 举报
回复
能否描述一下问题,不然也没人愿意拷贝下来跑一遍,自己还要找问题在哪?

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧