Ejemplo n.º 1
0
def test_next_player_action_after_perform_shift_should_be_move():
    """ Tests next_player_action and perform_action """
    player = Player(7, 0)
    turns = Turns(players=[player])
    turns.perform_action(player, PlayerAction.SHIFT_ACTION)
    assert turns.next_player_action() == PlayerAction(player,
                                                      PlayerAction.MOVE_ACTION)
Ejemplo n.º 2
0
def given_delay__when_waiting_long_enough__then_is_in_shift_state():
    player = Player(0)
    turns = Turns(prepare_delay=timedelta(milliseconds=5), players=[player])
    turns.start()

    time.sleep(timedelta(milliseconds=20).total_seconds())

    assert turns.next_player_action().action == PlayerAction.SHIFT_ACTION
Ejemplo n.º 3
0
def test_callback_with_one_player():
    """ Tests that the callback on a player is called after each move, even if he plays alone """
    turns = Turns()
    player1 = Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.start()
    player1.callback.assert_called_once()
    player1.callback.reset_mock()
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    turns.perform_action(player1, PlayerAction.MOVE_ACTION)
    player1.callback.assert_called_once()
Ejemplo n.º 4
0
def test_remove_first_player_next_player_action_should_be_remaining_player():
    """ Tests after removing the first of two players, next_player_action() should not return None """
    turns = Turns()
    player1, player2 = Mock(), Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.add_player(player2, turn_callback=player2.callback)
    turns.start()
    turns.remove_player(player1)
    assert turns.next_player_action() is not None
    assert turns.next_player_action().player is player2
    player2.callback.assert_called_once()
Ejemplo n.º 5
0
def test_remove_player__with_only_one_player__no_callback_called():
    turns = Turns()
    player = Mock()
    turns.add_player(player, turn_callback=player.callback)
    turns.start()
    player.callback.reset_mock()
    turns.remove_player(player)
    assert turns.next_player_action() is None
    player.callback.assert_not_called()
Ejemplo n.º 6
0
def test_bot_random_algorith_when_piece_is_pushed_out(post_move, post_shift,
                                                      time_sleep):
    """ Tests case where piece is positioned on a shift location, so that it is pushed out.
    Runs computation 100 times. Push-out expectation rate is 1/12.
    Probability that no push-out takes place in 100 runs is negligible
    .start() is patched so that the compute method runs sequentially.
    This test recreates a bug, where the pushed-out piece is not updated correctly, leading
    to exceptions thrown when bot makes a move.
    """
    board = create_board()
    piece = board.create_piece()
    piece.maze_card = board.maze[BoardLocation(3, 6)]
    game = Game(0, board=board, turns=Turns())
    bot = Bot(library_binding_factory=Mock(),
              move_url="move-url",
              shift_url="shift-url",
              identifier=9,
              piece=piece)
    bot.set_game(game)

    for _ in range(100):
        shift_action, move_location = bot.random_actions()
        shift_location, _ = shift_action
        allowed_coordinates = [(3, 6)]
        if shift_location == BoardLocation(3, 6):
            allowed_coordinates = [(3, 5)]
        elif shift_location == BoardLocation(3, 0):
            allowed_coordinates = [(3, 0)]
        allowed_moves = {
            BoardLocation(*coordinates)
            for coordinates in allowed_coordinates
        }
        assert move_location in allowed_moves
Ejemplo n.º 7
0
def create_game(maze_size=7, game_id=0, with_delay=True):
    """ Creates a game instance with a random board. Player and piece initialization
    is not done here. """
    if not with_delay:
        return Game(game_id, board=create_board(maze_size), turns=Turns())
    else:
        return Game(game_id, board=create_board(maze_size))
Ejemplo n.º 8
0
def test_random_actions_computes_valid_actions():
    """ Runs computation 100 times and expects that it returns valid actions in each run """
    orig_board = create_board()
    for _ in range(100):
        board = copy.deepcopy(orig_board)
        game = Game(0, board=board, turns=Turns())
        bot = Bot(library_binding_factory=Mock(),
                  move_url="move-url",
                  shift_url="shift-url",
                  identifier=9)
        bot.set_game(game)
        shift_action, move_location = bot.random_actions()
        shift_location, shift_rotation = shift_action
        assert shift_rotation in [0, 90, 180, 270]
        assert shift_location in board.shift_locations
        allowed_coordinates = [(0, 0)]
        if shift_location == BoardLocation(0, 1) and shift_rotation == 270:
            allowed_coordinates += [(0, 1)]
        elif shift_location == BoardLocation(0, 1) and shift_rotation == 180:
            allowed_coordinates += [(0, 1), (1, 1)]
        elif shift_location == BoardLocation(1, 0) and shift_rotation == 270:
            allowed_coordinates += [(1, 0)]
        elif shift_location == BoardLocation(1, 0) and shift_rotation == 0:
            allowed_coordinates += [(1, 0), (1, 1), (1, 2), (2, 1), (2, 2),
                                    (3, 1), (3, 2)]
        elif shift_location == BoardLocation(6, 1):
            allowed_coordinates += [(0, 1), (0, 2), (1, 1), (2, 1)]
        allowed_moves = {
            BoardLocation(*coordinates)
            for coordinates in allowed_coordinates
        }

        assert move_location in allowed_moves
