IchigoJam で「13日の金曜日」を探してみた。
前後2年、合計5年分の13日の曜日を表示し、金曜日ならハイライトする。
表示する範囲は移動できる。
※IchigoJamはjig.jpの登録商標です。
プログラム
10 ' 13 ニチ ノ キンヨウビ
20 N=2023
30 IF!NPOKE#7FE,#0A:IFI2CR(#51,#7FE,1,#7FF,1)N=2023ELSED=PEEK(#7FF):N=2000+D/16*10+D%16
40 POKE#700,16,16,124,16,16,16,254,0,126,66,66,126,66,66,126,0,62,34,62,34,62,66,134,0,16,16,84,88,16,40,198,0,16,18,244,56,84,146,48,0,16,254,16,56,84,146,16,0,16,40,254,16,254,84,254,0
50 POKE#700+8*7,64,126,144,124,80,254,16,0,136,190,136,136,184,204,186,0,62,66,222,86,94,66,70,0,30,234,190,228,174,252,14,0
60 FORI=0TO8*11-1:POKE#780+I,~PEEK(8*#30+I):NEXT:FORI=0TO7:POKE#780+8*11+I,~PEEK(8*#E2+I):POKE#780+8*12+I,~PEEK(8*#E6+I):NEXT
70 CLS:?13;CHR$(#E1,#E8,#E9,#EA,#E1);"?":FORD=-2TO2:Y=N+D:LOCATE(Y<1000)+(Y<100)+(Y<10),11+4*D:?Y;CHR$(#E7):FORM=1TO12:L=M:X=Y:IFL<3X=X-1:L=L+12
80 C=X/100:Z=X%100:G=5*C+C/4:H=(13+26*(L+1)/10+Z+Z/4+G)%7:K=H=6:LOCATE6+(M-1)%4*6,11+4*D+(M-1)/4:IFM<10?CHR$(#20+#6F*K);
90 IFKANDM>9?CHR$(#F0+M/10);
100 IFK?CHR$(#F0+M%10);ELSE?M;
110 ?CHR$(#E2+#19*K,#3A+#C0*K,(#E0+H)*!K+#FC*K):NEXT:NEXT
120 K=INKEY():D=(K=DOWNORK|#20=#61)-(K=UPORK|#20=#71):IFDN=N+D:GOTO70ELSEGOTO120
このプログラムは、CC0 1.0 でライセンスする。
20 N=2023
により、表示範囲の中央を設定している。この行を
20 N=0
とすると、GROVE - 高精度RTC から年を取得し、取得した年を表示範囲の中央の初期値とする。
取得を試みて失敗判定となった (I2CR
が非零を返した) 場合は初期値を2023年に設定するが、I2C 機器を全く接続していない場合に I2CR
がフリーズするケースがあったため、20行目により取得の試み自体を行わない設定にできるようにした。
操作方法
-
Q
キー / 矢印上キー:表示範囲を過去に移動する -
A
キー / 矢印下キー:表示範囲を未来に移動する
UART経由でも操作しやすいよう、矢印キーに加えてアルファベットキーでも操作できるようにした。
実行結果例
解説
10行目:タイトル
FILES
対応のタイトル行である。
20~30行目:表示範囲の初期値設定
20行目で、表示範囲 N
の初期値を設定する。
ここで 0
に設定した場合、30行目のRTCから年を取得して初期値に反映する処理を実行する。
40~60行目:フォントの設定
40行目・50行目で、美咲フォント (美咲ゴシック第2) のサブセットをキャラクターパターンRAMに書き込む。
今回用いる「土日月火水木金年は何曜」に対応するパターンを順に書き込んでいる。
60行目で、数字 (0~9)、コロン、「月」「金」に対応するパターンをそれぞれ白黒反転したパターンを作成する。
70~110行目:曜日の計算と描画
70 CLS:?13;CHR$(#E1,#E8,#E9,#EA,#E1);"?"
画面をクリアし、「13日は何曜日?」を描画する。
FORD=-2TO2:Y=N+D
表示範囲の中央 N
の前後2年の範囲を描画する。
中央との差 D
を具体的な年 Y
に変換する。
LOCATE(Y<1000)+(Y<100)+(Y<10),11+4*D:?Y;CHR$(#E7)
何年かを描画する。4桁未満の場合は描画位置を調整して「年」を揃える。
0年未満や9999年超には対応していない。
FORM=1TO12
それぞれの月 M
に関する描画を行う。
L=M:X=Y:IFL<3X=X-1:L=L+12 80 C=X/100:Z=X%100:G=5*C+C/4:H=(13+26*(L+1)/10+Z+Z/4+G)%7:K=H=6
ツェラーの公式 により、それぞれの月の13日の曜日 H
を求める。
さらに、それが金曜日かを判定し、変数 K
に格納する。
LOCATE6+(M-1)%4*6,11+4*D+(M-1)/4
それぞれの月の描画位置にカーソルを移動する。
IFM<10?CHR$(#20+#6F*K);
月が1桁の場合、空白を出力して描画位置を合わせる。
金曜日の場合は白い空白 #8F
を、そうでない場合は黒い空白 #20
を出力する。
90 IFKANDM>9?CHR$(#F0+M/10);
金曜日の場合、かつ月が2桁の場合、月の十の位を白黒反転した数字で描画する。
100 IFK?CHR$(#F0+M%10);ELSE?M;
金曜日の場合、月の一の位を白黒反転した数字で描画する。
それ以外の場合、月を普通の数字で描画する。(存在すれば十の位も含む)
110 ?CHR$(#E2+#19*K,#3A+#C0*K,(#E0+H)*!K+#FC*K)
「月:」および曜日を出力する。
金曜日の場合は白黒反転した文字を、そうでない場合は普通の文字を用いる。
NEXT:NEXT
月のループ、および年のループを進める。
120行目:操作受付
入力されたキーに応じて、変数 D
に描画範囲の移動幅を書き込む。
この移動幅が非零になったら、描画範囲に反映し、描画処理を実行する。
キーの値と #20
の論理和をとることで、入力がアルファベットである場合小文字に変換し、小文字のコードとの比較のみをすればよいようにした。