Casio Basic入門22

Casio Basic入門
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終: 2019/05/04

 4. CasioBasicを使ってみる(続き)

Chapter 4

◆ Chapter 4 の目標: 換算プログラム(令和対応版)を作る

前回: Casio Basic入門21



Chapter4-5
キー長押しの処理をつくる

前回説明した予定に従って、プログラムを変更および追加してゆきます。

これまでに作った 初期設定 と 表示の初期化ブロック は、以下です。

0→A:0→B:0→G

Locate 1,1,"0:AD"
Locate 10,1,"DMS"
Locate 11,1,"EXIT
"
Locate 1,2,"1:T"
Locate 10,2,"2:S"
Locate 1,3,"3:H"
Locate 10,3,"4:R"
Locate 1,4,"5:In("
Locate 5,4," "

Locate 10,4,"6:yσn"

Locate 14,4," "

While 1

一応、While 1 まで書きました。

表示の初期化ブロック をサブルーチン YRD に受け持たせるようにする場合、サブルーチン YRD は以下のようにします。

サブルーチン:YRD

Locate 1,1,"0:AD"
Locate 10,1,"DMS"
Locate 11,1,"EXIT
"
Locate 1,2,"1:T"
Locate 10,2,"2:S"
Locate 1,3,"3:H"
Locate 10,3,"4:R"
Locate 1,4,"5:In("
Locate 5,4," "

Locate 10,4,"6:yσn"

Locate 14,4," "


そして、メインルーチンの [初期設定]ブロック と [表示の初期化]ブロック を以下のようにします。

0→A:0→B:0→G

Whle 1

Prog "YRD"


ここで [表示の初期化]ブロック を While ループの中に移動させていることに注目してください。その意味は後でお分かり頂けると思います。

続いて、[メニュー番号取得]ブロック が続きます。このブロックは変更しません。

-1→N
Do
Getkey→K
LpWhile K=0
K=25⇒0→N
K=35⇒1→N
K=36⇒2→N
K=36⇒3→N
K=21⇒4→N
K=22⇒5→N
K=23⇒6→N


さて、プログラムの構造は以下のようなものにしてゆきます。

プログラムの構造

[初期設定]

While 1

  [表示の初期化]

    [メニュー番号取得]

  [キー長押し検出]

    [入力処理]

    [計算と出力処理]

WhileEnd

[キー長押し検出]ブロック を上記の位置に追加してゆくことにします。

このように、ブロック構造を意識しておくと、必要なところのみを変更し、独立したブロックを追加することで、機能追加がしやすくなります。

キー長押しを検出するには、

・ループの中で Getkeyコマンドを使い、
・あるキーのキーコードが押されている時だけ回るループを所定の回数だけ回して、
・その所定の回数でループから脱出してくれば、
・そのキーが長押しされたことが分かる


...と言うプログラムの考え方ロジック)を使います。

例えば、[1]キーの長押しは、以下のようにして検出できます。

0→F
0→C
While Getkey=35
Isz C
C=9⇒Break
WhileEnd

C=9⇒1→F

これを細かく見てみましょう。

変数F は長押しキーに対応するメニュー番号です。上記場合は、[1]キーを長押したので、F に 1 を代入しています。

なお、F を 0 で初期化しています。[1][4] のキーが長押しされなければ、F は 0 のままになります。メニュー番号に応じて処理を行う場合に、F が 0 ならば何も処理を行いません。 F が 1 ならば、明治の始まりと終わりの年月日をお表示する処理を行うわけです。

変数 F はプログラム実行中に勝手に変更されては困るので、予約変数として扱い、他の部分やサブルーチンでは使わない変数にする必要があります。いい変えれば、他の目的に使われてはマズイことになります。そこで、ここまでプログラムを作ったところで、まだ使われていない F を変数に選びました。


変数 C は、While ループが回る回数をカウントするカウンタ変数として使います。この変数は、Whileループの中だけで必要で、プログラムの他の部分で値が変わっても、全く影響ありません。つまり、変数 C は使い捨て変数として扱います。プログラムの他の部分で使用されていても良いので、カウンター C とわかりやすい名前にしています。

