Casio Basic入門12

Casio Basic入門
<目次>

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

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


Chapter 2 - 初級

◆ Chapter 2 の目標: 動きのあるプログラムを作る
簡単なアクションゲームを作る

前回: Casio Basic入門11


Chapter 2-6 で、「フライング」と「タイムアウト」に対応し、総合得点を計算して表示するまでを作りました。

プログラム名 CH2-6

0→P:20→L
Locate 1,1,"P:0"
Locate 1,3,"L:"
Locate 3,3,L

Lbl M

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"
    (頭にスペース1個)
Locate 1,2,"                "
    (スペース16個)

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"

Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Locate 8,2," "
    (スペース1個)

0→C
Do
E=1⇒Break
C>L⇒Break
Isz C
LpWhile Getkey≠57
C>L⇒2→E
Locate 8,2,C

If E=2
Then
P-L→P
Locate 5,2,"TIME OUT"
Else If E=1
Then
P-L+C→P
Locate 3,2,"FALSE START"
Else If E=0
Then
P+L→P
IfEnd
IfEnd
IfEnd
Locate 3,1,"    "
    (スペ-ス4個)
Locate 3,1,P

Goto M



プログラムのブロック構造は、次のようになります。

[プログラム全体の初期化]

Lbl M

    [繰り返し処理の初期化]

    [アニメーション表示]

    [反応速度の測定&表示]

    [例外処理]

Goto M



今回は、ゲームオーバーの処理を作り込んでゆきます。



Chapter 2-7

ゲーム仕様では、試行回数の残りが0になったらゲーム終了です。ゲーム開始時に、どの程度の試行回数を与えると良いかは、実際にゲームで遊んでみて微調整することにして、今は今はゲーム開始時に3回の試行回数を与えることにします。

試行回数は、試行 = トライ = TRY なので、頭のアルファベット T をとって、変数 T を残っている試行回数に割り当てることにします。ゲーム開始時に T に3を代入します。

そして、「タイムアウト」や「フライング」した時に、ペナルティーとして T を1つ減らすことにします。


これに伴う変更は、以下のようになります。

[プログラム全体の初期化] で、3→T を追加
[プログラム全体の初期化] で、T の表示を初期化する
[例外処理] で、タイムアウトとフライングの時に Dsz T を追加する
・新たに [ゲームオーバー時の処理] ブロックを追加し、そこでゲームオーバー時の表示を追加



[プログラム全体の初期化] 処理の変更

プログラムの1行目を、以下のようにします。

0→P:20→L:3→T
Locate 1,1,"P:0"
Locate 1,3,"L:"
Locate 3,3,L

Locate 10,1,"TRY:"
Locate 14,1,T

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

CH2-7_Start 


[例外処理] の変更

If E=2
Then
P-L:Dsz T
Locate 5,2,"TIME OUT"

Else If E=1
Then
P-L+C→P:Dsz T
Locate 3,2,"FALSE START"

Else If E=0
Then
P+L-C→P
IfEnd
IfEnd
IfEnd
Locate 3,1,"    "
Locate 3,1,P
Locate 14,1,T


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

ここで、追加した Dsz T は、T がゼロになると、Locate 文を飛ばして、次の Else If (正しくは Else)へジャンプすることを利用して余計な表示がされないようにしています。

そして、試行回数の残り T を表示します。


[ゲームオーバー時の処理] の追加

試行回数の残りが0になった時にゲームオーバーとするには、全体のループの Goto M を以下のように変更し、さらにゲームオーバー時の表示を追加します。

T⇒Goto M

Locate 1,2,"                "
Locate 4,2,"GAME OVER"
Locate 6,4,"  <AC>:QUIT


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

T⇒Goto M は、T がゼロになったら Goto M を飛ばして、次の Locate 1,2,"                " へジャンプします。これは、条件ジャンプ命令:⇒ の機能です。


一番最後に追加したものは、[AC] キーを押すとプログラムが終了する」、と画面表示で説明する部分です。
CasioBasicでは、[AC] キーを押すとプログラムが強制終了するので、これを利用しています。

但し、頭にスペースが2個入っていることに注意! こうしないと、<EXE>:START を完全に上書きできません。
これは、Locate 6,4," <(-)>:STOP" で頭にスペースを1個入れるのと同じ理由です。


CH2-7_Quit 


以上をまとめます。

プログラム名 CH2-7

0→P:20→L:3→T
Locate 1,1,"P:0"
Locate 1,3,"L:"

Locate 10,10,"TRY:"
Locate 14,1,T


Lbl M

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"
Locate 1,2,"                "

RanInt#(2,50)→C
Do

If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "

0→C
Do
E=1⇒Break
C>L⇒Break
Isz C
LpWhile Getkey≠57
C>L⇒2→E

If E=2

Then
P-L→P:Dsz T
Locate 5,2,"TIME OUT"

Else If E=1
Then
P-L+C→P:Dsz T
Locate 3,2,"FALSE START"
Else If E=0
Then
P+L-C→P
IfEnd
IfEnd
IfEnd
Locate 3,1,"    "
Locate 3,1,P
Locate 14,1,T

T⇒Goto M

Locate 1,2,"            "
Locate 4,2,"GAME OVER"
Locate 6,4,"  <AC>:QUIT"


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


プログラム構造は、以下のようになります。今回は新たに [ゲームオーバー時の処理] ブロックを追加しました。


[プログラム全体の初期化]

Lbl M

    [繰り返し処理の初期化]

    [アニメーション表示]

    [反応速度の測定&表示]

    [例外処理]

T⇒Goto M

[ゲームオーバー時の処理]




ゲーム仕様
1) ゲームスタート時、所定の試行回数与えられる
2) アニメーションを表示する待ち時間がある(待ち時間はランダム)
3) アニメーションが終わったら、できるだけ速くキーを押す
4) 反応が速いほうが多くの得点が加算される
5) 表示が変わる前のお手つきや、反応が遅すぎる場合は、得点試行回数が減る
6) 試行回数が0になるとゲーム終了し、その際の得点を競う

今回は、1)、4)、6) を追加して、ゲーム仕様を実装できました。



プログラム全体を、処理内容別のブロックを単純に並べた構造にしています。1つのブロック内で、分岐処理やループを使ってまとまった処理を行います。そして、次のブロックへ移ります。

プログラムをこのような構造にしておくと、機能追加や変更を、プログラムのどの部分でやれば良いかが分かりやすく、楽になることを、これまで体験してもらっています。



