分析

在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下——棋盘线的交点处。

功能实现

创建数据类型

  • 创建头文件chessData.h和源文件chessData.cpp
  • chessData.cppmain.cpp分别引用头文件chessData.h
#include "chessData.h"
  • 将之前在main.cpp中写的棋盘数据剪贴chessData.h
const float BLOCKSIZE = 67.4;
const int BLOCK_GRAD_SIZE = 13;
  • chessData.h中定义常量 POS_OFFSET,即鼠标有效点击距离上限
const int POS_OFFSET = BLOCKSIZE * 0.4;
  • chessData.h定义结构体 ChessData
struct ChessData{
//储存当前游戏棋盘的情况,空白为0,黑棋为1,白棋为-1
int chessMap[BLOCK_GRAD_SIZE][BLOCK_GRAD_SIZE];
//储存各点的评分情况,用于之后的AI走棋
int scoreMap[BLOCK_GRAD_SIZE][BLOCK_GRAD_SIZE]; bool playFlag; //表示下棋放,true黑棋,false白棋(AI) };
  • main.cpp中添加全局变量game
ChessData game;

初始化数据类型

  • chessData.h中添加函数声明
void initChessData(ChessData*);
  • chessData.cpp
void initChessData(ChessData *data){
if(!data) return;
memset(data->chessMap,0,sizeof(data->chessMap));
memset(data->scoreMap,0,sizeof(data->scoreMap));
data->playFlag = true; }

判断有效点击

算法原理

实现

  • main.cpp中添加全局变量
int clickPosRow, clickPosCol;    //用于储存点击位置
  • 定义函数clickBoard()
//有效点击返回true,无效点击返回false
//MOUSEMSG为鼠标信息类型
bool clickBoard(MOUSEMSG msg){ //(鼠标点击坐标 - 边界长度)/ 格宽 = 行(列)数 //计算列数并取整
int col = (msg.x - MARGIN_X) / BLOCKSIZE;
//计算行数取整
int row = (msg.y - MARGIN_Y) / BLOCKSIZE; //计算棋子正确坐标,即格子左上角棋子应在的棋盘格线交点处坐标
int leftTopPosX = MARGIN_X + BLOCKSIZE * col;
int leftTopPosY = MARGIN_Y + BLOCKSIZE * row; }
  • 在文件最上方引用头文件math.h用于后期计算
#include <math.h>
  • 之后要判断棋子应在四个交点中具体哪一点上,这里我们用一个do-while循环。继续添加clickBoard()函数的定义
int len; //用于计算两点见的距离(根据中学所学两点间距离公式)
int selectPos = false; //作为返回值 do{
//左上角
len = sqrt((msg.x - leftTopPosX)*(msg.x - leftTopPosX) + (y - leftTopPosY)*(msg.y - leftTopPosY));
if(len < POS_OFFSET){
clickPosRow = row;
clickPosCol = col;
if ( game.chessMap[clickPosRow][clickPosCol] == 0 ){
selectPos = true;
}
break;
} //右上角
len = sqrt((msg.x - leftTopPosX - BLOCKSIZE)*(msg.x - leftTopPosX - BLOCKSIZE) + (y - leftTopPosY)*(msg.y - leftTopPosY));
if(len < POS_OFFSET){
clickPosRow = row;
clickPosCol = col + 1;
if ( game.chessMap[clickPosRow][clickPosCol] == 0 ){
selectPos = true;
}
break;
} //左下角
len = sqrt((msg.x - leftTopPosX)*(msg.x - leftTopPosX) + (y - leftTopPosY - BLOCKSIZE)*(msg.y - leftTopPosY - BLOCKSIZE));
if(len < POS_OFFSET){
clickPosRow = row + 1;
clickPosCol = col;
if ( game.chessMap[clickPosRow][clickPosCol] == 0 ){
selectPos = true;
}
break;
} //右下角 len = sqrt((msg.x - leftTopPosX - BLOCKSIZE)*(msg.x - leftTopPosX - BLOCKSIZE) + (y - leftTopPosY - BLOCKSIZE)*(msg.y - leftTopPosY - BLOCKSIZE));
if(len < POS_OFFSET){
clickPosRow = row + 1;
clickPosCol = col + 1;
if ( game.chessMap[clickPosRow][clickPosCol] == 0 ){
selectPos = true;
}
break;
} }while(0); return selectPos;

更新底层数据

  • chessData.h
void updateGameMap(ChessData* data, int row, int col);
  • chessData.cpp
void updateGameMap(ChessData* data, int row, int col){
if(!data) return; if(data->playFlag){
data->chessMap[row][col] = 1;
}else{
data->chessMap[row][col] = -1;
} data->playFlag = !data->playFlag; //换下棋方 }
  • main.cpp
//玩家走棋
void manGo(){
chessDown(clickPosRow,clickPosCol,CHESS_BLACK);
updateGameMap(&game, clickPosRow, clickPosCol); }

最新文章

  1. iOS系列 基础篇 07 Action动作和输出口
  2. jquery版滑块导航栏
  3. KM模板
  4. C#高级进阶--重写函数
  5. Oracle数据库之PL/SQL基础
  6. NOR FLASH与NAND FLASH的区别
  7. jeecms获取栏目标题图
  8. Java JPA 查询实体部分字段
  9. 树形dp总结
  10. transition和animation做动画(css动画二)
  11. ESP32搭建1.VMware Workstation 12.5下Ubuntu16.04环境搭建(简易搭建)
  12. Sping4之依赖注入
  13. Android-textview图文混排(网络图片)
  14. 用C#实现C/S模式下软件自动在线升级
  15. luoguP2231 [HNOI2002]跳蚤
  16. Current urgent plan(3/30)
  17. Swift中的指针类型
  18. 【洛谷】P1631: 序列合并
  19. Redis(八):spring data redis 理解
  20. Dockerfile减少构建镜像大小的方法

热门文章

  1. ASP.NET Core框架探索之Authorization
  2. Net Framework 中托管代码与非托管代码的区别
  3. java-关于java
  4. java+eclipse安装及配置
  5. 航模电池平衡头接线,1S-6S原理图
  6. Python -用虚拟环境保存库文件
  7. Nacos 使用
  8. SpringAOP--代理
  9. vue-router的原理,例如hashhistory和History interface?
  10. CI_CD 简单了解