カウンタなので、C は0で初期化します。

While Getkey=35

これは、Getkey が実行された時に押されているキーのキーコードが 35 の場合は、ループに入る... ということです。
キーコード 35 は、[1]キーの対応します。

長押しキーが [1] でない時は、ループに入らず、WhileEnd までジャンプします。ここで Do ループを使うと、必ずループの入ってしまい、長押しキーが [1]でない時は、無駄な動作をします。従って、Whileループを使います。

While ループの中で実行するのは、以下です。

Isz C
C=9⇒Break


ループが回るたびに、Isz C で C をインクリメント(1つ増加)させています。
そして、C が 9 になったら、Breakコマンドを実行します。

Breakコマンドは、ループを強制的に抜けるコマンドです。
ループが9回まわった時、キーコードが依然として 35 である時、Whileループを脱出します。

長押し時間は、ループが9回まわるだけの時間、ということです。この 9 をを変更すれば、検出すべき長押し時間を調整できます。ここでは、9回まわる時間を長押し時間としています。


ループを脱出した直後に、

C=9⇒1→F

があります。カウンタ C が 9 の時、つまり[1]キーが所定の時間以上長押しされた時に、メニュー番号 F に 1 を代入しています。


これで、[1]キーが長押しされると メニュー番号 F に 1 を代入する...という動作をプログラミングできました。


この処理に続いて、[2]キーが長押しされた時に メニュー番号 F に 2 を代入する処理を書きます。

0→C
While Getkey=36
Isz C
C=9⇒Break
WhileEnd

C=9⇒2→F

書き換えているのは赤文字の部分のみで、あとは全く同じコードになっています。

ここでは、メニュー番号 F の初期化を行っていません。行う必要がありません。F の初期化は、どのキーも所定の時間以上長押しされなければ 0 にするのが目的でした。従って、一連の長押し検出ブロックの最初に一回初期化しておけば良いのです。

同様にして、[3]キーや [4]キーが長押しされた時の処理を続けて記述します。

0→C
While Getkey=37
Isz C
C=9⇒Break
WhileEnd

C=9⇒3→F

0→C
While Getkey=21
Isz C
C=9⇒Break
WhileEnd

C=9⇒4→F



さて、このようにして長押しされたキーが [1][4] のいずれか、或いはどれでもないことが検出されたら、メニュー番号 F に従った処理をサブルーチン YRD の中で行います。

Casio Basic の特殊性の1つに、メインプログラムの変数は、そのままサブルーチンで使えるという点があります。サブルーチンである変数が変更されたら、メインルーチンではその変数を参照すれば値が変更されているわけです。プログラムに慣れた人には、Casio Basic の変数は究極の大域変数だ、と言えば分かるでしょう。

さて、変数 F の値は、以下の可能性があります。

・F=0: キー長押しがされない時
・F=1: [1]キー長押しの時
・F=2: [2]キー長押しの時

・F=3: [3]キー長押しの時
・F=4: [4]キー長押しの時


サブルーチン YRD では、表示の初期化 も行いますので、

・F=-1: 表示の初期化を行う時

を追加しておきます。


そして、F の値に応じて、サブルーチン YRD の処理を行うようにします。さて、この処理はプログラム全体の流れとは全く無関係な処理です。つまり、プログラム全体の流れから見れば、例外処理といえます。

以前 Casiobasic入門11 で、例外処理について取り上げていますので、参考にしてください。

今回は、変数 F が0でないとき(真のとき)に、サブルーチン YRD を呼び出して、必要な処理を行うようにします。
そこで、F が0でない時、プログラムの最後、WhileEnd の手前に Goto コマンドでジャンプさせ、そこで例外処理を行います。

例外 = Exception (イクセプション)なので、Goto E / Lbl E を使うことにします。


さて、F が0以外の時に Goto E を実行するのは、以下のように簡潔に書けます。

F⇒Goto E

そして、Lbl E 以下を以下のようにします。

