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

【五子棋实战】第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请求调用就可以了。


继续学习下一篇实战!

  【五子棋实战】第4章 部署五子棋计算接口到Window、Linux上

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Web服务器群集:部署LNMP平台

目录 一、理论 1.LNMP平台 2.Nginx服务基础 3.Nginx访问控制 4.Nginx虚拟主机 5.PHP 二、实验 1.LNMP架构DISCUZ论坛应用 三、问题 1.没有规则可以创建“default”需要的目标“build”。 2.nginx重启报错 3.yum安装提示报错 4.配置文件报错 5.PHP页面无法打开 四…

菲涅尔圆孔衍射matlab完整程序分享

根据惠更斯 &#xff0d; 菲涅耳原理&#xff0c;光的衍射是光束内部的次波之间的相干叠加&#xff0c;衍射光波场的光振动符合菲涅耳积分公式。但直接运用菲涅耳积分公式计算衍射光场是很困难的。对于夫琅和费衍射(远场衍射)&#xff0c;在光源和接收屏距离衍射屏均为无穷远的…

【C++】内存管理、new和delete操作类型、operator new和operator delete函数、new和delete的实现原理

文章目录 1.C/C内存管理2.C语言的内存管理方式3.C内存管理方式3.1 new和delete操作内置类型3.2 new和delete操作自定义类型 4.operator new与operator delete函数5.new和delete的实现原理5.1内置类型5.2 自定义类型 1.C/C内存管理 在C/C中&#xff0c;内存管理是程序员负责管理…

TCP 学习笔记

Win R 打开控制台输入CMD 打开小黑窗&#xff0c; 输入ipconfig 查询本机地址 “外网IP是全世界唯一的IP地址,仅分配给一个网络设备。而内网IP是由路由器分配给每一部内部使用的IP地址,而内网的所有用户都是通过同一个外网IP地址进行上网的,而内网的IP地址每个人的都不一样…

SQL 基础语句

SQL 基础语句 DDL Data Definition Language 数据定义语言创建 create删除 drop修改 alter清空 truncate show tables ; --查看所有表&#xff1a; drop database db1; --删除数据库 create database db1 default character set utf8; --创建数据库 use databas…

十大基础算法

一、选择排序 过程简单描述&#xff1a; 首先&#xff0c;找到数组中最小的那个元素&#xff0c;其次&#xff0c;将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。其次&#xff0c;在剩下的元素中找到最小的元素&#xff0c;将它与数组的第二…

C++【STL】之priority_queue学习

优先级队列 优先级队列priority_queue也是STL库中容器适配器的一种&#xff0c;常用于进行数据优先级的处理&#xff0c;说到这儿是不是发现有些熟悉&#xff0c;没错它和我们之前讲解的堆本质上就是一个东西&#xff0c;底层都是数组存储的完全二叉树&#xff0c;它在STL库中…

设计模式(二十二):行为型之备忘录模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

华为OD机试真题 JavaScript 实现【最短木板长度】【2022Q4 100分】,附详细解题思路

一、题目描述 小明有 n 块木板&#xff0c;第 i ( 1 ≤ i ≤ n ) 块木板长度为 ai。 小明买了一块长度为 m 的木料&#xff0c;这块木料可以切割成任意块&#xff0c;拼接到已有的木板上&#xff0c;用来加长木板。 小明想让最短的木板尽量长。 请问小明加长木板后&#xff0c…

Android12之执行adb disable-verity后android无法启动(一百五十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

前沿应用丨大规模无人机集群与“虚实结合”半实物仿真系统

一、应用背景 无人机集群在军事、安全、救援、航空监测、物流配送等领域具有广泛的应用前景。它可以提高任务执行的效率、灵活性和安全性&#xff0c;同时降低人力资源的需求和风险&#xff0c;无人机集群研究涉及多个学科领域&#xff0c;如机器人学、控制理论、通信技术和人工…

Verilog | 基4 booth乘法器

上接乘法器介绍 原理 跟基2的算法一样&#xff0c;假设A和B是乘数和被乘数&#xff0c;且有&#xff1a; A ( a 2 n 1 a 2 n ) a 2 n − 1 a 2 n − 2 … a 1 a 0 ( a − 1 ) B b 2 n − 1 b 2 n − 2 … b 1 b 0 \begin{align}A&(a_{2n1}a_{2n})a_{2n−1}a_{2n−2}……

【ARIMA-LSTM】合差分自回归移动平均方法-长短期记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

基于Nginx1.22+PHP8+MySQL8安装Discuz! X3.5

基于Nginx1.22PHP8MySQL8安装Discuz! X3.5 1. 安装PHP82. 安装MySQL83. 配置Nginx1.224. 安装Discuz! X3.5 1. 安装PHP8 更新系统&#xff1a; yum update安装EPEL存储库&#xff1a; yum install epel-release安装Remi存储库&#xff08;提供了最新的 PHP 版本&#xff09;&…

阿里云主机详解:ECS/轻量/虚拟主机/GPU/裸金属/云电脑详解

阿里云云主机分为云虚拟主机、云服务器ECS、轻量应用服务器、GPU云服务器、弹性裸金属服务器、专有宿主机、FPGA云服务器、高性能计算E-HPC、无影云电脑等&#xff0c;阿里云百科来详细说下阿里云云主机详解&#xff1a; 目录 阿里云云主机 云服务器ECS 轻量应用服务器 云…

python数字猜谜2.0

改进了一下数字猜谜&#xff1a; 开头&#xff0c;可选等级&#xff1a; import random guess -1 c 0 print("数字猜谜游戏&#xff01;") n input("选择等级 A B C&#xff1a;") if (n "A") or (n "a"):guess random.randint…

学习css样式的第二章

1.CSS 布局 - display 属性 display 属性是用于控制布局的最重要的 CSS 属性。 display 属性 display 属性规定是否/如何显示元素。 每个 HTML 元素都有一个默认的 display 值&#xff0c;具体取决于它的元素类型。大多数元素的默认 display 值为 block 或 inline 块级元素…

JavaEE课程设计——校园招聘管理系统(vue框架分析)

目录 Vue架构 登录 Vue架构 前端执行命令 npm run serve 这是整个前端的目录结构 vue.config.js是对前端vue的一个配置&#xff0c; // var webpack require(webpack); const path require(path)function resolve(dir) {return path.join(__dirname, dir) }function pu…

centos下的Nginx的安装

1.Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。其特点是占有内存少&#xff0c;并发能力强。 其他服务器介绍&#xff1a;Apache服务器、Tomcat服务器、Lighttpd服务器 2.nginx依赖安装 yum -y instal…

【数据分享】1929-2022年全球站点的逐月平均海平面压力数据(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 对于具体到监测站点的气象数据&#xff0c;之前我们分享过1929-2022年全球气象…