2007年7月9日月曜日

格ゲーのようなコマンド解析

フォーチュンサモナーズ(素晴らしいゲームです)に触発されて作成。
文字列検索用の関数instr()を利用しています。
メジャーな実装方法は知りませんが、間違いなくこれはマイナーな実装方法でしょう……。

※キューに要素を追加することを正しくはエンキュー(enqueue)と呼ぶそうです。#const global COMMAND_LENGTH 16
#module
#deffunc shiftAndPush var p1, str p2, local l
    poke p1, 0strmid(p1, 1COMMAND_LENGTH - 2)
    poke p1, COMMAND_LENGTH - 2, p2
    poke p1, COMMAND_LENGTH - 10
    return
#global

    sdim sCommand, COMMAND_LENGTH
    gosub *clearCommand

// 方向をあらわす文字(テンキー同様、左が4・上が8・右が6……となっている)
    sdim sCom, 417
    sCom(1) = "4" // 左
    sCom(3) = "7" // 左上
    sCom(2) = "8" // 上
    sCom(6) = "9" // 右上
    sCom(4) = "6" // 右
    sCom(12)= "3" // 右下
    sCom(8) = "2" // 下
    sCom(9) = "1" // 左下
    sCom(16)= "A" // スペースキー

*main
    gosub *renewCommands
    gosub *serch
    title sCommand
    wait 2
    goto *main

// キューが更新されるかどうか判定
*renewCommands
    stick keys, 0b01111 : keys &= 0b11111

    if ((keys & 0b0101) == 0b0101) {
        // 上下同時押しは無効
        keys -= 0b0101
    }
    if ((keys & 0b1010) == 0b1010) {
        // 左右同時押しは無効
        keys -= 0b1010
    }
    if (keys != oldKeys) {
        if (keys & 0b11111) != (oldKeys & 0b01111) {
            // 新しく入力をキューに追加
            gosub *insert
        }
        oldKeys = keys
    }

    counter++
    if counter > 10 {
        // 10フレーム入力がないとキューを廃棄
        counter = 0
        gosub *clearCommand
    }
    return

// 入力されたボタンに応じてキューに文字列をプッシュ
*insert
    counter = 0
    if ((keys & 0b01111) != 0) & ((keys & 0b01111) ! (oldKeys & 0b01111)) {
        shiftAndPush sCommand, sCom(keys & 0b01111)
    }
    if (keys & 0b10000) {
        shiftAndPush sCommand, sCom(keys & 0b10000)
    }
    return

// 技の発動条件を検索
*serch
    if instr(sCommand, 0"41236A") > 0 {
        // 左 → 左下 → 下 → 右下 → 右 → スペースキー
        mes "超必殺拳発動!"
        gosub *clearCommand
    }
    if instr(sCommand, 0"236A") > 0 {
        // 下 → 右下 → 右 → スペースキー
        mes "必殺拳発動!"
        gosub *clearCommand
    }
    if instr(sCommand, 0"2146A") > 0 {
        // 下 → 左下 → 左 → 右 → スペースキー
        mes "気合脚発動!"
        gosub *clearCommand
    }
    return

// キューを廃棄
*clearCommand
    memset sCommand, '_'COMMAND_LENGTH - 1
    return

4 件のコメント:

kz3 さんのコメント...

キューに対する要素の追加はプッシュとよばず、エンキュー(enqueue)というみたいですよ。
プッシュと呼ぶときもあるのかも知れませんが・・・。

eller さんのコメント...

kz3さん、こんにちは。こんな駄スクリプトまで見てくださってありがとうございます。
どうやらご指摘の通りのようですね。またひとつ勉強になりました。

ただこれがキューなのかどうか自体怪しい感じですし、スクリプトはそのままにしておき、注意書きを添える程度にとどめておきます。

kz3 さんのコメント...

ellerさん違います^^;
キューに追加することをエンキューです。(スタックのプッシュに相当)
取り出しはデキュー(dequeue)です。

eller さんのコメント...

先ほど気づいて「しまったぁぁぁっ!」とダッシュで戻ってきたのですが、遅かったようです^^;
訂正させていただきました。