Lbl E
If F:then
Prog "YRD"
-1→F
IfEnd


WhileEnd


WhileEnd はプログラムの一番最後に記述するコマンドです。


変数 F を -1 にするのは、[表示の初期化] をサブルーチンYRD 内で実行する時です。
それならば、プログラムが起動した直後は F は -1 でなければなりません。そこで、初期化ブロック では、変数 F を -1 で初期化しておく必要があります。

同様に、上の 例外処理ブロック でも、サブルーチン YRD 実行後は、F を -1 にしておきます。


[初期設定] は、以下のように変更しておきます。

0→A:0→B:0→G
-1→F



変数 F が -1 の場合を考慮して、[表示の初期化]ブロック を以下のように変更しておきます。

If F:Then
Prog "YRD"
Prog "YRC"
IfEnd



ここでは、Prog "YRC" を追加しました。

サブルーチン YRC は既に作っています。ここでも変更しません。

和暦の始まりと終わりの年月日を サブルーチン YRD で表示し、[EXE]キーでメインルーチンに戻った後、表示の初期化を行って、さらに各項目で表示されていた値も再描画するためには、ここでサブルーチンYRC を実行しておく必要があるからです。

但し、プログラム起動時に、サブルーチン YRC が何もしないようにすべきです。そこで、初期設定ブロック で N を -1 で初期化しておくことにします。

YRCYRD は、紛らわしいので注意してください(紛らわしくてすみません)。


初期設定ブロック

0→A:0→B:0→G
-1→F:-1→N



以上をまとめると、プログラムの構造 は以下のようになります。

プログラムの構造

[初期設定]

While 1

  [表示の初期化]

    [メニュー番号取得]

  [キー長押し検出]

    [入力処理]

    [計算と出力処理]

  [例外処理]

WhileEnd


[入力処理]ブロック や [計算と出力処理]ブロック は変更がありません。


ここまでで変更したメインルーチンのプログラム名を YEAR CONV としましょう。以下にまとめます

プログラム名: YEAR CONV

0→A:0→B:0→G
-1→F:-1→N

While 1

If F:Then
Prog "YRD"
Prog "YRC"
IfEnd


-1→N
Do
Getkey→K
LpWhile K=0
K=25⇒0→N
K=35⇒1→N
K=36⇒2→N
K=36⇒3→N
K=21⇒4→N
K=22⇒5→N
K=23⇒6→N


0→F
0→C
While Getkey=35
Isz C:C=9⇒Break
WhleEnd:C=9⇒1→F

0→C
While Getkey=36
Isz C:C=9⇒Break
WhleEnd:C=9⇒2→F

0→C
While Getkey=37
Isz C:C=9⇒Break
WhleEnd:C=9⇒3→F

0→C
While Getkey=21
Isz C:C=9⇒Break
WhleEnd:C=9⇒4→F

F⇒Goto E


If N=0:Then
5→X:1→Y:4→D:1→E
Prog "INPI":Z→A

Else If N=1
Then
4→X:2→Y:4→D:1→E
Prog "INPI":Z→T

Else If N=2
Then
13→X:2→Y:4→D:1→E
Prog "INPI":Z→S

Else If N=3
Then
4→X:3→Y:4→D:1→E
Prog "INPI":Z→H

Else If N=4
Then
13→X:3→Y:4→D:1→E
Prog "INPI":Z→R

Else If N=5
Then
If A:Then
5→X:4→Y:4→D:1→E
Prog "INPI":Z→B
IfEnd

Else If N=6
Then
If A:Then
12→X:4→Y:3→D:1→E
Prog "INPI":Z→G
IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd

If N=0:Then
Prog "YRC"
Else If N=1
Then
T+1911→A
T=0⇒Isz A
Prog "YRC"

Else If N=2
Then
S+1925→A
S=0⇒Isz A
Prog "YRC"

Else If N=3
Then
H+1988→A
H=0⇒Isz A
Prog "YRC"

Else If N=4
Then
R+2018→A
R=0⇒Isz A
Prog "YRC"

Else If N=5
Then
If A:Then
Prog "YRC"
IfEnd

