SAP程序论坛

 找回密码
 立即注册
搜索
热搜: alv sap gui
查看: 253|回复: 3

[文档] ABAP新语法+OO之300行代码实现AI五子棋

[复制链接]

2

主题

3

帖子

28

积分

新手上路

Rank: 1

积分
28

最佳新人

发表于 2019-5-24 11:13:03 | 显示全部楼层 |阅读模式
本帖最后由 以秉 于 2019-5-29 14:49 编辑

技术要点:新语法+OO+AI算法
主要思想:
通过封装五子棋的方法,用SALV模拟棋盘,内表模拟数组(数组对于算法的支持优于内表)
回头填坑。
废话不多说,RT所示,如何使用ABAP新语法+OO之300行代码搞定AI五子棋,abap不是为了写应用而生的语言,所以此篇只为练习所用,并非不务正业。
首先是设计,思路大概为:抽象出五子棋的方法,封装成五子棋的class,利用salv模拟棋盘,内表模拟数组,图标模拟棋子,选取估值算法为AI(这个好写点,abap对算法支持没那么好,我又比较菜)
其次是方法:落子(双向)+判负+估值+棋盘绘制+初始化游戏
为大量节省代码,还封装了取棋盘任意位置的棋子类型的方法,大概看起来和数组一样。
插入代码没找到abap格式...

[SQL] 纯文本查看 复制代码
"类定义
CLASS cl_gobang DEFINITION.
  PUBLIC SECTION.
    "SALV对象
    DATA: mo_qp TYPE REF TO cl_salv_table.
    "常量:边界,以及两种棋子的图标
    CONSTANTS:border_ins TYPE c4 VALUE icon_border_inside."border
    CONSTANTS:player_wht TYPE c4 VALUE icon_incomplete.
    CONSTANTS:player_bak TYPE c4 VALUE icon_dummy.
    "步数,当前设定人先落子,所以步数为单数,轮到AI (可动态设定)
    DATA:step TYPE p VALUE 0.
    "核心表,存储当前棋盘
    "核心表设计思路:
    "需要模拟数组进行读取操作,所以对于行列敏感,除去边界,1-15行以及1-15列为棋盘,X为内表行,Y为列,列递增寻址,所以要基于列名的可拼接
    " 如C101,即为棋盘内表的第2列,棋盘的第一列,所以读取方式为 it_qp[ X ]-|C {Y + 99}|  => C {Y + 99}即为列名
    " 以下当传入参数为行列的i类型时,Y坐标为列的数字-99
    DATA :BEGIN OF wa_qp,
            c100 TYPE c4, "border
            c101 TYPE c4,c102 TYPE c4,c103 TYPE c4,c104 TYPE c4,c105 TYPE c4,
            c106 TYPE c4,c107 TYPE c4,c108 TYPE c4,c109 TYPE c4,c110 TYPE c4,
            c111 TYPE c4,c112 TYPE c4,c113 TYPE c4,c114 TYPE c4,c115 TYPE c4,
            c116 TYPE c4, "border
            "该列为TYPE列,设定该列支持link事件,详见初始化函数实现
            ctyp TYPE salv_t_int4_column,
          END OF wa_qp.
    DATA:it_qp LIKE TABLE OF wa_qp.
    "初始化棋盘,17*17的内表 其中最外围为边界,所以棋盘大小为15*15
    METHODS: ini_gobang.
    "棋盘绘制,调用SALV模拟棋盘
    METHODS: dis_gobang.
    "落子算法,绑定SALV的link click事件
    METHODS: set_gobang FOR EVENT link_click OF cl_salv_events_table IMPORTING row column.
    "AI核心算法,人落子之后,循环棋盘上所有未落子的点,调用估值算法估值,选择估值最高的点落子(基于博弈树的估值算法)
    METHODS: ai1_gobang."
    "模拟数组,并基于偏移方向以及偏移量的内表读取,分8个方向
    "偏移方向以及偏移量是可选的,当不传入的时候,返回当前坐标的值
    "返回值为基于偏移方向以及偏移量的内表字段值
    METHODS: get_gobang IMPORTING row TYPE i col TYPE i off TYPE i OPTIONAL set TYPE i OPTIONAL "偏移量
                                                                       RETURNING VALUE(value) TYPE c4.
    "AI核心估值算法,传入该点坐标以及需要估值的玩家,返回该点的估值
    METHODS: env_gobang IMPORTING row TYPE i col TYPE i player TYPE c4 RETURNING VALUE(value) TYPE i.
    "判负算法,通过对该点8个方向的延伸探索,判断四条线的同类棋子数目
    "返回值为以该点为原点,一条线上连续棋子的数量
    METHODS: win_gobang IMPORTING row TYPE i off TYPE i column TYPE c4 RETURNING VALUE(score) TYPE i."判负算法
    "消息
    METHODS: mes_gobang IMPORTING mes TYPE string.
ENDCLASS.


这部分是核心代码,实现部分我将会之后附上。
首先棋子图标的选取凭自己喜欢,以能分清为好,可以用icon事务码或者showicon程序查看所有图标代码选择自己喜欢的。
为了优化程序,我设计了16*16的数组(内表),最外一层为边界,这样可以不必担心越界问题,读到边界图标停止。
命名采用c1**的形式,所以读取的时候格式统一,不会出问题。
一个很有意思的方法是基于偏移量的内表读取,这其实是数组的概念,我们可以知道某位置的周边棋子分布,用来估值计算AI以及判负使用。
至于每个方法的用处,代码中注释已经说明了一切,是的,即使要300行实现五子棋,我也没有就省略注释,注释是一个很好的行为(虽然我也不喜欢写)



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

3

主题

7

帖子

59

积分

超级版主

Rank: 8Rank: 8

积分
59

最佳新人活跃会员

发表于 2019-5-24 11:30:58 | 显示全部楼层
前排支持
回复

使用道具 举报

2

主题

3

帖子

28

积分

新手上路

Rank: 1

积分
28

最佳新人

 楼主| 发表于 2019-5-29 14:34:31 | 显示全部楼层
本帖最后由 以秉 于 2019-5-29 14:41 编辑

想贴代码实现部分的代码的,结果长度超标了。所以我把整个源码(虽然就一个txt)打包了,挂在了一楼的附件上。
欢迎大家下载体验并交流。
FYI,仅供学习使用。


回复

使用道具 举报

22

主题

28

帖子

186

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
186
发表于 2019-5-29 14:37:04 | 显示全部楼层
以秉 发表于 2019-5-29 14:34
想贴代码实现部分的代码的,结果长度超标了

你可以分段来贴,我编辑了你的帖子,你看下效果,用的SQL格式去展示i代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|SAPCODE

GMT+8, 2019-10-17 05:07 , Processed in 0.081945 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表