pinfuさんへ
正解です。
ただし、Aボタン以外の情報というのが少し難しいですね。
IF B==16 THEN ~という処理と同等にするためには拡張スライドパッドのボタンが押されてないかも考えないといけないし、STARTやSELECTボタンが押されてないかも考えないと行けないです。
したがって、それらをすべて合計して16を引いた値にする必要があります。(ちなみにSTARTやSELECTは8192で取得可能)
Taku™¿¼³さんへ
正解です。
ただし、その方法ではELSEによって処理が入れ替わっているため実際にコードを書く場合にはその点だけは気を付ける必要があります。
2そうだね プレイ済み
1つ目は比較演算子をちゃんと書くというのは後からビット演算による判定を行おうとした際に理解しやすくなります。(IF B AND 16 THEN ~のように比較演算子を付けない書き方を行うとビット演算と同時に論理演算も理解しなくてはならないため一気にハードルが上がってしまいます)
あとBUTTON()が羅列する場合にはB=BUTTON()のように一旦変数に入れる方が見た目ですっきりします。(メインループが1フレーム以内の処理時間ならば一旦変数に入れても入れなくても処理は全く変わらない)
2つ目はBUTTON()は実行した時点でのボタン情報しか分からないため繰り返し処理が必要です。
3つ目はBUTTON()関数の情報はVSYNCのタイミングで更新されているためVSYNC無しだと誤動作の可能性があります。
1そうだね プレイ済み
「自分は初心者ではない」という人はIF B==16 THEN ~を比較演算(==)無しで記述できるかを考えてみましょう!(瞬時に分かれば中~上級者レベルかも)
1そうだね プレイ済み
初心者の人の贈るボタン入力判定の基本型
1つ目 IF BUTTON()==16 THEN (ボタンを押したときの処理)のように比較演算子(==)を省略せずに書く
2つ目 @ラベル~GOTO @ラベル、WHILE~WEND、REPEAT~UNTILなどを使いボタン入力待ちの繰り返し処理を行う
3つ目 ボタン入力待ちループの中に「VSYNC 1」を入れる
「IF B AND 16 THEN ~」のような比較演算子無しの書き方は「IF B==16 THEN ~」を比較演算子無しで書けるようになってからでも遅くはないです。
8そうだね プレイ済み
もう1つ注意点を書いておくと上記のサンプルプログラムでは書いてないですが、正しく判定させるためにはVSYNC 1をメインループの中に入れておいた方が良いです。
@LOOP
IF BUTTON()==16 THEN 押した時の処理
VSYNC 1
GOTO @LOOP
1そうだね プレイ済み
けいさんへ
32bit固定小数点演算のみをサポートしているプチコンmkIIは小数点以下3~4桁の演算精度しかないため演算中に0.999999という状態になることは無くてリテラルで記述する必要があるので実際は覚えなくても特に問題はないです。
詳しくは「コラム プチコンの演算精度」で検索してみてください。
ツララさんへ
逆に書けばエラーになるのがなぜかを考えるとプチコン3号の構文解析の仕組みが少しだけ見えてきますよね。
1そうだね プレイ済み
マニュアルやヘルプを見ての通りAボタンのボタン情報は16なのでそのBUTTON()関数の戻り値が16かどうかで判断すればいいです。
ただし、注意するのは正しく判定するにはボタン入力待ちのループを作る必要があります。
最も基本的な形は次のような感じです。
@LOOP
IF BUTTON()==16 THEN 押した時の処理
GOTO @LOOP
ループの書き方はいろいろあるし判定の仕方はいろいろありますが、まずは「BUTTON()==ボタン情報」で判定することを覚えましょう。
1そうだね プレイ済み
プチコンmkIIでは0.99999が0と解釈されて少し驚きましたがこれで有効数字をどのように丸めているのかがはっきり分かりました。(何の活用もできない発見ですが)
0そうだね プレイ済み
見つけるコツとしてはわざとエラーが出そうなコードを書いてみます。
その時点でエラー無しで動けばなぜそれでエラーが出ないのか探るだけですが、正常動作しない場合は少しずつ正常動作するコードに近づけることでギリギリのポイントが分かるし、プチコンの内部処理の挙動が少しずつ見えてきます。
1そうだね プレイ済み
けいさんへ
私はmkIIでもプログラムの最適化(高速化、リスト短縮化)のためエラーにならないギリギリのものを探し出してきましたが今回のは少し前に型判定ですごく苦労した部分があっさり解決できたので誰かが見つける前に自作関数への活用例として発表しました(笑)
大したものではない場合は自サイトのみでこっそり発表しています。
0そうだね プレイ済み
pinfuさんへ
? "A"==1
としてみてください。
本来ならば文字列と数値で比較演算はできないためType mismatchエラーとなりそうですが、画面には3と表示されていることが分かると思います。
これが何に使えるかというと型判定くらいしか私は思いつかないのですが、それだけでも大きなメリットだと思います。
1そうだね プレイ済み
けいさんへ
文字列と数値の比較演算で3を返すというのを使ったプログラムは私のSUFFIX関数くらいしかないと思います(笑)
これのお陰でinfとnanを駆使して行う必要があった型の判定がすごく短くできました。
ちなみに比較演算で3を返すようになったのはver.3.1.0からで私が自力で見つけました。
0そうだね プレイ済み
というわけで、初心者の人も難しく考えすぎずにDEFを使ってみてください。
新しい境地が開けると思います。
初級~中級者の人も今回書いたことを活用すればDEFで作った自作関数が不可解なエラー、不可解な動作をすることもなくなり、よりDEFを深く活用できるのではないかと思います。
3そうだね プレイ済み
サブルーチンとして作ってGOSUBで使用するという旧来のBASICの方法もありますが、やっぱりローカル変数やローカルラベルが使えて戻り値が設定できるのがDEFを使うメリットです。
ローカル変数が使えばそのプログラム(DEF以外の部分)で使っている変数名を気にせず変数を使用することができます。
DEF内ではローカル変数かグローバル変数の両方が使用できDEF内で定義したかDEF外で定義したかで使い分けることができます。
DEF内ではすべてローカルラベルとなっているためDEF内でジャンプする際にはラベルの重複を考えずにラベル名を付けることができます。
ただし、DEF内から外部のラベル(グローバルラベル)にはアクセスできないことに注意が必要です。
0そうだね プレイ済み
初心者にとってDEFというのはハードルが高いかもしれないですが、「こんな命令(関数)があったらいいな」というのも工夫次第でいくらでも作れてしまいます。
例えばver.3.1.0で新たに加わったシステム変数HARDWAREでNew3DSか旧3DSのどちらで動作させているのが分かるようになりましたが、私はプチコン3号が発売された日にそれと同等の機能を持つNEW3DS関数を作りました。
DEF NEW3DS()
VAR M=MAINCNT
FOR I=1TO 25000:NEXT
RETURN MAINCNT-M<3
END
このNEW3DS関数での機種判別の原理は見ての通りすごく単純です。
自分しか使わないだろうという命令や関数であっても一度作っておけば他のプログラムに流用が簡単にできます。
0そうだね プレイ済み
最初に書いたX2関数は数値も文字列も B*2 という処理を行いましたが、数値と文字列とで異なる動作をするような関数を作れば非常に自由度が高い関数になります。
例えば私が作ったBTWAIT命令では BTWAIT "AB" と記述すればAボタンとBボタンを両方押すまで待つという処理を行い、BTWAIT 48 と記述(Aボタン=16、Bボタン=32なのでA+Bは48)してもそれと同じ動作を行ってくれます。
ちなみに引数に代入されたのが文字列か数値かは私が作ったSUFFIX関数で判別可能です。(BTWAIT命令やSUFFIX関数については私の活動参照)
「文字列と数値の比較演算では3を返す」というのを利用してinfとnanを駆使して判定を行うよりも圧倒的に短いプログラムになっています。
0そうだね プレイ済み
DEF X2 A OUT B
B=0
IF A>0 THEN B=A*2
END
これで、ローカル変数Bは数値変数であることが確定します。(実数型か整数型かは確定しない)
B=0の時点で数値変数が確定するため引数に文字列を入れるとB=A*2の部分でType mismatchエラーとなります。
0そうだね プレイ済み
この関数を「Aが正の数のみ2倍にする」(負数の場合は0を戻す)という関数にしてみましょう。
DEF X2 A OUT B
IF A>0 THEN B=A*2
END
ここで X2 -1 OUT B とするとType mismatchエラーとなります。
引数が数値変数であるため戻り値も数値変数であるため問題ないはずですが、代入された時点で型が決まるため引数に負数を設定したらローカル変数Bには値が代入されてないため型が決まらず戻り値に数値変数を指定しているためType mismatchエラーとなるわけです。
エラーが出ないためにはローカル変数Bが数値変数で確定させる必要があり、最も簡単な方法はB=0をDEF内で実行させるということです。
0そうだね プレイ済み
DEFで定義している関数X2の引数に使用しているローカル変数Aは数値変数なので文字列を与えたら「Type mismatch」エラーが出ると思う人もいるでしょう。
しかし、実際は"123123"という値を返し、ローカル変数Aは文字列変数として解釈されています。
つまり、引数に使われる変数は記述した時点では型が決まらず、代入された時点で決まるということです。
X2関数を次のように書き換えました。
DEF X2 A OUT B
B=A*2
END
この場合は戻り値であるBも引数Aによって型が決まります。
したがって、引数がX2 123 OUT B のように引数が数値である場合は戻り値を入れる変数は数値変数にする必要があります。
同じ関数で引数を文字列にした場合には戻り値は文字列になるため X2 "123" OUT B$ のように戻り値には文字列変数を使う必要があります。
1そうだね プレイ済み