裏CHUNSOFT > ゲーム解析入門 > 3.乱数カウンタ

3.乱数カウンタ

乱数が生成される度に1ギタン増えるようにしてみます。

03F65F  08           PHP             ; 
03F660  C2 20        REP #$20        ; 2バイトモード
03F662  A5 B7        LDA $B7         ; "A" = $B7〜$B8
03F664  0A           ASL * 5         ; "A" *= 20 (を10000で割った余り)
03F669  45 B8        EOR $B8         ; "A" = "A" xor $B8〜$B9
03F66B  0A           ASL             ; "A" *= 02 (を10000で割った余り)
03F66C  E2 20        SEP #$20        ; 8ビットモード("A"の上位バイトはそのまま)
03F66E  A5 B8        LDA $B8         ; "A" = $B8
03F670  85 B9        STA $B9         ; $B9 = "A"
03F672  A5 B7        LDA $B7         ; "A" = $B7
03F674  85 B8        STA $B8         ; $B8 = "A"
03F676  A5 B6        LDA $B6         ; "A" = $B6
03F678  85 B7        STA $B7         ; $B7 = "A"
03F67A  EB           XBA             ; "A"の上位バイトと下位バイトを交換
03F67B  85 B6        STA $B6         ; $B6 = "A"
03F67D  85 00        STA $00         ; $00 = "A" (これが新しい乱数)
03F67F  64 01        STZ $01         ; 
03F681  28           PLP             ; 
03F682  6B           RTL             ; 

今回は新しくプログラムを追加しなければなりません。 しかしプログラムはぎっしり詰まっているので、03F800以降の空き領域に新しいプログラムを書いて、そこにジャンプすることにします。 ギタンは4バイトなので、勿論乱数カウンタは2バイトモードです。なので、C2 20(REP #$20)の後に20 00 F8(JSR $F800)を入れることにしましょう。 元のプログラムが3バイト上書きされてしまうので、その処理も03F800以降で行わなければなりません。

まず、ギタンを1増やす処理を書きます。 下位2バイトを1増やして、その結果が0000になったら、繰り上がりということなので上位バイトも1増やします。 ギタンを増やし終わったら、ジャンプ命令で上書きされる部分のプログラムを最後に書いておきます。

03F800  AF 3F 89 7E  LDA $7E893F     ; "A" = (ギタンの下位2バイト)
03F804  1A           INC             ; "A" ++
03F805  8F 3F 89 7E  STA $7E893F     ; (ギタンの下位2バイト) = "A"
03F809  D0 09        BNE #$09        ; 上記の結果が0000(繰り上がった)でないとき03F814へ
03F80B  AF 41 89 7E  LDA $7E8941     ; "A" = (ギタンの上位2バイト)
03F80F  1A           INC             ; "A" ++
03F810  8F 41 89 7E  STA $7E8941     ; (ギタンの上位2バイト) = "A"
03F814  A5 B7        LDA $B7         ; "A" = $B7〜$B8 ; 旧03F662
03F816  0A           ASL             ; "A" *= 02      ; 旧03F664
03F817  60           RTS             ; 元のルーチンへ

上の命令にジャンプするようにします。

03F65F  08           PHP             ; 
03F660  C2 20        REP #$20        ; 16ビットモード
03F662  20 00 F8     JSR $F800       ; 03F800へ
03F665  0A           ASL * 4         ; "A" *= 10
03F669  45 B8        EOR $B8         ; "A" = "A" xor $B8〜$B9

ということで以下のように変更すれば良いです。 フロアを1つ生成するのに数千回乱数が消費され、モンスターやNPCがいれば、ターン毎に必要に応じて乱数が消費されるのが分かります。 「偏る乱数」がよく言われますが、狙ってモンスターハウスや特殊攻撃を連続で出したりすることなんてできないということが分かります。

変更前
0003F660 C2 20 A5 B7 0A 0A 0A 0A 0A 45 B8 0A E2 20 A5 B8
……
0003F800 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0003F810 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
変更後
0003F660 C2 20 20 00 F8 0A 0A 0A 0A 45 B8 0A E2 20 A5 B8
……
0003F800 AF 3F 89 7E 1A 8F 3F 89 7E D0 09 AF 41 89 7E 1A
0003F810 8F 41 89 7E A5 B7 0A 60 FF FF FF FF FF FF FF FF

2010年8月8日更新

裏CHUNSOFT > ゲーム解析入門 > 3.乱数カウンタ