終了判定

とりあえず、一次選考通過の報告。そして、ついでにロジック解説。


128パーセク到達後に敵を殲滅かつ母艦健在である場合、離脱成功としています。
クリア判定処理に関与するコードを抜き出してみると、以下のような感じ。

if(plmode){   プレイ中であれば
    repeat 99   艦艇オブジェクトを操作するループ
        gosub *verdup  オブジェクト管理テーブルからID=cntのオブジェクト情報を変数にdupする処理。
        if(eep){          オブジェクト存在時の処理
            flag>>f0      敵ならフラグをクリア
            if(eep>=1000){ オブジェクトが健在
                flag|=(cnt=0) 母艦(cnt=0)であればflagに1をORする。
            }
        }
    loop
}
:
進行度が128パーセク以上でflag>0であればゲーム終了判定を出す。

このループでは、すべての艦艇オブジェクトに関して状態値eepを判断し、それぞれの操作(移動、当り判定、爆発、敵生成)などを行います。(クリア判定に関係のない処理は省いています)
同時に、フラグ変数flagの状態を変化させ、母艦健在で敵殲滅の状態になっているかを求めています。
128パーセク到達後に通る箇所でflag>0か判断。
クリア判定が出ていれば、ゲーム終了シーケンス(終了メッセージ表示、ハイスコア更新)を行って、タイトルへ移行します。


まず、ループ前にflagを初期化していません。
敵が一体でも存在(爆発含む)していれば0になるし、flag>0が意味を持つのは128パーセク到達後の1度だけ(1度クリア判定すればタイトルに移行する)なので、省略しても問題がないのです。


実質の初期化は、母艦が健在のときだけ意味のある処理として flag|=(cnt=0) で行っています。母艦が健在なら1をOR。
母艦以外でも該当オブジェクトが健在であれば実行されますが、cnt=0の比較演算が0を返すのでflagは変化しません。
この初期化の前にflagが1だったとしても、先にも書いたように128パーセクに到達していなければ不問となるので不都合はありません。
そもそも、終盤は敵の出現頻度が高く、flagが1のままフレームを持ち越すことがないというのもあります。


そして、敵が存在(健在もしくは爆発)している場合にflagを落す処理は、flag>>f0 。
f0は敵味方の処理振分け用に用意されている変数で、値は味方→0、敵艦→1、敵ミサイル→2 です(*vardupにてcnt/33相当の値を代入)。
つまり、味方以外の処理でここを通ると、f0が0ではないためflagの左シフトが発生。flagは0か1なので、1ビットでも左シフトすれば0クリアされる仕掛けです。


ゲーム終了の処理は、ゲームクリア、ゲームオーバー兼用で、母艦が存在するかどうかでメッセージとハイスコア記録用文字列を変えるだけとしています。
これらの作り込みにより、100Bytes以内のコストでゲームクリア関連処理の追加を実現しています。