当前位置: 首页 > news >正文

python-五子棋-AI

降智警告:本人为编程新手,遵守面向CSDN编程原则,代码架构具有个人特色,仅供参考

 

前言:课程期末项目写了个黑白棋,所以放假写个五子棋,作为今年的总结

(该五子棋仅涉及最基础的规则,轮留下,连五赢)

 

一.最终效果

功能:规定玩家先下,结束时展示结果。restart按钮会变色,鼠标在按钮上时颜色变深。按下restart按钮可以重新开局。

 

二.AI实现

1.思路

①棋局

使用二维列表表示棋盘,0表示空位,1表示玩家棋子(黑),2表示电脑棋子(白)

 

②局面评估

为了减少计算量,我将电脑当前的可下位置限制为,非空位置的八邻域中的空位。然后对每一个可下位置进行评估。

我们需要为每一个当前可下位置进行评估得到一个分数,然后取分数最高的位置作为本次的下子位置。

在评估时,我们需要考虑该位置对于本方的重要性,同时也要考虑该位置对敌方的重要性,所以我们需要将两个评估所得分数相加作为该位置的最终分数。

 

③评估方法

首先对于每一个需要评估的位置,先将电脑棋子放到该位置,然后分别取该位置的横,竖,左斜,右斜四个方向上的线上的所有位置作为四条棋线,对每个位置的四条棋线进行评估。然后反转棋盘,将电脑的棋子换为玩家棋子,玩家棋子换为电脑棋子,再对该位置进行评估。两个评估分数相加即为该位置的最终分数。

五子棋中有许多棋型,如连五,活四,冲四,活三等,为每一个棋型设置一个分数,每个位置的四条棋线中存在的所有棋型的分数相加,得到该位置的一方评估分数。

参考资料:棋型参考, 棋型评分参考

 

2.代码实现

这里仅给出根据当前棋局给出最佳下子位置的实现,项目完整代码在我的github

①获取当前棋局所有可下位置(限制条件下) 

def get_charge_pos(board) :
    #八邻域
    way = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
    ret = []

    for i in range(15) :
        for j in range(15) :
            #当前位置不为空位
            if board[i][j] != 0 :
                #搜索八邻域
                for w in way :
                    pos = (i + w[0], j + w[1])
                    if pos[0] not in range(15) or pos[1] not in range(15) :
                        continue
                    if (board[pos[0]][pos[1]] == 0) and (pos not in ret) :
                        ret.append(pos)
    return ret

②获取当前位置棋线

(将一条棋线上的位置整理为一个列表,将列表转化为字符串并进行处理,最终只剩下包含0,1,2三个数字的字符串,返回包含四条棋线代表的字符串的列表)

def get_score(pos, board) :
    #获取棋盘副本,在当前位置放入棋子
    ori = copy.deepcopy(board)
    ori[pos[0]][pos[1]] = 2
    #横,竖
    h = str(ori[pos[0]])[1:-1].replace(',', '').replace(' ', '')
    s = str([ori[i][pos[1]] for i in range(15)])[1:-1].replace(',', '').replace(' ', '')
    
    #左斜
    lx = str([ori[i][i - pos[0] + pos[1]] for i in range(15) if (i - pos[0] + pos[1]) in range(15)])[1:-1].replace(',', '').replace(' ', '')
    
    #右斜
    rx = str([ori[i][pos[0] + pos[1] - i] for i in range(15) if (pos[0] + pos[1] - i) in range(15)])[1:-1].replace(',', '').replace(' ', '')
    
    return get_line_score([h, s, lx, rx])

 

③棋线评分

(由于棋型过多,判断比较繁琐,截取部分代码作为示例)

注意:由于棋线上对于棋型是单向查找的,所以对于不对称的棋型要反转棋型再次查找

④主函数

实现对每个可下位置进行两次评分得到最终分数后,返回分数最高的位置

def get_pos(board) :
    pos = get_charge_pos(board)

    get = (-1, -1)
    score = -float("inf")

    for p in pos :
        #反转棋盘
        o_board = opp_board(board)
        s = get_score(p, board) + get_score(p, o_board)
        if s > score :
            get = p
            score = s
    return get

 

三.总结

这个项目的界面实现就不放代码了,有兴趣的可以看一下(项目代码)

使用pygame来构造界面,调用了棋盘,黑白棋子,restart按钮共五张图片,如果修改图片的话需要更改显示的具体参数

因为界面用到好几张图,如果转化为py文件一起打包的话,最后的exe会很大,所以就放在一个文件夹里直接调用了,顺便把程序框图标的ico也放进去了

最终的效果还是不错的,AI的胜率挺高的,也用到了今年所学的东西,也是今年的最后一个项目了。

相关文章:

  • Python-从视频到gif(imageio,moviepy,ffmpeg)
  • python-二分法插入排序(Binary Insert Sort)
  • 本地仓库关联Github仓库
  • macos可以升级到指定版本吗_iPhone 越狱后还可以保资料升级系统吗?
  • 2 shell 锂基脂_内蒙古锂基脂润滑油供应商
  • python编程中的不等于符号_python不等于符号怎么写
  • nacos 负载策略_Ribbon负载均衡
  • python文件传输模块_Python爱好者 socket模块传输文件 -
  • 红曲面怎么做_曲面屏是华为手机一大败笔?确实缺点很多,但华为为何钟爱呢?...
  • 高德地图 python面试_【高德地图面试|面试题】-看准网
  • tablayout 滚动模式_scrollview+tablayout实现联动
  • cboard企业版源码_数据可视化BI平台——CBoard的部署与使用(笔记整理)
  • 生活中的算法的实际举例_生活中的算法
  • pyecharts 绘制三维散点图_pyecharts
  • toolbar文本在最右侧_Toolbar中Menu的背景颜色、位置、同时显示文字等设置(亲测)...
  • 「译」Node.js Streams 基础
  • 2019.2.20 c++ 知识梳理
  • Android Volley源码解析
  • docker容器内的网络抓包
  • express + mock 让前后台并行开发
  • github指令
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java的Interrupt与线程中断
  • js写一个简单的选项卡
  • Linux快速复制或删除大量小文件
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • node入门
  • php中curl和soap方式请求服务超时问题
  • Redis 懒删除(lazy free)简史
  • vue脚手架vue-cli
  • 从零开始在ubuntu上搭建node开发环境
  • 批量截取pdf文件
  • 前端技术周刊 2019-02-11 Serverless
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • Spring第一个helloWorld
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • #define与typedef区别
  • #Linux(权限管理)
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #pragma预处理命令
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Java数据结构)ArrayList
  • (附源码)计算机毕业设计高校学生选课系统
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (篇九)MySQL常用内置函数
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)【Hibernate总结系列】使用举例
  • (转)甲方乙方——赵民谈找工作