当前位置: 首页 > 编程日记 > 正文

Python实现五子棋人机对战 | CSDN博文精选

640?wx_fmt=jpeg

作者 | 吴小鹏

来源 | 数据札记倌(ID:Data_Groom)


五子棋是常见的一款小游戏,五子棋问题是人工智能中的一个经典问题。这篇文章主要介绍了Python版本五子棋的实现代码,大家可以做个参考,与我的傻儿子对弈一下。


简 述


虽然计算机已经几乎破解了五子棋的取胜秘籍,甚至给出了取胜的具体方案,然而,对人来说,五子棋还是非常有玩头的。


我们往往有五子棋的技巧性和全局观远远比不上象棋,围棋之类的感觉:

这个真不一定,先说技巧性:五子棋、象棋、围棋的最初级技巧都是死活题。围棋那高难度的生死题我就不多说了。而象棋如果只是说铁门栓天地炮等等杀法,其实还是很好掌握的;如果加上各种基础的残局估计差不多。五子棋的话,坂田三手胜与天狗道场,或者是贴吧里边各种变态杀法题,也不敢说简单。


扯远啦~,这篇文章主要是要用python来实现五子棋的人机对战,可以趣味性地玩一下,远没有到不可战胜的程度。


问题描述


人机对弈算法属于策略型人工智能算法,本游戏中设置了人机对弈的游戏模式,整个程序我们有几个大的问题需要解决:


1)、计算机需要判断胜负

2)、计算机落子的逻辑

第一个问题的核心思想是要设置对局结束的判断逻辑,在这部分我们只需要写出五子相连的判断条件;

第二个问题的核心思想是要比较不同落子的优劣势,需要评估每一步的胜算。

其算法如下:


  • 写出获胜逻辑或者设置所有获胜组合


640?wx_fmt=png


获胜逻辑:一个二维坐标上,判断上下、左右、两个45度直线,是否有五个相同的直连棋子。


  • 评估棋格获胜分数


在计算机下棋之前,会计算空白棋格上的获胜分数,根据分数高低获取最佳位置。计算机会将棋子下在获胜分数最高的地方。

当已放置4颗棋子时,必须在第五个空棋格上设置绝对高的分值。
当获胜组合上有部分位置已被对手的棋格占据而无法连成五子时,获胜组合上空棋格的获胜分数会直接设置为0。
当有两组及其以上的获胜组合位置交叉时,对该位置的分数进行叠加,形成分数比周围位置明显高。


  • 计算机的攻击与防守


计算机计算获胜分值越高的棋格,就能确定能让自己的棋子最有可能达成联机的位置,也就是最佳进攻位置,而一旦计算机能确定自己的最高分值的位置,计算机就具备了进攻能力。同理,计算机能计算出玩家的最大分值位置,并抢先玩家获得该位置,这样计算机就具有了防御的能力。


代码实现


  • 棋盘


棋盘是我们整个游戏的落子范围,需要提前定义好大小:

# 画棋盘
def GobangWin():
    gw 
= GraphWin('AI Gobang', GRID_WIDTH*COLUMN, GRID_WIDTH*ROW)
    gw.setBackground('gray')
    for j in range(0, GRID_WIDTH*COLUMN+1, GRID_WIDTH):
        l 
= Line(Point(j, 0), Point(j, GRID_WIDTH*COLUMN))
        l.draw(gw)
    for i in range(0, GRID_WIDTH*ROW+1, GRID_WIDTH):
        l 
= Line(Point(0, i), Point(GRID_WIDTH*ROW, i))
        l.draw(gw)
    return gw


  • 棋子


在棋盘上画一个棋子:

col =(255, 0, 0)
surf.fill((255, 255, 255))
pygame.gfxdraw.aacircle(surf, x, y, 30, col)
pygame.gfxdraw.filled_circle(surf, x, y, 30, col)


640?wx_fmt=jpeg

  • 落子


通过鼠标点击的位置记录落子,这里核心是要实现的点击鼠标获取坐标,可以使用Graphics。

from graphics import * 
#设置画布窗口名和尺寸 
win = GraphWin('hehe', 666, 666) 
#关闭画布窗口 
win.getMouse() 
win.close()   
#画点 
pt = Point(100, 100) 
pt.draw(win) 
#画圆 
cir = Circle(Point(200, 200), 75) 
cir.draw(win) 
cir.setOutline('red') #外围轮廓颜色 
cir.setFill('yellow') #填充颜色  
#画线 
line = Line(Point(650, 100), Point(250, 100)) 
line.draw(win)  
#画矩形 
rect = Rectangle(Point(300, 300), Point(400, 400)) 
rect.setFill('red') #填充颜色 
rect.draw(win) 
#画椭圆 
oval = Oval(Point(450, 450), Point(600, 600)) 
oval.setFill('red') #填充颜色 
oval.draw(win)   
#显示文字 
message = Text(Point(win.getWidth()/2, 20), 'Click anywhere to quit.') 
message.draw(win)


  • 判断输赢


