944BASICの部屋の押し入れ
0番
2002.3.16更新
 
インフォーメーション
■自己紹介の部屋
■944BASICの部屋
■MI-E1ザウルスの部屋
■PI系ザウルスの部屋
■MI-10ザウルスの部屋
■リンクの部屋
 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)

◆石取り碁

ダウンロード:未完成です
 今、我が家では長男と囲碁ブームです。それはテレビ東京で始まった「ヒカルの碁」がきっかけです。
 実際、この漫画がきっかけで碁を始める小学生が増えたようです。

 それで、ザウルスで碁ができると、子供とどこでも遊べるなというのがきっかけです。まだ、初心者同志なので、九路盤です。

 現在、取るべき囲った石を見分けるプログラムまで出来ています。これでも遊べるのですが、「コウ」と「打てない所」の判断をつけた後、体裁を整えて公開したいです。