C++五子棋(三)——判断鼠标有效点击
分析
在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下——棋盘线的交点处。
功能实现
创建数据类型
- 创建头文件chessData.h和源文件chessData.cpp
- 在chessData.cpp和main.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);
}
C++五子棋(三)——判断鼠标有效点击的更多相关文章
- unity3D基础学习 通过判断鼠标点击的是否是目标物体,物体旋转,滑动滚轮缩放拉近视角
贴代码: 摄像机的拉近视角代码: public Transform target; public float minFov = 15f; public float maxFov = 7 ...
- GDI画图,判断鼠标点击点在某一画好的多边形、矩形、图形里
Region.IsVisible方法 简单方便准确 private bool CheckPntInPoly(Point[] points, Point pnt) { || pnt == Point.E ...
- js 如何判断鼠标点击事件还是js代码调用
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- 精通Web Analytics 2.0 (5) 第三章:点击流分析的奇妙世界:指标
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第三章:点击流分析的奇妙世界:指标 新的Web Analytics 2.0心态:搞定它.新的闪亮系列工具:是的.准备好了吗?当然 ...
- C#之在treeview中鼠标点击的所选的节点触发事件
一.背景 如下图所示,我想实现通过鼠标点击treeview的根节点,然后在文本框控件中显示鼠标点击的节点号. 二.程序实现 因为是要通过鼠标点击才发生的事情,所以这属于一个事件,需要触发才行,刚开始不 ...
- 【Unity3D】简单常用的功能实现1——鼠标点击实现移动
[鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...
- JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题
1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...
- JS判断鼠标移入元素的方向
最终效果 这里的关键主要是判断鼠标是从哪个方向进入和离开的 $("li").on("mouseenter mouseleave",function(e) { v ...
- Matlab判断鼠标移动
set(gcf,'WindowButtonMotionFcn',@get_cur_positon); 其中第二项是判断鼠标移动的属性参数,第三项为回调函数 et. main.m clear;clc;s ...
随机推荐
- ArcMap操作随记(5)
1.[栅格转面]等工具的使用 若栅格数据为浮点型,需使用[转为整型]工具,将栅格转为整型,再进行操作. 2.人口密度分布趋势图 使用[核密度分析]工具,也可尝试插值 3.点要素做面 [点集转线][要素 ...
- MySQL 字符集相关
为了支持各个国家的不同语言,MySQL 从4.0 版本开始支持了很多种字符集,且每种字符集支持了 N 多种排序规则.我们可以在建表的时候指定字符集的排序规则,不指定时会有一个默认规则. 字符集和排序规 ...
- Spring Boot 进行优雅的字段校验
Controller层 VS Service层 一般推荐与业务无关的放在Controller层中进行校验,而与业务有关的放在Service层中进行校验. 那么如何将参数校验写的优雅美观呢,如果都是if ...
- java+eclipse安装及配置
一.JDK安装 0x00 下载JDK 首先我们需要下载java开发工具包JDK 下载地址:https://www.oracle.com/technetwork/java/javase/download ...
- uoj310. 【UNR #2】黎明前的巧克力
题目描述: uoj 题解: WTF. 看题解看了一个小时才看明白. 首先有状态$f[i][j]$表示前$i$个东西两人取,最后两人异或和为$j$的有多少方案. 转移为$f[i][j]=f[i-1][j ...
- webapi_3 今天真真真全是大经典案例
这个项目一多起来了,还是分个序号比价好一点,你好我好大家好,然后关于这个标点符号的问题,我打字真的很不喜欢打标点符号,不是不好按,按个逗号其实也是顺便的事情,可能就是养成习惯了,就喜欢按个空格来分开, ...
- Lua协程的一个例子
很久没记录笔记了,还是养成不了记录的习惯 下面是来自 programming in lua的一个协程的例(生产者与用户的例子) 帖代码,慢慢理解 -- Programming in Lua Corou ...
- Java 将CSV转为Excel
CSV(Comma Separated Values)文件是一种纯文本文件,包含用逗号分隔的数据,常用于将数据从一个应用程序导入或导出到另一个应用程序.通过将CSV文件转为EXCEL,可执行更多关于数 ...
- 什么是MVC模式?
MVC (Model View Controller) 是一个设计模式,使用MVC应用程序被分成三个核心部件:模型.视图.控制器.它们各自处理自己的任务.M是指数据模型,V是指用户界面,C则是控制器. ...
- Java 线程池中 submit() 和 execute()方法有什么区别?
两个方法都可以向线程池提交任务,execute()方法的返回类型是 void,它定义在 Executor 接口中. 而 submit()方法可以返回持有计算结果的 Future 对象,它定义在 Exe ...