from gbso.cpu.insn import ADD_A_N, ADD_A_R, DEC_HL, LD_RR_NN
|
|
from gbso.program.mutate import *
|
|
|
|
# NOTE: All of these trial counts and probabilities could be a lot more precise,
|
|
# but it is easier to just throw extra trials at the problem.
|
|
|
|
|
|
def test_mutate_swap():
|
|
trials = 1000
|
|
swapped_count = 0
|
|
|
|
insn_a = ADD_A_R(R8.C)
|
|
insn_b = DEC_HL()
|
|
prgm = Program(insns=[insn_a, insn_b])
|
|
|
|
for _ in range(trials):
|
|
new_prgm = mutate_swap(prgm)
|
|
|
|
assert len(new_prgm.insns) == 2
|
|
assert isinstance(new_prgm.insns[0], Insn)
|
|
assert isinstance(new_prgm.insns[1], Insn)
|
|
assert new_prgm.insns == prgm.insns or new_prgm.insns == [insn_b, insn_a]
|
|
|
|
if new_prgm.insns != prgm.insns:
|
|
swapped_count += 1
|
|
|
|
assert abs(0.5 - (swapped_count / trials)) < 0.05
|
|
|
|
|
|
def test_mutate_insn():
|
|
trials = 1000
|
|
seen_add_insns = 0
|
|
seen_unused = 0
|
|
|
|
add_insn = ADD_A_N(128)
|
|
prgm = Program(insns=[add_insn])
|
|
|
|
for _ in range(trials):
|
|
new_prgm = mutate_insn(prgm, 0.5)
|
|
|
|
assert len(new_prgm.insns) == 1
|
|
assert isinstance(new_prgm.insns[0], Insn)
|
|
|
|
if new_prgm.insns[0] == add_insn:
|
|
seen_add_insns += 1
|
|
elif new_prgm.insns[0] == UNUSED():
|
|
seen_unused += 1
|
|
|
|
assert seen_add_insns < 10
|
|
assert abs(0.5 - (seen_unused / trials)) < 0.05
|
|
|
|
|
|
def test_create_random_insn():
|
|
insn = create_random_insn(ADD_A_R)
|
|
assert type(insn) == ADD_A_R
|
|
assert type(insn.r) == R8
|
|
|
|
insn = create_random_insn(ADD_A_N)
|
|
assert type(insn) == ADD_A_N
|
|
assert type(insn.n) == int
|
|
|
|
insn = create_random_insn(LD_RR_NN)
|
|
assert type(insn) == LD_RR_NN
|
|
assert type(insn.rr) == R16
|
|
assert type(insn.nn) == int
|
|
|
|
|
|
def test_create_random_operand():
|
|
op = create_random_operand(Operand.R8)
|
|
assert type(op) == R8
|
|
|
|
op = create_random_operand(Operand.R16)
|
|
assert type(op) == R16
|
|
|
|
for _ in range(100):
|
|
op = create_random_operand(Operand.R16_NO_SP)
|
|
assert type(op) == R16
|
|
assert op != R16.SP
|
|
|
|
for _ in range(100):
|
|
op = create_random_operand(Operand.IMM3)
|
|
assert type(op) == int
|
|
assert op >= 0 and op < 8
|
|
|
|
for _ in range(300):
|
|
op = create_random_operand(Operand.IMM8)
|
|
assert type(op) == int
|
|
assert op >= 0 and op < 256
|
|
|
|
for _ in range(500):
|
|
op = create_random_operand(Operand.IMM16)
|
|
assert type(op) == int
|
|
assert op >= 0 and op < 65536
|
|
|
|
for _ in range(300):
|
|
op = create_random_operand(Operand.SIMM8)
|
|
assert type(op) == int
|
|
assert op >= -128 and op < 128
|