Ejemplo n.º 9
0
def test_given_delay_with_two_players__when_player1_leaves_during_wait__player1_callback_is_not_called(
):
    turns = Turns(prepare_delay=timedelta(milliseconds=30))
    player1, player2 = Mock(), Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.add_player(player2, turn_callback=player2.callback)
    turns.start()
    time.sleep(timedelta(milliseconds=50).total_seconds())
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    time.sleep(timedelta(milliseconds=5).total_seconds())
    player1.callback.reset_mock()

    turns.remove_player(player1)
    time.sleep(timedelta(milliseconds=50).total_seconds())

    player1.callback.assert_not_called()
Ejemplo n.º 10
0
def _dto_to_turns(next_action_dto, players, prepare_delay=timedelta(0)):
    """ Maps a DTO to a Turns instance

    :param next_action_dto: a dictionary representing the next player action,
    as created by _turns_to_next_action_dto
    :param players: a list of players. The value of the PLAYER_ID field in the dto
    has to match one of the player's id
    :return: an instance of Turns
    """
    if not players:
        return Turns(prepare_delay=prepare_delay)
    player = next(player for player in players
                  if player.identifier == next_action_dto[PLAYER_ID])
    action = next_action_dto[ACTION]
    return Turns(players=players,
                 next_action=PlayerAction(player, action),
                 prepare_delay=prepare_delay)
Ejemplo n.º 11
0
 def _setup():
     game = Game(5, turns=Turns())
     game_repository = game_repository_coach.when_game_repository_find_by_id_then_return(
         game)
     game_repository.update = Mock()
     interactor = interactors.PlayerActionInteractor(
         game_repository=game_repository)
     return game, interactor, game_repository
Ejemplo n.º 12
0
 def _setup(game_id, player_id):
     game = Game(game_id, turns=Turns())
     game.add_player(Player(player_id))
     game_repository = game_repository_coach.when_game_repository_find_by_id_then_return(
         game)
     game_repository.update = Mock()
     interactor = interactors.PlayerInteractor(
         game_repository=game_repository)
     return game, interactor
Ejemplo n.º 13
0
def _turns_to_next_player_action_dto(turns: Turns):
    """ Maps an instance of Turns to a DTO, representing
    only the next player's action.
    """
    next_player_action = turns.next_player_action()
    if not next_player_action:
        return None
    return {PLAYER_ID: next_player_action.player.identifier,
            ACTION: next_player_action.action}
Ejemplo n.º 14
0
def given_prepare_state__when_player_tries_shift__raises_exception():
    player = Player(0)
    turns = Turns(prepare_delay=timedelta(milliseconds=10), players=[player])
    turns.start()

    with pytest.raises(TurnActionViolationException):
        turns.perform_action(player, PlayerAction.SHIFT_ACTION)
Ejemplo n.º 15
0
def given_delay__when_start__calls_callback_on_player():
    turns = Turns(prepare_delay=timedelta(milliseconds=5))
    player = Mock()
    turns.add_player(player, turn_callback=player.callback)
    turns.start()

    assert player.callback.call_count == 1
    player.callback.assert_called_with(PlayerAction.PREPARE_SHIFT)
