C++五子棋(四)——走棋原理及权值计算
2024-10-08 09:41:33
原理
计算
- 计算每个落子点的“权值”,找到权值最大的落子点
- 对于每个空白点,分别计算周围的八个方向
- 不妨以该空白点作为参照原点,以水平向右作为X轴正方向,以竖直向下为Y轴正方向建立平面直角坐标系
- 因为在计算某个方向时,正向和反向需同时考虑,实际上只需要四个方向,即向量(1,0)的方向、向量(1,1)方向、向量(0,1)方向和向量(-1,1)方向,图示如下(灵魂画图,请勿吐槽 滑稽)
走棋原理
产生效果
- 黑棋走这个点
产生效果 | 评分 |
---|---|
连2 | 10 |
死3 | 30 |
活3 | 40 |
死4 | 60 |
活4 | 200 |
连5 | 20000 |
- 如果白棋(AI)走这个点
产生效果 | 评分 |
---|---|
连1 | 5 |
连2 | 10 |
死3 | 25 |
活3 | 50 |
死4 | 55 |
活4 | 300 |
连5 | 30000 |
权值计算
- chessData.h
void calcScore(ChessData* data);
- chessData.cpp
#include <string>
void calcScore(ChessData* data){
if(!data) return;
//统计玩家或AI连子
int personNum = 0; //玩家
int botNum = 0; //AI
int emptyNum = 0; //各方向空白位数
//清空评分数组
memset(data->scoreMap, 0, sizeof(data->scoreMap));
for (int row = 0; row < BOARD_GRAD_SIZE; row++){
for(int col = 0; col < BOARD_GRAD_SIZE; col++){
//空白点计算
if(row >= 0 && col >= 0 && data->chessMap[row][col] == 0){
//遍历四个方向,然后分别计算正反四个方向
int directs[4][2] = {{1,0}, {1,1}, {0,1}, {-1,1}};
for(int k = 0; k < 4; k++){
int x = directs[k][0];
int y = directs[k][1];
//重置
personNum = 0;
botNum = 0;
emptyNum = 0;
//对黑棋评分(正向)
for(int i = 1; i <= 4; i++){
if(row + i * y >= 0 && row + i * y < BOARD_GRAD_SIZE &&
col + i * x >= 0 && col + i * x < BOARD_GRAD_SIZE &&
data->chessMap[row + i * y][col + i * x] == 1){
//玩家的子
personNum++;
}else if(row + i * y >= 0 && row + i * y < BOARD_GRAD_SIZE &&
col + i * x >= 0 && col + i * x < BOARD_GRAD_SIZE && data->chessMap[row + i * y][col + i * x] == 0){
//空白位
emptyNum++;
break; //遇到空白位置停止该方向搜索
}else{
break; //出边界或遇到白棋停止搜索
}
}
//对黑棋评分(反向)
for(int i = 1; i<= 4; i++){
if(row - i * y >= 0 && row - i * y < BOARD_GRAD_SIZE &&
col - i * x >= 0 && col - i * x <BOARD_GRAD_SIZE &&
data->chessMap[row - i * y][col - i * x] == 1){
personNum++;
}else if(row - i * y >= 0 && row - i * y <BOARD_GRAD_SIZE &&
col - i * x >= 0 && col - i * x < BOARD_GRAD_SIZE &&
data->chessMap[row -i * y][col - i * x] == 0){
emptyNum++;
break;
}else{
break;
}
}
if(personNum == 1){
data->scoreMap[row][col] += 10;
}else if(personNum == 2){
if(emptyNum == 1){
//死3
data->scoreMap[row][col] += 30;
}else if(emptyNum == 2){
//活3
data->scoreMap[row][col] += 40;
}
}else if(personNum == 3){
if(empty == 1){
//死4
data->scoreMap[row][col] += 60;
}else if (emptyNum == 2){
//活4
data->scoreMap[row][col] += 200;
}
}else if(personNum == 4){
data->scoreMap[row][col] += 20000;
}
emptyNum = 0; //清空
//对白棋评分(正向)
for(int i = 1; i <= 4; i++){
if(row + i * y > 0 && row + i * y < BOARD_GRAD_SIZE &&
col + i * x > 0 && col + i * x < BOARD_GARD_SIZE &&
data->chessMap[row + i * y][col + i * x == -1]){
botNum++;
}else if(row + i * y >0 && row + i * y < BOARD_GRAD_SIZE &&
col + i * x > 0 && col + i * x < BOARD_GRAD_SIZE &&
data->chessMap[row + i * y][col + i *x] == 0){
emptyNum++;
break;
}else{
break;
}
}
//白棋评分(反向)
for(int i = 1; i <= 4; i++){
if(row - i * y > 0 && row - i * y <BOARD_GRAD_SIZE &&
col - i * x > 0 && col - i * x < BOARD_GRAD_SIZE &&
data->chessMap[row - i * y][col -i * x] == -1){
botNum++;
}else if (row - i * y >0 && row - i * y < BOARD_GRAD_SIZE &&
col - i * x > 0 && col - i * x < BOARD_GRAD_SIZE &&
data->chessMap[row - i * y][col - i * x] == 0){
emptyNum++;
break;
}else{
break; //出边界
}
}
if(botNum == 0){
//连1
data->scoreMap[row][col] += 5;
}else if(botNum == 1){
//活2
data->scoreMap[row][col] += 10;
}else if(botNum == 2){
if(emptyNum == 1){
//死3
data->scoreMap[row][col] += 25;
}else if(emptyNum == 2){
//活3
data->scoreMap[row][col] += 50;
}
}else if(botNum == 3){
if(emptyNum == 1){
//死4
data->scoreMap[row][col] += 55;
}else if(botNum == 2){
//活4
data->scoreMap[row][col] += 300;
}
}else if(botNum >= 4){
//活5
data->scoreMap[row][col] += 30000;
}
}
}
}
}
}
最新文章
- OpenCASCADE View Manipulator
- tmodjS
- javascript练习-方法借用
- 【C语言入门教程】1.2 函数库 和 链接
- C/C++多种方法获取文件大小(转)
- TabLayout
- bzoj4165: 矩阵
- POJ 2480 Longge&#39;s problem (积性函数,欧拉函数)
- 踩过的坑系列之InputStream.read(byte[])方法
- android 反纠结app开发: 在线程中更新view
- Linux系统维护修复模式
- python web with bottle and session (beaker)
- Tomcat6 Session建立机制简要
- Ubuntu16.04 将其他磁盘挂载到 /home, 解决/home空间不足
- IO流实例
- Gym 102056L - Eventual … Journey - [分类讨论][The 2018 ICPC Asia-East Continent Final Problem L]
- IIS下载无后缀文件的设置
- tensorflow serving 编写配置文件platform_config_file的方法
- Unity优化方向——优化Unity游戏中的垃圾回收(译)
- python基础学习之路No.1