【五子棋实战】第3章 算法包装成第三方接口

news2024/11/15 23:34:10

【五子棋实战】第3章 算法包装成第三方接口

  • 使用Flask开放接口
    • ## 定义接口输入
    • ## 开放接口、跨域配置、数据解析
  • 数据预处理
    • ## 数据检查与异常捕获
    • ## 预处理数据
    • ## 定义接口输出
  • 开启接口
  • 继续学习下一篇实战!

  我们在上一章实现了博弈树负值极大alpha-beta剪枝算法,即ai()函数,拿到了四个返回值:x、y坐标,搜索次数、是否赢了。

  现在我们需要把这个ai()函数再套两层壳:

  1、第一层是预处理的壳。对于接口传入的参数,我们需要预处理成为ai()函数需要的数据结构;还需要检查输入对不对,如果输入的棋盘不是正方形的,或者输入的棋盘值除了1、0、-1还有其他值等等等等,我们要加以限制。

  2、第二层是套python的Flask库,把我们的函数开放为接口。包括一些请求的跨域配置、request请求数据的处理都在这完成。


使用Flask开放接口

## 定义接口输入

  接口输入的原则是,参数尽量少,要能够有通用性,比如对棋盘的输入,采取如下的形式:

[
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,1,-1,0,0,0,0],
	[0,0,0,0,-1,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0],
]

  直接把二维棋盘转化为二维数组就行,这样方便大家自定义自己的前端页面。

  所以综上原则,我们的接口有四个参数:

  ratio:ai的攻击系数。
  depth:算法遍历的深度。
  length:棋盘边长长度。
  board:从表单中获取的变量,二维数组,表示棋盘状态,通过逗号分隔的字符串形式表示。通过使用split函数将字符串拆分为整数列表。

## 开放接口、跨域配置、数据解析

app = Flask(__name__)
CORS(app, supports_credentials=True)

@app.route('/api/next_step', methods=['POST'])
@cross_origin(supports_credentials=True)
def api():
    try:
        ratio = int(request.form.get('ratio'))
        depth = int(request.form.get('depth'))
        length = int(request.form.get('length'))
        board = [int(_) for _ in request.form.get('board').split(',')]
        board = np.array(board).reshape(-1, length)
        return next_step(board, length, depth, ratio )  # 返回接口响应

    except Exception as e:
        return {
            'code': 300,
            'msg': str(e)
        }

if __name__ == '__main__':
    app.run()

  上面的代码是一个基于Flask框架的API接口,创建了路由 /api/next_step,该接口接受POST请求,并处理包含 ratio、depth、length 和 board 参数的表单数据。在请求中,它首先从表单数据中获取这些参数的值,并将 board 转换为二维数组。然后,它调用 next_step 函数来处理请求,并将返回的结果作为接口的响应返回。如果在处理过程中发生异常,它会返回一个包含错误信息的字典。最后,通过运行应用程序来启动服务。

  如果不加跨域的话,我们在前端侧访问接口要加一些配置,比较麻烦。

  对于前端侧传过来的二维数组,它其实是转化成了字符串形式的,所以接收之后,我们要手动转化成二维数组。然后就可以去交给预处理去执行了。


数据预处理