Else If N=6
Then
If A:Then
Prog "YRC"
IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd

Lbl E
If F:Then
Prog "YRD"
-1→F:IfEnd


WhileEnd


(追加した部分を赤文字で示した)


一見行数が多くなっていますが、各部分は類似のコードの繰り返しになっており、併せてブロック構造を考えて見れば、簡単な処理が並んでいるだけのものだと、お分かり頂けるでしょう。

 ⇒ CasioBasicコマンドリファレンス
  - Whileループ
  - Doループ
  - Getkeyコマンド
  - Isz命令
  - Breakコマンド
  - ⇒命令



Chapter4-6
サブルーチンを使いこなす

これまで、ブラックボックスのまま扱ってきた サブルーチン YRD を実際に書いてゆきます。

サブルーチン YRD は、変数 F の値に応じた表示処理を行います。

・F=0 の時: 何もしない
・F=-1 の時: 各項目の初期表示
・F=1 の時: 明治の始まりと終わりの年月日を表示
・F=2 の時: 大正の始まりと終わりの年月日を表示
・F=3 の時: 昭和の始まりと終わりの年月日を表示
・F=4 の時: 平成の始まりの年月日を表示



F=-1 の時の表示
各項目の初期表示
YearConv_1  

F=1 の時の表示
大正の始まりと終わり
Taisho  

F=2 の時の表示
昭和の始まりと終わり
Showa  

F=3 の時の表示
平成の始まりと終わり
Heisei 

F=4 の時の表示
令和の始まり
Reiwa  

F=1 ~ 4 の時は、右下に ►E の表示をしています。これは、[EXE]キーで元に戻るこを示す表示です。

サブルーチン: YRD

If F=-1:Then
Locate 1,1,"0:AD"
Locate 10,1,"DMS"
Locate 11,1,"EXIT
"
Locate 1,2,"1:T"
Locate 10,2,"2:S"
Locate 1,3,"3:H"
Locate 10,3,"4:R"
Locate 1,4,"5:In("
Locate 5,4," "

Locate 10,4,"6:yσn"

Locate 14,4," "
Return
IfEnd


Cls
Locate 14,4,"
►t"    ( [FUNCTION] [7] [3] [4] )
Locate 16,4,"E"


If F=1:Then
Locate 1,1,"TAISHO"
Locate 2,2,"FROM 1912.7.30"
Locate 2,3,"TO 1926.12.24


Else If F=2
Then
Locate 1,1,"SHOWA"
Locate 2,2,"FROM 1926.12.25"
Locate 2,3,"TO 1989.1.7"


Else If F=3
Then
Locate 1,1,"HEISEI"
Locate 2,2, "FROM 1989.1.8"
Locate 2,3,"TO 2019.4.30"


Else If F=4
Then
Locate 1,1,"REIWA"
Locare 2,2,"FROM 2019.5.1"


IfEnd:IfEnd
IfEnd:IfEnd
Cls


F=-1 の場合は、Return コマンドにより、サブルーチンから強制的にメインルーチンへ戻しています。

F=1~4 の場合の表示は、出力命令 ◢ を使って、プログラムを一時停止させています。一時停止を解除するには [EXE]キーを押す必要があります(出力命令の仕様)。従って、画面の右下に 
►E を表示して [EXE]キーを押すように説明します。
ここでは、If ~ Else If ~ IfEnd を使って、複数条件分岐の処理を行っています。

 ⇒ Casiobasicコマンドリファレンス
  - Returnコマンド
  - If 文
  - 出力命令◢



最後の仕上げとして、[EXIT]キーでプログラムが終了する部分を追加して完成させます。

[メニュー番号取得]ブロック内で、[EXIT] のキーコード 73 を取得し、取得したらプログラムを終了させるようにします。

[初期設定] ブロック以外が While ~ WhileEnd の中にあるので、[メニュー番号取得]ブロックの一番最後に

K=73⇒Break



の1行を追加します。[EXIT]キーを押すと、キーコード 73 が検出され、その時は Break コマンドで、While ~ WhileEnd の外、つまり WhileEnd の下の行に制御がジャンプします。

