投稿
おちゃめ ochame_nako
プチコン3号のボタン入力判定の中~上級者向けの問題です。 ABボタンを同時に押した瞬間(最大3フレームまでの差は許容する)に十字ボタンを押していなかったらBEEPが鳴るプログラムを作ろうと思います。 条件判断部分を記述してこのプログラムを完成させてください。 WHILE 1  IF 条件判断 THEN BEEP  VSYNC 3 WEND 締め切りは1月22日の23時です。回答をする場合はネタバレチェックを忘れずにお願いします。 締め切り後に正解例を提示して正解者には「そうだね」を押します。 腕に自信のある人の挑戦求む!
1そうだね
プレイ済み
返信[1]
親投稿
おちゃめ ochame_nako
《 補足 》 十字ボタンやABボタン以外のボタンが押されている場合でも正しく動作するようにしてください。 条件判断部分以外にも必要な命令等があれば追記は自由に行っても構いません。 「最大3フレームまでの差は許容」というのは例えばAボタンを押して1~2フレーム遅れてBボタンを押しても問題なく判定できるように意味ですが、これはVSYNC 3を活かせば特に気にする必要はありません。 他にも何か分からない部分、問題の不備な部分があればコメント欄でお願いします。 難易度はかなり高めですが、私のサイトのプチコン入門講座の内容を熟知していれば即答可能な優しい問題です。
0そうだね
プレイ済み
返信[2]
親投稿
otta777 otta777a
WHILE 1 OBU=BU:BU=BUTTON(0) IF (OBU AND 48)!=48 AND (BU AND 48)==48 AND (BU AND 15)==0 THEN BEEP VSYNC 3 WEND 押しっぱなしにした場合になりっぱなしにならないため前回の ボタン情報をチェックしていますが==0にしようか!=48にするか 迷いました。ANDでチェックするボタン情報を抜き出して 比較しています。
0そうだね
プレイ済み
返信[3]
親投稿
ねこはち neko80001
BUTTON(2) AND 48 かな?
0そうだね
プレイ済み
返信[4]
親投稿
おちゃめ ochame_nako
難しいと思うのでとりあえずヒント この問題の鍵になるのはVSYNC 3と同時押しの最大3フレームまでの許容です。 すでに回答している方もこのヒントを見て改めて回答しなおすのも大歓迎です!(これって「正解ではない」と言っているようなものだけど)
0そうだね
プレイ済み
返信[5]
親投稿
スー thanks_0u0
BUTTON(2)を使ってしまいそうになりましたけれど、これは罠でしょうかっ(`・д´・ ;) 多分これで動くと思うのですけれど…VSYNCのどこでABを押したかによっては3Fの猶予がないような気も…むむむ? WHILE 1 B=BUTTON(0) IF (B AND 48)==48&&!(B2 AND 48)THEN BEEP B2=B VSYNC 3 WEND
0そうだね
プレイ済み
返信[6]
親投稿
スー thanks_0u0
あっ、問題文読み間違えていますね。補足を、(十字ボタン)や(ABボタン以外のボタン)を押しても、と読んで勘違いしてしまいました(ノ´∀`*) 最大3Fも、最大、なので猶予が短くても良い、のでしょうか?一応これで再回答してみます(´=ω=`) WHILE 1 B=BUTTON(0) IF!(B AND 15)&&(B AND 48)==48&&!(B2 AND 48)THEN BEEP B2=B VSYNC 3 WEND
1そうだね
プレイ済み
返信[7]
親投稿
ねこはち neko80001
while 1 bt=button() if (bt and 48)==48 && !bt2 then beep bt2=button() and 48 vsync 3 wend これはむずい
0そうだね
プレイ済み
返信[8]
親投稿
けい kei0baisoku
追記OKを見て喜んで自由に書きましたが… 問題通りには動いたものの、制約から飛び出しちゃってる気もします…(´ω`)
2そうだね
プレイ済み
返信[9]
親投稿
ねこはち neko80001
while 1 bt=button() and 48 if bt==48 && !bt2 then beep bt2=bt and 48 vsync 3 wend 実機でごちゃごちゃやってたのは内緒で
0そうだね
プレイ済み
返信[10]
親投稿
ねこはち neko80001
く…”十字ボタンを押していなかったら”ってのを見落としてるよ。。。
1そうだね
プレイ済み
返信[11]
親投稿
もやしもどき Pseudomoyashi
追記を最小限に、条件式が一つの比較演算で済むように。 逆にごちゃごちゃになった感がしないでもないですが WHILE TRUE BC=B:B=BUTTON(0) IF ((NOT(BC AND &H30) AND B) AND &H3F)==&H30 THEN BEEP VSYNC 3 WEND
1そうだね
プレイ済み
返信[12]
親投稿
ツララ LongIceSword
(BUTTON(0) AND 48)==48 XOR ((BUTTON(0) AND 1)==1 OR (BUTTON(0) AND 2)==2 OR (BUTTON(0) AND 4)==4 OR (BUTTON(0) AND 8)==8) AND (BUTTON(0) AND 48)==48) 一寸長くなってしまいましたけど、どうでしょうか?
0そうだね
プレイ済み
返信[13]
親投稿
pinfu ANNAININ
さぱーり、です・・・ 初心者が参加すると、こんな感じになります(笑) WHILE 1 BC=B B=BUTTUN(0) IF (B AND 1)!=1 && (B AND 2)!=2 && (B AND 4)!=4 && (B AND 8)!=8 && (B AND 16+32)==48 THEN BEEP 1 VSNYC 3 WEND うーん。絶対違うな!(笑) おちゃめさん、いつもサイト更新お疲れ様です。参考にさせて頂いてます!
0そうだね
プレイ済み
返信[14]
親投稿
ねこはち neko80001
while 1 bt0=button() bt1=bt0 and 48 bt2=bt0 and 15 if bt1=48 && !bt2 && !bt3 then beep bt3=bt0 and 48 vsync 3 wend これでばっちり!
1そうだね
プレイ済み
返信[15]
親投稿
べー mmmggg
WHILE 1 B=BUTTON() IF (B AND &H3F)==&H30 && !(BOLD AND &H30) THEN BEEP BOLD=B VSYNC 3 WEND フレームは気にしなくてよいと言われたので気にしませぬ
1そうだね
プレイ済み
返信[16]
親投稿
ヒロブミ hirobumi-mmo
WHILE 1 IF (B AND &H3F)==&H30 THEN BEEP BB=BUTTON(0) AND &H30 VSYNC 3 B=BUTTON(0) B=(BB XOR B) AND B WEND
1そうだね
プレイ済み
返信[17]
親投稿
InDoor TheInDoor12
WHILE 1 BT=BUTTON() BT2=NOT OLD AND BT OLD=BT IF !(BT AND 15)&&(BT2 AND 16)&&(BT2 AND 32) THEN BEEP VSYNC 3 WEND 'こんなもんですかね。
1そうだね
プレイ済み
返信[18]
親投稿
Godot orz_127
参加してみます。 (BUTTON(0) AND 63)==48
0そうだね
プレイ済み
返信[19]
親投稿
WHILE TRUE B0%=BUTTON(0) IF !(B0% AND 15) && (B1% AND 48) != 48 && (NOT(B2% AND B1%) AND B0%) == 48 THEN BEEP B2%=B1%: B1%=B0% VSYNC 3 WEND 前提条件は以下の通りです。 ・3フレーム未満の間にボタン押下→離す操作が行われた場合については考慮しない ・ABの片方押下→3フレーム後に離す&もう片方を押下、という場合はAB同時押しと見なさない ・ABの片方押下&十字押下→3フレーム後にABの両方押下&十字を離す、という場合はAB同時押し時に十字押下なしと見なす
1そうだね
プレイ済み
返信[20]
親投稿
Godot orz_127
問題を読み直したら… ABボタンを押した瞬間でした^^; 前の回答だとABを押している時になってしまうorz と言うことでBUTTON(0)は止めます。 試してみたところBUTTON(1)だと押しっぱなしでも反応してしまうようなのでBUTTON(2)で。 以下に訂正します。 (BUTTON(2) AND 63)==48 でもこれだとSYNC 3毎のBUTTON()でABボタン同時押しの瞬間をとらえるのが難しく、ABを同時押ししたつもりでも、BEEPがなかなかならせない…。 違うような気も。
0そうだね
プレイ済み
返信[21]
親投稿
おちゃめ ochame_nako
回答者は全部でのべ18人、正解者は7人でした(正解率 39%) 《 ここがチェックポイント! 》 BUTTON(2)は60fpsで動作時以外は正常動作しないのでVSYNC 3を活かすには自前で押した瞬間のボタンを取得するプログラムを作る必要があります。 ループの1回前のボタンの状態を変数に入れておいて「前回押して無くて今回押したボタン」を調べればどのボタンを押した瞬間なのかが分かります。 つまり前回はABボタンを両方押して無く、かつ、今回は十字ボタンを押して無くて、かつ、ABボタンを両方押しているという3つの判定を行えば良いわけです。 ただし前回の時点では十字ボタンを押していても問題ないということに注意する必要があります。
0そうだね
プレイ済み
返信[22]
親投稿
おちゃめ ochame_nako
というわけで正解例はこちらです。 WHILE 1  A=B:B=BUTTON()  IF (A AND 48)==0 AND (B AND 63)==48 THEN BEEP  VSYNC 3 WEND ねっ!簡単でしょ? この正解例では「十字ボタンを押して無く、かつ、ABボタンを両方押している」という判定を(B AND 15)==0 AND (B AND 48)==48ではなく(B AND 63)==48という1つの式にまとめています。 これは私のプチコン3号入門講座でも書いている複数ボタンの入力判定ですがどのようなボタンの組み合わせであっても1つの式で簡単に判断が可能になります。
0そうだね
プレイ済み
返信[23]
親投稿
おちゃめ ochame_nako
VSYNC 3は安易にBUTTON(2)を使えないように60fpsでない場合を意図的に作り出すためです。 あと同時押しというものの解釈において私が意図しているものと異なる解釈ができないように最大3フレームまでの差を許容と書きました。 こうすることであらかじめAボタンを押しておいて後からBボタンを押した瞬間を「ABボタンを同時に押した瞬間」という解釈をできなくしています。
0そうだね
プレイ済み
返信[24]
親投稿
おちゃめ ochame_nako
otta777さんへ 「==0」ならば正解だったのですが、残念です。 スーさんへ 正解です! 察しのようにVSYNC 3だとあくまで「最大」3フレームの猶予なのですが、3フレームの猶予が必要というわけではないです。 けいさんへ 正解です。 問題の意図としてはBUTTON(2)が使えない時の記述方法だったのですが、ちゃんと3フレームの差を考慮してBUTTON(2)が使えるプログラムを作るとはうれしい誤算です。 もやしもどきさんへ 正解です! 強引に1つの比較演算でまとめたところがすごいです。
0そうだね
プレイ済み
返信[25]
親投稿
おちゃめ ochame_nako
ツララさんへ 現在押しているボタンしか考慮されてないためABボタンを押した瞬間はこれでは分からないですね。 pinfuさんへ せっかく変数BCに前回のボタンを入れているのに条件式ではそれが入ってないのが残念です。 あとサイトを見て頂きありがとうございます。 ねこはちさんへ 4度目の正直(?)で正解です。(比較演算はタイプミスで「=」になっていますが) べーさんへ 正解です。 InDoorさんへ 正解です。
0そうだね
プレイ済み
返信[26]
親投稿
おちゃめ ochame_nako
コア/co.aさんへ 前々回のボタンを取得しているのはなぜかと思いましたが、最大3フレームの猶予という解釈の違いなんですね。 これだと最大で6フレームの差でも同時押しと見なされますが、問題としている部分はクリアしているので正解とします。 Godotさんへ いい線いっているのですが、残念です。 VSYNC 3ではBUTTON(2)が正常動作しないのでこの問題ではそれを何とか工夫して判定できるようにする必要がありました。
0そうだね
プレイ済み
返信[27]
親投稿
ねこはち neko80001
やった~!
0そうだね
プレイ済み
返信[28]
親投稿
ねこはち neko80001
>おちゃめさん 丁寧な解説ありがとうございました
1そうだね
プレイ済み
返信[29]
親投稿
おちゃめ ochame_nako
抜けていた人があったので追記 ヒロブミさんへ 正解です。 というわけで正解者のカウント漏れがあったので訂正 回答者は全部でのべ17人、正解者は8人でした(正解率 47 %)
0そうだね
プレイ済み
返信[30]
親投稿
pinfu ANNAININ
問題作成、お疲れ様です! では、解説+サイトで復習してきます(笑) 個人的には、ビットの回が楽しみです!
0そうだね
プレイ済み
返信[31]
親投稿
3フレームの猶予→0〜2フレーム後まで、って事だったんですね。 お察しの通り、3フレーム後はOK・6フレーム後はNGと解釈していました。 けいさんの回答、応用が効きやすくて、いい回答ですね。
0そうだね
プレイ済み
返信[32]
親投稿
けい kei0baisoku
>おちゃめさん 問題作成と解説、ありがとうございます。やりがいがあって楽しかったです。 解答例、とてもシンプルでいいですね。 難しく考えないことって大切です。 問題見て、VSYNC 3をやめないと本当の意味では仕様を満たせないので迷わず分解したのですが、回答を投稿した後で、題意はビット演算だから的外れじゃないかとヒヤヒヤしていました……… 一応、問題の範囲に収まっていたようで良かったです。 >コア/co.aさん ありがとうございます。 多分、これまでの経験から本能が無意識に応用をさせるのだと思います……… 「おい、AB同時押しの猶予の3フレーム、あれアイテムとかでいろいろ増減することになったから」 ( Д ) ° °
0そうだね
プレイ済み
返信[33]
親投稿
Godot orz_127
SYNC 3にはそういう意図があったのですね。それが理解出来ず、せっかくのヒントも意味がわかりませんでしたorz ちなみに解答例では解りやすい様に1行追加する形式で書かれていますが、最初の問題文のとおり「条件判断」の部分に全て納めることは可能ですか? 解答を見たあとやってみましたがプチコン3では条件式に代入文をふくませようとすると文法エラーで弾かれてしまい旨くいきませんでした^^;
0そうだね
プレイ済み
返信[34]
親投稿
ツララ LongIceSword
なるほど!押した瞬間を判定する必要があるから、BUTTON()の返り値を変数に入れておく必要があるんですね。 勉強になりました。
0そうだね
プレイ済み
返信[35]
親投稿
おちゃめ ochame_nako
pinfuさんへ 入門講座のビット演算の回では初心者向けに2進数や16進数の基本からAND、OR、NOT、XORの仕組みについて書く予定です。 BUTTON(2)の代用として(Aに前回のボタン情報、Bに今回のボタン情報が入っている場合)NOT A AND Bで押した瞬間のボタンが取得できますが、それがなぜなのかの解説も書きます。 コア/co.aさんへ VSYNC 3で動作時に3フレームの猶予があるかというと実際は先に押したボタンのタイミングで変わってくるし、私のプログラムでは3フレームの猶予はないため「3フレームまでOK」と解釈した場合にはそのようになってしまいますよね。
1そうだね
プレイ済み
返信[36]
親投稿
おちゃめ ochame_nako
けいさんへ 本来は60fpsで動作しない場合のBUTTON(2)相当の判定方法のテストだったのですが、プログラミングは自由なので仕様通りに作られていれば何ら問題はないです。 最大3フレームの猶予というのが結構曖昧だったので補足で書いているようにVSYNC 3を活かしておけば細かいことは気にせずOKというスタンスでした(笑) Godotさんへ VSYNC 3のままだと前回のボタン情報が必須であるためIFとTHENの間にすべてを収めるのは無理ですね。 VSYNC 1だったら IF (BUTTON() AND 15)==0 AND (BUTTON(2) AND 48)==48 THEN BEEP とすることができますが。
0そうだね
プレイ済み
返信[37]
親投稿
おちゃめ ochame_nako
ツララさんへ BUTTON(1)、BUTTON(2)、BUTTON(3)は60fpsで動作時でないと正常な読み出しができないというのは覚えておいた方が良いですね。 そのための対策が今回の問題の意図ですが、瞬時の判定は「前回押してなくて今回押したボタン」であるため基本さえ抑えておけば難しくありません。
0そうだね
プレイ済み
返信[38]
親投稿
Godot orz_127
ご察しの通り、一旦その回答に。 実際に試したらVSYNC 3に阻まれ、結局2回目の回答に^^; IF THENの間に納める件 どうにかならないかと頑張った結果 ひとつ変数を減らす所まではできましたが… B=!!(B AND 48)*1024+BUTTON() IF (B AND 1087)==48 THEN BEEP この後、Bへの代入がどうにもならなくて…orz やはりプチコン3では無理ですか… 諦めます。
0そうだね
プレイ済み
返信[39]
親投稿
ツララ LongIceSword
『前回押していなくて、今押したボタン』 これを論理式で書き換えたのがつまり、pinfuさんへの回答で書かれている『Aに前回の、Bに今回のボタン情報を入れて、NOT A AND B』なんですね。 各命令で用意されている処理も、基本的な四則計算や論理演算でどういう事をやっているかまで分解して理解すれば、応用を考えるときのヒントにもなりますね。
0そうだね
プレイ済み