Пример #1
0
    def test_shorthand(self):
        test_layout = (""" ############
            #a  .  .  y#
            #b        x#
            ############ """)
        num_rounds = 5
        teams = [
            stepping_player('>v<^-', '-----'),
            stepping_player('<^>v-', '-----')
        ]
        state = setup_game(teams,
                           layout_dict=parse_layout(test_layout),
                           max_rounds=5)
        player0_expected_positions = [(1, 1), (2, 1), (2, 2), (1, 2), (1, 1),
                                      (1, 1)]
        player1_expected_positions = [(10, 2), (9, 2), (9, 1), (10, 1),
                                      (10, 2), (10, 2)]

        assert state['bots'][0] == player0_expected_positions[0]
        assert state['bots'][1] == player1_expected_positions[0]
        for i in range(1, num_rounds + 1):
            for step in range(4):
                state = play_turn(state)
            assert state['bots'][0] == player0_expected_positions[i]
            assert state['bots'][1] == player1_expected_positions[i]
Пример #2
0
def test_equal_positions():
    layout_str = """
        ########
        #0###  #
        # . ...#
        ########

        ########
        #1###  #
        # . ...#
        ########

        ########
        #E###  #
        # . ...#
        ########

        ########
        #E###  #
        # . ...#
        ########
    """
    layout = parse_layout(layout_str, allow_enemy_chars=True)
    assert layout['bots'] == [(1, 1), (1, 1)]
    assert layout['enemy'] ==  [(1, 1), (1, 1)]
    setup_test_game(layout=layout_str)
Пример #3
0
def test_initial_position(_n_test):
    """ Test that out test team receives the correct initial positions."""
    layout_name, layout_string = get_random_layout()
    l = parse_layout(layout_string)
    initial_pos = initial_positions(l['walls'])

    def move(bot, state):
        if bot.is_blue and bot.turn == 0:
            assert bot._initial_position == initial_pos[0]
            assert bot.other._initial_position == initial_pos[2]
            assert bot.enemy[0]._initial_position == initial_pos[1]
            assert bot.enemy[1]._initial_position == initial_pos[3]
        if bot.is_blue and bot.turn == 1:
            assert bot._initial_position == initial_pos[2]
            assert bot.other._initial_position == initial_pos[0]
            assert bot.enemy[0]._initial_position == initial_pos[1]
            assert bot.enemy[1]._initial_position == initial_pos[3]
        if not bot.is_blue and bot.turn == 0:
            assert bot._initial_position == initial_pos[1]
            assert bot.other._initial_position == initial_pos[3]
            assert bot.enemy[0]._initial_position == initial_pos[0]
            assert bot.enemy[1]._initial_position == initial_pos[2]
        if not bot.is_blue and bot.turn == 1:
            assert bot._initial_position == initial_pos[3]
            assert bot.other._initial_position == initial_pos[1]
            assert bot.enemy[0]._initial_position == initial_pos[0]
            assert bot.enemy[1]._initial_position == initial_pos[2]
        return randomBot(bot, state)

    state = run_game([move, move], max_rounds=3, layout_dict=l)
    # assertions might have been caught in run_game
    # check that all is good
    assert state['fatal_errors'] == [[], []]
Пример #4
0
def test_uniform_noise_4_bots_no_noise_manhattan():
    test_layout = (""" ##################
        # #.  .  # . 2   #
        # #####    #####3#
        #  0  . #  .  .#1#
        ################## """)
    parsed = parse_layout(test_layout)

    expected_0 = [(1, 1), (3, 1), (4, 1), (5, 1), (6, 1), (1, 2), (1, 3),
                  (2, 3), (3, 3), (4, 3), (5, 3), (6, 3), (7, 3), (7, 2)]
    position_bucket_0 = collections.defaultdict(int)

    expected_2 = [(13, 1)]
    position_bucket_2 = {(13, 1): 0}

    for i in range(200):
        noised = gf.noiser(walls=parsed['walls'],
                           bot_position=parsed['bots'][1],
                           enemy_positions=parsed['bots'][0::2])

        assert noised['is_noisy'] == [True, False]
        position_bucket_0[noised['enemy_positions'][0]] += 1
        position_bucket_2[noised['enemy_positions'][1]] += 1
    assert 200 == sum(position_bucket_0.values())
    assert 200 == sum(position_bucket_2.values())
    # Since this is a randomized algorithm we need to be a bit lenient with
    # our tests. We check that each position was selected at least once.
    assert set(position_bucket_0.keys()) == set(expected_0)
    assert set(position_bucket_2.keys()) == set(expected_2)