このジャンプ先に、以下のコードを追記しておきます。

Cls
Locate 7,2,"BTE!"



ここで、最終的に完成したコードをまとめます。

プログラムファイルのダウンロード

CcLinker で fx-5800P に転送できるCCLファイルのダウンロード
 ※ YEAR CONV.ccl、YRC.ccl、YRD.ccl、INPI.ccl を含む 圧縮ファイル (zip) が得られます。
 CcLinkerの紹介



ソースコード

スペースは で示し、改行も示しています。

YEAR CONV
0→A:0→B:0→G↵
-1→F:-1→N↵

While 1↵

If F:Then ↵
Prog "YRD"↵
Prog "YRC"↵
IfEnd↵

-1→N↵
Do↵
Getkey→K↵
LpWhile K=0↵
K=25⇒0→N↵
K=35⇒1→N↵
K=36⇒2→N↵
K=37⇒3→N↵
K=21⇒4→N↵
K=22⇒5→N↵
K=23⇒6→N↵
K=73⇒Break↵

0→F:0→C↵
While Getkey=35↵
Isz C:C=9⇒Break↵
WhileEnd:C=9⇒1→F↵
0→C↵
While Getkey=36↵
Isz C:C=9⇒Break↵
WhileEnd:C=9⇒2→F↵
0→C↵
While Getkey=37↵
Isz C:C=9⇒Break↵
WhileEnd:C=9⇒3→F↵
0→C↵
While Getkey=21↵
Isz C:C=9⇒Break↵
WhileEnd:C=9⇒4→F↵
F⇒Goto E↵

If N=0:Then ↵
5→X:1→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→A↵
Locate X,Y,A↵
IfEnd↵

Else If N=1↵
Then ↵
4→X:2→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→T↵
Locate X,Y,T↵
IfEnd

Else If N=2↵
Then ↵
13→X:2→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→S↵
Locate X,Y,S↵
IfEnd↵

Else If N=3↵
Then ↵
4→X:3→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→H↵
Locate X,Y,H↵
IfEnd↵

Else If N=4↵
Then ↵
13→X:3→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→R↵
Locate X,Y,R↵
IfEnd↵

Else If N=5↵
Then ↵
If A:Then ↵
5→X:4→Y:4→D:1→E↵
Prog "INPI"↵
If Z:Then Z→B↵
Locate X,Y,B↵
IfEnd:IfEnd↵

Else If N=6↵
Then ↵
If A:Then ↵
12→X:4→Y:3→D:1→E↵
Prog "INPI"↵
If Z:Then Z→G↵
Locate X,Y,G↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd↵

If N=0:Then ↵
Prog "YRC"↵

Else If N=1↵
Then ↵
T+1911→A↵
T=0⇒Isz A↵
Prog "YRC"↵

Else If N=2↵
Then ↵
S+1925→A↵
S=0⇒Isz A↵
Prog "YRC"↵

Else If N=3↵
Then ↵
H+1988→A↵
H=0⇒Isz A↵
Prog "YRC"↵

Else If N=4↵
Then ↵
R+2018→A↵
R=0⇒Isz A↵
Prog "YRC"↵

Else If N=5↵
Then ↵
If A:Then ↵
Prog "YRC"↵
IfEnd↵

Else If N=6↵
Then ↵
If A:Then ↵
Prog "YRC"↵
IfEnd↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd↵

Lbl E↵
If F:Then ↵
Prog "YRD"↵
-1→F:IfEnd↵

WhileEnd↵
Cls↵
Locate 7,2,"BYE!"↵


YRC
If N=1:Then ↵
A-1911→T↵
Else If N=2↵
Then ↵
A-1925→S↵
Else If N=3↵
Then ↵
A-1988→H↵
Else If N=4↵
Then ↵
A-2018→R↵
Else If N=5↵
Then ↵
B-A→G↵
Else If N=6↵
Then ↵
A+G→B↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵
IfEnd:IfEnd↵

