翔鹰帝国网|帝国时代论坛|帝国时代系列|神话时代
 找回密码
 注册翔鹰会员(昵称)
搜索
查看: 2421|回复: 8

[交流] AI脚本生成器设计文档..........进行当中.....

   关闭 [复制链接]

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
发表于 2012-9-9 19:50:41 | 显示全部楼层 |阅读模式
本帖最后由 tankant 于 2012-9-10 20:06 编辑

需求方面,我貌似看不到太多的建议。那么我根据自己的理解开始设计一个设计文档。大家可以看看我的想法是不是已经都被人实现过。如果是那样的话,我就放弃。

实现语言:Python
GUI类库:PySide
数据库:SQLite

功能模块:
I.读取文件。读取per文件作为内容,并判断语法错误,识别规则、条件、动作等信息表现在GUI上。
II.编辑AI。点击鼠标完成所有的设计。当然也可以直接对代码进行修改
III.写文件。检查代码,如果代码语法没有错误,根据鼠标的修改把结果保存到per文件去。
IV.版本切换。可以在1.0C版本和其他MOD转换。可以新建MOD脚本规则。比如新建单位和对应的代码。

我对一些概念的理解和设计如下:

条件:全是返回值为bool类型的函数
分为三种:
1.固定条件。就是没有参数的函数
2.自定义条件。就是有一个或多个参数的函数
3.组合条件。可以把任何多个条件(固定条件、自定义条件、组合条件)进行组合成一个组合条件,逻辑组合方式分为and和or组合。

动作组:多个动作的序列(包括一个动作)

规则:
一个条件+动作组的组合

GOAL:变量

希望我在文档设计阶段出现的错误,大家不要吝惜笔墨,请指出来。
感谢大家的鼓励与支持!感谢剧情狂的共同讨论!

个人主页www.orayes.com
回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-9 19:51:04 | 显示全部楼层
本帖最后由 tankant 于 2012-9-10 18:14 编辑

############################################
#读取脚本设计方案:
#I.逻辑步骤:

#读取文件(已完成)
#识别注释和字符串(已完成)
#定位所有的load
#定位所有defcon的位置,识别出常量和GOAL
#定位所有的#load-if-defined和#load-if-not-defined语句与其各自的#end-if、#else语句
#定位所有(defrule的位置和对应的右括号、=>符号,划分出条件部分和动作部分
#分析条件部分,划分出条件类型(我这个算法可能不好,肯定有更有效率的算法)
    #找到(or和对应的右括号,作为或类型的组合条件
    #找到(and和对应的右括号,作为与类型的组合条件;
    #找到连续两个的(和与之对应的右括号,作为与类型的组合条件;
    #找到最内侧的括号对,作为普通条件
#分析动作部分,定位所有动作部分的括号对,作为动作序列


#II.待写类:
#很多,最后列举

#III对应数据库相关的表设计:

#注释表(注释id,起始位置,结束位置)
#字符串表(字符串id,起始位置,结束位置)
#load表(load_id_PK,起始位置,导入的文件)
#常量和GOAL表(conid_PK,name,value)
#分支判断表(分支id,if位置,if类型,else位置,end位置)

#规则表(规则id,起始位置,结束位置,条件部分id,动作部分id)
#条件部分表((条件部分id,包含条件id)_PK)
#((条件id,包含条件id)_PK,逻辑组合类型,起始位置,结束位置)
#普通条件表((条件id)_PK,起始位置,结束位置)
#动作部分表((动作部分id,动作id)_PK)
#动作表(动作id_PK,动作次序)

#www.orayes.com

回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-9 19:51:16 | 显示全部楼层
本帖最后由 tankant 于 2012-9-10 02:37 编辑

成功读取了AI脚本到数据库后,则开始把内容显示到GUI上。如何布局GUI,既能满足所有的AI编写需要,有能有较好的用户体验,这是我一直苦苦思索的问题。作为程序设计者的我,思考更多的是满足所有AI编写的需要,而不是用户体验;而AI设计者是我的需求客户,所以大家应该在这个问题上好好探讨,多多提出意见。大概看了下卧龙先生的程序,否定了N多个方案后,以下是我的设计方案:

1.文件读取
    读取PER或者ZYP文件
2.文件保存
    2.1另存为PER脚本
    2.2另存为ZYP插件
3.添加状态(其实就是定义常量和GOAL)_QButton-->QWindow
    状态名称_QLineEdit
    状态值_QLineEdit
3.逻辑分支--逻辑分支列表_QListView
    3.1添加逻辑分支_QButton
        选择条件_QTreeView
        选择满足后的动作_QTreeView
        选择不满足后的动作_QTreeView
        确认添加_QButton
    3.2删除逻辑分支_QButton
4.规则--规则列表_QListView
    4.1.添加规则_QButton
        4.1.设置条件部分_QButton-->条件列表_QTreeView

            4.1.1.添加普通条件_QButton
                选择条件主语_QTreeView
                选择条件谓语_QListWidget
                选择条件宾语_QTreeView
            4.1.2.删除普通条件_QButton

            4.1.3.添加组合条件_QButton-->组合条件列表_QListView
                选择组合逻辑_QCheckBox

                4.1.3.1.添加普通条件_QButton
                    选择条件_QTreeView
                4.1.3.3.删除普通条件_QButton
                    选择条件_QTreeView

            4.1.4.重设条件部分_QButton

        4.2.设置动作部分_QButton--动作列表_QTreeView
            4.2.1.添加动作_QButton
                选择动作主语_QTreeView
                选择动作谓语_QListWidget
                选择动作宾语_QTreeView
            4.2.2.重设动作部分_QButton
    4.2.删除规则_QButton

5.格式化脚本
    5.1规范脚本的书写_QButton
    5.2自动添加注释_QButton

数据库需要建立的表:所有参数分门别类建立各自的表(很多,数据量很大,我录入都恶心了;另外这一步表名太多,需要有个命名规范,求资料!!!!!)

利用GUI保存数据后,再把数据写到per文件的实现就很简单了
#www.orayes.com
回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-9 19:51:47 | 显示全部楼层
本帖最后由 tankant 于 2012-9-10 19:01 编辑

开始实现一些方法
#www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################

#./t/public.py
#encoding:utf8
#公共方法


#设置测试字符串
#script = open ('./data').read()
#len_script=len(script)

###########################################
#方法1:定位第一个指定文本的位置
def first_fuhao(s,text,start,end):
    fuhao=range(start,len(s))
    for i in fuhao:
        if s==text:
            idx=i
            break
        else:
            None
    else:
        idx=-1
    return idx

#print '定位第一个(: '.decode("utf8"),first_fuhao(script,'(',0,len_script)
#################################################



#################################################
#方法2:定位所有指定文本的位置
#依赖方法1
def all_fuhao(s,text,start,end):
    next_search=0
    positions=[]
    len_text=len(text)
    while 1:
        pos=first_fuhao(s,text,next_search,end)
        if pos==-1:
            break
        positions.append(pos)
        next_search=pos+len_text
    return positions
#print '定位所有(: '.decode("utf8"),all_fuhao(script,'(',0,len_script)
#################################################


################################################
#方法3:定位第一个"对的位置
#依赖方法1
#前提是"必须是偶数个
def first_fenhao_pair(s,start,end):
    pos1=first_fuhao(s,'"',start,end)
    pos2=first_fuhao(s,'"',pos1+1,end)
    return [pos1,pos2]

#pair=first_fenhao_pair(script,0,len_script)
#print '定位第一对": '.decode("utf8"),pair[0],pair[1]

#
www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################
#www.orayes.com########################################   

#./read.py
#encoding:utf8


import sys
sys.path.append("./t")
import public

#测试字符串
cur_line='aasdf"afd"awe"as;df"asf'#假设这是脚本的一行