## 数据检查与异常捕获

  对于接口传过来的值,我们关心这样几个问题:

  1、棋盘边长会不会太小了
  2、棋盘是否不是正方形的
  3、遍历的深度要控制在1,2,3,4以内,不然太大了,进程一下就阻塞了,要是部署在服务器上,可能一下服务器就瘫痪了
  4、棋盘值会不会有超出1、0、-1以外的值
  5、棋盘会不会满了

	# 统计白子数
    white_count = np.count_nonzero(board == 1)
    # 统计黑子数
    black_count = np.count_nonzero(board == -1)
    # 统计空子数
    empty_count = np.count_nonzero(board == 0)

    """输入检查"""
    # TODO 修改最低大小
    if length < 12:
        raise ValueError(f"棋盘边长最低为12.")
    if board.shape[1] != length:
        raise ValueError(f"输入棋盘不是正方形.")
    if depth not in [1,2,3,4]:
        raise ValueError(f"输入的遍历深度有误, 应该为1,2,3或4.")
    assert (white_count + black_count + empty_count) == board.size,\
        "输入的棋盘数据有误.只能为0,1,-1.其中1代表白棋,-1代表黑棋,0代表空棋."
    if empty_count == 0:
        raise ValueError(f"输入的棋盘已满, 无法下棋.")

  统计白子数:
  使用 np.count_nonzero() 函数统计棋盘中值为1的元素个数,并将结果赋值给变量 white_count

  统计黑子数:
  使用 np.count_nonzero() 函数统计棋盘中值为-1的元素个数,并将结果赋值给变量 black_count

  统计空子数:
  使用 np.count_nonzero() 函数统计棋盘中值为0的元素个数,并将结果赋值给变量 empty_count

  输入检查:
  - 检查棋盘边长是否小于12,如果是,则抛出 ValueError 异常,提示棋盘边长最低为12。
  - 检查输入的棋盘是否为正方形,如果不是,则抛出 ValueError 异常,提示输入棋盘不是正方形。
  - 检查遍历深度是否为1、2、3或4,如果不是,则抛出 ValueError 异常,提示输入的遍历深度有误,应为1、2、3或4。
  - 使用断言语句检查棋盘中的元素总数是否与棋盘大小相等,如果不相等,则抛出 AssertionError 异常,提示输入的棋盘数据有误,只能为0、1、-1,其中1代表白棋,-1代表黑棋,0代表空棋。
  - 检查棋盘中空子的个数是否为0,如果是,则抛出 ValueError 异常,提示输入的棋盘已满,无法下棋。

## 预处理数据

	# 当前玩家
    player = 'black' if black_count == white_count else 'white'
    # 当前步数
    step = black_count + white_count + 1

    # 开始计时
    start_time = time.time()
    # 电脑计算
    x, y, search_count, flag = ai(player, ratio, length, board, depth)
    # 结束计时
    end_time = time.time()

  根据当前的黑子和白子个数,确定当前的玩家。并计算回溯算法执行时间。

## 定义接口输出

  定义的输出如下:

return {
        'code': 200,
        'msg': '成功',
        'data': {
            'x': x,
            'y': y,
            'time': end_time - start_time,
            'step': step,
            'player': player,
            'length': length,
            'search_count': search_count,
            'flag': flag,
            'info': "【默认黑子先行】"
                    "【黑子存-1,白子存1,空子存0】"
                    "【x:横坐标,从0开始,length结束】"
                    "【y:纵坐标,从0开始,length结束】"
                    "【time:搜索时间】"
                    "【step:这是第几步棋】"
                    "【player:当前下棋的玩家'black'/'white'】"
                    "【length:棋盘边长,线的个数,即格子的个数+1】"
                    "【search_count:搜索次数】"
                    "【flag:是否赢了】"
                    "【info:参数介绍】"
        }
    }

  上述代码是一个返回结果的字典,包含以下键值对:

  - 'code':表示返回的状态码,这里设置为 200 表示成功。
  - 'msg':表示返回的消息,这里设置为 ‘成功’。
  - 'data':表示返回的数据,是一个包含多个键值对的字典。
   - 'x':表示横坐标。
   - 'y':表示纵坐标。
   - 'time':表示搜索时间,是结束时间减去开始时间的差值。
   - 'step':表示当前步数。
   - 'player':表示当前下棋的玩家,可以是 ‘black’ 或 ‘white’。
   - 'length':表示棋盘边长,即格子的个数加1。
   - 'search_count':表示搜索次数。
   - 'flag':表示是否赢了。
   - 'info':表示参数介绍的字符串,包含一些说明信息。

  这段代码用于构建一个包含返回结果的字典,并将其作为函数的返回值。返回结果中包含了搜索结果的相关信息。