これまでの機能追加や変更について、ちょっと振り返ってみます。

[アニメーション表示]ブロックでは、フライングを検出しています。フライング検出後すぐに表示を行わずに、例外フラグを設定するだけにして、次のブロックへ処理を移しています。フライング検出をした直後で "FALSE START" と表示すれば楽なのに、回りくどいと思われたかも知れません。

実際問題、"FALSE START" の表示以外に、総得点の計算や、試行回数の計算も追加していますが、これらを [例外処理] ブロックにまとめることで、他のブロックを殆ど変更せずに機能追加ができました。これがブロック構造の利点です。

今回のようなアクションゲームでは、アニメーション表示 や 反応速度測定&表示 のループが軽く、速く回る必要があります。これが遅くなると、ゲームのレスポンスが遅くなり、つまらなくなる恐れがあります。なので、これらのループの中には余計な処理を入れたくないわけです。従って、余計な処理は別のブロックに入れた方が良い、と言う事情もあります。


[反応時間測定&表示]ブロックでは、タイムアウトを検出しています。ここでも例外フラグを設定するだけで、次のブロックへ処理を移しています。フライングフラグが設定されている時にも、直ちに次のブロックへ移動しています。


このように、まとまった処理ごとのブロックを作って、これらのブロックが上から下へ連なる構造を意図的に作る方法を、構造化プログラミングと言います。構造化プログラミングについては、こちら で裏話をしています。興味のある方は読んでみて下さい。

簡単なプログラム、特にプログラム関数電卓での簡単なプログラムは、ブロックを意識する必要の無いことも多いのでですが、ちょっと機能追加をしようと思うと、とたんにプログラムが複雑になってしまいます。

「ブロックを並べて作る」構造化プログラミングの対極にあるのが、思いつきで色々な機能を追加したり変更し、同種の処理がプログラムのあちこちに分散しているもので、Goto を多用することが最大の原因です。


さて、このゲームで実際に遊んでみると、確実に試行回数が減ってゲーム終了....なんだか面白くありません。そこで、次回はゲームがチョットだけ面白くなる機能を追加しようと思います。



つづく...


CasioBasic入門13 / 目次




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



カシオプログラム関数電卓 FX-5800P-Nカシオプログラム関数電卓 FX-5800P-N
(2006/09/22)
CASIO(カシオ)

商品詳細を見る



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

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


関連記事

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

Casio Basic入門11

Casio Basic入門
<目次>

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

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


Chapter 2 - 初級

◆ Chapter 2 の目標: 動きのあるプログラムを作る
簡単なアクションゲームを作る

前回: Casio Basic入門10


Chapter 2-4 でフライング対策をしたゲームの基本部分ができました。

プログラム名 CH2-4

0→E

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "

0→C
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd



プログラムのブロック構造

[初期化処理] ブロック

[アニメーション表示] ブロック

[反応時間測定&表示] ブロック

[例外処理] ブロック




ゲーム仕様
1) ゲームスタート時、所定の試行回数与えられる
2) アニメーションを表示する待ち時間がある(待ち時間はランダム)
3) アニメーションが終わったら、できるだけ速くキーを押す
4) 反応が速いほうが多くの得点が加算される
5) 表示が変わる前のお手つきや、反応が遅すぎる場合は、得点試行回数が減る
6) 試行回数が0になるとゲーム終了し、その際の得点を競う


項目の 2) と 3) と 5)の一部は実現できました。


残る部分を作るには、これまで作った部分を繰り返すようにプログラムの変更が必要だとわかります。その上で、試行回数、得点を表示し、試行回数0でゲームが終わるようにすれば完成です。



Chapter 2-5
プログラム制御

プログラムを繰り返すには、ループを使えば良いので、全体を繰り返すループに Lbl / Goto ループを使うことにします。メインループなので、Main LoopM を使って Lbl M / Goto M とします。

Lbl M
[ゲーム全体の処理]
Goto M


これは、無限ループです。

ゲーム仕様に従えば、試行回数(トライ回数)の残りが0になればゲーム終了となるので、試行回数(トライ回数)の残りが 0 になったときにループを終了すれはOKです。試行回数を変数 T (トライ=Try の T)に代入しておき、何かの条件により T を減らすようにしてゆきます。

T がゼロになったときゲームを終了するためには、以下のように 条件ジャンプ命令⇒ を使うと、うまくループを終了できます。

Lbl M
[ゲーム全体の処理]
M⇒Goto M


条件ジャンプ命令の仕様から、Mがゼロでない時は Goto M を実行しますが、Mがゼロになると、Goto M を飛ばして、次へジャンプするので、ループが終了します。トライ回数を減らす条件については、後で作ることにし、今は無限ループにしておきます。

それでは、無限ループを組み込みます。

Lbl M

0→E

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "

0→C
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd

Goto M

これを走らせてみてください。

プログラムが全く止まりません。忙しすぎて、メリハリが無くて、ゲームとしては問題です。そこで、アニメーションを開始するところで、一旦プログラムを止めます。止まると同時に操作方法を表示させることにします。

操作方法の表示のために、プログラム冒頭にある初期化処理部分に操作方法表示の Locate コマンドを追加します。


初期化処理部分は、今のところ

0→E

だけで、ここに以下のように追加します。

0→E
Locate 6,4,"<EXE>:START"◢

ここで、出力命令 を利用します。


出力命令 には一時停止の機能が付加されおり、それを利用するわけです。画面の右下に <EXE>:START と表示され、プログラムが一時停止します。

プログラムが出力命令 で止まった後、停止解除するには [EXE] キーを押します。それ以外のキーでは停止解除しません。従って、<EXE>:START としました。


[EXE] キーを押すと、ゲームが始まり、[(-)] キーを押せば、結果が出るかフライングになって、また最初の表示に戻ってプログラムが一時停止します。

操作方法を表示するのなら、ついでに <(-)>:STOP も表示させましょう。
[EXE] キーを押してゲームがスタートしたら、<(-)>:STOP に表示を切り替えることにします。
そして、結果が出るかフライングになるか、いずれにせよ [(-)] キーを押したときに、表示を <EXE>:START に切り替えます。

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"


<(-)>:STOP の前に、スペースが1つ入っていることに注意してください。<EXE>:START をきれいに上書きするためには、このスペースが必要です。スペ-スを入れることで、どちらの表示も11桁になるように揃えました。

CH2-4_Start 

CH2-4_Stop 