一个二维坐标上,判断上下、左右、两个45度直线,是否有五个相同的直连棋子,只要五子相连则游戏结束。或者遍历每一种获胜情况都可以做出判断:

# 四种情况
def is_GameOver(list_now):
    for c in range(COLUMN):
        for r in range(ROW):
            if r < ROW - 4 and (r, c) in list_now and (r+1, c) in list_now and (r+2, c) in list_now and (r+3, c) in list_now and (r+4, c) in list_now:
                return True
            elif c < COLUMN - 4 and (r, c) in list_now and (r, c+1in list_now and (r, c+2in list_now and (r, c+3in list_now and (r, c+4in list_now:
                return True
            elif r < ROW - 4 and c < COLUMN - 4 and (r, c) in list_now and (r+1, c+1in list_now and (r+2, c+2in list_now and (r+3, c+3in list_now and (r+4, c+4in list_now:
                return True
            elif r > 3 and c < COLUMN - 4 and (r, c) in list_now and (r-1, c+1in list_now and (r-2, c+2in list_now and (r-3, c+3in list_now and (r-4, c+4in list_now:
                return True
    return False


演示操作


下面直接看一下实际操作结果吧~


这里执行起来还是挺慢的,在执行逻辑的判断方面还有很多可以优化的地方。



呼~,傻儿子玩得还不错,还好赢了~


代码下载地址:

https://pan.baidu.com/s/16aSLqCKXNX1XVAt_cTcV4Q

密码:u7ao


另外这个不是深度学习的实现办法,如果想尝试深度学习方法戳这里:


AlphaZero实战:从零学下五子棋(附代码)

https://github.com/junxiaosong/AlphaZero_Gomoku


如果你喜欢的话点个再看,让更多人看到~


扫码查看原文
▼▼▼

640?wx_fmt=jpeg


(*本文为AI科技大本营转载文章,转载联系作者



精彩推荐




2019 中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读,深入解析热门技术在行业中的实践落地。6.6 折票限时特惠(立减1400元),学生票仅 599 元!


640?wx_fmt=png


推荐阅读

相关文章:

HTTPS协议简介

HTTPS(HyperText Transfer Protocol Secure, 超文本传输安全协议)&#xff1a;是一种透过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信&#xff0c;但利用SSL/TLS来加密数据包。HTTPS开发的主要目的&#xff0c;是提供对网站服务器的身份认证&#xff0c;保护交换…

闭包回调的写法

初学swift&#xff0c;封装了NSURLSession的get请求,在请求成功闭包回调的时候程序崩溃了 然后在图中1&#xff0c;2&#xff0c;3位置加上惊叹号“&#xff01;”&#xff0c;再把4&#xff0c;5&#xff0c;6的惊叹号去掉就闭包回调成功了

错误 1 “System.Data.DataRow.DataRow(System.Data.DataRowBuilder)”不可访问,因为它受保护级别限制...

new DataRow 的方式&#xff1a; DataTable pDataTable new DataTable();DataRow pRow new DataRow(); 正确的方式&#xff1a; DataRow pRowpDataTable.newRow(); 转载于:https://www.cnblogs.com/wangzianan/p/4034892.html

iOS 支付 [支付宝、银联、微信]

这是开头语 前不久做了一个项目&#xff0c;涉及到支付宝和银联支付&#xff0c;支付宝和银联都是业界的老大哥&#xff0c;文档、SDK都是很屌&#xff0c;屌的找不到&#xff0c;屌的看不懂&#xff0c;屌到没朋友&#xff08;吐槽而已&#xff09;&#xff0c;本文将涉及到的…

base64开源库介绍及使用

网上有一些开源的base64编解码库的实现&#xff0c;下面介绍几个&#xff1a; cppcodec是一个仅包括头文件的C11库&#xff0c;用于编解码RFC 4648中指定的base64, base64url, base32, base32hex等&#xff0c;它的License为MIT&#xff0c;源码在https://github.com/tplgy/cp…

情感识别难?图神经网络创新方法大幅提高性能

作者 | Kevin Shen译者 | Monanfei出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】最近&#xff0c;深度学习在自然语言处理领域&#xff08;NLP&#xff09;取得了很大的进步。随着诸如 Attention 和 Transformers 之类新发明的出现&#xff0c;BERT 和 XL…

Java的学习之路(1)

学过C语言之后&#xff0c;尝试接触Java. 借博文来记录自己学习的过程. Test01:利用循环&#xff0c;输出整数1-999之和 1 //2 //循环计算1到999的整数之和并输出3 //4 package demo;5 6 public class Main {7 8 public static void main(String[] args) {9 int su…

Swift - 使用addSubview()方法将StoryBoard中的视图加载进来

使用 Storyboard 我们可以很方便地搭建好各种复杂的页面&#xff0c;同时通过 segue 连接可以轻松实现页面的跳转。但除了segue&#xff0c;我们还可以使用纯代码的方式实现Storyboard界面的跳转。 比如&#xff1a;使用 presentViewController() 方法将当前页面视图切换成新视…

这项技术厉害了!让旅行者 2 号从星际空间发首批数据!

立即购票&#xff1a;https://dwz.cn/z1jHouwE物联网作为信息系统向物理世界的延伸&#xff0c;极大地拓展了人类认知和控制物理世界的能力&#xff0c;被称为继计算机和互联网之后的世界信息产业的第三次浪潮&#xff0c;正在深刻地改变着人类的生存环境和生活方式。据最新报道…

Ubuntu 14.04上使用CMake编译MXNet源码操作步骤(Python)

MXNet源码版本号为1.3.0&#xff0c;其它依赖库的版本号可参考&#xff1a;https://blog.csdn.net/fengbingchun/article/details/84997490 。 为了通过编译源码支持python接口&#xff0c;这里在 https://blog.csdn.net/fengbingchun/article/details/85162936 的基础上对bui…

近段时间学习html和CSS的一些细碎总结

1、边框圆角属性&#xff1a;border-radius&#xff0c;取值能够是 百分比 / 自己定义长度&#xff0c;不能够取负值。假设是圆&#xff0c;将高度和宽度设置相等&#xff0c;而且将border-radius设置为100% 2、IE6&#xff0c;IE7&#xff0c;IE8&#xff0c;opera&#xff0c…

Swift:闭包

[objc] view plaincopy print?/* 闭包&#xff08;Closures&#xff09; * 闭包是自包含的功能代码块&#xff0c;可以在代码中使用或者用来作为参数传值。 * 在Swift中的闭包与C、OC中的blocks和其它编程语言&#xff08;如Python&#xff09;中的lambdas类似。 * 闭包…

Ubuntu下使用CMake编译OpenSSL源码操作步骤(C语言)

OpenSSL的版本为1.0.1g&#xff0c;在ubuntu下通过CMake仅编译c代码不包括汇编代码&#xff0c;脚本内容如下&#xff1a; build.sh内容&#xff1a; #! /bin/bashreal_path$(realpath $0) dir_namedirname "${real_path}" echo "real_path: ${real_path}, di…

从词袋到Transfomer,NLP十年突破史

作者 | Zelros AI译者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】通过 Kaggle 竞赛视角&#xff0c;观察 NLP 十年发展简史。根据上下文&#xff08;这里指句子的最后一个词&#xff09;&#xff0c;“它”可以指“动物”或“街道”。图源 | Goog…

《千只鹤》--[日]川端康成

《千只鹤》&#xff0c;作者是川端康成 故事梗概&#xff1a; 三谷菊治的父亲是个著名的茶道师匠&#xff0c;他生前与一位叫栗本近子的女人有染&#xff0c;后来又 钟情于太田夫人&#xff0c;而且由于后者而疏远了前者&#xff0c;但前者仍出入于三谷家。在三谷先生去 世四年…

所有接口添加plist文件的写法 swift

第一步 建立plist文件 interface JMTConfigUtils : NSObject /** * 获取配置文件中友盟key * * return NSString */ - (NSString *)umengKey; /** * 微信AppId * * return NSString */ - (NSString *)wxAppId; /** * 微信appSecret * * return NSString */ - (NSString…

提高C++性能的编程技术笔记:标准模板库+测试代码

标准模板库(Standard Template Library, STL)是容器和通用算法的强效组合。 渐近复杂度&#xff1a;算法的渐近复杂度是对算法性能的近似估计。它是算法集到特定性能标准集的映射。如果需要对包含N个整数的向量的所有元素求和&#xff0c;那么每个整数必须且仅需检查一次&…

「创式纪」人工智能应用创新大赛启动,首次结合商业计划和机器学习

谈到人工智能&#xff0c;技术和应用场景成为了大家广泛关注的话题。技术的演进&#xff0c;是推动人工智能发展的核心&#xff0c;而广泛的场景应用&#xff0c;则是人工智能真正价值所在。现阶段&#xff0c;精准营销、信贷风控、人脸比对等为人熟知的AI&#xff0c;已经经过…

linux chattr命令

chattr 设置linux文件的属性 (参照man手册进行翻译&#xff0c;常用的属性都翻译过来&#xff0c;个人觉得很少用到的属性就没有翻译&#xff09; 用法&#xff1a;chattr [ -RVf ] -[acdeijstuADST] files选项&#xff1a;-R 对目录进行递归处理-V 显示详细的输出-F 忽略…

swift 中高德地图随时读取坐标地点的写法

自己写的方法 不比比 自己能看懂就行 只用作自己学习swift的总结 import UIKit typealias block (String,String) ->() class MoveCarViewController: UIViewController,MAMapViewDelegate,AMapLocationManagerDelegate,AMapSearchDelegate,UITextFieldDelegate,UIAler…

万字干货 | Python后台开发的高并发场景优化解决方案

嘉宾 | 黄思涵 来源 | AI科技大本营在线公开课互联网发展到今天&#xff0c;规模变得越来越大&#xff0c;也对所有的后端服务提出了更高的要求。在平时的工作中&#xff0c;我们或多或少都遇到过服务器压力过大问题。针对该问题&#xff0c;本次公开课邀请到了金山办公AI平台研…

提高C++性能的编程技术笔记:引用计数+测试代码

引用计数(reference counting)&#xff1a;基本思想是将销毁对象的职责从客户端代码转移到对象本身。对象跟踪记录自身当前被引用的数目&#xff0c;在引用计数达到零时自行销毁。换句话说&#xff0c;对象不再被使用时自行销毁。 引用计数和执行速度之间的关系是与上下文紧密…

如何提升 CSS 选择器的性能?

CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间&#xff0c;所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器。而在这之前我们需要了解CSS选择器匹配的机制&#xff0c; 如子选择器规则&#xff1a; #header > a {font-weight:blod;} 我…

百度AI攻坚战:PaddlePaddle中国突围

作者 | 阿司匹林出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;2013年&#xff0c;百度开始研发深度学习框架PaddlePaddle&#xff0c;搜索、凤巢CTR预估上线DNN模型。2016年&#xff0c;在百度世界大会上&#xff0c;百度宣布PaddlePaddle开源&#xff…

提高C++性能的编程技术笔记:编码优化+测试代码

缓存&#xff1a;在现代处理器中&#xff0c;缓存经常与处理器中的数据缓存和指令缓存联系在一起。缓存主要用来存储使用频繁而且代价高昂的计算结果&#xff0c;这样就可以避免对这些结果的重复计算。如&#xff0c;循环内对常量表达式求值是一种常见的低性能问题。 预先计算…

Swift 中使用 SQLite——打开数据库

关于Swift中使用SQLite&#xff0c;接下来可能会分别从打开、增、删、改、查&#xff0c;几个方面来介绍SQLite的具体使用&#xff0c;这一篇重点介绍一下如何打开。 定义全局数据库访问句柄 /// 全局数据库访问句柄 private var db: COpaquePointer nil实现打开数据库函数 …

MVC中获取模型属性的Range和StringLength验证特性设置

MVC中的客户端及服务端模型验证信息都以ModelMetadata类型作为承载&#xff0c;在获得属性的ModelMetadata之后&#xff08;还不知道怎么获取ModelMetadata的童鞋请自行恶补&#xff09;&#xff0c;我们可以轻松得到一些我们在模型中定义的特性&#xff0c;比如显示名称、是否…

以安装PyTorch为例说明Anaconda在Windows/Linux上的使用

在Windows10上配置完MXNet 1.3.0后&#xff0c;再配置PyTorch 1.0时&#xff0c;发现两者需要依赖的NumPy版本不一致&#xff0c;之前是通过pip安装NumPy&#xff0c;根据pip的版本不同&#xff0c;会安装不同版本的NumPy&#xff0c;使用起来很不方便&#xff0c;而且MXNet和P…

常用 SQL介绍

创建表 /*创建数据表CREATE TABLE 表名 (字段名 类型(INTEGER, REAL, TEXT, BLOB)NOT NULL 不允许为空PRIMARY KEY 主键AUTOINCREMENT 自增长,字段名2 类型,...)注意&#xff1a;在开发中&#xff0c;如果是从 Navicat 粘贴的 SQL&#xff0c;需要自己添加一个指令IF NO…

AttoNets,一种新型的更快、更高效边缘计算神经网络

作者 | Alexander Wong, Zhong Qiu Lin, and Brendan Chwyl 译者 | Rachel 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;尽管机器学习已经在很多复杂的任务中取得了进展&#xff0c;但现有模型仍然面临许多边缘计算实践的困难&#xff0c;这些边缘计算场景包括移…