예제 #1
0
def merge(gens):
    saw_pos = False
    iters = [iter(x) for x in gens]
    pos = [None for x in gens]
    ok = True
    buff = []
    while ok:
        ok = False
        for i in range(len(iters)):
            x = next(iters[i], None)
            if not x:
                buff.append(Cmd.Wait())
            else:
                ok = True
                if type(x) == Pos:
                    saw_pos = True
                    pos[i] = x
                    buff.append(Cmd.Wait())
                else:
                    ok = True
                    buff.append(x)
        if ok:
            for x in buff:
                yield x
            buff = []
    if saw_pos:
        yield pos
예제 #2
0
def test_illegal_smoves():
    em = Cpp.Emulator(set_cpp_state())

    # bot 2 moves out of bounds
    assert em.check_add_command(ctp(pc.Wait())) == ''
    msg = em.check_command(ctp(pc.SMove(Diff(0, 0, 3))))
    assert msg != ''

    # bot 2 moves through the filled area
    msg = em.check_command(ctp(pc.SMove(Diff(3, 0, 0))))
    assert msg != ''

    # ...
    c = ctp(pc.Wait())
    em.add_command(c)
    em.add_command(c)
    em.run_step()

    # bot 1 moves through bot 2
    msg = em.check_command(ctp(pc.SMove(Diff(0, 0, 3))))
    assert msg != ''

    # bot 2 moves through volatile area
    assert em.check_add_command(ctp(pc.Fill(Diff(0, 1, 1)))) == ''
    msg = em.check_command(ctp(pc.SMove(Diff(0, 1, 0))))
    assert msg != ''

    # bots 2 & 3 move freely
    assert em.check_add_command(ctp(pc.SMove(Diff(1, 0, 0)))) == ''
    assert em.check_add_command(ctp(pc.SMove(Diff(0, 4, 0)))) == ''
    assert em.steptrace_is_complete()
    em.run_step()
예제 #3
0
def merge_line(bots, pos, delta):
    tasks1 = {}
    for i in bots:
        tasks1[i] = []

    for i in range(0, len(bots) - 1, 2):
        a = bots[i]
        b = bots[i + 1]
        tasks1[b] = navigate(pos[b], pos[a] + delta)

    yield tasks1

    # Issue fussion commands
    tasks = {}
    for i in bots:
        tasks[i] = []

    new_bots = []
    for i in range(0, len(bots) - 1, 2):
        a = bots[i]
        b = bots[i + 1]
        tasks[a] = [Cmd.FusionP(delta)]
        tasks[b] = [Cmd.FusionS(delta * (-1))]

        new_bots.append(a)
        del pos[b]

    if len(bots) % 2:
        new_bots.append(bots[-1])
        tasks[bots[-1]] = [Cmd.Wait()]
    yield tasks

    if len(new_bots) > 1:
        yield from merge_line(new_bots, pos, delta)
예제 #4
0
 def _clear(self):
     self.moves = {}
     for i in self.next_bots:
         x = self.next_bots[i]
         self.bots[x.id] = x
     self.next_bots = {}
     for i in self.bots:
         self.moves[i] = Cmd.Wait()
예제 #5
0
def test_illegal_lmoves():
    em = Cpp.Emulator(set_cpp_state())

    # bot 2 moves out of bounds
    assert em.check_add_command(ctp(pc.Wait())) == ''
    msg = em.check_add_command(ctp(pc.LMove(Diff(0, -1, 0), Diff(0, 0, 3))))
    assert msg != ''

    msg = em.check_add_command(ctp(pc.LMove(Diff(0, 1, 0), Diff(0, 0, 3))))
    assert msg != ''

    msg = em.check_add_command(ctp(pc.LMove(Diff(0, 0, 2), Diff(0, 0, 2))))
    assert msg != ''

    # bot 2 moves through the filled area
    msg = em.check_add_command(ctp(pc.LMove(Diff(2, 0, 0), Diff(0, 0, 1))))
    assert msg != ''

    msg = em.check_add_command(ctp(pc.LMove(Diff(0, 3, 0), Diff(3, 0, 0))))
    assert msg != ''

    # ...
    em.add_command(ctp(pc.Wait()))

    # bot 3 moves through bots 1 & 2
    msg = em.check_add_command(ctp(pc.LMove(Diff(-1, 0, 0), Diff(0, 0, 4))))
    assert msg != ''

    # ...
    em.add_command(ctp(pc.Wait()))
    em.run_step()

    # bot 2 moves through volatile area
    assert em.check_add_command(ctp(pc.Fill(Diff(0, 1, 0)))) == ''
    msg = em.check_add_command(ctp(pc.LMove(Diff(0, 1, 0), Diff(0, 0, -1))))
    assert msg != ''

    # bot 2 moves freely
    assert em.check_add_command(ctp(pc.LMove(Diff(0, 2, 0), Diff(0, 0,
                                                                 -1)))) == ''

    # bot 2 dangles around freely
    assert em.check_add_command(ctp(pc.LMove(Diff(2, 0, 0), Diff(-3, 0,
                                                                 0)))) == ''
