Ejemplo n.º 1
0
 def test_get_simple_bad(self):
     board = Board(2)
     for x, y in [
         (1, 5), (5, 1), (-1, 2), (3, -2)
     ]:
         with self.assertRaises(Exception):
             board.get(x, y)
Ejemplo n.º 2
0
 def test_get_simple(self):
     board = Board(2)
     for x in range(2):
         for y in range(2):
             self.assertEqual(
                 board.get(x, y),
                 None
             )
Ejemplo n.º 3
0
class Game:
    def __init__(self):
        self.player_a = None
        self.player_b = None
        self.events = []

        self.remaining_pieces = []
        self.board = None
        self.next_piece = None
        self.__init_game()
        self.winner = None

    def join_game(self, player):
        if self.player_a is None:
            self.player_a = player
        elif self.player_b is None:
            if self.player_a == player:
                raise GameStateError('Player already in game')
            self.player_b = player
        else:
            raise GameStateError('Game already full')

    def to_dict(self):
        return {
            'player_a': self.player_a.to_dict() if self.player_a else None,
            'player_b': self.player_b.to_dict() if self.player_b else None,
            'winner': self.winner.to_dict() if self.winner else None,
            'events': [
                event.to_dict() for event in self.events
            ]
        }

    @classmethod
    def from_dict(cls, in_dict):
        game = cls()
        if in_dict['player_a'] is not None:
            game.player_a = Player.from_dict(in_dict['player_a'])
        if in_dict['player_b'] is not None:
            game.player_b = Player.from_dict(in_dict['player_b'])
        for event_dict in in_dict['events']:
            event = Event.from_dict(event_dict)
            game.apply_event(event)
        return game

    @property
    def turn(self):
        return len(self.events)

    def __init_game(self):
        self.board = Board()
        for value in range(1 << 4):
            self.remaining_pieces.append(
                Piece(value)
            )

    def apply_event(self, event):
        # ok, the game goes through two different types of moves
        # and in rotation around the players... sooo

        # move 0, 4, 8 & so on is player 1 picking a piece for player 2
        # move 1, 5, 9, etc player 2 chosing where to place a piece
        # 2, 6, 10 player 2 picking a piece for player 1
        # 3, 7, 11 player 1 placing a piece.
        # so:

        if self.winner is not None:
            raise GameStateError("Player has already won")

        if self.player_a is None or self.player_b is None:
            raise GameStateError("Missing players")

        if self.turn % 4 in (0, 3):
            if event.player != self.player_a:
                raise GameStateError("Illegal player")
        else:
            if event.player != self.player_b:
                raise GameStateError("Illegal player")

        event.move.validate(self)
        victory = event.move.apply(self)
        self.events.append(
            event
        )
        if victory:
            self.winner = event.player

    def check_win(self, x, y):
        # Check if we've just won a game, based on having added
        # a piece to position x, y
        for winning_sets in self.board.get_rows(x, y):
            pieces = []
            for _x, _y in winning_sets:
                last_piece = self.board.get(_x, _y)
                if last_piece is None:
                    break
                pieces.append(last_piece)
            if (
                len(pieces) == 4 and
                Piece.overlap(*pieces)
            ):
                return True
        return False