Example #1
0
    def move_broadside(self, boundaries: Tuple[Space, Space],
                       direction: Direction) -> None:
        """Performs a broadside move. With a broadside move a line of adjacent marbles is moved sideways into empty\
        spaces. However, it is not possible to push the opponent's marbles. A broadside move is denoted by the two\
        outermost `abalone.enums.Space`s of the line to be moved and the `abalone.enums.Direction` of movement. With a\
        broadside move two or three marbles can be moved, i.e. the two boundary marbles are either direct neighbors or\
        there is exactly one marble in between.

        Args:
            boundaries: A tuple of the two outermost `abalone.enums.Space`s of a line of two or three marbles.
            direction: The `abalone.enums.Direction` of movement.

        Raises:
            IllegalMoveException: Elements of boundaries must not be `abalone.enums.Space.OFF`
            IllegalMoveException: Only two or three neighboring marbles may be moved with a broadside move
            IllegalMoveException: The direction of a broadside move must be sideways
            IllegalMoveException: Only own marbles may be moved
            IllegalMoveException: With a broadside move, marbles can only be moved to empty spaces
        """
        if boundaries[0] is Space.OFF or boundaries[1] is Space.OFF:
            raise IllegalMoveException(
                'Elements of boundaries must not be `Space.OFF`')
        marbles, direction1 = line_from_to(boundaries[0], boundaries[1])
        if marbles is None or not (len(marbles) == 2 or len(marbles) == 3):
            raise IllegalMoveException(
                'Only two or three neighboring marbles may be moved with a broadside move'
            )
        _, direction2 = line_from_to(boundaries[1], boundaries[0])
        if direction is direction1 or direction is direction2:
            raise IllegalMoveException(
                'The direction of a broadside move must be sideways')
        for marble in marbles:
            if self.get_marble(marble) is not _marble_of_player(self.turn):
                raise IllegalMoveException('Only own marbles may be moved')
            destination_space = neighbor(marble, direction)
            if destination_space is Space.OFF or self.get_marble(
                    destination_space) is not Marble.BLANK:
                raise IllegalMoveException(
                    'With a broadside move, marbles can only be moved to empty spaces'
                )
        for marble in marbles:
            self.set_marble(marble, Marble.BLANK)
            self.set_marble(neighbor(marble, direction),
                            _marble_of_player(self.turn))
Example #2
0
def _format_move(turn: Player, move: Tuple[Union[Space, Tuple[Space, Space]],
                                           Direction], moves: int) -> str:
    """Formats a player's move as a string with a single line.

    Args:
        turn: The `Player` who performs the move
        move: The move as returned by `abalone.abstract_player.AbstractPlayer.turn`
        moves: The number of total moves made so far (not including this move)
    """
    marbles = [move[0]] if isinstance(move[0], Space) else line_from_to(
        *move[0])[0]
    marbles = map(lambda space: space.name, marbles)
    return f'{moves + 1}: {turn.name} moves {", ".join(marbles)} in direction {move[1].name}'
Example #3
0
 def test_line_from_to(self):
     """Test `abalone.utils.line_from_to`"""
     self.assertTupleEqual(
         line_from_to(Space.A1, Space.D4),
         ([Space.A1, Space.B2, Space.C3, Space.D4], Direction.NORTH_EAST))
     self.assertTupleEqual(
         line_from_to(Space.E6, Space.E9),
         ([Space.E6, Space.E7, Space.E8, Space.E9], Direction.EAST))
     self.assertTupleEqual(
         line_from_to(Space.C7, Space.C4),
         ([Space.C7, Space.C6, Space.C5, Space.C4], Direction.WEST))
     self.assertTupleEqual(line_from_to(Space.D2, Space.E3),
                           ([Space.D2, Space.E3], Direction.NORTH_EAST))
     self.assertEqual(line_from_to(Space.A1, Space.B4), (None, None))
     self.assertEqual(line_from_to(Space.F2, Space.F2), (None, None))
     self.assertRaises(Exception, lambda: line_from_to(Space.OFF, Space.A1))
     self.assertRaises(Exception, lambda: line_from_to(Space.A1, Space.OFF))
     self.assertRaises(Exception,
                       lambda: line_from_to(Space.OFF, Space.OFF))