zoukankan      html  css  js  c++  java
  • 开源围棋A.I. FoolGo

      这几天把围棋A.I.最后的部分写好了,9路小棋盘上看上去运行得还不错,更名为FoolGo。先讲一下UCT博弈树的实现。

      鉴于FoolGo的MC模拟速度和棋盘对象的大小,如果直接用树结构实现,用不了几分钟,我的MBP的4G内存就会被棋盘挤爆。所以要通过置换表实现博弈树。

      哈希算法当然是zobrist哈希。如果哈希值的类型是uint32_t的话,不同棋局哈希冲突的概率就是1 / ~(uint32_t)0——可以认为不同的哈希值意味着不同的棋局。不用自己写哈希表,C++11新增有标准容器unordered_map,很含蓄的名字,就是哈希表。

      zobrist哈希值可以增量计算,不过实现起来有些麻烦,暂不实现,因为FoolGo目前的性能瓶颈还是在落子动作上。

      UCT搜索过程中多处要取到子节点的哈希值,如果为此落子很昂贵,因此置换表项须要携带子节点的哈希值,然后通过ChildKey函数取得哈希值:

    template <BoardLen BOARD_LEN>
    HashKey Engine<BOARD_LEN>::ChildKey(const BoardInGm<BOARD_LEN> &parent,
                                        PointIndex indx) const
    {
        HashKey prnt_key = parent.HashKey();
        HashKey chldrn_key = table_[prnt_key].children_key_[indx];
        if (chldrn_key == NONE) {
            BoardInGm<BOARD_LEN> b;
            b.Copy(parent);
            PlayerColor color = OppstColor(b.LastPlayer());
            b.PlayMove(Move(color, indx));
            HashKey key = b.HashKey();
            table_[prnt_key].children_key_[indx] = key;
            return key;
        } else {
            return chldrn_key;
        }
    }

      有了这个置换表后,易实现UCT博弈树。只是刚写完时bug较多,这种海量计算的函数,debug起来比较头疼……

      测试下来,在9路的初始棋盘上,模拟3w局MC对局用时大概9秒多,随着棋局的进行会加快。9秒一步还是比较愉快,就拿来和一个在线围棋A.I.单挑了一下 http://peepo.com/ 。FoolGo无耻地执黑先行:

      棋盘上面的数值是FoolGo对该落子点的评估(即下在那里的话最后能占几子)

      之前走成裂形了,可以看到FoolGo对局面的评估也持悲观,不过这串的滚打包收还不错。

      双方地域基本确定,黑棋败势已定……

          额操作失误了,我的测试程序没法悔棋,PK到此为止。

      把模拟局数的参数设大一些应该会更强,不过人家的在线A.I.几秒种一步棋,我也不好意思再占便宜。

      代码:https://github.com/chncwang/FoolGo

      额对了,目前找工作中,之前做过iPhone开发,想转型做服务端的C++开发,比较向往的方向是推荐算法和搜索引擎开发。我还是比较感兴趣用C++高效实现一些东西。联系邮箱:chncwang@gmail.com,工作地点杭州。

  • 相关阅读:
    [Umbraco] DocumentType设计指南
    [Umbraco] 入门教程(转)
    [Umbraco] 熟悉管理页面
    [Umbraco] 创建第一个页面
    [Umbraco] 开篇
    简单的文字上下滚动
    快速判断ie10及以上版本浏览器
    最短JS判断是否为IE6(IE的写法)
    editplus 常用快捷键汇总 大小写代码折叠
    滚动双联广告
  • 原文地址:https://www.cnblogs.com/qswang/p/2818870.html
Copyright © 2011-2022 走看看