有时,您需要多次执行重复性操作。 在此情况下,大多数文本编辑器都提供了所谓的“宏”功能。 通常,这是指您录制某些操作,以便多次执行这些操作。 在YSokoban中,您可以使用简单的文本编辑器,通过复制/粘贴功能来完成此任务。 自版本1.500后,您可以在“宏”对话框的帮助下完成该任务。 按“宏”按钮可激活此功能。 在“宏”对话框中,要创建新宏,您可以直接以lurd表示法输入步骤,或按“开始记录”按钮。 然后,YSokoban会记录您的所有操作。 完成之后,请按“停止记录”按钮(“宏”将更改为“停止记录”),您的所有移动步骤将记录在新宏中。 现在,您就可以多次执行该宏,并且/或者在“名字”编辑框中输入名称,然后按“保存”按钮来保存宏。 “宏”对话框的左侧部分将显示保存的所有宏。 您可以从中选择并执行选定的某个宏。
在YSokoban中,玩家可以通过按M和Shift-M键来执行新宏或选定的宏。
用鼠标点击已保存宏的列表,将完成以下操作:
如果将“*”(而不是数字)用作重复计数器,则会重复执行后续命令(或者宏或组),直到出错。例如:*(lddr)或*{macro}或只是*l。 如果使用*(lr)或*(ldru),小人将进行无限循环移动(如果有空间给它移动)。
如果使用“&”而不是“*”作为重复计数器,那么YSokoban会对移动/推动进行严格检查。 这意味着,进行严格检查时,如果指定了移动,则它不会进行推动。 因此,对严格检查来说,“r”指向右移动,而不是向右推动,“R”指向右推动,而不只是移动。
可以在宏中指定撤销——用“~”表示撤销。
有时需要保存小人当前所在的位置,并在稍后返回该位置。
使用[x,y]可以指定推动位置的相对偏移值,或者用(x,y)指定用绝对值的坐标。 例如,+[3,4]将小人的推动位置增加3列4行(正数表示向右或向下,负数表示向左或向上)。 但+(3,4)会推动到绝对值坐标3,4这个位置。 稍后,^(或者@)会将小人移动到那里。
@[3,5]不会从堆栈中提取位置,小人只会相对于偏移值3,5移动(位置current_x+3和current_y+5)。 @(3,5)(请注意,是圆括号而不是方括号)会将小人移动到绝对位置3, 5。 (不会从堆栈中提取任何内容)
绝对坐标与alt-R中的坐标相同(用数字表示的标尺),第一个坐标为x(列),第二个坐标为y(行)。
总结上面这些符号的用途:
符号 | 操作 | 使用[x,y]时的操作 | 使用(x,y)时的操作 |
---|---|---|---|
+ | 将小人的目前位置保存到堆栈中 | 保存用相对坐标修改后的目前位置 | 保存绝对值坐标x, y |
^ | 从堆栈中提取位置, 然后去到这个位置 | 从堆栈中提取位置, 然后去到这个位置+相对坐标 | 从堆栈中提取位置, 然后去到绝对坐标的位置 (堆栈中的坐标资料完全没有用到) |
# | 从堆栈中提取位置(但不用这个位置) | pop position from stack modify it with relative coordinates and push back to stack (modify top of stack)从堆栈中提取位置,用这个提取的位置+相对坐标,然后将这个新位置保存到堆栈中(修改堆栈顶部) | 从堆栈中提取位置,然后将这个绝对坐标位置保存到堆栈中(修改堆栈顶部) |
@ | 从堆栈中提取位置, 然后去到这个位置(操作与^相同) | 去目前人的位置+相对偏移值 (完全不提取堆栈中的位置) | 去到绝对坐标的位置x,y (完全不提取堆栈中的位置) |
在宏中可以使用类似于if-then-else这样的结构。语法为:
? expression : then-moves / else-moves ;
或者为
? expression : then-moves ;
因此,关键字符为?、 :、 / 和 ;
在宏中可以使用类似于while-do-otherwise这样的结构。 语法为(与IF的语法相同,但使用两个?):
?? expression : do-moves / otherwise-moves ;
或者为
?? expression : do-moves ;
在此情况下,当表达式为真时,将重复执行do-move。 如果表达式为假,则执行otherwise-moves,但只执行一次。
在条件表达式中,您可以通过指定单元格坐标来比较单元格的内容:
单元格可以与以下项目进行比较:
比较结果可以为:
可以使用二元运算符:
没有规定优先次序,因此,将从左至右执行&和|(如果需要优先级,请使用{和})
要中断循环,请使用!
它会中断 ?? 循环或 &(...) 或 *(...)
用在 ?? 循环的 / ... ; 部分中时,它会中断外部循环(没有理由会中断??循环的/部分,因为该部分只执行一次)。
示例:
*( ... // 一些移动步骤 ? [1,1]=# : ! ; // 这会中断 *( ... ) 循环 ... // 其它一些移动步骤 )
*( ... // 一些移动步骤 ?? [1,1]=_ : rd / ! ; // 这会向右向下移动,然后在 ?? 末尾中断 *( ... ) 循环 ... // 其它一些移动步骤 )
如果要中断多个嵌套循环,请连续使用几个!(不空格)。 例如:
*( *( ... // 一些移动步骤 ? [1,1]=# : !! ; // 这会中断 *( *( ...) ) 循环 ... // 其它一些移动步骤 ) )
另一个示例:
*( ?? [1,1]=_ : ... // 一些移动步骤 ? [1,1]=# : !! ; // this will break *( ) loop (actually both loops, the *(...) and the ?? ... ;)这会中断 *( )循环,实际为两个循环, *(...) 和 ?? ... ; ... // 其它一些移动步骤 ; )
宏文本可以包含C++注释,因此,宏会直接忽略一行中//之后的任何内容。
处于调试模式时,将会逐步执行宏。 按“调试”按钮可以激活调试模式。
要重置宏,请按“重置”按钮。
在宏代码的某个位置插入“`”符号(后单引号)将会中断执行宏并激活“宏”对话框,即使当前宏未处理调试模式也是如此。 此时不会打开调试模式,因此,按“执行”将继续执行宏。 玩家可以切换到调试模式,继续逐步执行宏。