Ejemplo n.º 16
0
def _create_test_game(with_computer=False):
    """ Creates a Game instance by hand """
    card_factory = MazeCardFactory()
    board = Board(leftover_card=MazeCard(0, MazeCard.T_JUNCT, 0))
    for row in range(board.maze.maze_size):
        for column in range(board.maze.maze_size):
            if row == 0 and column == 0:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.STRAIGHT, 0)
            elif row == 1 and column == 1:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.CORNER, 0)
            elif row == 2 and column == 2:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.T_JUNCT, 270)
            else:
                board.maze[BoardLocation(
                    row, column)] = card_factory.create_instance(
                        MazeCard.T_JUNCT, 0)
    player_ids = [3, 4]
    players = [
        Player(identifier=player_id, game=None) for player_id in player_ids
    ]
    if with_computer:
        player_ids.append(42)
        players.append(
            create_computer_player(player_id=42,
                                   compute_method="dynamic-foo",
                                   shift_url="shift-url",
                                   move_url="move-url"))
    for player in players:
        player.set_board(board)
    players[0].piece.maze_card = board.maze[BoardLocation(3, 3)]
    players[1].piece.maze_card = board.maze[BoardLocation(5, 5)]
    players[0].piece.piece_index = 1
    players[1].piece.piece_index = 0
    players[0].score = 7
    players[1].score = 8
    board._objective_maze_card = board.maze[BoardLocation(1, 4)]
    turns = Turns(players,
                  next_action=PlayerAction(players[1],
                                           PlayerAction.MOVE_ACTION))
    game = Game(identifier=7, turns=turns, board=board, players=players)
    for player in players:
        player._game = game
    game.previous_shift_location = BoardLocation(0, 3)
    return game, player_ids
Ejemplo n.º 17
0
def test_start__calls_callback_if_present():
    """ Tests start for player with callback """
    turns = Turns()
    player = Player(7, 0)
    callback = Mock()
    turns.add_player(player, turn_callback=callback)
    callback.assert_not_called()
    turns.start()
    callback.assert_called_once_with(PlayerAction.SHIFT_ACTION)
Ejemplo n.º 18
0
def test_given_delay__when_waiting_long_enough__then_calls_callback_on_player(
):
    turns = Turns(prepare_delay=timedelta(milliseconds=5))
    player = Mock()
    turns.add_player(player, turn_callback=player.callback)
    turns.start()

    time.sleep(timedelta(milliseconds=20).total_seconds())

    assert player.callback.call_count == 2
    player.callback.assert_called_with(PlayerAction.SHIFT_ACTION)
Ejemplo n.º 19
0
def test_random_actions_should_respect_no_pushback_rule():
    """ Runs computation 50 times and checks that none of the computed shifts reverts the previous shift action """
    orig_board = create_board()
    for _ in range(50):
        board = copy.deepcopy(orig_board)
        maze = board.maze
        piece = board.create_piece()
        piece.maze_card = maze[BoardLocation(0, 0)]
        game = Game(0, board=board, turns=Turns())
        game.previous_shift_location = BoardLocation(0, 3)
        bot = Bot(library_binding_factory=Mock(),
                  move_url="move-url",
                  shift_url="shift-url",
                  identifier=9,
                  piece=piece)
        bot.set_game(game)
        shift_action, _ = bot.random_actions()
        shift_location, _ = shift_action
        assert shift_location != BoardLocation(6, 3)
Ejemplo n.º 20
0
def test_removed_player_no_callback_called():
    """ Tests remove_player """
    turns = Turns()
    player1 = Mock()
    player2 = Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.add_player(player2, turn_callback=player2.callback)
    turns.start()
    turns.remove_player(player2)
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    turns.perform_action(player1, PlayerAction.MOVE_ACTION)
    player2.callback.assert_not_called()
Ejemplo n.º 21
0
def test_is_action_possible_with_complete_cycle():
    """ Tests is_action_possible """
    players = [Player(id, 0) for id in [2, 1]]
    turns = Turns(players=players)
    assert turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[0], PlayerAction.MOVE_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.MOVE_ACTION)
    turns.perform_action(players[0], PlayerAction.SHIFT_ACTION)
    turns.perform_action(players[0], PlayerAction.MOVE_ACTION)
    turns.perform_action(players[1], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[0], PlayerAction.MOVE_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
    assert turns.is_action_possible(players[1], PlayerAction.MOVE_ACTION)
    turns.perform_action(players[1], PlayerAction.MOVE_ACTION)
    assert turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[0], PlayerAction.MOVE_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.MOVE_ACTION)
    turns.perform_action(players[0], PlayerAction.SHIFT_ACTION)
