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()

运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534498.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis小计(2)

目录 1.exists命令 2.del命令 3.expire/pexpire命令 4.ttl命令 5.redis对于key过期的删除策略 1.exists命令 exists X1 X2 X3 X4&#xff1a;返回四个key存在的个数。 2.del命令 del X1 X2&#xff1a;删除key。 3.expire/pexpire命令 给key设置超时时间。 expire key…

unity 彩带粒子_iOS动画开发----粒子系统---彩带效果

参考博文地址:http://my.oschina.net/u/2340880/blog/485095?fromerrbgjLq4Mw一、粒子发射器iOS中的粒子效果有两部分组成&#xff0c;一部分为发射器&#xff0c;设置例子发射的宏观属性&#xff0c;另一部分是粒子单元&#xff0c;用于设置相应的粒子属性。粒子发射器是基于…

一秒执行一次_《一秒钟》:一贯的粗旷式抓大放小,张艺谋的自命题作业总是要观众自己再做一遍...

还有不变的永远在奔跑的大棉裤花棉袄的圆脸妮子&#xff0c;这是导演张艺谋最新作品《一秒钟》的最直接观感。张艺谋是个善于从普世情怀处挖掘题材的导演。之前诸多现实题材类型作品&#xff0c;诸如讲父子和解的《千里走单骑》、夫妻爱情的《归来》以及《我的父亲母亲》&#…

latex 作者加小标_Latex 写期刊论文的小技巧

在不同文字处理系统(如 MiKTeX, TeX Live, CTeX, cwTex) 或 不同整合开发环境 ( 如Texstudio, WinEdt, TeXstudio, TeXmaker) 中&#xff0c;我用了 Miktex Texstudio 的常用组合 (win10环境中)。1: 先MiKTeX&#xff0c;后Texstudio ;2&#xff1a; 安装包(packages);3&#…

unity 畸变_unity3d 几种镜头畸变

1.Fisheye distortion 鱼眼镜头解释来自百度百科&#xff1a;鱼眼镜头是一种焦距为16mm或更短的并且视角接近或等于180。 它是一种极端的广角镜头&#xff0c;“鱼眼镜头”是它的俗称。为使镜头达到最大的摄影视角&#xff0c;这种摄影镜头的前镜片直径很短且呈抛物状向镜头前…

restfull加签_SpringBoot RestFull API签名

一、需求如下对指定的API路径进行签名认证&#xff0c;对于没有指定的无需认证&#xff0c;认证具体到方法。二、查阅资料与开发1.了解JWT&#xff0c;实际上用的开源jjwt2.编写自定义注解3.编写拦截器&#xff0c;主要是拦截特定的url进行签名验证&#xff0c;这里解析请求的h…

mysql 5.5.18下载_MySQL5.7.18下载和安装过程图文详解

MySql下载1、打开官网找到下载路口&#xff0c;这里直接给出下载的地址2、选择64位版本3、直接下载MySql5.7.18.1安装过程1 、运行安装软件&#xff0c;接受协议2、选择默认安装3、下一步到检查环境界面&#xff0c;点击“Execute”执行检查 (可以后面单独下载插件安装)&…

mysql找不到performance_Mysql安装完毕运行时没有mysql和performance_schema数据库_MySQL

Mysql问题 ERROR 1045 (28000): Access denied for user ‘root’’localhost’ (using password: YES)Mysql安装完毕运行时没有 mysql 和 performance_schema 数据库问题一&#xff1a;之前卸载未卸载干净问题二&#xff1a;没有管理员权限进入问题三&#xff1a;登录时&#…

mysql latid1_mysql触发器的实战经验

1 引言Mysql的触发器和存储过程一样&#xff0c;都是嵌入到mysql的一段程序。触发器是mysql5新增的功能&#xff0c;目前线上凤巢系统、北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本&#xff0c;很多程序比如fc-star管理端&#xff0c;sfrd(das)&#xff0c;dorad…

mysql数据库sql注入原理_SQL注入原理解析以及举例1

sql注入是指web应用程序对用户输入数据的合法性没有判断&#xff0c;导致攻击者可以构造不同的sql语句来实现对数据库的操作。sql注入漏洞产生满足条件&#xff1a;1&#xff1b;用户能够控制数据的输入。2&#xff1b;原本需要执行的代码&#xff0c;拼接了用户的输入。举例&a…

