python井字棋ai_实现AI下井字棋的alpha-beta剪枝算法(python实现)
代码参考自中国大学mooc上人工智能与信息社会陈斌老师的算法,我在原来的基础上增加了玩家输入的异常捕获 AlphaBeta剪枝算法是对Minimax方法的优化,能够极大提高搜索树的效率,如果对这个算法感兴趣的可以去参考相关资料。 当正确理解AlphaBeta剪枝算法后,还可以将它应用在象棋、围棋等一些高级游戏的算法搜索上,使得电脑寻找最优胜率的速度加快
python代码实现
#coding:utf-8
'''井字棋(Tic tac toe)Python3语言实现, 带有Alpha-Beta剪枝的Minimax算法.
代码参考自中国大学mooc 人工智能与信息社会(陈斌)'''
import random
# 用如下的9个数字来表示棋盘的位置:
# 0 1 2
# 3 4 5
# 6 7 8
# 设定获胜的组合方式(横、竖、斜)
WINNING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8),
(0, 3, 6), (1, 4, 7),(2, 5, 8),
(0, 4, 8), (2, 4, 6))
# 设定棋盘按一行三个打印
PRINTING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8))
# 用一维列表表示棋盘:
SLOTS = (0, 1, 2, 3, 4, 5, 6, 7, 8)
# -1表示X玩家 0表示空位 1表示O玩家.
X_token = -1
Open_token = 0
O_token = 1
MARKERS = ['_', 'O', 'X']
END_PHRASE = ('平局', '胜利', '失败')
def alpha_beta_valuation(board, player, next_player, alpha, beta):
"""运用AlphaBeta剪枝来计算当前局面的分值
因为搜索层数少,总能搜索到最终局面,估值结果为[-1,0,1]
"""
wnnr = winner(board)
if wnnr != Open_token:
# 有玩家获胜
return wnnr
elif not legal_move_left(board):
# 没有空位,平局
return 0
# 检查当前玩家"player"的所有可落子点
for move in SLOTS:
if board[move] == Open_token:
board[move] = player
# 落子之后交换玩家,继续检验
val = alpha_beta_valuation(board, next_player, player, alpha, beta)
board[move] = Open_token
if player == O_token: # 当前玩家是O,是Max玩家(记号是1)
if val > alpha:
alpha = val
if alpha >= beta:
return beta # 直接返回当前的最大可能取值beta, 进行剪枝
else: # 当前玩家是X,是Min玩家(记号是-1)
if val < beta:
beta = val
if beta <= alpha:
return alpha # 直接返回当前的最小可能取值alpha, 进行剪枝
if player == O_token:
retval = alpha
else:
retval = beta
return retval
def print_board(board):
"""打印当前棋盘"""
for row in PRINTING_TRIADS:
r = ' '
for hole in row:
r += MARKERS[board[hole]] + ' '
print(r)
def legal_move_left(board):
""" 判断棋盘上是否还有空位 """
for slot in SLOTS:
if board[slot] == Open_token:
return True
return False
def winner(board):
""" 判断局面的胜者,返回值-1表示X获胜,1表示O获胜,0表示平局或者未结束"""
for triad in WINNING_TRIADS:
triad_sum = board[triad[0]] + board[triad[1]] + board[triad[2]]
if triad_sum == 3 or triad_sum == -3:
return board[triad[0]] # 表示棋子的数值恰好也是-1:X,1:O
return 0
def determine_move(board):
"""决定电脑(玩家O)的下一步棋,若估值相同则随机选取步数"""
best_val = -2 # 本程序估值结果只在[-1,0,1]中
my_moves = []
print("开始思考")
for move in SLOTS:
if board[move] == Open_token:
board[move] = O_token
val = alpha_beta_valuation(board, X_token, O_token, -2, 2)
board[move] = Open_token
print("Computer如果下在", move, ",将导致", END_PHRASE[val])
if val > best_val:
best_val = val
my_moves = [move]
if val == best_val:
my_moves.append(move)
return random.choice(my_moves)
HUMAN = 1
COMPUTER = 0
def main():
"""主函数,先决定谁是X(先手方),再开始下棋"""
next_move = HUMAN
opt = input("请选择先手方,输入X表示玩家先手,输入O表示电脑先手:")
if opt == "X":
next_move = HUMAN
elif opt == "O":
next_move = COMPUTER
else:
print("输入有误,默认玩家先手")
# 初始化空棋盘
board = [Open_token for i in range(9)]
# 开始下棋
while legal_move_left(board) and winner(board) == Open_token:
print()
print_board(board)
if next_move == HUMAN and legal_move_left(board):
try:
humanmv = int(input("请输入你要落子的位置(0-8):"))
if board[humanmv] != Open_token:
continue
board[humanmv] = X_token
next_move = COMPUTER
except:
print("输入有误,请重试")
continue
if next_move == COMPUTER and legal_move_left(board):
mymv = determine_move(board)
print("Computer最终决定下在", mymv)
board[mymv] = O_token
next_move = HUMAN
# 输出结果
print_board(board)
print(["平局", "Computer赢了", "你赢了"][winner(board)])
if __name__ == '__main__':
main()
运行结果
python井字棋ai_实现AI下井字棋的alpha-beta剪枝算法(python实现)相关推荐
- 五子棋AI算法第三篇-Alpha Beta剪枝
剪枝是必须的 五子棋AI教程第二版发布啦,地址:https://github.com/lihongxun945/myblog/labels/%E4%BA%94%E5%AD%90%E6%A3%8BAI% ...
- alpha-beta剪枝五子棋c语言,五子棋AI算法第三篇-Alpha Beta剪枝
剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250 ...
- 五子棋AI算法-Alpha Beta剪枝
上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250000,在我的 ...
- 基于python的AI五子棋实现(极大极小值搜索和alpha beta剪枝)
1.极大极小值搜索介绍 人机博弈是人工智能的重要分支,人们在这一领域探索的过程中产生了大量的研究成果,而极小化极大算法(minimax)是其中最基础的算法,它由Shannon在1950年正式提出. M ...
- python井字棋ai_[Python100行系列]-井字棋游戏
博客:Hzy的博客 | Hzy Bloghzeyuan.cn一些学习python的小项目,小游戏.python小项目github.com 话不多说,今天尝试用turtle库来写一个井字棋游戏.1. ...
- python alpha beta 剪枝_一看就懂的 Alpha-Beta 剪枝算法详解
Alpha-Beta剪枝用于裁剪搜索树中没有意义的不需要搜索的树枝,以提高运算速度. 假设α为下界,β为上界,对于α ≤ N ≤ β: 若 α ≤ β 则N有解. 若 α > β 则N无解. ...
- python中模块是什么意思_Python中的模块是什么?3分钟搞懂Python中的模块问题
Python 中的模块是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句,模块让你能够有逻辑地组织你的 Python 代码段.把相关的代码分配到一个模块里能 ...
- k-medoid(k中心点)聚类算法Python实现
k-means算法有个很大的缺点,就是对孤立点敏感性太高,孤立点即是脱离群众的点,与众不同的点,即在显示中与其他点不是抱在一团的点. 为了体现两者的不同,我特意温习了一下知识,在构造初始点的时候,自己 ...
- python井字棋游戏代码_python实现井字棋游戏
python实现井字棋游戏 来源:中文源码网 浏览: 次 日期:2018年9月2日 [下载文档: python实现井字棋游戏.txt ] (友情提示:右键点上行txt文档名->目标 ...
最新文章
- 港口物流系统设计与优化-SMU在线学习笔记
- 用上微软Bosque 困扰程序员30年的问题解决了
- JavaScript——jQuery AJAX链式编程(流式编程)DEMO
- vue 图片资源应该如何存放并引入(public、assets)?
- php 解析yaml,php yaml 解析 报错问题
- 如何去学好JS的8条小建议
- android smb 图片,谷歌放出安卓版Samba客户端 但仅支持SMBv1
- Java异常处理机制(基础知识)
- html中下拉日历控件,HTML5之日历控件
- 个人分享:一些学者实用的网站
- Java SE Java EE和Java ME的区别
- SPSS神经网络心得(一)
- 采写编杂志采写编杂志社采写编编辑部2022年第10期目录
- php混淆解密,php混淆加密解密实战
- hive中的date函数
- Action Unit到底是什么?
- 设计模式(17)----中介者模式
- Linux libusb开发教程<一> 介绍与安装
- Mysql Tigger触发器创建和使用
- 分布式开发--分布式定时任务
热门文章
- .net core razor ajax,.NET CORE Razor Pages Ajax 调用 C# 方法
- php validate form,laravel 中validate验证规则 利用FormRequest进行数据验证
- java操作_JAVA操作文件大全(一)
- hibernate 复合主键 根据主键删除_Python 之 MySql“未解之谜”11--主键 id 那些事
- button hover逐渐变色_两当水库界桩@产品长久不变色 - 两当安全防护
- C++实现单链表的反序
- qt自定义按钮类,每个按钮自带一个右键弹出框,如何使同一时刻只显示一个弹出框
- qt种实现搜索栏功能
- QtCreate由MinGW编译的项目,换为MSVC编译器后编译无法通过
- BugkuCTF-MISC题神秘的文件