分享

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

 九州好人 2022-05-30 发布于辽宁

前言

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


一、中国象棋云库

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

二、网页URL程序编写

1.引入库

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

import requests

2.代码实现

网页api使用的格式为:
http://www./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.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)的解码(fen转python字典)代码,由于是我同门完成的,这里只贴代码。

    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

另外还有棋局编码转化为python字典的代码:

    def fen_to_the_dict(self, org_gen):
        self.ax_9, self.ax_8, self.ax_7, self.ax_6, self.ax_5, self.ax_4, self.ax_3, self.ax_2, self.ax_1, self.ax_0 = org_gen.split(
            '/')
        self.ax_list_key = ['ax_9', 'ax_8', 'ax_7', 'ax_6',
                            'ax_5', 'ax_4', 'ax_3', 'ax_2', 'ax_1', 'ax_0']
        self.ax_list_value = [self.ax_9, self.ax_8, self.ax_7, self.ax_6,
                              self.ax_5, self.ax_4, self.ax_3, self.ax_2, self.ax_1, self.ax_0]
        self.ax_dict = dict(zip(self.ax_list_key, self.ax_list_value))
        dict_key = []
        non = '0'
        for j in self.latter_table:
            for i in range(10):
                dict_key.append(j + str(i))
        dictvalue = [non for i in range(0, 90)]
        self.dictorg = dict(zip(dict_key, dictvalue))
        self.cal_chess('self.ax_9')
        self.cal_chess('self.ax_8')
        self.cal_chess('self.ax_7')
        self.cal_chess('self.ax_6')
        self.cal_chess('self.ax_5')
        self.cal_chess('self.ax_4')
        self.cal_chess('self.ax_3')
        self.cal_chess('self.ax_2')
        self.cal_chess('self.ax_1')
        self.cal_chess('self.ax_0')
        return self.dictorg

总结

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多