Пример #5
0
def test_uniform_noise_manhattan(noise_radius, expected, test_layout=None):
    # Test how bot 1 observes bot 0
    if not test_layout:
        test_layout = (""" ##################
            # #.  .  # .     #
            # #####    ##### #
            #  0  . #  .  .#1#
            ################## """)
    parsed = parse_layout(test_layout)

    position_bucket = collections.defaultdict(int)
    for i in range(200):
        noised = gf.noiser(walls=parsed['walls'],
                           bot_position=parsed['bots'][1],
                           enemy_positions=[parsed['bots'][0]],
                           noise_radius=noise_radius)
        if noise_radius == 0:
            assert noised['is_noisy'] == [False]
        else:
            assert noised['is_noisy'] == [True]

        noised_pos = noised['enemy_positions'][0]
        position_bucket[noised_pos] += 1
    assert 200 == sum(position_bucket.values())
    # Since this is a randomized algorithm we need to be a bit lenient with
    # our tests. We check that each position was selected at least once.
    assert set(position_bucket.keys()) == set(expected)
Пример #6
0
def test_cascade_kill_rescue_1():
    """ Checks that killing occurs only for the bot whose turn it is
    or for any bot that this bot moves onto.
    If a bot respawns on an enemy, it will only be killed when it is its own
    or the enemy’s turn (and neither of them moves).
    If bot moves before it is the enemy’s turn. Bot is rescued.
    """
    cascade = [
    """
    ########
    #30.. 2#
    #1     #
    ########
    """,
    """
    ########
    #0 .. 2#
    #1     #
    ########

    ########
    #  .. 3#
    #      #
    ########
    """,
    """
    ########
    #0 ..23#
    #1     #
    ########
    """
    ]
    def move(bot, state):
        if bot.is_blue and bot.turn == 0 and bot.round == 1:
            return (1, 1)
        if bot.is_blue and bot.turn == 1 and bot.round == 1:
            return (5, 1)
        return bot.position
    layouts = [layout.parse_layout(l) for l in cascade]
    state = setup_game([move, move], max_rounds=5, layout_dict=layout.parse_layout(cascade[0]))
    assert state['bots'] == layouts[0]['bots']
    state = game.play_turn(state) # Bot 0 moves, kills 3. Bot 2 and 3 are on same spot
    assert state['bots'] == layouts[1]['bots']
    state = game.play_turn(state) # Bot 1 stands. Bot 2 and 3 are on same spot
    assert state['bots'] == layouts[1]['bots']
    state = game.play_turn(state) # Bot 2 moves. Rescues itself
    assert state['bots'] == layouts[2]['bots']
Пример #7
0
def test_cascade_kill_2():
    """ Checks that killing occurs only for the bot whose turn it is
    or for any bot that this bot moves onto.
    If a bot respawns on an enemy, it will only be killed when it is its own
    or the enemy’s turn (and neither of them moves).
    """
    cascade = [
        ("""
    ########
    #ya.. b#
    #x     #
    ########
    """, {}),
        ("""
    ########
    #a .. b#
    #x     #
    ########
    """, {
            'y': (6, 1)
        }),
        ("""
    ########
    #a .. y#
    #x     #
    ########
    """, {
            'b': (1, 2)
        }),
        ("""
    ########
    #a .. y#
    #b    x#
    ########
    """, {}),
    ]

    def move(bot, state):
        if bot.is_blue and bot.turn == 0 and bot.round == 1:
            return (1, 1)
        return bot.position

    layouts = [layout.parse_layout(l, bots=b) for l, b in cascade]
    state = setup_game([move, move], max_rounds=5, layout_dict=layouts[0])
    assert state['bots'] == layouts[0]['bots']
    state = game.play_turn(
        state)  # Bot 0 moves, kills 3. Bot 2 and 3 are on same spot
    assert state['bots'] == layouts[1]['bots']
    state = game.play_turn(state)  # Bot 1 stands. Bot 2 and 3 are on same spot
    assert state['bots'] == layouts[1]['bots']
    state = game.play_turn(
        state)  # Bot 2 stands, gets killed. Bot 1 and 2 are on same spot
    assert state['bots'] == layouts[2]['bots']
    state = game.play_turn(state)  # Bot 3 stands. Bot 1 and 2 are on same spot
    assert state['bots'] == layouts[2]['bots']
    state = game.play_turn(state)  # Bot 0 stands. Bot 1 and 2 are on same spot
    assert state['bots'] == layouts[2]['bots']
    state = game.play_turn(state)  # Bot 1 stands, kills 2.
    assert state['bots'] == layouts[3]['bots']
