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