もう一つ、必要な表示処理があります。フライングになった場合は 2行目の中央に FALSE START と表示されます。次の試行の前に、これを一旦消さないと、アニメ-ション表示と重なって表示されてしまいます。そこで、一旦2行目を端から端まで消去します。

2行目の1桁めから16桁めまで、スペースで上書きすればOKですね。

以上から、初期化部分は、以下のようになります。

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"
Locate 1,2,"                "


これで、連続して何回もゲームを続けられるようになりました。


プログラム名 CH2-5

Lbl M

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"
Locate 1,2,"                "


RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "

0→C
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd

Goto M



プログラムのブロック構造

Lbl M

[初期化処理] ブロック

[アニメーション表示] ブロック

[反応速度測定&表示] ブロック

[例外処理] ブロック

Goto M



Chapter 2-6
複数条件分岐の記法

ゲームを何回もトライして、その点数を付ける機能を、追加します。

点数の付け方を次のようにしでみます。
1.毎回のトライで得た得点を積算して、総得点Pとする
2.制限時間を設定する: 変数L (Limit の L)、20とする
3.反応時間は、カウンターC
4.得点を、L-C とする
5.フライング時は、減点を L-C とする
6.タイムアウト時は、減点を L とする

ゲーム進行上は以下のようになります。
・制限時間を超えるとタイムアウト。減点L
・制限時間ギリギリで反応すると、得点ゼロ
・制限時間内で、速く反応するほど高得点になる: L-C
・フライングの時は、減点L-C。フライングが速いほど減点が多くなる。



このように決めると、実際の総得点は、

A) フライングしない時の総得点計算: P+L-C→P
B) フライングしたときの総得点計算: P-L+C→P
C)タイムアウトした時の総得点計算: P-L→P
※今は、Lを20とします。

最終的には、L をゲーム進光状況に応じて変化させると、ゲームが面白くなるかもしれません。そこで、制限時間には、決め打ちの20ではなくて、変数 L を使って、プログラムを作ります。但し、L の初期値は20としておきます。


先ずは、[初期化処理] (1ブロック)

0→P:20→L

を追加します。


今回、タイムアウトと言う要素を追加します。タイムアウトの条件は、C>L です。
タイムアウトは [反応時間測定&表示] (3ブロック)での例外事象として扱います。

0→0
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57

Locate 8,2," "    (スペース16個)

この [反応時間測定&表示] (3ブロック)で、C>L の時 Break コマンドで  Doループから抜け、抜けた直後に 例外フラグE に 2 を代入します。

その結果、例外フラグE は3つの値をとります。例外フラグEが1の時はフライング、2の時はタイムアウトと言うわけです。例外でない場合は例外フラグEは0です。


以上をプログラムに反映させると、

0→C
Do
E=1⇒Break
C>L⇒Break

Isz C
LpWhile Getkey≠57
C>L⇒2→E
Locate 8,2,C


追加部分は、赤文字で示しました。


例外処理

総得点の計算は、[例外処理] ブロックで行います。

<総得点計算>
Eが2の時: P-L→P 
Eが1の時: P-L+C→P
Eが0の時: P+L-C→P

の計算を追加します。


表示内容は、以下の場合分けになります。

<表示内容>
Eが2の時: TIME OUT
Eが1の時: FALSE START
Eが0の時: 特になし


総得点の表示は、例外フラグEの値に関わらず、共通の処理で実装可能です。

Locate 3,1,"    "    (スペース4個)
Locate 3,1,P

総得点は増減するものなので、少ない桁数で更新されることもあります。その時は、既に何度も行っているように、あらかじめ消去(スペースで上書き)した上に、総得点を上書きする必要があります。


複数条件分岐

If ~ Then ~ Else ~ IfEnd は、1つの条件に対して、それが成り立つかそうでないか、つまり真か偽かによって処理を振り分けます。二者択一の処理をします。

今回は例外フラグEが、2、1、0 の3通りの値になります。これらを条件として3通りに処理を振り分けたいので、Ifを使う場合は Ifの中にもう1つ Ifを入れる多重構造(入れ子構造)が必要になります。

ところで、Visualbasicでは、ElseIf と言うコマンドがあって、

If [条件1]
    Then [処理1]
ElseIf [条件2]
    Then [処理2]
ElseIf [条件3]
    Then [処理3]
        :
        :
Else
[処理0]
End If

といった、複数の条件による分岐処理が可能です。


或いは、

Select Case [変数]
    Case 1
        [処理1]
    Case 2
        [処理2]
    Case 3
        [処理3]
    Case 4
        [処理4]
        :
        :
End Select


といった、複数分岐処理も可能です。


C言語でも

switch (変数) {
    case 1:
        [処理1];
    case 2:
        [処理2];
    case 3;
        [処理3];
    case 4:
        [処理4];
        :
        :
    default:
        [処理0];
}


といった処理が可能です。

このように、多くの高級言語には、複数条件分岐処理が可能なステートメントが備わっています。一方で、Casio Basicには、このような複数条件分岐処理のステートメントが用意されておらず不便に感じます。

ところが、Casio Basic では、次のような記述方法を使えば、簡単に複数条件分岐処理を実現できます。


CasioBasic用 複数条件分岐の構文

基本構文は以下の通りです(Else と If を組み合わせるところがミソ):

If [変数]=4:Then
[処理4]
Else If [変数]=3:Then
[処理3]
Else If [変数]=2:Then
[処理2]
Else If [変数]=1:Then
[処理1]
Else If [変数]=0:Then
[処理0]
IfEnd
IfEnd
IfEnd
IfEnd
IfEnd

※注意点: If の数と同数の IfEnd を最後に書くこと

Else If は、普通に ElseIf を続いて入力します。

Casio Basic には ElseIf と言う1語(ワンワード)のコマンドは用意されていないものの、ElseIf を並べて書くことで、プログラムの読みやすさ(可読性)を損なわずに複数条件分岐ができます。但し、この記法を用いる時には、最後に IfEnd を If と同じ数だけ記述する点に留意してください。

※ IfEnd が If の数よりも少なくても正常動作する可能性はありますが、運が良いだけです。制御構造が複雑になると必ず誤動作するので、原則通りにIfEndを記述すべきです。


さて、今回の例外処理を行うには、[変数]「例外フラグE」を使えば良いわけです。

※ CasioBasicコマンドリファレンス
      - If 文


[例外処理] ブロックのプログラム

話を元に戻して、[例外処理]ブロックのプログラムは、以下のようになります。

