def rng_gen(seed=0, stop=None): if stop is None: stop = seed a = seed while True: yield a a = (17*a + 23)%256 if a == stop: break def calc_fight(start): a = start mob_str = [] count = 0 for _ in range(8): a = (17*a + 23)%256 #roll for mob, 50% if (a * 0x80 // 256) & 0x08 != 0: a = (17*a + 23)%256 #roll for extra hp, d15 mob_str += "1" count += 1 else: mob_str += "0" if mob_str[3] == "0": mob_str[3] = "1" count += 1 mobs = count mob_strs = [mob_str[:]] #18+139+77 = ~234 battle setup/teardown #(14+32)/2 +81 = 104 per undead cast #98 per mob killed #338 + 98X for fastest battle frames = 338 + 98*count while True: for i in range(8): if mob_str[i] == '1': a = (17*a + 23)%256 #roll for hit, 75% if a < 192: count -= 1 a = (17*a + 23)%256 #roll for damage, 255 mob_str[i] = '0' if count == 0: break mob_strs.append(mob_str[:]) for _ in range(count+1): a = (17*a + 23)%256 #roll for movement, plus extra?? #(12+16)/2 = ~14 per turn passed *3 #60 for monsters turn + 25 per mob #104+3*14+60+25*X = 206 +25X for undead recast frames += 206 + 25*count a = (17*a + 23)%256 #extra spin on victory return mob_strs, mobs, a, frames rng_map = {n:i for i,n in enumerate(rng_gen())} for i,n in enumerate(rng_gen()): ms, c, a, f = calc_fight(n) ms_out = " ".join("".join(m) for m in ms) score = int(f/c-140.25) print("{:02x} {:02x} {:02x} {:02x} {:4d} {} {:3d} {} ".format(i,n,a,rng_map[a],f,c,score,ms_out,))