Пример #8
0
def test_multiple_enemies_killing():
    """ Check that you can kill multiple enemies at once. """

    l0 = """
    ########
    #  ..  #
    # bxa  #
    ########
    """

    l1 = """
    ########
    #  ..  #
    #  xay #
    ########
    """
    # dummy bots
    stopping = lambda bot, s: (bot.position, s)

    parsed_l0 = layout.parse_layout(l0, bots={'y': (3, 2)})
    for bot in (0, 2):
        game_state = setup_game([stopping, stopping], layout_dict=parsed_l0)

        game_state['turn'] = bot
        # get position of bots x (and y)
        kill_position = game_state['bots'][1]
        assert kill_position == game_state['bots'][3]
        new_state = apply_move(game_state, kill_position)
        # team 0 scores twice
        assert new_state['score'] == [10, 0]
        # bots 1 and 3 are back to origin
        assert new_state['bots'][1::2] == [(6, 2), (6, 1)]

    parsed_l1 = layout.parse_layout(l1, bots={'b': (4, 2)})
    for bot in (1, 3):
        game_state = setup_game([stopping, stopping], layout_dict=parsed_l1)

        game_state['turn'] = bot
        # get position of bots 0 (and 2)
        kill_position = game_state['bots'][0]
        assert kill_position == game_state['bots'][2]
        new_state = apply_move(game_state, kill_position)
        # team 1 scores twice
        assert new_state['score'] == [0, 10]
        # bots 0 and 2 are back to origin
        assert new_state['bots'][0::2] == [(1, 1), (1, 2)]
Пример #9
0
def test_initial_positions_same_in_layout(layout_name):
    """Check initial positions are the same as what the layout says for all layouts"""
    l = layout.get_layout_by_name(layout_name=layout_name)
    parsed_l = layout.parse_layout(l)
    exp = parsed_l["bots"]
    walls = parsed_l["walls"]
    out = initial_positions(walls)
    assert out == exp
Пример #10
0
def test_initial_positions_same_in_layout_random(layout_t):
    """Check initial positions are the same as what the layout says for 30 random layouts"""
    layout_name, layout_string = layout_t # get_random_layout returns a tuple of name and string
    parsed_l = layout.parse_layout(layout_string)
    exp = parsed_l["bots"]
    walls = parsed_l["walls"]
    out = initial_positions(walls)
    assert out == exp
Пример #11
0
def test_get_legal_positions_basic():
    """Check that the output of legal moves contains all legal moves for one example layout"""
    l = layout.get_layout_by_name(layout_name="small_100")
    parsed_l = layout.parse_layout(l)
    legal_positions = get_legal_positions(parsed_l["walls"], parsed_l["shape"],
                                          parsed_l["bots"][0])
    exp = [(1, 4), (1, 6), (1, 5)]
    assert legal_positions == exp
Пример #12
0
def test_uniform_noise_manhattan_graphical(noise_radius, test_layout):
    # Test how bot 1 observes bot 0
    # the expected locations are where the food is placed
    parsed = parse_layout(test_layout)
    expected = parsed['food'] + [parsed['bots'][0]]
    test_uniform_noise_manhattan(noise_radius,
                                 expected,
                                 test_layout=test_layout)