If E=2
Then
P-L→P
Locate 5,2,"TIME OUT"
Else If E=1
Then
P-L+C→P
Locate 3,2,"FALSE START"
Else If E=0
Then

P+L-C→P
IfEnd
IfEnd
IfEnd

Locate 3,1,"    "        (スペース4個)
Locate 3,1,P


ここまでをまとめると、以下のプログラムになります。

プログラム名 CH2-6

0→P:20→L
Locate 1,1,"P:0"
Locate 1,3,"L:"
Locate 3,3,L

Lbl M

0→E
Locate 6,4,"<EXE>:START"◢
Locate 6,4," <(-)>:STOP"
    (頭にスペース1個)
Locate 1,2,"                "
    (スペース16個)

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"

Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Locate 8,2," "
    (スペース1個)

0→C
Do
E=1⇒Break
C>L⇒Break
Isz C
LpWhile Getkey≠57
C>L⇒2→E
Locate 8,2,C

If E=2
Then
P-L→P
Locate 5,2,"TIME OUT"
Else If E=1
Then
P-L+C→P
Locate 3,2,"FALSE START"
Else If E=0
Then
P+L→P
IfEnd
IfEnd
IfEnd
Locate 3,1,"    "
    (スペ-ス4個)
Locate 3,1,P

Goto M



プログラムのブロック構造


Lbl M

[初期化処理]

[アニメーション表示]

[反応速度測定&表示]

[例外処理]

Goto M


フライングとタイムアウトの例外処理を作り、総合得点の表示までできました。プログラムを走らせてみると、なんとかゲームの形ができあがってきたことが分かります。

次回では、引き続きゲームオーバーの処理を作り込んでゆきます。



つづく...


CasioBasic入門12 / 目次




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


カシオプログラム関数電卓 FX-5800P-Nカシオプログラム関数電卓 FX-5800P-N
(2006/09/22)
CASIO(カシオ)

商品詳細を見る



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

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



関連記事

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

Casio Basic: Stop

Casio Basic
コマンドリファレンス

Casio fx-5800P、fx-9860GII、fx-CG20、fx-CG50 で確認をとっています。Casio fx-FD10 Pro では互換性はあると考えられますが、実機で確認していないので「可能性」としてご覧ください。
2015/01/09 更新

fx-5800P / fx-9860GII / fx-CG20 / fx-CG50


Stop

◆ 概 要: プログラムを強制終了させるコマンド

◆ 書 式: Stop

◆ 引 数:なし

◆ 戻り値:なし


[AC] キーと同様に、実行中のプログラムを強制終了させる。

サブルーチンでStopコマンドを実行すると、呼出元のメインルーチンの実行を強制終了させる。


Returnコマンドは、サブルーチンで実行すると実行されたサブルーチンのみを強制終了させ、メインルーチンは終了させない。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


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

リンク集 | ブログ内マップ
関連記事

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

楽屋裏 - 多重ループの謎

楽 屋 裏
e-Gadget

最終更新: 2014/03/10

[2014/03/10 追記]: 今回の異常が発生する条件以外でも多重ループの異常が見つかりましたこちらへ


原因不明の Syntac ERROR の件の続報:

問題を単純化すると、こうなります。

以下のようなWhile ループ内にDoをループが入ったプログラムで、Syntax Errorが発生し、問題の発生場所が WhileEnd だと表示されます。

プログラム1
While 1
20→C
Do
Dsz C
LpWhile 1
WhileEnd


=====

頭のWhile 1 を Lbl 0 に、お尻の WhileEnd を Goto 0 に変更した以下のプログラムでは エラーが発生しません。

プログラム2
Lbl 0
20→C
Do
Dsz C
LpWhile 1
Goto 0


エラーの発生源である WhileEnd を無くせばエラーが消えるわけで、問題はWhile ループにあることが確認されます。

=====

次に、Dsz C の代わりに、C-1→C とジャンプのためのGoto / Lbl に置き換えます。

プログラム3
While 1
20→C
Do
C-1→C:C=0⇒Goto 0
LpWhile 1
Lbl 0
WhileEnd


この場合は、エラーは発生せず、正常動作します。
どうやら、Dsz C で WhileEnd にジャンプする時にエラーが発生するようです。

=====

While ループの代わりに Doループを使うと、以下になります。

プログラム4
Do
20→C
Do
Dsz C
LpWhile 1
LpWhile 1


内側の Doループから抜けると、外側の LpWhile 1 から外側の Do までジャンプするのが正常動作ですが、内側の Do にジャンプするようです。ループの相手を見つける検索に問題が発生してるようです。

具体的には、以下を実行してはっきりました。

プログラム5
Do
20→C
C◢
Do
Locate 1,1,"    "
LOocate 1,1,C◢
Dsz C
LpWhile 1
Cls
LpWhile 1


これを実行すると、動作異常の状況がはっきりします。

=====

While ループの例と同様に、Dsz C を C-1→C:C=0⇒Goto 0 と Lbl 0 に変えて以下を実行すると、正常動作します。

プログラム6
Do
20→C
C◢
Do
Locate 1,1,"    "
Locate 1,1,C◢
C-1→C:C=0⇒Goto 0
LoWhile 1
Lbl 0:Cls
LpWhile 1


=====


以上から、WhileループやDoループを2重構造にして、内側のループを抜けるために Dsz 命令を使うと正常動作しないことが分かりました。

改めて、問題のプログラム2つを書いてみます。

これらは、特に問題を感じないプログラムです。

問題プログラム1
While 1
20→C
Do
Dsz C
LpWhile 1
WhileEnd


これは、最後のWhileEndでSyntax ERROR が発生します。


問題プログラム2
Do
20→C
Do
Dsz C
LpWhile 1
LpWhile 1


これは、エラーとして検出されませんが、外側のDoループが異常動作します。
その結果、Cをマイナスの値でどんどん減らしながら、内側のDoループが回り続けることになります。


これら2つの問題プログラムは、皆さんのfx-5800Pでも同じように異常になりますでしょうか?
是非お聞かせください。




現時点では、
「While および Do ループからの脱出に Dsz命令を使う場合は、さらにその外側に While およびDo ループを使ってはならない」
と言う予防策を講じる必要があります。



もし私のfx-5800Pだけでの問題でないことが分かれば、カシオに相談したいと思いますので、ご協力をお願い致します。





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


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

リンク集 | ブログ内マップ
関連記事

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

楽屋裏 - Else If

楽 屋 裏
e-Gadget


思い込みとは怖いものだ。

Ifにまつわる話です。

