基于机器视觉与深度学习的人机对弈机器人——【决策篇】

文章目录


前言

棋盘识别部分已经在上一篇博客讲过了,这篇主要讲如何进行决策。
决策,即让程序、机器人自行决策下一步走什么棋,我这边想到的方法有三种。第一,使用强化学习,消耗的资源较多;第二,手动编程,对于这样娱乐、没有工资的项目,妥妥的不可能;第三,直接调用中国象棋云库,这也是我要介绍的方法。


一、中国象棋云库

先放地址:中国象棋云库
https://www.chessdb.cn/query/
其实这网页不仅仅能够玩中国象棋,国际象棋也可以,基本操作都差不多。
我们的目的是使用代码,让这个云库帮助我们进行决策。

二、网页URL程序编写

1.引入库

在python中,使用的库是requests,直接导入

import requests

2.代码实现

网页api使用的格式为:
http://www.chessdb.cn/chessdb.php?action=[ACTION]{&[OPTION1]=[VALUE1]…&[OPTIONn]=[VALUEn]}
具体的见官方网页:中国象棋云库接口说明

但是,在我多次尝试下发现,这个api使用有点问题,当然,也可能是我的打开方式不对。我发现,这个api不能在棋局编码(FEN码)后面直接添加多个行棋信息(moves 后面的是行棋信息),这样:
rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w moves g3g4 h7g7 b2e2 g9e7 f0e1
一步两步还行,但是多了之后就有bug或者计算不出来,实在是无奈。

不过我们可以通过每次的行棋信息,来更新我们的棋局编码,这样我们每次传入的api只有一步行棋,例如:
rnbakabnr/9/1c4c2/p1p1p3p/9/2P3p2/P3P3P/1CN4CB/9/R1BAKA1NR b moves h9i7
这样在每次使用api获得结果后对棋局编码和行棋编码进行解码,解码完成后,机器人走棋,再更新了棋局,对棋局重新编码,识别了玩家(人类)的行棋信息后,再向云库传输完整的api,获取下一步行棋方法。

发送api命令代码如下:

def sendw(api_open):
    api_0 = "http://www.chessdb.cn/chessdb.php?action=querybest&board="
    url = api_0 + api_open + ' w'
    print(url+'\n')
    ret = requests.post(url=url)
    a = ret.content.decode('utf-8')
    if 'search' in a:
        d = a.split('|')
        c = d[-1]
        b = c[7:11]
        print(b)
    else:
        b = (a[5:])
        print(b)
    return b

url变量就是向网页输出的命令,字符串的组合而已,在云库的说明里面有解释,之后就是使用post发送命令,ret接受,再解码,解码之后,使用判断来提取我们需要的返回数据,存在b中。

而这段代码的上级如下:

def compute_walk(api_open='9/9/3k5/9/2b6/4N4/9/1c2B4/4K4/3A5'):
    result = sendw(api_open=api_open)
    org = result[:2]
    tar = result[2:4]
    dictorg[tar]=dictorg[org]
    dictorg[org] = '0'
    return result

这段代码就是对上个函数结果的处理,解析行棋信息(起点与终点)。dictorg是一个棋盘映射字典,存储的棋局信息。

此外,还有对棋局编码(FEN)的解码代码,由于是我同门完成的,这里只贴代码。

    def inver_list_to_fen(self, ax_i_new):
        self.stri = ''
        count = 0
        inti = 0
        count_i = []
        for i in ax_i_new:
            count += 1
            inti += 1
            if i.isdigit():
                count_i.append(i)
            else:
                count_i.append(i)
                if count_i[inti - 2].isdigit():
                    self.stri += str(count - 1)
                    self.stri += i
                else:
                    self.stri += i
                count = 0
        self.stri += str(count)
        if self.stri[-1] == '0':
            self.stri = self.stri[:-1]
        return self.stri

总结

总的来说,实现决策的步骤就是:
1.解析棋局信息,转换成FEN码。
2.学习中国象棋云库api的使用方法
3.将棋局编码填入api命令,获取返回值
4.根据返回值操纵机械臂行棋落子
5.更新棋局信息,等待下一步行棋

上一篇:使用Gmail SMTP通过PHP发送电子邮件


下一篇:【设计模式 - 创建型模式】1. 工厂模式