かけらの記録ノート

かけらの記録ノート

主にポケモンの乱数について語るブログ

【コロシアム乱数】ホウオウの生成について

基本的な生成は戦闘時まばたきと同じであるが、瞬きの間にカメラのアングル決定処理を挟むので、少々複雑になっている。

  • カメラのアングル決定処理
def get_move(RNG, angle):
    f28 = 0
    f29 = 0
    f30 = 0
    f31 = 0
    frame = 0
    if(angle == 0):
        f28 = 20
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 60
        f29 = 20
        f0 = f0 - f28
        f28 = f0 * f1 + f28
        f31 = f28

        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 60
        f0 = f0 - f29
        f0 = f0 * f1 + f29
        f30 = f0
        if(f28 < f0):
            f30 = f28
            f31 = f0
        f28 = 6

        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 16.2497
        f0 = f0 - f28
        f0 = f0 * f1 + f28
        f29 = f0

        f28 = 0.314159

        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 1.09956
        f0 = -1.5708
        f2 = f2 - f28
        f0 = f0 + f28
        f28 = f2 * f2 + f0
        #print("静止1 f28:%.2f f29:%.2f f30:%.2f"%(f28,f29,f30,(f31-f30)))
        return frame, f31 - f30

    elif(angle == 1):
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 10
        f0 = 25
        f30 = f2 * f1 + f0
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 9
        f0 = 1
        f29 = f2 * f1 + f0
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 30
        f0 = 20
        f31 = f2 * f1 + f0
        #print("左右 f28:%.2f f29:%.2f f30:%.2f %.2f"%(f28,f29,f30,f30))
        return frame, f30

    elif(angle == 2):
        f28 = 20
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 60
        f29 = 6
        f0 = f0 - f28
        f30 = f0 * f1 + f28

        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 16.2497
        f0 = f0 - f29
        f31 = f0 * f1 + f29

        f28 = 0.314159
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 1.09956
        f0 = -1.5708
        f2 = f2 - f28
        f29 = 0.314159
        f0 = f0 + f28
        f28 = f2 * f1 + f0

        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 1.09956
        f0 = -1.5708
        f2 = f2 - f29
        f0 = f0 + f29
        f29 = f2 * f1 + f0

        if(f29 < f28):
            f0 = f28
            f28 = f29
            f29 = f0
        #print("右左 f28:%.2f f29:%.2f f30:%.2f %.2f"%(f28,f29,f30,(f29-f28)))
        return frame, f29 - f28

    if(angle == 3):
        f29 = 0
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f0 = 16.2497
        f0 = f0 - f29
        f29 = f0 * f1 + f29

        f30 = 0.314159
        f1 = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        f2 = 1.09556
        f0 = -1.5708
        f2 = f2 - f30
        f0 = f0 + f30
        f30 = f2 * f1 + f0
        #print("静止2 f28:%.2f f29:%.2f f30:%.2f %.2f"%(f28,f29,f30,0))
        return frame, 0
        
def Attention(RNG, prev_angle):
    frame = 0
    while(True):
        rand = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        if(rand < 0.25):
            angle = 3
            if(prev_angle != angle):
                break
        if(rand < 0.5):
            angle = 0
            if(prev_angle != angle):
                break
        if(rand < 0.75):
            angle = 1
            if(prev_angle != angle):
                break
        if(rand < 1):
            angle = 2
            if(prev_angle != angle):
                break
    if(angle == 0):
        rand = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        if(rand < 0.7):
            f28 = 0.3
            #f29 = 0.65
        else:
            f28 = 0.5
            #f29 = 0.75
        rand = (RNG.Advance(1) >> 16) / 0x10000
        frame += 1
        if(f28 <= rand):
            RNG.Advance(2)
            frame += 2
        gen_frame, move = get_move(RNG, angle)
        frame += gen_frame
        RNG.Advance(1)
        frame += 1
        zoom = None
    else:
        gen_frame, move = get_move(RNG, angle)
        frame += gen_frame
        if(angle == 3):
            RNG.Advance(1)
            frame += 1
        rand = (RNG.Advance(1) >> 16) / 0x10000
        RNG.Advance(1)
        frame += 2
        if(rand < 0.2 or (0.45 <= rand and rand < 0.65)):
            if(0.45 <= rand and rand < 0.65):
                zoom = "zoomout"
            else:
                zoom = "zoomin"
            RNG.Advance(2)
            frame += 2
        else:
            zoom = None
    return frame, angle, move, zoom

Aボタンを押すと同時に上の処理が走り、カメラが移動する。そして、カメラ遷移前の瞬きの状態から、カメラ遷移後の乱数値を使って、日本版では101F、欧州版50Hzでは126F瞬き処理が進んだ後に個体の生成が発生する。
ツールの計算結果を見れば分かるが、この時間はツボツボ、ホウオウどちらも同じであった。表示されている強制消費の値は、カメラのアングル決定処理+カメラ決定後の瞬き消費を含んだものとしている。

いくつか存在するコロシアム乱数のどのツールでもホウオウの生成だけが見つからなかったのでまとめておきました。
ツールを公開してからだいぶ経ちましたが、挑戦した人は片手で数えられるくらいしかいないので需要はほとんどないと思います。
これでおそらくコロシアム乱数における既知の情報のすべてが開示されたと思うので、挑戦してみたい人がいれば実装するなり参考にして調査してみてください。