944BASICの部屋で古くなったものを収納する押入れです。
目 次
◆マルチステートメントを使わない方法 2002.2.6
◆ネストしないでNEXTから抜ける方法 2002.2.6
-
◆入力を考える1 数字ボタン作り
2002.2.5
◆ここまで来たら、Power関数も作ろう
◆数値計算には必須の自然指数(EXP)
◆数値計算には必須の自然対数(LOG)
-
◆石取り碁
◆マルチステートメントを使わない方法(2002.2.6)
944BASICでマルチステートメントが多いと動作がおかしくなる現象があるようです。それなら、「なるべくマルチステートメントを使わないでプログラムを組む方法は無いか?」ということで説明します。
BASICで一番マルチステートメントを使いたくなるのは、IF文だと思います。何故ならIF文はTHEN以降の命令は改行までの1行のみしか有効とならないからです。
(例1)
IF A0=1 THEN B=0:C=0:D=0:GOSUB *FOO
IF A1=1 THEN B=1:C=1:D=1:GOSUB *FOO
上のような感じのプログラムがあったとします。これをVisualBasic風に書くと以下のようになります。
(例1のVB風)
If A0=1 Then
B = 0
C = 0
D = 0
Call foo
End If
If A1=1 Then
B = 1
C = 1
D = 1
Call foo
End If
944BASICでも、こんな感じに書けないか。書ければIF〜THEN〜のマルチステートメントの嵐におさらばだ。ということで、私がいつも使っている書き方を紹介します。
ELSE とGOTO文を組み合わせて、IF文が複数行書けるかのように見せる方法です。下記のようです。
(例1改)
IF A0=1 THEN ELSE GOTO *ABC00
B=0
C=0
D=0
GOSUB *FOO
GOTO *ABC01
*ABC00
IF A1=1 THEN ELSE GOTO *ABC01
B=1
C=1
D=1
GOSUB *FOO
*ABC01
こんな感じです。また、IF〜THEN〜ELSE〜のような構文の場合は、以下のようになります。
(例2)
IF A0=1 THEN B=0:C=0:D=0:GOSUB *FOO ELSE B=1:C=1:D=1:GOSUB *FOO
(例2改)
IF A0=1 THEN ELSE GOTO *ABC00
B=0
C=0
D=0
GOSUB *FOO
GOTO *ABC01
*ABC00
B=1
C=1
D=1
GOSUB *FOO
*ABC01
この書き方に慣れると、マルチステートメントはずいぶん少なくなると思います。
ただ、ここにあげた例は、ちょっと悪い例かもしれません。もっともっとマルチステートメントが続くときに使う方が良いと思います。
あまり単純なIF文にも、この書き方を使っていると、ソースが凄く見にくくなってしまいます(^^;。
まっ、こんな例もあるんだなぁということで・・・。
◆ネストしないでNEXTから抜ける方法(2002.2.6)
944BASICでは、ネストのスタックが1024もあるので、そう簡単にスタックがオーバーフローしないと思いますが、昔のBASICではネストが5つまでとか、結構スタックの無いことが多く、極力「FORループの途中から抜けない」とか、「サブルーチンの途中からGOTOで抜けない」とか考えてプログラムを作ったものでした。年がバレルゾ(^^;。
んで、私がFORループで良く使う手を紹介します。当たり前といえば当たり前ですが・・・。
(例1)
A=5
FOR I=0 TO 10
IF B=0 THEN GOTO *BREAK00
B=A-I
NEXT
*BREAK00
T=I*5
上のようなプログラムがあったとします。これでは、FORループを途中から抜け出ることになりまして、調子が悪いです。そこで、下のようにするとFORループの終了条件を満たして、ループから抜けてきます。抜け出るときのIの値を参照したいときには、THENの後でIの値を他の変数に代入してからI=10として抜けます。
(例1改)
A=5
FOR I=0 TO 10
IF B=0 THEN C=I:I=10:GOTO *BREAK00
B=A-I
*BREAK00
NEXT
I=C
T=I*5
こんな感じです。あんまり参考にならないかな・・・?(^^;
-
◆入力を考える1
数字ボタン作り 2002.2.5
-
ダウンロード:trsctes0.LZH
-
数値計算のルーチンやVAL関数のようなものを作ってきましたが、944BASICにはまだ、入力系がサポートされていません。そこで、数字の入力関連の自作を始めました。
こんな感じの数字キーのボタンをタップして、キーのアスキーコード例えば「1」なら48とかを返すプログラムを試しに作ってみました。入力が行えるようになるには、入力部に当たる数字ボタンと、後は、編集部「行編集」、表示部「数値表示」を作らなければなりません。
ボタンの部分はスプライトで作ろうとも思いましたが、今回はグラフィックを使って作成しました。こっちの方が汎用性があるかな???と思ったので(^^;。
アップしたプログラムとしては、ペンの動作処理である「数字キー入力」*InputNumKeyルーチンを中心に、ペンタッチがあったら、そこの座標のボタンのアスキーコードを計算する「タップ位置チェック」*TapCheckルーチンと、ボタンのコードによって、ボタンの絵を反転させたり戻したりする「指定ボタンの絵描画」*BotActルーチンで出来あがっています。
◆ここまで来たら、Power関数も作ろう
ダウンロード:trscatn0.lzh
Power関数とは、XのY乗を求める関数です。BASICの文法でいうところのX^Yの属に言うヤママーク(こんなことを言っているのは私だけ?)です。944BASICはこの演算子もサポートしていないので、自前で作ることにしました。XのY乗はYが正数なら話しは簡単で、Yの数だけXを掛け合せれば良いのですが、そうは問屋が下ろしません。
でも、LOGとEXPを求めるルーチンを作ってしまったので、鬼に金棒、こいつらを使って簡単に作れてしまいます。
A=X^Yとすると、両方対数にして、LOG(A)=LOG(X^Y)=Y*LOG(X)、下に書いたEXPとLOGの関係より A=EXP(LOG(X)*Y)が求まります。
REM ****** POW( POWX,POWY ) POWX^POWY
REM ****** 戻り値 POWA ********
*POW
IF INT(POWY)=POWY THEN GOTO *POWSEISU
LOGX=POWX:GOSUB *LOG
EXPX=POWY*LOGY:GOSUB *EXP
POWA=EXPY
RETURN
*POWSEISU
POWA=1
IF POWY=0 THEN RETURN
IF POWY>0 THEN ELSE GOTO *POWFU
FOR POWI=1 TO POWY
POWA=POWA*POWX
NEXT
RETURN
*POWFU
POWJ=-POWY
FOR POWI=1 TO POWJ
POWA=POWA/POWX
NEXT
RETURN
上のルーチンでは、計算を早くするために、Yが整数ならば、FORループで計算するようにしています。
◆数値計算には必須の自然指数(EXP)
ダウンロード:trscatn0.lzh
自然指数とはあまり呼ばれませんが、eでよく表されるエキスポネンシャルのことです。この関数もポケコン等には当たり前のように持っています。944BASICには無いので、これもテイラー展開を用いて計算でもとめるプログラムを作って見ました。
下記のような、こんな簡単なプログラムです。
REM ****** EXP( EXPX ) ********
REM ****** 戻り値 EXPY ********
*EXP
EXPK=1:EXPY=EXPK:EXPN=1
*EXPLOOP
EXPK=EXPK*(EXPX/EXPN)
IF ABS(EXPK)<0.0000001 THEN RETURN
EXPY=EXPY+EXPK
EXPN=EXPN+1
GOTO *EXPLOOP
EXPとLOG(自然対数)は以下のような関係にありますので書いておきます。
Y=EXP(X) のとき、
X=LOG(Y)
◆数値計算には必須の自然対数(LOG)
ダウンロード:trscatn0.lzh
BASICでは何故か、自然対数(ln)のことをLOGと書きます。LOGというと普通は底が10である常用対数のことので、すごくまぎらわしいです。
でも、ここはBASICらしく?(^^;、自然対数LOGを944BASICで作ってみましょう。
LOGを作るには、ちょっと面倒なことをします。詳しい話しは省きますが、Xの値が2以下のときと2以上のときとに分けて考えます。2以上のときはXは2の何乗以下かというのを調べて、それで割った値を用いて計算します。
LOGのサブルーチンの中で、再帰的に呼び出しているようなところがありますが、再帰呼び出しにはなっていません。リストを読んでみて下さい。
REM *** LOG( LOGX ) 自然対数***
REM ****** 戻り値 LOGY ********
*LOG
IF LOGX<=2 THEN LOGZ=LOGX:GOTO *LOGANS
LOGC=1:LOGD=1
*LOGEANS
LOGD=LOGD*2
LOGE=LOGX/LOGD
IF LOGE<=2 THEN GOTO *LOGCANS
LOGC=LOGC+1
GOTO *LOGEANS
*LOGCANS
LOGZ=LOGE:GOSUB *LOGANS
LOGY=LOGC*0.69314718+LOGY
RETURN
*LOGANS
LOGY=(LOGZ-1):LOGB=LOGY:LOGN=2
*LOGLOOP
LOGB=LOGB*(LOGZ-1)
LOGK=LOGB/LOGN
IF ABS(LOGK)<0.0000001 THEN RETURN
IF LOGN%2=0 THEN LOGY=LOGY-LOGK ELSE LOGY=LOGY+LOGK
LOGN=LOGN+1
GOTO *LOGLOOP
自然対数から常用対数を求める式を書いておきます。
常用対数 LOG10(X)=LOG(X)/LOG(10)
-
◆石取り碁
ダウンロード:未完成です
|
今、我が家では長男と囲碁ブームです。それはテレビ東京で始まった「ヒカルの碁」がきっかけです。
実際、この漫画がきっかけで碁を始める小学生が増えたようです。
それで、ザウルスで碁ができると、子供とどこでも遊べるなというのがきっかけです。まだ、初心者同志なので、九路盤です。
現在、取るべき囲った石を見分けるプログラムまで出来ています。これでも遊べるのですが、「コウ」と「打てない所」の判断をつけた後、体裁を整えて公開したいです。 |
|