AI脚本生成器设计文档..........进行当中.....
本帖最后由 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
本帖最后由 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
本帖最后由 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 本帖最后由 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
#pair=first_fenhao_pair(script,0,len_script)
#print '定位第一对": '.decode("utf8"),pair,pair
#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+=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
#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+=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,pair
for cur_fenhao in all_fenhao:
if cur_fenhao>pair and cur_fenhao<pair:
#print cur_fenhao,'分号失效'.decode("utf8")#当前没有用的分号
active_fenhao.remove(cur_fenhao)
#print '剩余有效分号'.decode("utf8"),active_fenhao
#print '剩余有效分号: '.decode('utf8'),active_fenhao
if pair==-1:
#print "语法错误-1:一行内有效引号不成对".decode("utf8")
active_yinhao_pairs.append([-1,-1])
break
start_pos=pair+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+=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
return ]
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
所有有效的引号对 [, ]
注释开始位置: 13
[[, ], 13]
情况4:有成对有效引号,无注释
aasdf"afd"awe"as;df"asf
所有有效的引号对 [, ]
注释开始位置: -1
[[, ], -1]
#www.orayes.com
回复 tankant 的帖子
楼主加油,如果能够将AI的编辑智能化,将是一大壮举 本帖最后由 得闲人 于 2012-9-10 11:38 编辑
建议增加插件(例如不动AI数字AI等)
-------------------------------
是否能做到给出一个AI就知道它是什么意思
本帖最后由 tankant 于 2012-9-10 20:06 编辑
累死我了,我得休息会儿。。。。。 本帖最后由 tankant 于 2012-9-11 10:10 编辑
回复 得闲人 的帖子
1.插件。。。这种东西也计划可以用这个程序生成、读取。你指的是ZYP文件吗?
2.你是说直观性。。。能做到。关键是参数太多,需要时间整理录入。录入完后才能进行下一步GUI的设计。 本帖最后由 tankant 于 2012-11-2 16:42 编辑
我已经把剧情狂翻译的那个AI帮助手册的数据输入到数据库中了。最近编写了无数脚本,积累了许多经验,提高了许多认识。感觉这里面的讲究很多,比较复杂。不过思路理清了许多。知道怎样入手了。希望写脚本的朋友能给我提出更多建议。
已经做出一个初步的样子,目前只能生成AI脚本,保存按钮不知道放在哪里合适:
https://www.hawkaoe.net/bbs/thread-95096-1-1.html
页:
[1]