ADD 1 TO WS-COUNT. ADD 1 TO WS-SCORE WS-STEPS. *> 多目标 ADD WS-A WS-B GIVING WS-SUM. *> 结果存入新变量
SUBTRACT(减)
1 2
SUBTRACT 1 FROM WS-COUNT. SUBTRACT WS-A FROM WS-B GIVING WS-DIFF.
MULTIPLY(乘)
1 2
MULTIPLY WS-A BY WS-B. MULTIPLY WS-A BY WS-B GIVING WS-PROD.
DIVIDE(除)
1 2
DIVIDE WS-A BY WS-B GIVING WS-QUOT. DIVIDE WS-A INTO WS-B GIVING WS-QUOT REMAINDER WS-REM.
COMPUTE(复合运算)
最灵活,支持表达式:
1 2 3 4
COMPUTE WS-NEW-Y = WS-SY(1) - 1. COMPUTE WS-DIST = FUNCTION ABS(WS-TRY-X - WS-FOOD-X) + FUNCTION ABS(WS-TRY-Y - WS-FOOD-Y). COMPUTE WS-SEED = FUNCTION NUMVAL(WS-TIMESTAMP(9:8)).
运算符:+-*/**(幂)
ROUNDED 与 ON SIZE ERROR
1 2 3
COMPUTE WS-AVG ROUNDED = WS-TOTAL / WS-COUNT. ADD 1 TO WS-COUNT ON SIZE ERROR DISPLAY "溢出!".
4. 条件语句 IF
基本形式
1 2 3
IF WS-SCORE > 100 DISPLAY "优秀" END-IF.
IF-ELSE
1 2 3 4 5 6
IF WS-NEW-X < 1 OR WS-NEW-X > 20 MOVE "撞到墙壁" TO WS-END-REASON MOVE 0 TO WS-RUNNING ELSE PERFORM MOVE-FORWARD END-IF.
比较运算符
运算符
等价写法
含义
=
EQUAL
等于
<
LESS
小于
>
GREATER
大于
<=
NOT >
小于等于
>=
NOT <
大于等于
<>
NOT =
不等于
逻辑运算符
1 2 3 4 5 6 7
IF WS-A > 0 AND WS-B > 0 DISPLAY "都为正" END-IF.
IF WS-X = 1 OR WS-X = 2 OR WS-X = 3 DISPLAY "在范围内" END-IF.
复合条件与括号
1 2 3 4
IF WS-DIST < WS-BEST-DIST OR (WS-DIST = WS-BEST-DIST AND WS-TRY-DIR = WS-DIR) MOVE WS-DIST TO WS-BEST-DIST END-IF.
条件名(88 层级)
1 2 3 4 5 6
01 WS-RUNNING PIC 9 VALUE 1. 88 GAME-OVER VALUE 0.
IF GAME-OVER DISPLAY "游戏结束" END-IF.
5. 分支语句 EVALUATE
EVALUATE 类似其他语言的 switch,但更强大。
基本形式
1 2 3 4 5 6 7 8 9 10 11 12
EVALUATE WS-DIR WHEN 1 COMPUTE WS-NEW-Y = WS-SY(1) - 1 WHEN 2 COMPUTE WS-NEW-Y = WS-SY(1) + 1 WHEN 3 COMPUTE WS-NEW-X = WS-SX(1) - 1 WHEN 4 COMPUTE WS-NEW-X = WS-SX(1) + 1 WHEN OTHER DISPLAY "无效方向" END-EVALUATE.
多值匹配
1 2 3 4 5 6 7 8
EVALUATE WS-CODE WHEN 1 WHEN 2 WHEN 3 DISPLAY "低" WHEN 4 THRU 6 DISPLAY "中" WHEN OTHER DISPLAY "高" END-EVALUATE.
条件匹配(EVALUATE TRUE)
1 2 3 4 5 6 7 8
EVALUATE TRUE WHEN WS-SCORE >= 90 DISPLAY "A" WHEN WS-SCORE >= 60 DISPLAY "B" WHEN OTHER DISPLAY "C" END-EVALUATE.
6. 循环语句 PERFORM
PERFORM 是 COBOL 唯一的循环/调用机制,功能丰富。
6.1 调用段落(无循环)
1 2
PERFORM INIT-GAME. PERFORM SHOW-GAME.
6.2 条件循环(先判断)
1
PERFORM GAME-LOOP UNTIL WS-RUNNING = 0.
6.3 条件循环(后判断,至少执行一次)
1 2
PERFORM PROCESS-RECORD WITH TEST AFTER UNTIL WS-EOF = 1.
6.4 计数循环(VARYING)
1 2 3
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 12 DISPLAY WS-I END-PERFORM.
6.5 嵌套循环
1 2 3 4 5
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 12 PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 20 MOVE 0 TO WS-CELL(WS-I, WS-J) END-PERFORM END-PERFORM.
6.6 内联 PERFORM(END-PERFORM)
1 2 3 4 5 6
PERFORM UNTIL WS-I >= WS-SNAKE-LEN COMPUTE WS-K = WS-SNAKE-LEN - WS-I + 1 COMPUTE WS-J = WS-K - 1 MOVE WS-SX(WS-J) TO WS-SX(WS-K) ADD 1 TO WS-I END-PERFORM.
6.7 提前退出
1 2 3 4 5
PERFORM VARYING WS-K FROM 1 BY 1 UNTIL WS-K > WS-SNAKE-LEN IF WS-SX(WS-K) = WS-NEW-X EXIT PERFORM *> 跳出当前循环 END-IF END-PERFORM.
CHOOSE-DIR. MOVE 99 TO WS-BEST-DIST MOVE 0 TO WS-BEST-DIR PERFORM VARYING WS-TRY-DIR FROM 1 BY 1 UNTIL WS-TRY-DIR > 4 PERFORM TEST-DIRECTION IF WS-SAFE = 1 COMPUTE WS-DIST = FUNCTION ABS(WS-TRY-X - WS-FOOD-X) + FUNCTION ABS(WS-TRY-Y - WS-FOOD-Y) IF WS-DIST < WS-BEST-DIST OR (WS-DIST = WS-BEST-DIST AND WS-TRY-DIR = WS-DIR) MOVE WS-DIST TO WS-BEST-DIST MOVE WS-TRY-DIR TO WS-BEST-DIR END-IF END-IF END-PERFORM IF WS-BEST-DIR NOT = 0 MOVE WS-BEST-DIR TO WS-DIR END-IF.
分析: 遍历 4 个方向,对每个安全方向计算到食物的曼哈顿距离,选择距离最小的方向(贪心算法)。
延时控制
1 2 3 4 5 6 7 8
DELAY. IF WS-SCORE < 35 COMPUTE WS-DELAY-US = 200000 - WS-SCORE * 4000 ELSE MOVE 60000 TO WS-DELAY-US END-IF CALL "usleep" USING BY VALUE WS-DELAY-US END-CALL.
分析: 分数越高延时越短(速度越快),最低 60ms。通过 CALL 调用 C 库函数 usleep。