これまで、Basic言語一般で使える記法 ElseIf が、CasioBasic には無いので、Else If は可読性が悪くなって使えないものとばかり思っていたのですが、思い込みだと言うことが分かりました。

Else If は結構使えます!


何のことかと言えば...

変数Eが、0、1、2、3 と異なる値になるとき、Eの値に応じて処理を切り替える...これは、Else If と言う記法を使えば、見やすいプログラムが書けるのですが、それが出来ないと思っていたばっかりに、確かめもせずに、If 文の入れ子構造が複雑になって使えず、不便だなぁ、と...

Else If の入力方法は、単に If を入力し、続けて Else を入力するだけです。

Else If を使えば、以下のように可読性を犠牲にせず、スッキリと書けます。

If E=3:Then
[処理3]
Else If E=2:Then
[処理2]
Else If E=1:Then
[処理1]
Else If E=0:Then
[処理0]
IfEnd
IfEnd
IfEnd
IfEnd


但し、If と同数の IfEnd を最後にまとめて書きます。


このように便利な Else If は使えないと思っていたので、Goto / Lbl を使って同じ構文を作って使っていました。Goto を使うのは出来れば避けたいところですが、正しく使えば役に立つ事例として、私は考えていました。

E=3⇒Goto 3
E=2⇒Goto 2
E=1⇒Goto 1
E=0⇒Goto 0
Goto Z

Lbl 3
[処理3]

Goto Z

Lbl 2
[処理2]

Goto Z

Lbl 1
[処理1]

Goto Z

Lbl 0
[処理0]

Goto Z

Lbl Z



一時の恥は一生の得 ということで、これからは Else If を必ず検討しようと思います。

懺悔にも近いこんなことを書いたのは、少し前 藤堂様 とのやりとりで、Goto は用法・用量を守って正しく使えば良い、と私の主張をし、その効用の1例として、上の複数条件分岐を例として挙げたのです。

それを、キチンと訂正したいと思ったので、別エントリーに書くことにしました。

藤堂様、失礼しました。


但し、一言だけ言い訳をしますと、

switch(E) {
    case 3:
       
[処理3]
        break;
    case 2:
        [処理2]
        break;
    case 1:
        [処理1]
    case 0:    
        [処理0]
}


といった、C言語風の処理は、Else If では出来ないのです。
case 3:case 2: では、break; がありますが、case1:case 0: では break; が省略されています。
break; によって siwtch( )文を抜けます。

Eが3や2、そして0 の時は、それぞれ対応する処理を行います。

ところが、Eが1の時は [処理1] に続いて [処理0] を行います。[処理1] の後に break; が無いためです。

私が作った構文では、Goto Zbreark; に相当するので、C言語と同等の柔軟性がありますが、Else If の記法 にはそのような柔軟性が有りません。

(言い訳終わり) (^^;)


...と言うことで、CasioBasicコマンドリファレンスIf 文 の項目も修正しました。

但し、Goto は用法・用量を守って正しく使いましょう! は撤回せずにおきます。





応援クリックをお願いします。励みになりますので...

人気ブログランキングへ


FC2ブログランキングへ


keywords: fx-5800PCasioBasicElse If複数条件分岐プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ
関連記事

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

楽屋裏 - Syntax ERROR

楽 屋 裏
e-Gadget


実は今、原因不明の Syntac ERROR に悩んでいます。

CasioBasic入門10 で作ったプログラム CH2-4 を Whle 1 と WhileEnd で挟んでループにすると、WhileEnd のところで Syntax ERROR が表示されます。

具体的には、

While 1

0→E

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey→K
K=57⇒1→E
Dsz C
LpWhile K≠57
Locate 8,2," "

0→C
Do
E≠0⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd


WhileEnd


プログラムCH2-4 を単に While 1 / WhileEnd で挟んだだけです。

While  1 /  WhileEnd の代わりに、Do / LpWhile 1 で挟むと、LpWhile 1 から Do までキチンと戻らず、2行を読み飛ばして3行目にジャンプすることが分かっています。

いずれの場合も、解決策としては、最後の WhileEnd あるいは LpWhile 1 の直前に Goto Z:Lbl Z を追加すれば良く、エラーは無くなり正常に動作します。

面白いことに、上で赤文字で示した If 文を、以下のように書き換えると、エラーは発生せず、正常に動作ます。

E=1⇒Goto 1
Goto Z

Lbl 1
Locate 3,2,"FALSE START"

Goto Z

Lbl Z


実は、このコードを書くとエラーが発生しないことから、Goto Z:Lbl Z を入れるとエラーが無くなることが分かったのです。
このコードは、上の If 文と同じことを If を使わずに書いたコードです。

WhileループやDoループの代わりに、Lbl / Goto でループを作ると、エラーは発生しません。

具体的には、While 1 の代わりに Lbl M、WhileEnd の代わりに Goto M を書くとエラーが発生しないのです。


そこで、原因にならない部分をそぎ落としてゆくと

While 1

20→C
Do
Dsz C
LpWhile 1

WhileEnd


といったシンプルなプログラムで、Syntac ERROR が発生し、発生部位が WhileEnd と表示されます。

このシンプルなプログラムで、WhileEnd の直前に、Goto 0:Lbl 0 を書くとエラーは消えます。

While 1

20→C
Do
Dsz C
LpWhile 1

Goro 0:Lbl0
WhileEnd



どうやら、私の fx-5800P では、While ループや Do ループで エラーが発生していることがハッキリしました。


さらに、While / WhileEndLbl / Goto に置き換えると、異常が発生しません。

Lbl M

20→C
Do
Dsz C
LpWhile 1

Goto M



以上から、今のところ言えるのは、WhileDoループの中に WhileDoループを入れる、つまり多重ループ構造にすると問題が発生するようです。



皆さんの fx-5800P でも同じことが発生するでしょうか?



私のfx-5800P特有の問題なのかどうかが分からないので、バグだと断定するのはまだ早いのですが....


ちなみに、これまで作ったプログラムを見直してみると、ループの中にループを書いたプログラムは無く、私にとっては多重ループは今回始めてのケースです。と言うのも、実行速度を早くするために、私は Lbl / GotoDsz を組み合わせたループLbl / Goto と ジャンプ命令⇒ を組み合わせたループを多用していて、WhileDo の多重ループは必要に迫られた時に使うつもりでした。