mysql存储map数据结构_map数据结构

Go map实现原理 - 恋恋美食的个人空间 - OSCHINA - 中文开源技术交流社区 https://my.oschina.net/renhc/blog/2208417// A header for a Go map.type hmap struct {// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.// Make sure this…

四因素三水平正交表_做论文要用正交表?我打包送给你

正交试验目前在国内的应用量仍然是比较高的&#xff0c;许多高校毕业生喜欢利用正交试验来获取研究数据&#xff0c;最终完成毕业论文的撰写或者期刊投稿。正交试验方案的设计&#xff0c;必然要用到(标准)正交表。那么大家都是从哪里获取正交表的呢&#xff1f;小兵给这方面的…

plsql视图添加表字段_Oracle-单表多字段查询(不使用*)

环境&#xff1a;Oracle 11g&#xff0c;plsql 14目的&#xff1a;不使用*,查询拥有上百个字段的表的所有字段。懒人大法&#xff1a;在文章末尾。sql实现逻辑&#xff1a;1、首先建一张100个字段以上的表&#xff0c;通过excel的方式将表建好后直接复制粘贴到plsql的建表界面。…

mysql 编译安装与rpm安装的区别_编译安装与RPM安装的区别

建议在安装线上的生产服务器软件包时都用源码安装&#xff0c;这是因为源码安装可以自行调整编译参数&#xff0c;最大化地定制安装结果。这里以MySQL 5线上环境的编译安装来说明之&#xff0c;其编译参数如下所示&#xff1a;./configure-prefix/usr/local/mysql -without-deb…

python字符串变量s的值是python网络爬虫_【Python爬虫作业】-字符串

一、定义字符串变量1.请定义三个字符串a,b,c值分别为 I,like, python2.请将上面三个变量合并输出I like pythonaIblikecpythonprint(a)print(b)print(c)print(a,b,c)二、定义一个变量 s sdghHhf 1.请先将变量s的空白符去掉 赋值给新变量s1 打印输出2.请分别将s1变为全部大写(命…

lableimg闪退_CV学习笔记(二十五):数据集标注与制作

最近在做一些数据标注的工作&#xff0c;虽然标注数据比较枯燥&#xff0c;但这也是每个做算法的工程师升级打怪的必由之路。使用一些合适的工具往往可以事半功倍&#xff0c;效率UP。一&#xff1a;数据标注流程二&#xff1a;数据处理的一些小代码1&#xff1a;重命名当得到这…

mysql show profile详解_SQL 性能分析利器 show profile

本文首发个人公众号《andyqian》, 期待你的关注&#xff5e;前言在之前的文章中&#xff0c;我们提到过一些慢SQL优化的步骤。其中就包括&#xff1a;使用 explain 关键字来查看执行计划&#xff0c;是否命中索引。通过计算某列的区分度&#xff0c;来判断该列是否适合新建索引…

php判断给定的整数是否是2的幂_C++_C语言判断一个数是否是2的幂次方或4的幂次方,快速判断一个数是否是2的幂次 - phpStudy...

C语言判断一个数是否是2的幂次方或4的幂次方快速判断一个数是否是2的幂次方&#xff0c;若是&#xff0c;并判断出来是多少次方&#xff01;将2的幂次方写成二进制形式后&#xff0c;很容易就会发现有一个特点&#xff1a;二进制中只有一个1&#xff0c;并且1后面跟了n个0&…

python 包编译安装mysql_CentOS7编译安装MySQL8.0.23和Python3.1.9

卸载mariadbrpm -qa | grep mariadbmariadb-libs-5.5.64-1.el7.x86_64yum remove mariadb-libs.x86_64 -y安装高版本GCC&#xff0c;解决编译中会遇到的GCC 5.3 or newer is required (-dumpversion says 4.8.5)cd /optyum install centos-release-scl -yyum install devtoolse…

python3.0下载用什么浏览器_无法让Python下载网页源代码:“不支持浏览器版本”...

查看您列出的url&#xff0c;我执行了以下操作&#xff1a;使用wget下载了页面将urllib与ipython一起使用并下载了页面使用chrome&#xff0c;只保存了url所有3个都给了我相同的结果文件(相同的大小&#xff0c;相同的内容)。在这可能是因为我没有登录&#xff0c;但我确实看到…