SHIROのIchigoJam日記

マイコン「IchigoJam」(イチゴジャム)の電子工作とプログラミングをメインに

大学入学共通テストのすごろく

2021年度大学入学共通テストが1/16(土)・17(日)に行われましたが、17日の科目「情報基礎」の第3問
https://mainichi.jp/exam/kyotsu-2021/q/?sub=IFB10
で、すごろくのプログラミングの問題が出ました。
IchigoJam BASICで、そのすごろくを組んでみました。
ゲームプログラムを作ったことがある受験生は「うんうん、配列変数はこんな風に使うよね」でしょうが、未経験だとかなり難しいんじゃないでしょうか。

問1「基本のすごろく」

問題を穴埋めした正解のプログラムはこちら。

(01) ninzu←2, owari←0, r←0
(02) iを1からninzuまで1ずつ増やしながら,
(03) | Koma[i,r]←1
(04) を繰り返す
(05) owari=0の間,
(06) | r←r+1
(07) | iを1からninzuまで1ずつ増やしながら,
(08) | | Saikoro[i,r]←【出た目を入力】
(09) | | k←Koma[i,r-1]
(10) | | bairitu←Masu[k]
(11) | | もしbairitu=0かつSaikoro[i,r]≧4ならば
(12) | | | bairitu←1
(13) | | を実行する
(14) | | idou←切り捨て(Saikoro[i,r]×bairitu)
(15) | | Koma[i,r]←k+idou
(16) | | もしKoma[i,r]<1ならばKoma[i,r]←1を実行する
(17) | | もしKoma[i,r]≧15ならば
(18) | | | Koma[i,r]←15, owari←1
(19) | | を実行する
(20) | を繰り返す
(21) を繰り返す

これをIchigoJam BASICで組んでみたのがこちら。
スペースキーを押すと、プレイヤーが交互にさいころを振って進みます。コースの15のマスに着くと終了します。
f:id:shiro0922:20210119001556p:plain
IchigoJam webで動かせます。

1 CLS
2 LET [1],1,1,-1,2,1,0,1,0,1,1,-1,2,1,-1,1
3 LC 0,2
4 FOR X=1 TO 15
5 IF [X]=1 ?"-";
6 IF [X]=-1 ?"/";
7 IF [X]=0 ?"O";
8 IF [X]=2 ?"@";
9 NEXT
10 N=2:E=0:R=0
20 FOR I=1 TO N
22 LC 0,I-1
23 ?I
25 LC 0,I*5
26 ?"==PLAYER";I;"=="
27 ?"-":?"-":?1
30 [I*20+R]=1
40 NEXT
50 @LOOP
60 R=R+1
70 FOR I=1 TO N
72 LC R*3,I*5+1
73 ?R
74 BEEP:WAIT 30
75 IF !BTN(32) CONT
76 SRND TICK()
80 [40+I*20+R]=RND(6)+1
85 LC R*3,I*5+2
86 ?[40+I*20+R]
90 K=[I*20+R-1]
100 B=[K]
110 IF B=0 AND [40+I*20+R]>=4 THEN B=1
120 '
130 '
140 D=[40+I*20+R]*B
141 IF B=2 D=[40+I*20+R]/2
150 [I*20+R]=K+D
160 IF [I*20+R]<1 THEN [I*20+R]=1
170 IF [I*20+R]>=15 THEN [I*20+R]=15:E=1
180 '
190 '
191 V=#900+32*(I-1)
192 POKE V,0
193 COPY V+1,V,31
194 LC [I*20+R]-1,I-1
195 ?I
197 LC R*3,I*5+3
198 ?[I*20+R];
200 NEXT
210 IF E=0 GOTO @LOOP
211 BEEP 10,30
212 LC 0,15
213 CLK
  • 行番号は、問題プログラムの(01)→10、(02)→20…と10刻みに対応しています。それ以外の行は画面表示など他の処理をしています。
  • 変数は以下のように変えています。
    • owari → E
    • bairitu → B
    • idou → D
    • Koma[*,*] → [20]~[39](プレイヤー1)、[40]~[59](プレイヤー2)
    • Saikoro[*,*] → [60]~[79](プレイヤー1)、[80]~[99](プレイヤー2)

問2「オバケを追加」

問題を穴埋めした正解のプログラムはこちら。

(01) ninzu←2, owari←0, r←0, obake←6
(02) iを1からninzuまで1ずつ増やしながら,
(03) | Koma[i,r]←1
(04) を繰り返す
(05) owari=0の間,
(06) | r←r+1
(07) | a←(r-1)%4
(08) | もしa<2ならば
(09) | | obake←obake+1
(10) | を実行し, そうでなければ
(11) | | obake←obake-1
(12) | を実行する
(13) | iを1からninzuまで1ずつ増やしながら,
(14) | | Saikoro[i,r]←【出た目を入力】
(15) | | k←Koma[i,r-1]
(16) | | bairitu←Masu[k]
(17) | | もしbairitu=0かつSaikoro[i,r]≧4ならば
(18) | | | bairitu←1
(19) | | を実行する
(20) | | idou←切り捨て(Saikoro[i,r]×bairitu)
(21) | | Koma[i,r]←k+idou
(22) | | もしKoma[i,r-1]<obake かつ Koma[i,r]>obakeならば
(23) | | | Koma[i,r]←obake
(24) | | を実行する
(25) | | もしKoma[i,r]<1ならばKoma[i,r]←1を実行する
(26) | | もしKoma[i,r]≧15ならば
(27) | | | Koma[i,r]←15, owari←1
(28) | | を実行する
(29) | を繰り返す
(30) を繰り返す