def abc(line):
    ########识别当前行分号和双引号哪个是有效的
    len_line=len(line)

    #定位第一个;的位置
    first_fenhao=public.first_fuhao(cur_line,';',0,len_line)
    #print 'first_fenhao ',first_fenhao

    #定位第一个"的位置
    first_yinhao=public.first_fuhao(cur_line,'"',0,len_line)
    #print 'first_yinhao',first_yinhao

    #定位所有"的位置
    all_yinhao=public.all_fuhao(cur_line,'"',0,len_line)
    #print 'all_yinhao',all_yinhao
    #active_yinhao=all_yinhao#初始化有效"
    active_yinhao=public.all_fuhao(line,'"',0,len_line)
    #print 'active_yinhao',active_yinhao

    #定位所有;的位置
    all_fenhao=public.all_fuhao(line,';',0,len_line)
    #print 'all_fenhao',all_fenhao
    #active_yinhao=all_yinhao#初始化有效"
    active_fenhao=public.all_fuhao(line,';',0,len_line)

    start_pos=0
    active_yinhao_pairs=[]
    while 1:
        #print '==========='
        if first_fenhao==-1:
            #print '没有注释'.decode("utf8")
            #把有效引号序列变成有效引号对序列
            len_active_yinhao=len(active_yinhao)
            num=0
            active_yinhao_pairs=[]
            while num<len_active_yinhao:
                active_yinhao_pairs.append([active_yinhao[num],active_yinhao[num+1]])
                num+=2
            active_fenhao.append(-1)
            break
        if first_yinhao==-1:
            #print '剩余没有引号了'.decode("utf8")
            break
        if first_fenhao<first_yinhao:#假设第一个;在第一个"前面
            #print first_fenhao,'之后所有"将失效'.decode('utf8')
            #print active_yinhao
            len_active_yinhao=len(active_yinhao)
            #print range(len_active_yinhao),'-----------'
            num=0
            for cur_yinhao in active_yinhao:
                if cur_yinhao>first_fenhao:
                    start_del_yinhao=active_yinhao.index(cur_yinhao)
                    for i in range(num,len_active_yinhao):#把当前分号之后所有引号全部设置为无效
                        del active_yinhao[start_del_yinhao]
                        #print active_yinhao
                    break
                else:
                    None
                num+=1
            #print '=================='
            #把有效引号序列变成有效引号对序列
            len_active_yinhao=len(active_yinhao)
            num=0
            active_yinhao_pairs=[]
            while num<len_active_yinhao:
                active_yinhao_pairs.append([active_yinhao[num],active_yinhao[num+1]])
                num+=2
            break
        if first_yinhao<first_fenhao:#假设第一个"在第一个;前面
            #print '第一个"对之间的;将失效'.decode('utf8')
            #print 'all_fenhao',all_fenhao
            #print 'active_fenhao',active_fenhao
            pair=public.first_fenhao_pair(line,start_pos,len_line)
            #print '定位第一对": '.decode("utf8"),pair[0],pair[1]
            for cur_fenhao in all_fenhao:
                if cur_fenhao>pair[0] and cur_fenhao<pair[1]:
                    #print cur_fenhao,'分号失效'.decode("utf8")#当前没有用的分号
                    active_fenhao.remove(cur_fenhao)
                    #print '剩余有效分号'.decode("utf8"),active_fenhao
            #print '剩余有效分号: '.decode('utf8'),active_fenhao
        if pair[1]==-1:
            #print "语法错误-1:一行内有效引号不成对".decode("utf8")
            active_yinhao_pairs.append([-1,-1])
            break
        start_pos=pair[1]+1#新循环的开始位置
        #print 'start_pos :',start_pos
        if start_pos==-1:
            #print '=================='
            #把有效引号序列变成有效引号对序列
            len_active_yinhao=len(active_yinhao)
            num=0
            
            while num<len_active_yinhao:
                active_yinhao_pairs.append([active_yinhao[num],active_yinhao[num+1]])
                num+=2
            break
        all_fenhao=active_fenhao
        first_fenhao=public.first_fuhao(line,';',start_pos,len_line)
        first_yinhao=public.first_fuhao(line,'"',start_pos,len_line)

    print '所有有效的引号对'.decode("utf8"),active_yinhao_pairs
    print '注释开始位置:'.decode("utf8"),active_fenhao[0]
    return [active_yinhao_pairs,active_fenhao[0]]
