加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Zillions语言教程(五)

(2009-04-07 10:56:36)
标签:

杂谈

Zillions语言教程(五)
2008-07-15 19:20

第五章 棋子(二)
上次说到关于棋子下落与移动,由于这两项是Zillions中最复杂的地方,所以分在此节中讲。

首先先说一个:
(define <command> ...)
在game、variant段之外的,定义模块。这样就可以用(<command>)这一段字符代替之后的命令了。之后的语句里若带有$1、$2……的符号,那么在使用时,是如下形式:
(<command> #1 #2 ...)#1、#2……为不含有空格和(、)、"的字符串,执行时将会用#1、#2……代替语句中的$1、$2……了解了这点,在之后的编程中便会感到简便。

drops和moves当中都是由一组组由括号围着的流程块组成。所谓流程块,便是指棋子的判断流程,按照这个顺序去做。

例如:流程块(n (while empty? add n) (verify not-friend?) add)
它所描述的就是象棋里的“车”往上走的走法(n为北,即“上”)。用流程图表示为:

(①n (while ②empty? ③add ④n) (verify ⑤not-friend?) ⑥add)
原位→①往n方向移动一格→②是空的吗(是)→③增加一个目标点→④往n方向移动一格→转到②
②是空的吗(否)→⑤不是己方棋子→⑥增加一个目标点

下面就来详细讲解流程块的编写。如果学过逻辑学的话,这里的将会简单。
内部包含条件和命令两种内容。刚才所看到的,①③④⑥是命令,②⑤是条件。下面先讲条件的内容。
条件分为三种类型:
(verify <condition>)判断结构。如果条件成立,则往后进行,否则终止流程。
(if <condition> ... else ...)选择结构。如果条件成立,则执行...中的语句,否则执行else之后的语句,之后仍然继续。(else可有可无)
(while <condition> ...)循环结构。如果条件成立,则执行...中的语句,反复循环,直到不符合<condition>为止,执行while之外的语句。
这几种结构可以互相套用,从而达到一定目的。
条件分为这些内容:
empty?:判定是否为空,例如车、炮移动时的判定。
friend?:判定是否为己方棋子,例如Tafl棋中夹着吃子的判定。
enemy?:判定是否为对方棋子,例如炮吃子的判定。
attacked?:判定是否为对方可达到的位置,如国际象棋的“王”走的位置判定。
defended?:判定是否为己方可达到的位置,如泰将棋的“自在天王”走的位置判定。
on-board?:判定是否在棋盘上,例如围棋的边界判定。
(position? U1):判定是否为位置U1,例如放在某个固定的地方的不能移动的子。
(in-zone? xxx):判定是否在区域xxx内,例如中国象棋中帅、士、象的移动范围。
(piece? xxx):判定是否为棋子xxx,例如国际象棋变体中的不允许走的地方(红叉)。
adjacent-to-enemy?:判定从这个位置是否在对方的行进位置。
goal-position?:判定这个位置是否是目标点。如Tafl中四个目标点可作为棋子用。
neutral?:判定这个位置是否是中立方的。所谓中立方,就是没有轮流的机会的方,例如七国象棋的“周”。
(flag? <flag-name>):判定这个棋子是否有旗帜。
(position-flag? <flag-name>):判定这个位置是否有位置旗帜。
marked?:判定这个位置是否被存档了。
<attribute>:判定这个位置的棋子的变量值是否为真。例如国际象棋的王、车易位前是否已动过。
以上的之后均可加方向或位置,需用括号括住。如:(verify(friend? n))

命令:

可以跟方向、位置,则直接到达方向、位置。

add | add-copy | add-partial | add-copy-partial
增加一个目标点。也就是说,可以往这儿移动,并且执行之前的命令。有-copy的表示并不将原来的棋子移动至此,而是复制一个与之完全相同的棋子。有-partial的表示开始部分移动,如果最后跟上移动类型,则表示部分移动只能进行这种移动类型的移动。如果在后面(移动类型之前)跟上一种或多种棋子,那么则会在移动之后变成这种棋子。并且受option中的影响,会造成可以或无法移动。

mark/(mark   <position> | <direction>)
记下当前位置。用back则可以回到这个位置,并且这里也成为marked?判断为真的地方。

back
回到mark的位置。如果一个mark后面跟多个back,则可多次返回。

capture
(capture   <position> | <direction>)
吃子。将这里(或某个位置、方向)的棋子吃掉,如果作用于最后到达的点,则会连自己一块儿吃掉。另外有个BUG:当capture后面跟有add时,则这个目标点只执行这个capture。所以需要用(if on-board? capture)来代替。

cascade
“溪流”命令。这是个奇特的命令。在使用cascade之后,再使用from,则棋子会到cascade所在位置,而所有之后的命令将给此处的另一个棋子。如果在使用cascade之后,再使用to,则另一个棋子会到to所在位置,而所有之后的命令将仍然给原棋子。例如:(n cascade (verify not-empty?) from s add),将使该棋子到达上方一格,而上方一格的棋子会到达这个位置的下方一格,即原位,从而交换二者位置。

change-owner
(change-owner   <position> | <direction>)
改变所属方。会将其改变为自己的棋子,例如黑白棋中的反转。

(change-type   <piece-type>   [<position> | <direction>])
改变棋子类型。会将其类型改变,如车变成炮。

create
(create   [<player>]   [<piece-type>]   [<position> | <direction>])
产生一个棋子。如果没有<player>,则是自己的棋子,如果没有<piece-type>,则跟自己一样。

flip
(flip   <position> | <direction>)
改变所属方。不同于change-owner,这个会根据players中注册的所属方顺序,逐个往后变化。

from
标记为“来的”。那么使用了之后,原棋子不变,而这个位置的棋子执行之后的命令。

to
标记为“去的”。那么使用了之后,另一个棋子留在这里,而原棋子继续流程。

(go   from | to | last-from | last-to | mark)
去某个位置。分别是去标记为“来的”的位置、

(opposite   <direction>)
走与之相反的方向。这条件用的不多,因为可以直接用相反的方向代替(n代替s),如果该方向多对一的话,则不能使用该命令。

(set-attribute   <attribute>   <condition>)
设置变量。设置变量为真条件是根据之后的<condition>的真假决定的。

(set-flag   <flag-name>   <condition>)
设置旗帜。设置旗帜为真条件是根据之后的<condition>的真假决定的。不同于变量,旗帜可以为任何棋子所设定,不需要先行注册。

以上便是全部的条件与命令。这次就讲到这里,以后会在高级应用中谈到。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有