Пример #13
0
def test_suicide():
    """ Check that suicide works. """

    l0 = """
    ########
    #  ..  #
    #ybxa  #
    ########
    """

    l1 = """
    ########
    #  ..  #
    #  xayb#
    ########
    """
    # dummy bots
    stopping = lambda bot, s: (bot.position, s)

    parsed_l0 = layout.parse_layout(l0)
    for bot in (1, 3):
        game_state = setup_game([stopping, stopping], layout_dict=parsed_l0)

        game_state['turn'] = bot
        # get position of bot 2
        suicide_position = game_state['bots'][2]
        new_state = apply_move(game_state, suicide_position)
        # team 0 scores
        assert new_state['score'] == [5, 0]
        #        # bots 1 and 3 are back to origin
        if bot == 1:
            assert new_state['bots'][1::2] == [(6, 2), (1, 2)]
        elif bot == 3:
            assert new_state['bots'][1::2] == [(3, 2), (6, 1)]

    parsed_l1 = layout.parse_layout(l1)
    for bot in (0, 2):
        game_state = setup_game([stopping, stopping], layout_dict=parsed_l1)

        game_state['turn'] = bot
        # get position of bot 3
        suicide_position = game_state['bots'][3]
        new_state = apply_move(game_state, suicide_position)
        # team 0 scores
        assert new_state['score'] == [0, 5]
Пример #14
0
def test_get_legal_positions_random(layout_t, bot_idx):
    """Check that the output of legal moves returns only moves that are 1 field away and not inside a wall"""
    layout_name, layout_string = layout_t # get_random_layout returns a tuple of name and string
    parsed_l = layout.parse_layout(layout_string)
    bot = parsed_l["bots"][bot_idx]
    legal_positions = get_legal_positions(parsed_l["walls"], bot)
    for move in legal_positions:
        assert move not in parsed_l["walls"]
        assert  abs((move[0] - bot[0])+(move[1] - bot[1])) <= 1
Пример #15
0
 def test_stepping_players(self):
     test_layout = (""" ############
         #a  .  .  x#
         #b        y#
         ############ """)
     movements_0 = [east, east]
     movements_1 = [west, west]
     teams = [
         stepping_player(movements_0, movements_0),
         stepping_player(movements_1, movements_1)
     ]
     state = setup_game(teams,
                        layout_dict=parse_layout(test_layout),
                        max_rounds=2)
     assert state['bots'] == [(1, 1), (10, 1), (1, 2), (10, 2)]
     state = run_game(teams,
                      layout_dict=parse_layout(test_layout),
                      max_rounds=2)
     assert state['bots'] == [(3, 1), (8, 1), (3, 2), (8, 2)]
Пример #16
0
 def test_too_many_registered_teams(self):
     test_layout_4 = (
     """ ##################
         #a#.  .  # .     #
         #b#####    #####x#
         #     . #  .  .#y#
         ################## """)
     team_1 = stopping_player
     with pytest.raises(ValueError):
         setup_game([team_1] * 3, layout_dict=parse_layout(test_layout_4), max_rounds=300)
Пример #17
0
def test_speaking_player():
    test_layout = (""" ############
        #ab#.  .#yx#
        ############ """)
    teams = [speaking_player, random_player]
    state = run_game(teams,
                     layout_dict=parse_layout(test_layout),
                     max_rounds=1)
    assert state["say"][0].startswith("Going")
    assert state["say"][1] == ""
Пример #18
0
    def test_demo_players(self):
        test_layout = (""" ################
            #b            y#
            #              #
            #              #
            #   a      x   #
            #              #
            #              #
            #              #
            #.            .#
            ################ """)
        teams = [random_player, random_player]
        state = setup_game(teams,
                           layout_dict=parse_layout(test_layout),
                           max_rounds=20,
                           seed=20)
        assert state['bots'][0] == (4, 4)
        assert state['bots'][1] == (4 + 7, 4)

        state = run_game(teams,
                         layout_dict=parse_layout(test_layout),
                         max_rounds=20,
                         seed=20)
        pos_left_bot = state['bots'][0]
        pos_right_bot = state['bots'][1]

        # running again to test seed:
        state = run_game(teams,
                         layout_dict=parse_layout(test_layout),
                         max_rounds=20,
                         seed=20)
        assert state['bots'][0] == pos_left_bot
        assert state['bots'][1] == pos_right_bot

        # running again with other seed:
        state = run_game(teams,
                         layout_dict=parse_layout(test_layout),
                         max_rounds=20,
                         seed=200)
        # most probably, either the left bot or the right bot or both are at
        # a different position
        assert not (state['bots'][0] == pos_left_bot
                    and state['bots'][1] == pos_right_bot)