예제 #6
0
def cmd_from_cpp(ccmd):
    if isinstance(ccmd, Cpp.Halt):
        return commands.Halt()
    if isinstance(ccmd, Cpp.Wait):
        return commands.Wait()
    if isinstance(ccmd, Cpp.Flip):
        return commands.Flip()
    if isinstance(ccmd, Cpp.SMove):
        return commands.SMove(ccmd.lld)
    if isinstance(ccmd, Cpp.LMove):
        return commands.LMove(ccmd.sld1, ccmd.sld2)
    if isinstance(ccmd, Cpp.Fission):
        return commands.Fission(ccmd.nd, ccmd.m)
    if isinstance(ccmd, Cpp.Fill):
        return commands.Fill(ccmd.nd)
    if isinstance(ccmd, Cpp.Void):
        return commands.Void(ccmd.nd)
    if isinstance(ccmd, Cpp.GFill):
        return commands.GFill(ccmd.nd, ccmd.fd)
    if isinstance(ccmd, Cpp.GVoid):
        return commands.GVoid(ccmd.nd, ccmd.fd)
    assert False, ccmd
예제 #7
0
def with_delay(n, x):
    return append([Cmd.Wait() for x in range(n)], x)
예제 #8
0
def main_run_interactive():

    import production.utils as utils

    # assuming we have left state and expecting right state
    #   x->
    # z ...  ...  ...  |  2..  ...  ...
    # | 2o.  ...  ...  |  .o.  .o.  ...
    # v ...  ...  ...  |  3..  ...  ...
    #   y ---------->

    m = Model(3)
    m[Pos(1, 0, 1)] = 1

    s = State(3)
    s.matrix = m
    s.harmonics = LOW
    s.energy = 30
    s.bots = [Bot(bid=2, pos=Pos(0, 0, 1), seeds=[3, 4, 5])]

    cmds = [
        commands.Fill(Diff(1, 1, 0)),
        commands.Fission(Diff(0, 0, 1), 2),
        commands.SMove(Diff(0, 0, -1)),
        commands.Wait()
    ]

    # pass state to emulator (step count set to 0)

    em = Cpp.Emulator(state_to_cpp(s))

    # LOGGING -- temporary out of service
    # if no logfile name given, emulator doesn't log
    # problemname & solutionname are optional

    from production import utils
    em.setlogfile(str(utils.project_root() / 'outputs' / 'cpp_emulator.log'))
    em.setproblemname("some handmade problem")
    em.setsolutionname("John Doe's ingenious alg")

    # OPTION 1: Run set of commands

    cpp_cmds = list(map(cmd_to_cpp, cmds))
    em.run_commands(cpp_cmds)

    cs = em.get_state()
    print("Energy: ", cs.energy)
    print("Central cell: ", cs[Cpp.Pos(1, 1, 1)])
    print("Active bots: ", sum(b.active for b in cs.bots))

    # OPTION 2: Command by command

    #    x->
    # z  2..  ...  ...
    # |  .o.  .o.  ...
    # v  3..  ...  ...
    #    y ---------->

    ccmd = cmd_to_cpp(commands.LMove(Diff(1, 0, 0), Diff(0, 0, 1)))
    msg = em.check_command(ccmd)
    print(msg == '', 'Error: ', msg)

    # void string if command is valid

    ccmd = cmd_to_cpp(commands.Fill(Diff(0, 0, 1)))
    msg = em.check_command(ccmd)
    print(msg == '', 'Error: ', msg)

    em.add_command(ccmd)

    ccmd = cmd_to_cpp(commands.SMove(Diff(0, 0, -1)))
    msg = em.check_command(ccmd)
    print(msg == '', 'Error: ', msg)

    # to check command and add iff it's valid

    ccmd = cmd_to_cpp(commands.Wait())
    msg = em.check_add_command(ccmd)
    print(msg == '', 'Error: ', msg)

    # if there are enough commands for next step, new commands cannot
    # be checked until change of state, and every check will fail

    ccmd = cmd_to_cpp(commands.Wait())
    msg = em.check_add_command(ccmd)
    print(msg == '', 'Error: ', msg)

    # you can still add command without checks

    print('Trace is full: ', em.steptrace_is_complete())
    print('Energy: ', em.energy())
    em.add_command(ccmd)
    em.run_step()
    print('Trace is full: ', em.steptrace_is_complete())
    print('Energy: ', em.energy())