ORANGE pico のタートルグラフィックスで「大石泉すき」

今日は14日…「石」を感じるね！
そして、石といえば大**石**泉だね！
というわけで、[ORANGE pico](http://www.picosoft.co.jp/orange/) のタートルグラフィックスで「大石泉すき」を描いてみた。

# プログラム

```
10 turtle 1,10,40,1,100
20 move 80
30 pen 0
40 turn -165
50 move 40
60 turn -105
70 pen 1
80 move 15
90 turn 45
100 move 40
110 pen 0
120 turn 180
130 move 40
140 turn 90
150 pen 1
160 move 40
170 pen 0
180 '
190 turn -95
200 move 50
210 turn 50
220 pen 1
230 move 80
240 pen 0
250 turn 180
260 move 40
270 turn -45
280 pen 1
290 move 50
300 pen 0
310 turn 180
320 move 24
330 turn 135
340 pen 1
350 move 20
360 pen 0
370 turn 180
380 move 20
390 turn 90
400 pen 1
410 move 40
420 turn 90
430 move 20
440 pen 0
450 turn 90
460 move 40
470 turn 180
480 pen 1
490 move 40
500 pen 0
510 '
520 turn -30
530 move 100
540 turn 165
550 pen 1
560 move 10
570 pen 0
580 turn 45
590 move 40
600 turn -90
610 pen 1
620 move 20
630 pen 0
640 turn 180
650 move 20
660 turn 90
670 pen 1
680 move 80
690 turn 90
700 move 20
710 pen 0
720 turn 97
730 move 81
740 turn 173
750 pen 1
760 move 80
770 pen 0
780 turn 173
790 move 81
800 turn -173
810 pen 1
820 move 80
830 pen 0
840 turn 180
850 move 40
860 turn -90
870 pen 1
880 move 50
890 turn 120
900 move 15
910 pen 0
920 turn 20
930 move 35
940 turn 130
950 pen 1
960 move 35
970 turn 145
980 move 40
990 pen 0
1000 turn -165
1010 move 70
1020 turn 190
1030 pen 1
1040 move 32
1050 turn -125
1060 move 30
1070 turn -45
1080 move 10
1090 pen 0
1100 '
1110 turn 177
1120 move 250
1130 turn -177
1140 pen 1
1150 move 60
1160 pen 0
1170 turn -155
1180 move 25
1190 turn -115
1200 pen 1
1210 move 30
1220 for i=1 to 36
1230 turn 10
1240 move 2
1250 next
1260 move 15
1270 turn 50
1280 move 30
1290 pen 0
1300 '
1310 turn -170
1320 move 100
1330 turn 20
1340 pen 1
1350 move 50
1360 pen 0
1370 turn 165
1380 move 50
1390 turn -165
1400 pen 1
1410 move 50
1420 pen 0
1430 turn -140
1440 move 35
1450 turn -140
1460 pen 1
1470 move 40
1480 turn 110
1490 move 10
1500 pen 0
1510 turn -30
1520 move 20
1530 turn -110
1540 pen 1
1550 move 15
1560 turn -40
1570 move 40
```

このプログラムは、[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja) でライセンスする。
このプログラム (改造したものを含む) を公開の場で利用する際は、出典を示していただけると嬉しい。
これは、Qiitaの利用規約に基づくプログラムの利用を禁止するものではない。

# 実行結果

大石泉すき。

![タートルグラフィックスによる「大石泉すき」](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/808d5c74-04bf-1735-4d58-62298ee2f7b3.png)

# 作った方法

インタラクティブモードでコマンドを打ち込んで結果を確認しながら、行番号をつけない状態で実行したコマンドを記録することで、描画を行うコマンド列を作っていった。
このコマンド列は、コピーしてUART (端末ソフトウェア) に貼り付けることで、実行し、それまでの部分を実行して描画できる。
途中 `for` コマンドを用いたループ

```
1220 for i=1 to 36
1230 turn 10
1240 move 2
1250 next
```

があるが、ORANGE pico では `for` 文を1行で書いても繰り返し処理が行われない罠があるため、開発中はループをunrollした以下の状態で書いておいた。

```
' 36 times
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2:turn 10:move 2
turn 10:move 2
```

満足のいく図形が描けたら、

* ループを `for` 文に切り替える
* `turtle` コマンドの遅延時間を設定する
* 空行 (文字の区切り) を空コメントにする

などの仕上げを行い、行番号を追加して完成させた。
ただし、行数が多く、行番号を手動で追加するのは大変である。
そこで、以下のプログラム (C言語) で行番号のデータを生成し、これを用いて[キーボードシミュレータ](https://www.vector.co.jp/soft/winnt/util/se391764.html)でテキストエディタに対し行番号を追加する操作を行った。
(このとき、「Enterを入力しない」を有効にした上で実行した)

```c
#include <stdio.h>

int main(void) {
    for (int i = 10;i <= 1570; i += 10) {
        printf("%d [VK_HOME][VK_DOWN]\n", i);
    }
    return 0;
}
```

# 今回新たに発見した罠

## 同じようにコマンドの引数を省略しても Syntax error になったりならなかったりする

`turtle` コマンドは、タートル番号、x座標、y座標、表示フラグ、遅延時間、の5個の引数をとる。
さらに、公式のコマンド一覧の説明では「パラメーターをすべて省略した場合」についての言及があり、パラメーターの一部のみを省略することもできそうに思える。

たとえば、遅延時間のみを省略した

```
turtle 1,250,150,1
```

コマンドは、インタラクティブモードで実行できた。

![4引数、単独で実行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7bd91f98-4a2a-4716-be24-1c4a833216ef.png)

さらに、このコマンドのみを含むプログラム

```
10 turtle 1,250,150,1
```

も、実行できた。

![4引数、単体のプログラム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/1c55f28f-4ebc-9221-188d-693c814bce04.png)

しかし、後ろに適当な処理として `print` コマンドを追加したプログラム

```
10 turtle 1,250,150,1
20 print 1
```

を実行しようとすると、「Syntax error in 10」が (しかも、なぜか2個) 出てきて、タートルは現れたが「1」は出力されなかった。

![print を後ろに追加したプログラム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/55b371fa-788d-4693-9899-c81ec8ec0a7c.png)

`turtle` の前に `print` コマンドを追加したプログラムは、素直に実行できた。

```
10 print 1
20 turtle 1,250,150,1
```

![print を前に追加したプログラム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6caa9dfd-4a8a-6eab-a728-a9db8e1c73e8.png)

さらに奇妙なことに、`print 1` のかわりに `?1` を追加する (`?` は `print` コマンドの省略形である) と、なぜか画面の表示内容が消え (`cls` コマンドの動作？)、「1」が表示された。

```
10 turtle 1,250,150,1
20 ?1
```

![?1 実行直前](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/6854cda2-a7ed-4471-4dc0-2dbdb97b6095.png)

上の状態からUARTでCRを送信する (Enterキーを押す) と、下の状態になった。

![?1 実行直後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/0befdbde-9424-7709-9dd4-97325fd312b2.png)

さらにさらに奇妙なことに、インタラクティブモードであっても、一旦 `turtle` コマンドに6個の引数を与えて Syntax error を発生した後だと、これまでは実行できていた4引数の `turtle` コマンドでも Syntax error が出るようになった。

![6引数の後の4引数で Syntax error](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/12560569-11bb-0890-7e6d-35fc054ee61d.png)

さて、`sprite` コマンドも、`turtle` コマンドと同様に5個の引数をとる。(スプライト番号、x座標、y座標、パターン番号、モード)
試してみると、`sprite` コマンドでも、引数を4個だけ指定して実行すると、`turtle` コマンドと同様に以下の現象が確認できた。

* 単体のプログラムや直前に `print` コマンドを置いたプログラムは実行できるが、直後に `print` コマンドを追加すると Syntax error が出る
* 直後に `?1` を置いて実行すると、画面がクリアされて「1」が表示される
* インタラクティブモードで6引数で実行し Syntax error を出すと、4引数でも Syntax error が出るようになる

![4引数の sprite の後に print を置くと Syntax error](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/5bdca3af-61c3-b40d-df1d-3c69633e5e9b.png)
![sprite で Syntax error の出方が変化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7fd4bbff-807d-0d5a-be91-61cf1552d4d7.png)

同じく5引数 (x座標、y座標、幅、アドレス、色コード) の `gput` コマンドで試すと、4引数での呼び出しは単体であっても Syntax error となり、今回の現象は確認できなかった。

![gput コマンドの実験](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/85ded884-e926-c8f6-62be-f3366e4caee6.png)

したがって、この現象は `turtle` 固有ではなく、他の一部のコマンドでもみられるが、定義された引数の数が同じすべてのコマンドでみられるというわけではないといえる。

そもそも、`turtle` コマンドも `sprite` コマンドも、公式のコマンド一覧の説明では引数を1個だけ省略できるとは書かれていない。(できないとも書かれていない)
必ず正常に動くわけでもなく、必ずエラーになるわけでもなく、複雑で不可解な挙動を示すというのは、罠であるといえるだろう。
回避方法は、引数を省略せずにすべて明示することだろう。