print abc(cur_line)
#www.orayes.com


以下是./read.py的测试用例:

情况1:有效引号不成对(语法错误)
aa"bb"c";cdd;eeff

所有有效的引号对 [[-1, -1]]
注释开始位置: 8
[[[-1, -1]], 8]

情况2:没有有效引号
asdf;asdf"asdf";asdfasf

所有有效的引号对 []
注释开始位置: 4
[[], 4]

情况3:有成对有效引号,有注释
aa"bb"c";c"dd;"ee"ff

所有有效的引号对 [[2, 5], [7, 10]]
注释开始位置: 13
[[[2, 5], [7, 10]], 13]

情况4:有成对有效引号,无注释
aasdf"afd"awe"as;df"asf

所有有效的引号对 [[5, 9], [13, 19]]
注释开始位置: -1
[[[5, 9], [13, 19]], -1]


#www.orayes.com
回复

使用道具 举报

53

主题

5

精华

4万

积分

圣徒

耕战
7862
鹰币
54260
天龙币
0
回帖
2351

翔鹰建站十周年纪念章一级帝国勋章二级翔鹰勋章二级嘉禾勋章翔三电影节冠军冒险七王者

附庸关系0
发表于 2012-9-9 23:13:25 | 显示全部楼层
回复 tankant 的帖子

楼主加油,如果能够将AI的编辑智能化,将是一大壮举
回复

使用道具 举报

9

主题

1

精华

6176

积分

国王

耕战
557
鹰币
4971
天龙币
0
回帖
886

翔鹰建站十周年纪念章二级嘉禾勋章

附庸关系0
发表于 2012-9-10 00:44:23 | 显示全部楼层
本帖最后由 得闲人 于 2012-9-10 11:38 编辑

建议增加插件(例如不动AI数字AI等)
-------------------------------
是否能做到给出一个AI就知道它是什么意思
回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-10 19:32:52 | 显示全部楼层
本帖最后由 tankant 于 2012-9-10 20:06 编辑


累死我了,我得休息会儿。。。。。
回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-11 10:07:22 | 显示全部楼层
本帖最后由 tankant 于 2012-9-11 10:10 编辑

回复 得闲人 的帖子

1.插件。。。这种东西也计划可以用这个程序生成、读取。你指的是ZYP文件吗?
2.你是说直观性。。。能做到。关键是参数太多,需要时间整理录入。录入完后才能进行下一步GUI的设计。
回复

使用道具 举报

38

主题

0

精华

5066

积分

国王

耕战
933
鹰币
4
天龙币
0
回帖
249

三级嘉禾勋章

附庸关系0
 楼主| 发表于 2012-9-29 21:07:01 | 显示全部楼层
本帖最后由 tankant 于 2012-11-2 16:42 编辑

我已经把剧情狂翻译的那个AI帮助手册的数据输入到数据库中了。最近编写了无数脚本,积累了许多经验,提高了许多认识。感觉这里面的讲究很多,比较复杂。不过思路理清了许多。知道怎样入手了。希望写脚本的朋友能给我提出更多建议。


已经做出一个初步的样子,目前只能生成AI脚本,保存按钮不知道放在哪里合适:
https://www.hawkaoe.net/bbs/thread-95096-1-1.html
回复

使用道具 举报

本版积分规则

排行榜|小黑屋|翔鹰帝国

GMT+8, 2024-5-12 00:43 , Processed in 3.984954 second(s), 107 queries , File On.

Powered by Hawk Studio  QS Security Corp.® Licensed

Copyright © 2001-2023, Hawkaoe.net All Rights Reserved

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