Пример #19
0
 def test_too_many_moves(self):
     test_layout = (""" ############
         #a  .  .  x#
         #b        y#
         ############ """)
     movements_0 = [east, east]
     movements_1 = [west, west]
     teams = [
         stepping_player(movements_0, movements_0),
         stepping_player(movements_1, movements_1)
     ]
     state = run_game(teams,
                      layout_dict=parse_layout(test_layout),
                      max_rounds=2)
     assert state['fatal_errors'] == [[], []]
     state = run_game(teams,
                      layout_dict=parse_layout(test_layout),
                      max_rounds=3)
     assert len(state['fatal_errors'][0])
Пример #20
0
def test_minimal_game():
    def move(b, s):
        return b.position

    layout_name, layout_string = layout.get_random_layout()
    l = layout.parse_layout(layout_string)
    final_state = run_game([move, move], max_rounds=20, layout_dict=l)
    assert final_state['gameover'] is True
    assert final_state['score'] == [0, 0]
    assert final_state['round'] == 20
Пример #21
0
def test_invalid_setup_game_closes_players():
    layout_name, layout_string = layout.get_random_layout()
    l = layout.parse_layout(layout_string)

    # setup a remote demo game with "0" and "1" but bad max rounds
    state = setup_game(["0", "1"], layout_dict=l, max_rounds=0, allow_exceptions=True)
    assert state["gameover"]
    # Check that both processes have exited
    assert state["teams"][0].proc[0].wait(timeout=3) == 0
    assert state["teams"][1].proc[0].wait(timeout=3) == 0
Пример #22
0
 def test_too_few_registered_teams(self):
     test_layout_4 = (
     """ ##################
         #0#.  .  # .     #
         #2#####    #####1#
         #     . #  .  .#3#
         ################## """)
     team_1 = stopping_player
     with pytest.raises(ValueError):
         setup_game([team_1], layout_dict=parse_layout(test_layout_4), max_rounds=300)
Пример #23
0
def test_minimal_remote_game():
    def move(b, s):
        return b.position

    layout_name, layout_string = layout.get_random_layout()
    l = layout.parse_layout(layout_string)
    final_state = run_game(["test/demo01_stopping.py", move], max_rounds=20, layout_dict=l)
    final_state = run_game(["test/demo01_stopping.py", 'test/demo02_random.py'], max_rounds=20, layout_dict=l)
    assert final_state['gameover'] is True
    assert final_state['score'] == [0, 0]
    assert final_state['round'] == 20
Пример #24
0
def setup_random_basic_gamestate(*, round=1, turn=0):
    """helper function for testing play turn"""
    l = layout.get_layout_by_name("small_100")
    parsed_l = layout.parse_layout(l)

    stopping = lambda bot, s: (bot.position, s)

    game_state = setup_game([stopping, stopping], layout_dict=parsed_l)
    game_state['round'] = round
    game_state['turn'] = turn
    return game_state
Пример #25
0
def test_non_existing_file():
    # TODO: Change error message to be more meaningful
    layout_name, layout_string = layout.get_random_layout()
    l = layout.parse_layout(layout_string)
    res = run_game(["blah", "nothing"], max_rounds=1, layout_dict=l)
    assert res['fatal_errors'][0][0] == {
        'description': '("Could not load blah: No module named \'blah\'", \'ModuleNotFoundError\')',
        'round': None,
        'turn': 0,
        'type': 'PlayerDisconnected'
    }
Пример #26
0
 def test_demo_players(self):
     test_layout = (""" ############
         #a#.   .# x#
         ###.   .####
         #b#.   .# y#
         ############ """)
     teams = [nq_random_player, nq_random_player]
     state = run_game(teams,
                      layout_dict=parse_layout(test_layout),
                      max_rounds=1)
     assert state['bots'][0] == (1, 1)
     assert state['bots'][1] == (9, 1)