开启接口

  此时去运行编写的接口的py文件:

在这里插入图片描述
  如上图,表示开启成功,然后去写post请求调用就可以了。


继续学习下一篇实战!

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

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

相关文章

最适合入门的100个深度学习实战项目

&#x1f6a8;注意&#x1f6a8;&#xff1a;最近经粉丝反馈&#xff0c;发现有些订阅者将此专栏内容进行二次售卖&#xff0c;特在此声明&#xff0c;本专栏内容仅供学习&#xff0c;不得以任何方式进行售卖&#xff0c;未经作者许可不得对本专栏内容行使发表权、署名权、修改…

Linux系统安装nginx+入门笔记

安装过程 1.加载wget命令 yum install wget 2.拉取安装包 wget https://nginx.org/download/nginx-1.16.1.tar.gz 3.解压安装包 tar -zxvf nginx-1.16.1.tar.gz 4.执行这个命令自动配置一下 5.编译安装 make make install 6.查看nginx安装的位置 whereis nginx 7.…

基于Python的反爬虫技术的研究设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

链表刷题(4~8)

目录 反转链表 返回中间节点 倒数k个节点 链表分割 判断回文 反转链表 单链表刷题时我们遇到过一个反转链表&#xff0c;那时我们采用的是头插的方式达到反转的效果&#xff0c;那能不能把指针反过来呢&#xff1f;答案是可以的。 这里用三个指针是为了记录后面节点的数据&…

SpringBoot+Vue 的智慧养老系统(Java 项目,附源码,数据库)

作者&#xff1a;程序员徐师兄 个人简介&#xff1a;7 年大厂程序员经历&#xff0c;擅长Java、微信小程序、Python、Android等&#xff0c;大家有这一块的问题可以一起交流&#xff01; 各类成品java毕设 。javaweb&#xff0c;ssh&#xff0c;ssm&#xff0c;springboot等等项…

Jira 8.4.1在Windows环境下的安装和配置

一. Jira安装的环境准备 1.JDK1.8的下载和安装 Jira的运行是依赖java环境的&#xff0c;也就是说需要安装JDK并且要是1.8以上版本。(网上搜一下教程) 2.MySQL数据库的下载和安装(网上搜一下教程) 数据库版本&#xff1a;MySQL5.6&#xff0c;版本太高有时会出现连接不到的…

从双目标定到立体匹配:pyton实践指南

文章目录 前言标定立体匹配文章已经同步更新在3D视觉工坊啦&#xff0c;原文链接如下&#xff1a; 前言 立体匹配是计算机视觉中的一个重要领域&#xff0c;旨在将从不同角度拍摄的图像匹配起来&#xff0c;以创建类似人类视觉的3D效果。实现立体匹配的过程需要涉及许多步骤&a…

华为OD机试真题B卷 Java 实现【统计每个月兔子的总数】,附详细解题思路

一、题目描述 有一种兔子&#xff0c;从出生后第3个月起每个月都生一只兔子&#xff0c;小兔子长到第三个月后每个月又生一只兔子。 例如&#xff1a;假设一只兔子第3个月出生&#xff0c;那么它第5个月开始会每个月生一只兔子。 一月的时候有一只兔子&#xff0c;假如兔子都…

dvwa靶场通关(七)

第七关&#xff1a;SQL Injection&#xff08;sql注入&#xff09; low 我们输入 1,出现报错信息&#xff0c;根据报错信息可知&#xff0c;查询语句是单引号闭合的字符型 接着判断字段数 1 order by 3# 报错 1 order by 2# 正常 所以字段数就是2 利用联合查询爆出数据库名…

农村小子背井离乡北漂的这些年

人生虽不尽人意、生活也并不完美、可生活依旧很美 1. 写在前面 由于工作变动及其他种种原因吧&#xff0c;很长的一段时间内没有再去写文章。始于2019年初夏&#xff0c;止于2020年初冬&#xff0c;再次落笔于2023年的夏季。恰好今天是端午节&#xff0c;祝大家端午安康 白驹过…

