赞
踩
高级算法初步
走对自己利益最大的路
它有难了不要慌,抛弃它,以这盘棋局的胜利为他报仇
碰撞检测与跨步算法原理图
反向计算权重
每次计算完权重,都要进行一次反向权重计算
权重值 : 两侧的权重值相加
权重计算代码–这里还是拿第一节的代码:
/*
x 和 y 代表坐标
* xx :x方向需要增加的值
* yy :y方向需要增加的值
*
* 例如xx = -1 yy= -1
* 代表需要获取(x-1,y-1)的棋子
*
* xx = 1 yy= 1
* 代表需要获取(x+1,y+1)的棋子
*
* */
/**
* 计算权重
* @param x x坐标
* @param y y坐标
* @param xx x方向
* @param yy y方向
* @param size 缓存变量如果当前检测是棋子是你的棋子
* 那么就会保存这个变量继续递归获取下一个位置的权重
* @param c 自己的棋子颜色
* @return 返回计算后的权重
*/
private int ishas(int x,int y,int xx,int yy,int size ,char c){
//边缘检测防止超出棋盘位置
if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)) return size;
if(table[x+xx][y+yy] == c){
return ishas(x+xx,y+yy,xx,yy,size+1,c);
}
return size;
}
反向计算权重 伪代码
//之前计算权重的代码
旧计算权重(x,y,你棋子的颜色 简称->颜色){
//xx 和 yy 代表方向 这里不细说了
//这里 0 代表默认权重 由于它是递归实现的 所以 给一个 0 让他累加
return ishas(x,y,xx,yy,0,颜色);//返回的只是一个方向的权重计算
}
新计算权重(x,y,你棋子的颜色 简称->颜色){
//这里的 -xx 和 -yy 就是对xx和yy进行相反的方向运算
int n = ishas(x,y,xx,yy,0,颜色)+ishas(x,y,-xx,-yy,0,颜色);
return n;
}
碰撞检测
通过递归检测 如果检测到对手棋子
对他的权重-1 因为对手可以直接堵住你
如果他的权重是4 那么就落子,结束这场游戏
碰撞检测代码
碰撞检测也是对之前的权重计算进行优化
原来的代码
private int ishas(int x,int y,int xx,int yy,int size ,char c){
if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)) return size;
if(table[x+xx][y+yy] == c){
return ishas(x+xx,y+yy,xx,yy,size+1,c);
}
return size;
}
进行碰撞检测优化后的
//本方法可以进行对手棋子检测 这里 c 表示你要计算的权重颜色 c2 阻碍检测棋子的颜色
//也可以对c2进行优化 去掉这个参数 使用判断 只要不是默认颜色和你的颜色 一切视为阻碍
private int ishas(int x,int y,int xx,int yy,int size ,char c,char c2){
/**
这里对 size>3 ? size+2:size-1
进行一次说明
三目运算 : 条件 ? 成立的结果:不成立的结果;
如果条件成立 返回成立的结果 如果不成立返回不成立的结果
这里说 如果size>3的话 就说明从这个位置开始 有4个棋子 那么就返回当前权重
如果 size<3 的话 代表一个棋子可以干掉,不足以重视
**/
if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)){return size>3 ? size:size-1}
if(table[x+xx][y+yy] == c){//如果是我要的棋子 继续计算
return ishas(x+xx,y+yy,xx,yy,size+1,c,c2); //size+1 本次计算有效 给权重+1 进行下一次计算
}else if(table[x+xx][y+yy] == c2){ //如果是阻碍棋子 那么就意味着你要检测是棋子已经被堵了 没必要浪费时间 除非能赢
return size>3 ? size:size-1;//这里在上面的注释上有讲解
}
return size;
}
优先权检测
如果检测对手的权重和 自己的权重一样而且跨步权重(稍后讲)也一样
自己的利益最大,没必要做无谓的争斗
在同一个坐标的位置,如果检测的优先权和对手的优先权一样的话,直接走自己的棋子
可以对棋子类加上一个color变量
如果所有的格子遍历完毕的话 同等的优先权 先走自己的棋子
代码实现
智能计算(){
*是否第一步--> return 随机中间棋子(8,8)
遍历所有格子 ->结果(x,y,当前格子颜色){
if(当前格子颜色 == 空){
//两个都要计算并且把计算结果保存到棋子类
计算权重(对手)-->两个方向计算权重
计算权重(自己)-->两个方向计算权重
//如果权重一样那么 对手权重-1 让自己先来
谁的权重大--> 棋子列表.加入棋子(new 棋子(x,y,权重,你棋子的颜色))
}
}
//遍历完毕
棋子列表.按权重排序(同等权重下自己的棋子优先)
返回棋子 = 棋子列表.get(0);
return (返回棋子);
}
这个代码和第一篇的代码变化:
谁的权重大–> 棋子列表.加入棋子(new 棋子(x,y,权重,你棋子的颜色))
这个地方增加了棋子的颜色
棋子列表.按权重排序(同等权重下自己的棋子优先)
优化排序算法,让权重相等的时候自己的棋子优先
跨步权重
这个就是重点了 要知道究竟什么对你有利
这里的跨步权重指的是
除了最 高的权重 的 最高权重 也是就第二高的权重
根据跨步权重可以推算,在权重相等的情况下,究竟哪个棋子对你最有利
跨步权重的实现:
每次进行权重计算的时候 将他保存一个数组或者集合里
然后取出最大的当做权重
第二大的当做跨步权重
隔空跨步权重
隔空跨步权重就是对跨步权重进行一次优化
隔空跨步算法解决的是更准确的计算跨步权重
你可以设置一个值 就是允许跨的格子 一般建议1 - 2
跨步值 1的时候 模拟一次 为2的时候 模拟2次
详细请见图解
隔空跨步权重算法实现
前面介绍的跨步权重还不够完善 无法达到想象中的地步
那么怎么解决呢?
让棋子进行 “猜测”
重新写一个 隔空跨步权重算法
每一次计算完权重的时候 保留xx和yy的值 当 权重计算出来的时候 同时告诉隔空跨步算法 不让他对xx和yy进行计算
伪代码实现
智能计算(){
*是否第一步--> return 随机中间棋子(8,8)
// 自己棋子的颜色 简称 -> 自己
// 对手棋子的颜色 简称 -> 对手
遍历所有格子 ->结果(x,y,当前格子颜色){
if(当前格子颜色 == 空){
//两个都要计算并且把计算结果保存到棋子类
计算权重(x,y,对手)-->两个方向计算权重
计算权重(x,y,自己)-->两个方向计算权重
//如果权重一样那么 对手权重-1 让自己先来
谁的权重大--> 棋子列表.加入棋子(new 棋子(x,y,权重,自己))
}
}
//遍历完毕
棋子列表.按权重排序(同等权重下自己的棋子优先)
返回棋子 = 棋子列表.get(0);
return (返回棋子);
}
ishas(int x,int y,int xx,int yy,int size ,char c,char c2);//计算权重算法
计算权重(x,y,你棋子的颜色 简称->颜色){
//这里的 -xx 和 -yy 就是对xx和yy进行相反的方向运算
int n = ishas(x,y,xx,yy,0,颜色)+ishas(x,y,-xx,-yy,0,颜色);
return n;
}
跨步权重(x,y,除去xx,除去yy,你棋子的颜色 简称->颜色){
...各种方向运算...//各种 x=0 -1 1 .....
if(xx == 除去xx && yy == 除去yy ) return 0;//这里是主权重所以跨步权重不参与
int n = ishasKuaBu(x,y,xx,yy,0,颜色,1)+ishasKuaBu(x,y,-xx,-yy,0,颜色,1);
return n;
}
//这里对ishas进行重新定义 增加了跨步跳转次数
ishasKuaBu(int x,int y,int xx,int yy,int size ,char c,char c2,int 跨步跳转次数){
if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)){return size>3 ? size:size-1}
if(table[x+xx][y+yy] == c){//如果是我要的棋子 继续计算
return ishas(x+xx,y+yy,xx,yy,size+1,c,c2); //size+1 本次计算有效 给权重+1 进行下一次计算
}else if(table[x+xx][y+yy] == c2){ //如果是阻碍棋子 那么就意味着你要检测是棋子已经被堵了 没必要浪费时间 除非能赢
return size>3 ? size:size-1;//这里在上面的注释上有讲解
}else if(table[x+xx][y+yy] == 空 && 跨步跳转次数 > 0 ){//有跨步跳转机会 假装有棋子
return ishas(x+xx,y+yy,xx,yy,size,c,c2,跨步跳转次数-1); //进行下一次计算,权重不变
}
return size;
}
经过学习本次算法 你已经能写一个能够虐人(新手)的五子棋程序了
由于本人的下棋技术也一般般,如果有高手的话,欢迎加我微信,咱们来探讨探讨
之后再更新高级算法
推算算法:猜测如果你下了这步棋 计算对手落子是否对自己有害
全局算法:你每一次下棋 ->进行一次分叉树计算 ->取获胜几率最大的一步棋
阵法初步
等等等…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。