Пример #27
0
def test_cascade_kill():
    cascade = [
        ("""
    ########
    #x ..ya#
    #     b#
    ########
    """, {}),
        ("""
    ########
    #a .. y#
    #     b#
    ########
    """, {
            'x': (1, 1)
        }),
        ("""
    ########
    #a .. y#
    #     x#
    ########
    """, {
            'b': (6, 2)
        }),
        ("""
    ########
    #a .. y#
    #b    x#
    ########
    """, {}),
    ]

    def move(bot, state):
        if not bot.is_blue and bot.turn == 1 and bot.round == 1:
            return (6, 1)
        return bot.position

    layouts = [layout.parse_layout(l, bots=b) for l, b in cascade]
    state = setup_game([move, move], max_rounds=5, layout_dict=layouts[0])
    assert state['bots'] == layouts[0]['bots']
    state = game.play_turn(state)  # Bot 0 stands
    assert state['bots'] == layouts[0]['bots']
    state = game.play_turn(state)  # Bot 1 stands
    state = game.play_turn(state)  # Bot 2 stands
    state = game.play_turn(
        state)  # Bot 3 moves, kills 0. Bot 0 and 1 are on same spot
    assert state['bots'] == layouts[1]['bots']
    state = game.play_turn(
        state)  # Bot 0 stands, kills 1. Bot 1 and 2 are on same spot
    assert state['bots'] == layouts[2]['bots']
    state = game.play_turn(state)  # Bot 1 stands, kills 2.
    assert state['bots'] == layouts[3]['bots']
Пример #28
0
def test_remote_errors(tmp_path):
    # TODO: Change error messages to be more meaningful
    # we change to the tmp dir, to make our paths simpler
    syntax_error = dedent("""
    def move(b, state)
        return b.position
    """)
    import_error = dedent("""
    import does_not_exist
    def move(b, state):
        return b.position
    """)

    layout_name, layout_string = layout.get_random_layout()
    l = layout.parse_layout(layout_string)

    with temp_wd(tmp_path):
        s_py = Path("s.py")
        s_py.write_text(syntax_error)
        i_py = Path("i.py")
        i_py.write_text(import_error)

        res = run_game([str(s_py), str(i_py)], layout_dict=l, max_rounds=20)
        # Error messages have changed in Python 3.10. We can only do approximate maching
        assert "SyntaxError" in res['fatal_errors'][0][0].pop('description')
        assert res['fatal_errors'][0][0] == {
            'round': None,
            'turn': 0,
            'type': 'PlayerDisconnected'
        }
        # Both teams fail during setup: DRAW
        assert res['whowins'] == 2
        res = run_game(["0", str(i_py)], layout_dict=l, max_rounds=20)
        # Error messages have changed in Python 3.10. We can only do approximate maching
        assert "ModuleNotFoundError" in res['fatal_errors'][1][0].pop(
            'description')
        assert res['fatal_errors'][1][0] == {
            'round': None,
            'turn': 1,
            'type': 'PlayerDisconnected'
        }
        assert res['whowins'] == 0
        res = run_game([str(i_py), "1"], layout_dict=l, max_rounds=20)
        # Error messages have changed in Python 3.10. We can only do approximate maching
        assert "ModuleNotFoundError" in res['fatal_errors'][0][0].pop(
            'description')
        assert res['fatal_errors'][0][0] == {
            'round': None,
            'turn': 0,
            'type': 'PlayerDisconnected'
        }
        assert res['whowins'] == 1
Пример #29
0
def test_initial_positions_basic():
    """Checks basic example for initial positions"""
    simple_layout = """
    ########
    #a ##b #
    #x   y #
    ########
    """
    parsed = layout.parse_layout(simple_layout)
    out = initial_positions(parsed['walls'], parsed['shape'])
    exp = [(1, 1), (6, 2), (1, 2), (6, 1)]
    assert len(out) == 4
    assert out == exp
Пример #30
0
def test_initial_positions_basic():
    """Checks basic example for initial positions"""
    simple_layout = """
    ########
    # ###  #
    #      #
    ########
    """
    walls = layout.parse_layout(simple_layout)['walls']
    out = initial_positions(walls)
    exp = [(1, 1), (6, 2), (1, 2), (6, 1)]
    assert len(out) == 4
    assert out == exp