springboot第28集:springboot一些概念

DataScopeAspect 数据过滤处理 此切面在执行带有ControllerDataScope注解的方法之前进行数据权限过滤。首先获取当前登录用户&#xff0c;然后判断当前用户是否为超级管理员。如果不是超级管理员&#xff0c;则获取权限字符&#xff0c;默认使用上下文中的权限字符。接下来&am…

【计算机组成原理】2、二进制和十六进制转换,进制相减、内存地址偏移计算与容量计算

文章目录 一、进制转换1.1 二进制转十六进制1.2 十六进制转二进制 二、进制相减2.1 十六进制 三、内存地址偏移计算3.1 根据首末地址&#xff0c;求存储容量3.2 根据末地址 和 存储容量&#xff0c;求首地址 一、进制转换 1.1 二进制转十六进制 因 2 4 16 2^416 2416&#…

leetcode300. 最长递增子序列(动态规划-java)

最长递增子序列 leetcode300. 最长递增子序列题目描述解题思路代码演示: 二分法改进(N * logN)动态规划专题 leetcode300. 最长递增子序列 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/longest-increasing-subsequenc…

C++标准输出

C将输入和输出看作字节流&#xff0c;输入时&#xff0c;程序从输入流中抽取字节&#xff0c;输出时&#xff0c;程序将自己插入到输出流中&#xff0c;流充当了程序与流源或流目标之间的桥梁&#xff0c;也就是说C通过流与硬件&#xff0c;文件相关联&#xff0c;流赋予了C程序…

[数字图像处理]第六章 彩色图像处理

第六章 彩色图像处理 引言 ​ 彩色图像处理可分为两个主要领域&#xff1a;全彩色处理和伪彩色处理。在第一类中&#xff0c; 通常要求图像用全彩色传感器获取&#xff0c;如彩色电视摄像机或彩色扫描仪。在第二类中&#xff0c;问题是对一种特定的单色灰度或灰度范围赋予一种…

设计模式之装饰者模式笔记

设计模式之装饰者模式笔记 说明Decorator(装饰)目录装饰者模式示例类图快餐类炒饭类炒面类装饰者类鸡蛋类培根类测试类 说明 记录下学习设计模式-装饰者模式的写法。JDK使用版本为1.8版本。 Decorator(装饰) 意图:动态地给一个对象添加一些额外的职责。 结构: 其中&#x…

【Neo4j教程之CQL命令基本使用】

&#x1f680; Neo4j &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;C…

Python基础篇(二):入门基础必备知识

Python基础篇(一)&#xff1a;如何使用PyCharm创建第一个Python项目(包含tools) 入门基础必备知识 1. 标识符2. 关键字2.1 关键字字典 3. 引号3.1 表示字符串3.2 在字符串中使用引号3.3 创建多行字符串3.4 在注释中使用引号 4. 编码5. 输入输出5.1 输入示例5.2 输出示例5.3 格…

王道计算机网络学习笔记(3)——数据链路层

前言 文章中的内容来自B站王道考研计算机网络课程&#xff0c;想要完整学习的可以到B站官方看完整版。 三&#xff1a;数据链路层 3.1&#xff1a;数据链路层功能概述 结点&#xff1a;主机、路由器 链路&#xff1a;网络中两个结点之间的物理通道&#xff0c;链路的传输介…

PolarFormer:Multi-camera 3D Object Detection with Polar Transformer——论文笔记

参考代码&#xff1a;PolarFormer 1. 概述 介绍&#xff1a;在仓库RoboBEV中总结了现有的一些bev感知算法在不同输入情况下的鲁棒性&#xff0c;在这些感知算法中PolarFormer拥有较为不错的泛化性能。这个算法的思想是将之前由直角坐标系栅格化构建bev网格&#xff0c;转换到由…