QT黑白棋AI项目详解:一种另类的绘制方式_qt黑白棋教程

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

ui->labelWhite->show();



ui->labelBlack->hide();




ui->lcdNumberWhite->display(2);



ui->lcdNumberBlack->display(2);



}


绘制如下:这个项目的重点就是在一开始就把棋盘的起点坐标和方格的大小都知道了,从而当鼠标点击的时候,就会知道点击的是哪个方格。




void Widget::paintEvent(QPaintEvent *)



{



//绘图事件,画棋盘,画棋子



QPainter p(this); //创建画家,指定窗口为画布



//背景图(棋盘)



p.drawPixmap(this->rect(),QPixmap(“:/image/chess2.png”));



int startX = 0;



int startY = 0;



//根据棋盘二维数组的状态画棋子



for(int i = 0; i < 8; i++){



for(int j = 0; j < 8; j++){



startX = startPoint.x() + i*(gridWidth+1);



startY = startPoint.y() + j*(gridHigh+1);



if(chessStatus[i][j] == Black){



//画黑子



p.drawPixmap(startX, startY,



gridWidth-7, gridHigh-4, QPixmap(“:/image/Black.png”));



}



else if(chessStatus[i][j] == White){



//画白子



p.drawPixmap(startX, startY,



gridWidth-7, gridHigh-4, QPixmap(“:/image/White.png”));



}



}



}



}


  

黑白棋的逻辑如下:




int Widget::judgeRole(int x, int y, ChessFlag currentRole, bool eatChess)



{



//落子的八个方向



int dir[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};



int tmpX = x,tmpY = y; //临时保存棋盘坐标位置



int i = 0, eatNum = 0; //初始化数据




if(chessStatus[tmpX][tmpY] != Empty){//如果此方格中已经有棋子无效操作,直接返回



return 0;



}



//棋盘的8个方向



for(i=0; i<8; i++){



//从鼠标点击点开始



tmpX = x;



tmpY = y;



//确定一个方向:dir[i][0]



tmpX += dir[i][0];



tmpY += dir[i][1];




if(tmpX < GRID_NUMBER && tmpX >= 0 && tmpY < GRID_NUMBER && tmpY >= 0



&& (chessStatus[tmpX][tmpY] != currentRole) && (chessStatus[tmpX][tmpY] != Empty)){




//如果没有出界并且相邻棋子是对方棋子才有可能吃子



tmpX += dir[i][0];



tmpY += dir[i][1];//向前走一步,开始判断该方向还有无自己棋子




while(tmpX < GRID_NUMBER && tmpX >= 0 && tmpY < GRID_NUMBER && tmpY >= 0){



if(chessStatus[tmpX][tmpY] == Empty){



break;//遇到空位跳出循环,外部if最后一个条件也会不满足,则直接判断下一个方向



}



if(chessStatus[tmpX][tmpY] == currentRole){//找到自己的棋子代表可以吃子



//能吃子则点击点标记为自己的棋子,update后是自己的棋子,否则点击处不能落子



(true == eatChess) ? (chessStatus[x][y] = currentRole) : true;



tmpX -= dir[i][0];



tmpY -= dir[i][1];//回退一步开始吃子



//没有回到开始的位置就继续执行



while((tmpX != x) || (tmpY != y)){//没有回退到点击处则继续修改原有棋子状态



//若为true则为落子,修改为自己的棋子,如果为false则为测试,不用修改



(true == eatChess) ? (chessStatus[tmpX][tmpY] = currentRole) : true;



tmpX -= dir[i][0];



tmpY -= dir[i][1];//回退一格,继续



eatNum++; //吃子累计



}



break;//跳出循环,结束该方向的判断



}



//没找到自己的棋子就向前(指定方向)走一步,走到0或GRID_NUMBER边界条件时就结束该层if语句



tmpX += dir[i][0];



tmpY += dir[i][1];



}



}



}



return eatNum;



}


  



电脑下子时:找到的是最大吃子的位置,而且调用的是



judgeRole同一个方法,


  

  





void Widget::machinePlay()



{



timer.stop();//定时器停止




int max = 0, num = 0;



int px = 0, py = 0;




//判断能落子的最大值



for(int i = 0; i<8; i++){



for(int j = 0; j<8; j++){



//判断能吃的位置,机器为黑子



if( num = judgeRole(i, j, role, false) > max){//寻找最多吃子的位置



max = num;



px = i;



py = j;



}



}



}



if(max == 0){//没有可走的了



if((blackFlag | whiteFlag)){



WHITE_FLAG();



BLACK_FLAG();



changeRole();



return;



}



else{



if(overFlag == false){



overFlag = true;



//修改标志位并弹出结果提示信息,在函数返回时另一个gameOver()就不会执行了



gameOver();



}



}

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

`

 return;
 }
 else{
 if(overFlag == false){
 overFlag = true;
 //修改标志位并弹出结果提示信息,在函数返回时另一个gameOver()就不会执行了
 gameOver();
 }
 }


[外链图片转存中...(img-2h0vq1U2-1715790574919)]
[外链图片转存中...(img-cJOiKWDy-1715790574919)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值