取扱説明書を見ても、多重ループに関する記述が見つかっていません(´д`)


もし、皆さんのfx-5800Pでも再現するならば、仕様なのかバグなのか、カシオに聞いて確かめようと思っています。





 [2014/02/23 追記]

CasioBasic入門では、ループには WhileDo を使わず、Lbl / Goto を使って進める予定です。手元で完成しているプログラムでも多重ループを使わなければ異常動作は発生していません。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


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

リンク集 | ブログ内マップ
関連記事

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

楽屋裏 - スプラッシュ

楽 屋 裏
e-Gadget


読者の方からのレスポンスは、本当に嬉しい( ^o^)ノ

少し前に、読者の Ku さんから、愉しいメッセージが届きました



fx-5800Pのプログラムでは、数字とアルファベットを使えますが、アルファベットは大文字のみです。

Kuさんは、うまく工夫することで、

e-Gadget 

と表示できることを示してくれました。


ハイ、この通り!

e-Gadget Logo






私もチョット頑張って、自分のハンドルネーム Krtyski の表示に成功( ^o^)ノ


さらに悪のりして、こんな画面を作りました↓↓




fx-5800P のゲームプログラム起動時に表示するスプラッシュ画面です。


CasioBasic入門では、「動きのあるプログラムを作る」と言うテーマで、アクションゲームを題材にしています。連載の記事よりも、手元では進んでいて、ゲームはほぼ完成していて、 React! と名付けました。CasioBasic入門でも、このスプラッシュ画面の作り方を紹介する予定です。

読者の方からのコメントや情報は、このように役立っています。


CasioBasic入門は、fx-5800Pでプログラムを作るための入門講座です。
題材のプログラムは、プログラムの作り方を説明するためのものですが、どうせ作るなら面白いプログラムにしたいと、力が入ってしまいます。

それによって、解説の難易度が上がってしまっていないか? と少し気にしています。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


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

リンク集 | ブログ内マップ
関連記事

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

Casio Basic入門10

Casio Basic入門
<目次>

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

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


Chapter 2 - 初級

◆ Chapter 2 の目標: 動きのあるプログラムを作る
簡単なアクションゲームを作る

前回: Casio Basic入門9


Chapter 2-1 で羽根が回るアニメーションを作りました。

プログラム名 CH2-1
50→C
Lbl 0
If C-4Int(C÷4)≦1
Then
Locate 8,2,"X"
Else
Locate 8,2,"+"
IfEnd
Dsz C
Goto 0
Locate 8,2," "


羽根が回る時間は、カウンターCで決まり、今はCが50に固定されています。反射ゲームでは、羽根が回る時間をランダムにします。



Chapter 2-2
ランダム関数を使う

fx-5800Pには、Ran#RanInt# の2つのランダム関数が用意されています。

Ran#
0~1の間のランダムな小数を返します。
羽根を回す時間は、整数のカウンタC をランダムに設定する必要があります。そのためにはRan#が返す小数から整数を作る必要があります。例えば、2桁の整数を得るには、Int(100Ran#) とします。

RanInt#(L,H)
整数 L 以上、整数 H 以下の範囲でランダムな整数を返します。
羽根を回す時間は、整数のカウンタC をランダムに設定したので、整数を返す RanInt#( ) 関数を用いる方がシンプルです。そこで、2~50の間の整数をランダムに得て、それをカウンタC に使うことにします。

そこで、50→C を RanInt#(2,50)→C  に置き換えます。

RanInt#(2,50)→C
Lbl 0
If C-4Int(C÷4)≦1
Then
Locate 8,2,"X"
Else
Locate 8,2,"+"
IfEnd
Dsz C
Goto 0
Locate 8,2," "



ところで、ここで 0~50 の間の整数を得ようとして、RanInt#(0,50) とすると、たまに問題が発生します。つまりバグです。

RanInt#(0,50) は、0を返すことがあります。すると、カウンタ C が0になります。

この場合、Locate 8,2,"×" に続いて Dsz C が実行されると、Cが1つ減って-1になります。ループが回るに従ってC はどんどん減ってゆき、0になることが決してありません。ループを脱出するのはC が0になる時です。つまり、いつまでたってもループが回り続けるので、ゲームになりません。

では、RanInt#(1,50) はどうでしょうか?
1を返すときは早過ぎて、表示と同時に消えてしまい、ゲームとしては鬼仕様に過ぎます。実際に実行すると分かります。

そこで、RanInt#(2,50) としました。

これで、アニメーションを表示し、ランダムな時間が経過すると消える部分(ゲームの前半)ができました。

プログラム名 CH2-2
RanInt#(2,50)→C
Lbl 0

If C-4Int(C÷4)≦1
Then
Locate 8,2,"X"
Else
Locate 8,2,"+"
IfEnd
Dsz C
Goto 0
Locate 8,2," "


続いてプログラムの後半部分を作ります。



Chapter 2-3
再びGetkeyDoループでカウンタ計測

プログラムの後半部分は、アニメーションが消えた後、キーを押すまでの反応時間を計測して、その結果を表示する機能です。

そのためには、何かキーが押されるまでループをまわし、ループの中でカウンタを増やしてゆく....これで反応時間を測定できます。キーが押されてループから抜けた時、カウンタの値を表示すれば、後半部分ができそうです。

今回は特定のキー、fx-5800P の [EXE] キーの隣にある [(-)] キーを押すことにして、このキーが押されることは Getkeyで検出します。このキーが押されたらループから抜けて、その時のカウンタの数を表示させます。

さて、[(-)] キーのキーコードは、......Chapter 1 で作った Get Keycode プログラムで調べてみてください。DoループとGetkeyの使いこなしを、Chapter 1 で紹介しています。


先ずは、Do ループ:

Do
[処理]
LpWhile
[ループ継続条件]


ここで、ループ継続条件は、「押されたキーが [(-)] でないこと」 となります。従って、

Do
[処理]

LpWhile Getkey≠57

となります。


次に、このループ内でカウンタを増やす処理を追加します。

Chapter 2-2 で作った部分でもカウンタC を使っています。カウンタは0からスタートさせる必要があり、0→Cで初期化しておくのが常道です。

ところで、アニメーションが終わった時は、このカウンタC は必ず0(ゼロ)になります。そして、今作るループでは、カウンタを0からスタートすれば良いので、そのままカウンタCを使えば良さそうですが、今後のプログラム変更でどうなるか分かりません。

もし、Cがゼロから始まらないようなプログラム変更を行い、その時、ゼロに初期化していないことを忘れていると、バグに悩むことになります。そこで、明示的に 0→C で初期化しておきましょう。

ループがまわるたびにカウンターを1づつ増やせば良いので、Isz C を使います。

[(-)] キーを押すとループから抜けるので、ループから抜けた直後にカウンターCの値を表示します。

これで、今回の追加部分がきそうです。

プログラム名 CH2-3
RanInt#(2,50)→C
Lbl 0
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Dsz C
Goto 0
Locate 8,2," "

0→C
Do
Isz C
LpWhile Getkey≠57
Locate 8,2,C


今回追加した部分は、赤文字で示しています。

実際にプログラムを走らせてみてください。ゲームの基本的動作を確認できます。



Chapter 2-4
例外処理・例外フラグ・Breakコマンド

これまでに作ったプログラムを走らせて遊んでみます。

すると、アニメーションが表示されている時から、[(-)] キーを連打し続けると、1 を表示させることができてしまいます。フライングができるわけです。これではマズイ。ゲームになりません。

フライングしたらペナルティーを与えるとゲームらしくなります。

そこで、今回はフライングしたことを検知するようにします。具体的なペナルティーについては、点数の付け方やゲーム全体のルールをに即して、あとで考えることにします。

アニメーションを表示するループを抜き出します。

Lbl 0
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Dsz C
Goto 0


このループの中で、[(-)] キーが押されたら、それはフライングです。

フライングを検出したら、直ちにループから抜け出し、さらに「フライング」と表示するように、プログラムを変更しようと思います。

[(-)] キーのキーコードは、57なので、Getkeyの戻り値を監視して、57になればループを抜けるようにすれはOKですね。

このループは、カウンタC がゼロになればループから抜けるようになっています。これら2つの条件でループを抜けるように変更しなければなりません。

そこで、Lbl/Goto + Dsz ループとは別に、Doループ + Dsz を使うと、2つの条件でループを抜ける方法が、簡単に実現できるので、ループ自体を Doループに変更します。

Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Dsz C
LpWhile Getkey≠57


Lbl 0 / Goto 0Do / LpWhile Getkey≠57 に置き換えただけですが、Cがゼロになる時とキーコード57になる時の2つの条件でループを抜けられます。とても簡単に変更できました。



では次に、ループを抜けた後、フライングがあったことをを表示する方法を考えます

本来のプログラムの流れとは別に、例外的なことが発生した時に対処することを「例外処理」と言います。今回のフライングを「例外処理」として扱うことにします。


例外処理は、本来のプログラムの流れとは別に、一括して処理するのが良い方法です。プログラムの構造を単純化し、流れを明確にするために役立ち、バグの発生を抑える効果があります。

複数の異なる例外に対しても、一カ所でまとめて処理するようにします(ゲームを完成させるためには、他の例外処理も必要になりそうです)。

そこで、例外が発生した時に、その例外の種類を「例外フラグ」という変数に記録し、例外1、例外2、例外3,といったように区別します。こうしておくと、例外を一括処理する時に、フラグの内容に応じて、場合分けをして処理を行います。

本来のルートからちょっと寄り道して例外処理を行って、それが終われば元のルートに戻る、これが例外処理です。



例外検知と例外フラグ

フライングは、ループで構成されるプログラムの流れを壊す例外事象なので、「フライングだゾ!」と表示し、さらにゲーム進行上の変数(点数など)を変更するのは、一括して 「例外処理」として扱うことにします。なお、例外が発生したことを記録しておく例外フラグの「フラグ」とは旗のことです。「例外が発生したゾ!」と旗を揚げるイメージですね。フラグの最初の概念は、0 か 1、つまり旗を下げるか挙げるかのどちらかでした。

しかし、例外フラグに整数を割り当てる方が便利です。例外が発生していない時は、フラグは0(ゼロ)、例外発生時には0以外の整数値を割り当てることで、例外の種類を区別して記録できます。

ここでは、変数 E を例外フラグとします。例外 = Exception (イクセプション )の頭文字をとって E としました。

・例外フラグ E は、例外が発生していない時はゼロと決めます。つまり最初はゼロに初期化します: 0→E

・フライングが発生した時は例外フラグ E の値を 1 とします:
1→E



すると、以下のように変更できます。

Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0


※ 重要: 例外フラグ E は、プログラムの先頭部分で0に初期化しておく必要があります。

変更した部分を赤文字で示しています。Getkeyの戻り値が57の時、例外フラグ E に 1 を代入します。
ここで、If を使っても良いのでですが、より動作の速い ⇒(ジャンプ命令) を使いました。

LpWhile [ループ継続条件] の部分を、E=0 としました。例外が発生しなければ、例外フラグ E はゼロなので、この時はDoループを継続します。フライングと言う例外が発生して、例外フラグ E が 1 になると Doループを抜けます。

同時に、カウンタC がゼロになると、Dsz C のおかげで、LpWhile E=0 をジャンプして、次へ進んでループを抜けられます。


今後、フライング以外に新たな例外に対応する必要になれば、例外フラグ E に、2、3...と別の整数を割り当てます。その場合でも、Eは 0 以外ですから、ループを抜けられます。

以上をまとめます。

0→E
RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "



そして、キーを押すまでの反応時間を測定して表示を行う以下の処理が続きます。

0→C
Do
Isz C
LpWhile Getkey≠57
Locate 8,2,C



さて、フライングをした場合は、反応時間の計測は不要で、直ちにこのブロックを通り抜けて欲しい。

そこで、フライングした時、つまり例外フラグEが1の時に、直ちにDoループを抜けるようにします。そこで、CasioBasicに備わっているBreakコマンドを使います。Breakコマンドはループから抜けだすコマンドです。


※ CasioBasicコマンドリファレンス
      - Break



そこで、以下のようにプログラムを変更します(赤文字が変更部分)。

0→C
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd

Doループの中では、Eが1 ならば Break を実行して、ループから抜けます。

Doループが終われば、例外処理を一括して行う部分です。Eが1ならは「フライング」と表示を行います。

※ フライングは和製英語なので英語としては通じません。そこで FALSE START (不正スタート)と表示することにします。


これで、フライング検知と表示を盛り込むことができました。

プログラム名 CH2-4

0→E

RanInt#(2,50)→C
Do
If C-4Int(C÷4)≦1
Then
Locate 8,2,"×"
Else
Locate 8,2,"+"
IfEnd
Getkey=57⇒1→E
Dsz C
LpWhile E=0
Locate 8,2," "

0→C
Do
E=1⇒Break
Isz C
LpWhile Getkey≠57
Locate 8,2,C

If E=1
Then
Locate 3,2,"FALSE START"
IfEnd


改行を使って機能ブロックに分けています。CasioBasicでは、このように改行を入れてもエラーになりません。

1ブロック: 初期化
2ブロック: アニメーション表示(フライング検出)
3ブロック: 反応時間計測と表示
4ブロック: 例外処理(フライング表示)



次回は、これまで作ったプログラムを繰り返すようにし、さらに得点を計算させて、ゲーム仕様に近づけてゆきます。



つづく...


CasioBasic入門11 / 目次


応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


カシオプログラム関数電卓 FX-5800P-Nカシオプログラム関数電卓 FX-5800P-N
(2006/09/22)
CASIO(カシオ)

商品詳細を見る



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

リンク集 | ブログ内マップ
関連記事

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

Casio Basic: Break

Casio Basic
コマンドリファレンス

Casio fx-5800P、fx-9860GII、fx-CG20、fx-CG50 で確認をとっています。Casio fx-FD10 Pro では互換性はあると考えられますが、実機で確認していないので「可能性」としてご覧ください。
修正: 2015/01/09

fx-5800P / fx-9860GII / fx-CG20 / fx-CG50
Break

◆概 要:
ループから強制的に抜ける

◆書 式: Break

◆引 数:なし

◆戻り値:なし


Doループ、Whileループ、Forループの中で Break が実行されると、実行されたところから強制的にループの外へ抜け、そのループの次に記述されている処理までジャンプします。

例外処理やエラー処理などで有用です。



使用例

0→E:-1→X
Do
[処理]
If E≠0
Then Break
IfEnd
LpWhile X
"getting out of Do loop!" 


変数Eが0でない時、Doループを強制終了し、getting out of Do loop! (Doループから出た!) を表示します。

Breakを利用すると、複数の条件でループから抜けることができます。この例では、[処理] の中で、Eが0でなくなる時、Xが0になる時、の2つの条件でループから出られます。


0→M
While Getkey
[処理]
M⇒
Break

WhileEnd
"getting out of While loop"


変数Mがゼロでない時、Whileループを強制終了し、getting out of While loop (Whileループから出た) を表示します。

何かキーが押されていると Whileループへ入り [処理] を行います。そして [処理] の中で変数Mが変化して0でなくなると、ループを抜けます。これも2つの条件でループを抜けられる事例。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ


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

リンク集 | ブログ内マップ
関連記事

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

Casio Basic: Int / Frac

Casio Basic
コマンドリファレンス

Casio fx-5800P、fx-9860GII、fx-CG20、fx-CG50 で確認をとっています。Casio fx-FD10 Pro では互換性はあると考えられますが、実機で確認していないので「可能性」としてご覧ください。
2015/01/09 更新

fx-5800P/ fx-9860GII / fx-CG20 / fx-CG50
Int関数 / Frac関数

◆概 要: Int 関数は数値の整数部を、Frac 関数は数値の小数部を取り出す

◆書 式: Int(引数) / Frac(引数)
  • fx-9860GII や fx-CG20/50 では、( ) なしで引数を書けるが、( ) を使っても問題ない
◆引 数: 数値、変数、戻り値のある関数を指定
  • fx-9860GII や fx-CG20/50 で引数に式を使う場合は、引数の範囲を明確にするために ( ) 使用を勧める

Int や Frac は、関数電卓として内蔵されている関数機能。


Frac 関数では、内部精度15桁を超える引数を与えると、丸め誤差が発生する。Int 関数では、このような丸め誤差は発生しない。




Int や Frac の使用例

1) 整数Nを3で割った余りMを求める: Int( )関数の使用例

N-3Int(N÷3)→M

(証明)

任意の整数は3で割った余りが、必ず0、1、2のいずれかになります。
Nを3で割った時の余りをMとすると、整数Aを用いて

N = 3A+M
    ・・・(式1)


と表すことができます。従って余りMは、

M = N - 3A      ・・・(式2)

となります。ここで、Mを求めるためには、Aを知る必要があります。


そこで、(式1)を変形して、

N/3 = A + M/3      ・・・(式3) 

但し、M = 0, 1, 2 なので、M/30以上1未満になります (0 ≦ M/3 <1)。
従って、A + M/3 を小数で表すと、

A + 0.xxxxxxxxx


となります。

ここで、Aは整数なので、A+M/3 の整数部は、A になります。
これを Int( )関数を用いて表すと、

A = Int(A+M/3)

となり、(式3)から、Int( ) の引数は、N/3 に置き換えられるので、

A = Int(N÷3)      ・・・(式4)

(式4)を(式2)に代入すると、

M = N - 3Int(N÷3)

が得られます。

(証明終わり)



2) 整数Nの偶数 / 奇数の判定:Frac 関数の使用例

If Frac(N÷2)
Then "N is odd"
Else "N is even"
IfEnd


Nが奇数の場合は、2で割り切れません。このとき N÷2 は整数にならず、小数を伴う数値になります。つまり、Frac(N÷2) は0になりません。Frac(N÷2)0でないは、Frac(N÷2) が「真」です。If [条件][条件]「真」なので、Then 以下を処理し、N is odd (Nは奇数) と表示します。
Nが偶数の場合は、2で割り切れます。このとき N÷2 は整数になり、小数部はありません。つまり、Frac(N÷2) は0になります。「Frac(N÷2)0である」は、Frac(N÷2)「偽」で、「真」でありません。If [条件][条件]が「真」でないので、Else以下を処理し、N is evern (Nは偶数)と表示します。

この場合、Frac の引数である N÷2 が、少数以下14桁になることはあり得ないので、丸め誤差が発生することはありません。従って Frac を使っても問題はありません。


( ) を使わない引数指定時の注意 [fx-9860GII や fx-CG20]

1.2→A
Int A+0.8


を実行した結果は 1.8 となる。Int の引数の範囲が A+0.8 ではなくて、A  のみになっていることが分かる。

A+0.8 を引数にするには、( ) を使って、

1.2→A
Int (A+0.8)

とする必要がある。




応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ

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

リンク集 | ブログ内マップ
関連記事

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

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

やす (Krtyski)

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


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

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

おもしろい・役に立つならクリックしてください。励みになります。
にほんブログ村 IT技術ブログ 開発言語へ
にほんブログ村


人気ブログランキングへ


FC2ブログランキングへ


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

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

RSSリンクの表示
最新トラックバック
ブロとも申請フォーム

この人とブロともになる

QRコード
QR