0_0_57B

 obake   specification   version 

0.57A で発見されたバグを修正後。新機能の実装中。

新しいお化けを補充するにあたって、盤面の状態を示す定数として -5 を導入しようかと思っていた。0.55D でバグが発見されたため、さきにバグを直すことを急いだため、-5 の導入は一時保留され無かったことに。

バグも修正されたので、もう一度 -5 定数として SummonObake をロジックへ組み込んでみる。もっと別の方法があればそちらのほうが良いのだけど。

他の仕組みを考える

定数は安易だけど、状態を確認するためのフラグとしては有効。しかし既存の条件判断にひと手間かかってしまうことを考えると、負荷を減らす効率的な処理に成るとも思えない。ならば二つ変数を用意してビットで状態を管理することもできそう。そっちで管理してみるか。

変数 DoronArTX( 初期値は 0 )

変数 DoronArTY( 初期値は 0 )

グリッドの状態管理ならばこれでいけるだろう。

a.TX == 1 のとき、DoronArTX += ( 1 << a.TX); こんな感じでグリッド毎に X , Y 毎に Pow2 使って足し算していく。

大失敗

二つ変数用意しても無駄だった。グリッドの状態を適切に管理するためには bitwise と一つの変数で良い。2つ用意しても無駄だし、上記方法では位置重複するため、管理自体が破綻している。

二次元配列を一次元配列化する方法で考えると、変数は一次元配列で、7*7 マスのグリッドならば 49 個の配列要素を持つ。問題は GM:S の変数は実数型、これは表現できる数値の範囲がどれくらいなのかよくわからない。少なくとも 49 個の要素をバイナリで管理する場合、10 進数表現で 15 桁の数値を扱う( 1<<49 = 562949953421312 ) 必要がある。

これだと float 型は一般的に精度がまったく足りない。double だったら環境によって異なる可能性を含め、最低でも有効桁数が 15 〜 16 ( 二進数で 52 桁 ) だから、まさしくギリギリながら保証されている精度の範囲内で収まっている・・・はず。

GM:S 側の対応は以下ドキュメントにあるが、やはりプラットフォーム毎の環境依存に注意が必要となってくる。

参考(YoYoGames):Real Number Functions

int64 の場合は 19 桁、GM:S でも環境依存無しで 15 桁くらいならなんとかなる?たしか二進数へ自動変換する標準の組み込み関数は無いんだよな。色々厳しいけれど一応エクスポートする場合の互換性も含めて 15 桁ならばなんとかなりそうだが、やってみるしかないだろう。

できるかな?

できたけど、環境依存発生

Windows PC では正常に動くロジックができた。問題は JavaScript の方。たぶん Android は問題無いだろう。

m = (k + (((i << 2)+(i << 1)) + i));// calculate on (columns + rows) == (k + (AW * i));
n = (1 << m);                       // Number of Pow2
o = ((DoronBitXY & n) == n);        // boolean(true or false)
    if ( !o ) {    // if (FALSE) then
        d = TDX[k];// rows
        e = TDY[i];// columns
        g = OG[# k , b-i];
        h = g.TiD;
        with (instance_create(d,e, rebirth))
        {
            TX           = k;
            TY           = i;
            sprite_index = Set_Animation_Stocker(TiD);
        };
        DoronBitXY += n;
    };

計算が一部ややこしく見えるが、二進数使ったハードコードだから。これで問題無いが、HTML5 ではおかしな動作をする。double では桁が足りない?よく考えたら最大で 15 桁の数値を扱うって前提だと、15 桁同士を足したら 16 桁にもなるんよね。

>>> 1<<49
562949953421312
>>> 1<<48
281474976710656
>>> 1<<47
140737488355328

互換性を維持しながらこのコードをベースにして書くのならば、数値の精度があとちょっと足りない。Windows は良いんだけど、JavaScript の double は 64 ビット浮動小数点、整数の場合だと 53 ビット精度。ブラウザ毎に実装がどうなってるのか分かり難いし、このやり方だと HTML5 では正常に動かない。

つまり互換性のためにバイナリは諦め、普通に一次元配列使うことにした。

    if (c == noone)
    {
    m = (k + (((i << 2)+(i << 1)) + i));// calculate on (columns + rows) == (k + (AW * i));
    if ( DoronBitXY[m] == false )
    {
        d = TDX[k];// rows
        e = TDY[i];// columns
        g = OG[# k , b-i];
        h = g.TiD;
        with (instance_create(d,e, rebirth))
        {
            TX           = k;
            TY           = i;
            sprite_index = Set_Animation_Stocker(TiD);
        };
        DoronBitXY[m] = true;
    };
    };

配列を使ったことで HTML5 でも無難に収まった。

そして完成したタイミングでまた新しい既存のバグを発見。こないだ直した 0.55D 以前からあったバグの亜種。やはり懸念していた通り、非常に稀なタイミングで発生するから発見が難しかったもの。修正を加えるべき場所はわかっているので比較的気は楽。発生条件を把握するまでが大変。

画面のキャプチャを撮りながらデバッグをしたが、0.57A で修正した所がモロにバグを仕込んでいると分かった。動画を見ると分かるがスワップキャンセラが壊れている。これは前回のデバッグで直したところが影響している。

0.55D で試したが 0.55D では確認できないバグだったので 0.57A で修正が入った時に、バグも同時に仕込んでいたらしい。

最終的にコードは以下のように修正した。

    if (TAFlag == true){
      AddVspeeD = true; // to Physics Canseller.
        if (a == ev.PickTiID){
            TiDBak    = TiD;
            TiD       = noone;
        }
        else{
              if (ev.PickTiID != noone) 
              { 
                  ev.PickTiID = noone; 
              };
        }; 
    }

安定したようにみえるので、ココで一度 YYC を使ってコンパイル実行。現状でも回転機能を使わなければ安定しているはず。

ついでに新しいコンボを発見したので、これまでの最高が 7 コンボだったが、記録は 8 コンボとなった。




次へ

前へ