これをIchigoJam BASICで組んでみたのがこちら。
f:id:shiro0922:20210119002411p:plain
IchigoJam webで動かせます。

1 CLS
2 LET [1],1,1,-1,2,1,0,1,0,1,1,-1,2,1,-1,1
3 LC 0,3
4 FOR X=1 TO 15
5 IF [X]=1 ?"-";
6 IF [X]=-1 ?"/";
7 IF [X]=0 ?"O";
8 IF [X]=2 ?"@";
9 NEXT
10 N=2:E=0:R=0:G=6
20 FOR I=1 TO N
22 LC 0,I-1
23 ?I
25 LC 0,I*5
26 ?"==PLAYER";I;"=="
27 ?"-":?"-":?1
30 [I*20+R]=1
40 NEXT
50 @LOOP
60 R=R+1
70 A=(R-1)%4
80 IF A<2 THEN G=G+1 ELSE G=G-1
90 '
100 '
110 '
120 '
121 LC G-2,2:?CHR$(0,237,0)
130 FOR I=1 TO N
132 LC R*3,I*5+1
133 ?R
134 BEEP:WAIT 30
135 IF !BTN(32) CONT
136 SRND TICK()
140 [40+I*20+R]=RND(6)+1
145 LC R*3,I*5+2
146 ?[40+I*20+R]
150 K=[I*20+R-1]
160 B=[K]
170 IF B=0 AND [40+I*20+R]>=4 THEN B=1
180 '
190 '
200 D=[40+I*20+R]*B
201 IF B=2 D=[40+I*20+R]/2
210 [I*20+R]=K+D
220 IF [I*20+R-1]<G AND [I*20+R]>G THEN [I*20+R]=G
230 '
240 '
250 IF [I*20+R]<1 THEN [I*20+R]=1
260 IF [I*20+R]>=15 THEN [I*20+R]=15:E=1
270 '
280 '
281 V=#900+32*(I-1)
282 POKE V,0
283 COPY V+1,V,31
284 LC [I*20+R]-1,I-1
285 ?I
287 LC R*3,I*5+3
288 ?[I*20+R];
290 NEXT
300 IF E=0 GOTO @LOOP
301 BEEP 10,30
302 LC 0,15
303 CLK
  • 変数は以下のように変えています。
    • obake → G

ケーブル通信ボード

f:id:shiro0922:20201225125203j:plain

f:id:shiro0922:20201225125405j:plain
2台のIchigoJam/IchigoDakeをケーブルでつないで双方向通信するボードです。
基本的には3本のケーブルでTX、RX、GND端子をクロス配線でつなげばいいだけなのですが、学校やクラブで簡単に使える教材として、専用基板を作ってみました。

使い方

  • ケーブル両端の基板のピンヘッダを、2台のIchigoJam/IchigoDakeのCN3ソケットに差します。
  • 基板上のスライドスイッチを、最初はOFFにしておいてください。OFFの状態だと通信しません。
  • IchigoJam/IchigoDakeの電源を入れます。
  • 基板上のスライドスイッチをONにして、互いに通信します。キー入力してEnterキーを押すと、その内容が相手に送信されます。入力を間違えて「Syntax error」の嵐になった時は、スイッチをOFFにして通信を止めてください。

スライドスイッチは、RX端子へつながる入力ラインをON/OFFしています。OFFにすると、相手から信号が送られて来ても受信しなくなります。

中学校技術科での「ネットワークを使った双方向通信のプログラミング」は、私はこれまでの出張授業で、IchigoJam+MixJuiceを使って無線通信でやってきました。
が、2台だけならちゃんと通信するのですが、教室内で18ペア(36台)でやると、電波干渉のためか接続が切れるペアが続出します。一度切れてしまうと「MJ TCP ~」の設定からやり直さないといけないので、かなり面倒なことになります。

このボードを使って有線接続にすると、ペアの机をくっつけてケーブルを張らないと引っかけてしまうなどの問題はありますが、面倒な設定無しで確実につながりますし、そうそう切れません。通信速度も高速です。
「Syntax error」の嵐になった時はスイッチを切ればいいので、対処も楽です。

基板データ

*同じ基板を10枚配置しています。基板を5枚発注すれば50枚取れるので、1クラス分が賄えます。
*この基板データは、CC BYライセンスとします。どうぞご利用ください。