Ejemplo n.º 22
0
def test_is_action_possible_with_next_action():
    """ Tests is_action_possible and constructor parameter next_action """
    players = [Player(id, 0) for id in [9, 0, 3]]
    turns = Turns(players=players,
                  next_action=PlayerAction(players[2],
                                           PlayerAction.MOVE_ACTION))
    assert not turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
    assert turns.is_action_possible(players[2], PlayerAction.MOVE_ACTION)
    turns.perform_action(players[2], PlayerAction.MOVE_ACTION)
    assert turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert not turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
    turns.perform_action(players[0], PlayerAction.SHIFT_ACTION)
    turns.perform_action(players[0], PlayerAction.MOVE_ACTION)
    assert not turns.is_action_possible(players[0], PlayerAction.SHIFT_ACTION)
    assert turns.is_action_possible(players[1], PlayerAction.SHIFT_ACTION)
Ejemplo n.º 23
0
def test_perform_invalid_action_does_not_alter_turns():
    """ Tests perform_action """
    player1, player2 = Player(7, 0), Player(11, 0)
    turns = Turns(players=[player1, player2])
    with pytest.raises(TurnActionViolationException):
        turns.perform_action(player2, PlayerAction.SHIFT_ACTION)
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    turns.perform_action(player1, PlayerAction.MOVE_ACTION)
    turns.perform_action(player2, PlayerAction.SHIFT_ACTION)
    with pytest.raises(TurnActionViolationException):
        turns.perform_action(player2, PlayerAction.SHIFT_ACTION)
Ejemplo n.º 24
0
def test_perform_invalid_action_should_raise():
    """ Tests perform_action """
    player1, player2 = Player(7, 0), Player(11, 0)
    turns = Turns(players=[player1, player2])
    with pytest.raises(TurnActionViolationException):
        turns.perform_action(player2, PlayerAction.SHIFT_ACTION)
Ejemplo n.º 25
0
def test_given_delay_with_two_players__when_player1_leaves_during_wait__another_wait_leads_to_player2_shift(
):
    turns = Turns(prepare_delay=timedelta(milliseconds=30))
    player1, player2 = Player(1), Player(2)
    callback1, callback2 = Mock(), Mock()
    turns.add_player(player1, turn_callback=callback1)
    turns.add_player(player2, turn_callback=callback2)
    turns.start()
    time.sleep(timedelta(milliseconds=50).total_seconds())
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    time.sleep(timedelta(milliseconds=5).total_seconds())
    turns.remove_player(player1)
    callback2.reset_mock()

    time.sleep(timedelta(milliseconds=50).total_seconds())

    assert callback2.call_count == 1
    assert turns.next_player_action().player == player2
    assert turns.next_player_action().action == PlayerAction.SHIFT_ACTION
Ejemplo n.º 26
0
def test_remove_second_player_next_player_action_should_be_remaining_player():
    """ Tests after removing the second of two players, next_player_action() should not return None """
    turns = Turns()
    player1, player2 = Mock(), Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.add_player(player2, turn_callback=player2.callback)
    turns.start()
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    turns.perform_action(player1, PlayerAction.MOVE_ACTION)
    player1.callback.reset_mock()
    turns.remove_player(player2)
    assert turns.next_player_action() is not None
    assert turns.next_player_action().player is player1
    player1.callback.assert_called_once()
Ejemplo n.º 27
0
def test_given_delay_with_two_players__when_player1_leaves_during_wait__has_prepare_player2_state(
):
    turns = Turns(prepare_delay=timedelta(milliseconds=30))
    player1, player2 = Mock(), Mock()
    turns.add_player(player1, turn_callback=player1.callback)
    turns.add_player(player2, turn_callback=player2.callback)
    turns.start()
    time.sleep(timedelta(milliseconds=50).total_seconds())
    turns.perform_action(player1, PlayerAction.SHIFT_ACTION)
    time.sleep(timedelta(milliseconds=2).total_seconds())

    turns.remove_player(player1)

    assert player2.callback.call_count == 1
    assert turns.next_player_action().player == player2
    assert turns.next_player_action().action == PlayerAction.PREPARE_SHIFT
Ejemplo n.º 28
0
def test_next_player_action_should_be_none_without_players():
    """ Tests next_player_action """
    turns = Turns()
    assert turns.next_player_action() is None
Ejemplo n.º 29
0
def test_next_player_action_with_one_player_should_be_shift():
    """ Tests next_player_action """
    player = Player(7, 0)
    turns = Turns(players=[player])
    assert turns.next_player_action() == PlayerAction(
        player, PlayerAction.SHIFT_ACTION)
Ejemplo n.º 30
0
def given_delay__when_start__is_in_prepare_state():
    player = Player(0)
    turns = Turns(prepare_delay=timedelta(milliseconds=10), players=[player])
    turns.start()

    assert turns.next_player_action().action == PlayerAction.PREPARE_SHIFT