A-1911→T↵
A-1925→S↵
A-1988→H↵
A-2018→R↵
Locate 5,1,"□□□□□"↵
A>0⇒Locate 5,1,A↵
Locate 4,2,"□□□□□□"↵
T>0⇒Locate 4,2,T↵
Locate 13,2,"□□□□"↵
S>0⇒Locate 13,2,S↵
Locate 4,3,"□□□□□□"↵
H>0⇒Locate 4,3,H↵
Locate 13,3,"□□□□"↵
R>0⇒Locate 13,3,R↵

B-A→G↵
If G>999 Or G<-99:Then ↵
Locate 12,4,"□yσn"↵
Locate 14,4,"□□"↵
Return↵
IfEnd↵

If B Or G:Then ↵
Locate 5,4,"□□□□□"↵
Locate 5,4,B↵
Locate 12,4,"□□□"↵
Locate 12,4,G↵
If Abs(G):Then ↵
13+Int(log(Abs(G)))→D↵
Else 13→D:IfEnd↵
G<0⇒D+1→D↵
Locate D,4,"yσn"↵
Locate D+1,4,"□□"↵
IfEnd



YRD
If F=-1:Then ↵
Locate 1,1,"0:AD"↵
Locate 10,1,"▸DMS"↵
Locate 11,1,"EXIT"↵
Locate 1,2,"1:T"↵
Locate 10,2,"2:S"↵
Locate 1,3,"3:H"↵
Locate 10,3,"4:R"↵
Locate 1,4,"5:Int("↵
Locate 5,4,"□□"↵
Locate 10,4,"6:□yσn"↵
Locate 14,4,"□□"↵
Return↵
IfEnd↵

Cls↵
Locate 15,4,"▸t"↵
Locate 16,4,"E"↵

If F=1:Then ↵
Locate 1,1,"TAISHO"↵
Locate 2,2,"FROM□1912.7.30"↵
Locate 2,3,"TO□□□1926.12.24"◢

Else If F=2↵
Then ↵
Locate 1,1,"SHOWA"↵
Locate 2,2,"FROM□1926.12.25"↵
Locate 2,3,"TO□□□1989.1.7"◢

Else If F=3↵
Then ↵
Locate 1,1,"HEISEI"↵
Locate 2,2,"FROM□1989.1.8"↵
Locate 2,3,"TO□□□2019.4.30"◢

Else If F=4↵
Then ↵
Locate 1,1,"REIWA"↵
Locate 2,2,"FROM□2019.5.1"◢
IfEnd:IfEnd↵
IfEnd:IfEnd↵
Cls↵




「入力ボックス」を用いた 西暦・和暦換算プログラム が完成しました。

Chapter 4 では、
  • 入力ボックスの使い方
  • サブルーチンと共有する"予約変数" と メインルーチン内で効率よく使う"使捨て変数" を意識した変数の使い方
  • サブルーチンの使いこなし
  • "キー長押し" と "普通押し" のキー操作違いで、1つのキーに異なる役割を与える方法
を経験してもらいました。

CasioBasic入門 を最初からここまで読んでくると、プログラム電卓でのプログラミングが自由自在になったのではないでしょうか?


つづく...


CasioBasic入門23 / 目次




応援クリックをお願いします。励みになるので...
にほんブログ村 IT技術ブログ 開発言語へ


 




keywords: fx-5800PCasioBasicプログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ

関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

コメントの投稿

非公開コメント

最新記事
検索フォーム
最新コメント
カテゴリ
C# (3)
Visitors
Online Counter
現在の閲覧者数:
プロフィール

やす (Krtyski)

Author:やす (Krtyski)
since Oct 30, 2013


プログラム電卓は、プログラムを作って、使ってナンボ!

実際に触って気づいたこと、自作プログラム、電卓プログラミングについて書いています。

なお管理人はカシオ計算機の関係者ではなく、Casio Basicが面白いと感じる1ユーザーです。


写真: 「4駆で泥んこ遊び@オックスフォード郊外」

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

ブロとも申請フォーム

この人とブロともになる

QRコード
QR