(C) 2020 Shiro Saito (https://www.ichigojaman.jp)

エニグマ暗号機

★この記事は「IchigoJam Advent Calendar 2020」にエントリーしています。

先日公開した「かんたん暗号作成」プログラムをさらに発展させて、第2次世界大戦中にドイツ軍が使った暗号機「エニグマEnigma)」を再現してみました。
f:id:shiro0922:20201220072903p:plain

使い方

  • 起動すると「Rotor Set No.=?」と聞かれるので、換字ローターをセットする初期値(数字)を入力します。その後、ローターをセットする間待たされます。(IchigoJam実機で数秒、IchigoJam webで10秒ほど)
  • 「KEY INPUT (A-Z)?」と聞かれるので、原文の文字列を1文字ずつ入力します(A~Zの範囲。それ以外の文字は無視されます)。その下の行に暗号文が1文字ずつ表示されます。終了する時はEnterキーを押してください。
  • エニグマは暗号化だけでなく、原文に戻す復号化もできます。同じローター初期値を設定して、暗号文を入力すると、原文が出てきます。

プログラム

10 CLV:?"***ENIGMA***"
20 INPUT "Rotor Set No.=?",S
30 SRND S
40 FOR R=0 TO 2
50 Q=R*26
60 FOR I=0 TO 25
70 [Q+I]=I
80 NEXT
90 FOR I=1 TO 100
100 A=RND(26):B=RND(26)
110 C=[Q+A]:[Q+A]=[Q+B]:[Q+B]=C
120 NEXT
130 NEXT
140 ?"*KEY INPUT (A-Z)?"
150 @KLOOP
160 K=INKEY():IF !K CONT
170 IF K=10 ?:?:END
180 K=K-65
190 IF K<0 OR K>25 GOTO @KLOOP
200 ?CHR$(K+65,10,23);
210 FOR R=0 TO 2
220 K=[R*26+K]
230 NEXT
240 K=25-K
250 FOR R=2 TO 0 STEP -1
260 S=R*26
270 IF [S]!=K S=S+1:CONT
280 K=S-R*26
290 NEXT
300 ?CHR$(K+65,30);
310 R=0:GSB @ROT
320 GOTO @KLOOP
330 @ROT
340 Q=R*26:A=[Q]
350 FOR I=0 TO 24
360 [Q+I]=[Q+I+1]
370 NEXT
380 [Q+25]=A
390 [100+R]=[100+R]+1
400 IF [100+R]=26 [100+R]=0:IF R<2 R=R+1:GSB @ROT
410 RTN

IchigoJam web版はこちら。

エニグマでの暗号化

エニグマ暗号機の内部には、回転するローターが3個、反転ローター(固定)が1個あります。
f:id:shiro0922:20201220211041p:plain
キーボードで入力した文字は、①ローター1→②ローター2→③ローター3→④反転ローター→⑤ローター3→⑥ローター2→⑦ローター1と合計7回変換され、ランプボードで変換後の文字ランプが点きます。

また、3個のローターは1文字変換するごとに回転します。

  • 1文字変換すると、ローター1が1目盛り回転
  • ローター1が1周(26目盛り)回転すると、ローター2が1目盛り回転
  • ローター2が1周(26目盛り)回転すると、ローター3が1目盛り回転

つまり、換字表の組み合わせが1文字ごとに変わります。そのため、例えば「AAA」と同じ文字を連続して入力しても、同じ文字に変換されるとは限りません。

上図のように内部で反転して戻る回路になっているため、暗号化と複合化が1台の機械でできます。
例えば、原文の「A」が暗号文の「S」に変換されたとすれば、同じローター配置で「S」を入力すれば「A」に変換されます。
実機のエニグマでは、電気回路の設計上「A」→「A」と同じ文字に変換されることは無いのですが、このプログラムではそうした制限はありません。

ドイツ軍の実際の運用では、5個以上のローターを用意して、日によって使うローター・入れる順番・初期位置を変えていました。(このプログラムでは、最初の「Rotor Set No.」入力がその設定だと思ってください)
また、実機のエニグマには上記のローターに加えて、特定の文字を交換するプラグボードがありましたが、このプログラムでは実装していません。

プログラム説明

  • 20~30行…ローターの初期値を入力して、SRNDで乱数を初期設定。
  • 40~130行…ローター3個(プログラム内では0番~2番)の初期設定。60~80行でA~Z(0~25)を順に配列変数へセットし、90~120行で乱数で取り出した配列2個の値を交換×100回して、ランダムなローターに。
  • 150~200行…文字入力と画面表示。A~Z以外の文字は無視。Enterキー(文字コード10)が入力されたら終了。200行の表示では、文字コード10(改行)+文字コード23(行末移動)で、下の暗号文の行末へカーソル移動。
  • 210~300行…文字変換。上図で言うと、210~230行がローター変換①②③、240行が反転ローター④、250~290行がローター逆変換⑤⑥⑦(換字表配列を逆引きして変換)、300行で変換後の文字を表示。
  • 330~410行…ローターの回転処理サブルーチン。26目盛り回転ごとに再帰呼び出しして、ローター0番~2番の回転を処理。

参考資料

プログラム作成に当たって、以下のページを参考にさせていただきました。