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)
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 )
def test_get_rows_mid_right(self): board = Board() rows = board.get_rows(3, 2) self.assertEqual( rows, [ [(0, 2), (1, 2), (2, 2), (3, 2)], [(3, 0), (3, 1), (3, 2), (3, 3)] ] )
def test_get_rows_bottom_left(self): board = Board() rows = board.get_rows(0, 0) self.assertEqual( rows, [ [(0, 0), (1, 0), (2, 0), (3, 0)], [(0, 0), (0, 1), (0, 2), (0, 3)], [(0, 0), (1, 1), (2, 2), (3, 3)] ] )
def test_get_rows_mid(self): board = Board(3) rows = board.get_rows(1, 1) self.assertEqual( rows, [ [(0, 1), (1, 1), (2, 1)], [(1, 0), (1, 1), (1, 2)], [(0, 0), (1, 1), (2, 2)], [(0, 2), (1, 1), (2, 0)] ] )
def test_setup(self): board = Board() self.assertEqual( len(board.positions), 4 ) for column in board.positions: self.assertEqual( len(column), 4 )
def test_setup_specify_size(self): board = Board(3) self.assertEqual( len(board.positions), 3 ) for column in board.positions: self.assertEqual( len(column), 3 )
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
def __init_game(self): self.board = Board() for value in range(1 << 4): self.remaining_pieces.append( Piece(value) )
def test_put_simple(self): board = Board(2) piece = Piece.from_attributes(True, False) board.put(piece, 1, 1) with self.assertRaises(Exception): board.put(piece, 1, 1)