[Java五子棋小游戏-Ai算法精讲以及实现]-02--高级算法初步

高级算法初步

  • 走对自己利益最大的路
  • 它有难了不要慌,抛弃它,以这盘棋局的胜利为他报仇

碰撞检测与跨步算法原理图

在这里插入图片描述


反向计算权重

每次计算完权重,都要进行一次反向权重计算

  • 权重值 : 两侧的权重值相加
权重计算代码–这里还是拿第一节的代码:
/*
           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;
}




经过学习本次算法 你已经能写一个能够虐人(新手)的五子棋程序了

由于本人的下棋技术也一般般,如果有高手的话,欢迎加我微信,咱们来探讨探讨



上一篇[Java五子棋小游戏-Ai算法精讲以及实现]-01–初步算法
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您提供一个基于 Python 的五子棋小游戏实现,使用了 α-β剪枝算法实现电脑的 AI 策略。 首先,为了实现五子棋,我们需要一个棋盘,可以使用二维数组来表示: ```python board = [[0 for i in range(15)] for j in range(15)] ``` 其中,0 表示该位置为空,1 表示该位置为黑子,2 表示该位置为白子。 接着,我们需要实现落子函数,来让玩家和电脑下棋: ```python def move(board, row, col, player): if board[row][col] != 0: return False board[row][col] = player return True ``` 其中,`player` 参数表示玩家或电脑,1 表示玩家,2 表示电脑。 接下来,我们需要实现电脑的 AI 策略,使用 α-β剪枝算法来优化搜索: ```python def alphabeta(board, depth, alpha, beta, player): if depth == 0: return evaluate(board, player) if player == 2: best_score = -999999 for row in range(15): for col in range(15): if board[row][col] == 0: board[row][col] = player score = alphabeta(board, depth - 1, alpha, beta, 1) board[row][col] = 0 best_score = max(best_score, score) alpha = max(alpha, score) if beta <= alpha: break return best_score else: best_score = 999999 for row in range(15): for col in range(15): if board[row][col] == 0: board[row][col] = player score = alphabeta(board, depth - 1, alpha, beta, 2) board[row][col] = 0 best_score = min(best_score, score) beta = min(beta, score) if beta <= alpha: break return best_score ``` 其中,`depth` 参数表示搜索的深度,`alpha`、`beta` 参数分别表示 α、β 值。 最后,我们需要实现评估函数,来评估当前棋盘的得分: ```python def evaluate(board, player): score = 0 for row in range(15): for col in range(15): if board[row][col] == player: score += 1 return score ``` 最后,我们可以将上述函数整合到一个完整的程序中,来实现五子棋小游戏: ```python import random board = [[0 for i in range(15)] for j in range(15)] def move(board, row, col, player): if board[row][col] != 0: return False board[row][col] = player return True def alphabeta(board, depth, alpha, beta, player): if depth == 0: return evaluate(board, player) if player == 2: best_score = -999999 for row in range(15): for col in range(15): if board[row][col] == 0: board[row][col] = player score = alphabeta(board, depth - 1, alpha, beta, 1) board[row][col] = 0 best_score = max(best_score, score) alpha = max(alpha, score) if beta <= alpha: break return best_score else: best_score = 999999 for row in range(15): for col in range(15): if board[row][col] == 0: board[row][col] = player score = alphabeta(board, depth - 1, alpha, beta, 2) board[row][col] = 0 best_score = min(best_score, score) beta = min(beta, score) if beta <= alpha: break return best_score def evaluate(board, player): score = 0 for row in range(15): for col in range(15): if board[row][col] == player: score += 1 return score def play(): while True: print("请输入您要下棋的位置,用逗号分隔行列,如 1,1 表示第一行第一列:") row, col = map(int, input().split(",")) if move(board, row - 1, col - 1, 1): print("您下了一步棋,当前棋盘:") for row in board: print(row) if evaluate(board, 1) >= 5: print("您赢了!") break print("电脑正在思考,请稍等...") best_score = -999999 best_row = -1 best_col = -1 for row in range(15): for col in range(15): if board[row][col] == 0: board[row][col] = 2 score = alphabeta(board, 3, -999999, 999999, 1) board[row][col] = 0 if score > best_score: best_score = score best_row = row best_col = col move(board, best_row, best_col, 2) print("电脑下了一步棋,当前棋盘:") for row in board: print(row) if evaluate(board, 2) >= 5: print("电脑赢了!") break if __name__ == "__main__": play() ``` 在上述程序中,我们使用了 `play()` 函数来启动五子棋游戏,玩家先手,电脑后手,电脑使用 α-β剪枝算法实现 AI 策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Timeless小帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值