def test_get_required_moves(self): b = Board([BoardLocation(False, False, False)] * 64) b[0, 2] = BoardLocation(True, True, True) b[1, 3] = BoardLocation(True, True, False) self.assertListEqual([Move(0, 2, Direction.Positive, Direction.Positive)], b.get_required_moves(Direction.Positive, True)) self.assertListEqual([], b.get_required_moves(Direction.Positive, False))
def parse_and_decode(cls, data: bytes) -> "InvalidMove": if len(data) < cls.calc_size() + 1: raise NotEnoughData() if data[0] != cls.type: raise InvalidType() res = unpack('<' + cls.fmt, data[1:cls.calc_size() + 1]) return cls(Move.from_bytes(res[0]), Board.from_bytes(res[1]))
def __init__(self, player_one: "Session", player_two: "Session", logger: Logger): """ A Game takes two players, assign the one with lower rating to be player one and go first Also generate a default board start :param player_one: The first player in the game :param player_two: The second player in the game """ if player_one.username == player_two.username: logger.warning( "Attempting to start game between two of {user}".format( user=player_one.username)) raise InvalidGameException() if player_one.rating < player_two.rating: self.__player_one = player_one self.__player_two = player_two else: self.__player_one = player_two self.__player_two = player_one self.__logger = logger self.__board = Board.generate_game_start() self.game_active = True player_one.on_game_start(player_two.username, player_two.rating, self) player_two.on_game_start(player_one.username, player_one.rating, self) self.__next_to_go = self.__player_one # Request a move from the first player self.__next_to_go.on_request_move( Move(0, 0, Direction.Negative, Direction.Negative), self.__board)
def test_game_over(self): b = Board([BoardLocation(False, False, False)] * 64) b[0, 2] = BoardLocation(True, True, True) b[1, 3] = BoardLocation(True, True, False) self.assertFalse(b.check_game_over(True)) self.assertFalse(b.check_game_over(False)) b.apply_move(Move(0, 2, Direction.Positive, Direction.Positive), Direction.Negative, True) self.assertTrue(b.check_game_over(True)) self.assertFalse(b.check_game_over(False))
def test_game_over_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = GameOver(0xFF, 1338, 1337, move, board) self.assertEqual(0xFF, m.you_won) self.assertEqual(1338, m.new_rating) self.assertEqual(1337, m.old_rating) self.assertEqual(move, m.winning_move) self.assertEqual(board, m.board)
def test_board(self): b = Board([BoardLocation(True, False, False)] * 64) self.assertEqual(b.to_bytes(), b"\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$") self.assertEqual(b.to_bytes(), Board.from_bytes(b.to_bytes()).to_bytes()) self.assertEqual(b[(0, 0)], b[0][0]) with self.assertRaises(KeyError): a = b['A'] b[0, 0] = BoardLocation(True, False, True) b[7, 7] = BoardLocation(True, True, False) b[1, 0] = BoardLocation(False, False, False) rb = b.translate_to_other_user() self.assertEqual(b[1, 0], rb[1, 0]) self.assertEqual(BoardLocation(True, False, False), rb[0, 0]) self.assertEqual(BoardLocation(True, True, True), rb[7, 7])
def test_apply_move(self): b = Board.generate_game_start() b.apply_move(Move(0, 2, Direction.Positive, Direction.Positive), Direction.Positive, False) self.assertEqual(BoardLocation(False, False, False), b[0, 2]) self.assertEqual(BoardLocation(True, False, False), b[1, 3]) with self.assertRaises(InvalidMove): # Try moving a piece that doesn't exist b.apply_move(Move(0, 2, Direction.Positive, Direction.Positive), Direction.Positive, False) with self.assertRaises(InvalidMove): # Try jumping your own piece b.apply_move(Move(0, 0, Direction.Positive, Direction.Positive), Direction.Positive, False) # Move a piece right b.apply_move(Move(1, 3, Direction.Positive, Direction.Positive), Direction.Positive, False) # Move a piece left b.apply_move(Move(2, 2, Direction.Negative, Direction.Positive), Direction.Positive, False) with self.assertRaises(InvalidMove): # Try moving a piece the wrong direction b.apply_move(Move(1, 3, Direction.Positive, Direction.Negative), Direction.Positive, False) with self.assertRaises(InvalidMove): # Try moving an opponent's piece b.apply_move(Move(3, 5, Direction.Negative, Direction.Negative), Direction.Positive, False) b.apply_move(Move(1, 3, Direction.Negative, Direction.Positive), Direction.Positive, False) # Jump! b.apply_move(Move(3, 5, Direction.Negative, Direction.Negative), Direction.Negative, True) # Cheat a little bit to delete some pieces and check that promotion works b[2, 6] = BoardLocation(True, False, False) b[3, 7] = BoardLocation(False, False, False) # Move to the edge and promote b.apply_move(Move(2, 6, Direction.Positive, Direction.Positive), Direction.Positive, False) self.assertTrue(b[3, 7].promoted) # Cheat a little to check moving to the bottom b[4, 2] = BoardLocation(True, False, True) b[2, 0] = BoardLocation(False, False, False) b.apply_move(Move(4, 2, Direction.Negative, Direction.Negative), Direction.Negative, True) self.assertTrue(b[2, 0].promoted) # Try to move out of bounds with self.assertRaises(InvalidMove): b.apply_move(Move(2, 0, Direction.Negative, Direction.Negative), Direction.Negative, True)
def test_invalid_board(self): with self.assertRaises(TypeError): Board([])
def test_get_all_moves(self): b = Board([BoardLocation(False, False, False)] * 64) b[0, 2] = BoardLocation(True, True, True) self.assertListEqual( [Move(0, 2, Direction.Positive, Direction.Positive), Move(0, 2, Direction.Positive, Direction.Negative)], b.get_possible_moves(Direction.Negative, True))
class TestAllMessages(TestCase): messages_to_test = [ (Connect, [1, b"username", b"password"], b"\x01\x01username\x00\x00\x00\x00\x00\x00\x00\x00password\x00\x00\x00\x00\x00\x00\x00\x00" ), (InvalidLogin, [InvalidLogin.Reasons.AccountDoesNotExist], b"\x02\x00"), (InvalidVersion, [1, 2], b"\x0D\x01\x02"), (QueuePosition, [1, 2, 3], b"\x03\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00"), (GameStart, [b"opponent", 16], b'\x04opponent\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00'), (YourTurn, [ Move(1, 2, Direction.Positive, Direction.Negative), Board([BoardLocation(True, False, True)] * 64) ], b"\x05*\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm" ), (MakeMove, [Move(2, 1, Direction.Negative, Direction.Positive)], b"\x06\x45"), (CompulsoryMove, [ Move(1, 2, Direction.Positive, Direction.Negative), Board([BoardLocation(True, False, True)] * 64) ], b"\x07*\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm" ), (InvalidMove, [ Move(1, 2, Direction.Positive, Direction.Negative), Board([BoardLocation(True, False, True)] * 64) ], b"\x08*\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm" ), (OpponentDisconnect, [], b"\x09"), (GameOver, [ 255, 2, 1, Move(1, 2, Direction.Positive, Direction.Negative), Board([BoardLocation(True, False, True)] * 64) ], b"\n\xff\x02\x00\x00\x00\x01\x00\x00\x00*\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm\xb6\xdbm" ), (ReQueue, [], b"\x0B"), (LogOut, [], b"\x0C"), ] def test_messages(self): for constructor, args, packed in TestAllMessages.messages_to_test: obj = constructor(*args) self.assertEqual(packed, obj.encode(), msg="packed vs encode for {}".format( constructor.__name__)) self.assertEqual(obj.encode(), constructor.parse_and_decode(packed).encode(), msg="encode vs repack for {}".format( constructor.__name__)) self.assertEqual(obj.__dict__, constructor.parse_and_decode(packed).__dict__, msg="compare dict for {}".format( constructor.__name__)) with self.assertRaises( NotEnoughData, msg="Message {} still works with too little data".format( constructor.__name__)): constructor.parse_and_decode(packed[:-1]) with self.assertRaises( InvalidType, msg="Message {} still works with wrong type number".format( constructor.__name__)): constructor.parse_and_decode(b'\x00' + packed[1:]) def test_strip(self): self.assertEqual(bytes_strip(b"abc\x00"), b"abc") self.assertEqual(bytes_strip(b"abc"), b"abc") def test_connect_message(self): m = Connect(1, b"cameron", b"password") self.assertEqual(1, m.version) self.assertEqual(b"cameron", m.username) self.assertEqual(b"password", m.password) def test_invalid_login_message(self): m = InvalidLogin(InvalidLogin.Reasons.AccountDoesNotExist) self.assertEqual(InvalidLogin.Reasons.AccountDoesNotExist, m.reason) def test_invalid_version_message(self): m = InvalidVersion(3, 2) self.assertEqual(3, m.highest_supported_version) self.assertEqual(2, m.lowest_supported_version) def test_queue_position_message(self): m = QueuePosition(3, 2, 1337) self.assertEqual(3, m.queue_size) self.assertEqual(2, m.queue_pos) self.assertEqual(1337, m.rating) def test_game_start_message(self): m = GameStart(b"opp", 24) self.assertEqual(b"opp", m.opponent_name) self.assertEqual(24, m.opponent_rating) def test_your_turn_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = YourTurn(move, board) self.assertEqual(move, m.last_move) self.assertEqual(board, m.board) def test_make_move_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) m = MakeMove(move) self.assertEqual(move, m.move) def test_compulsory_move_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = CompulsoryMove(move, board) self.assertEqual(move, m.move) self.assertEqual(board, m.board) def test_invalid_move_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = InvalidMove(move, board) self.assertEqual(move, m.move) self.assertEqual(board, m.board) def test_opponent_disconnect_message(self): m = OpponentDisconnect() # No fields to test def test_game_over_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = GameOver(0xFF, 1338, 1337, move, board) self.assertEqual(0xFF, m.you_won) self.assertEqual(1338, m.new_rating) self.assertEqual(1337, m.old_rating) self.assertEqual(move, m.winning_move) self.assertEqual(board, m.board) def test_re_queue_message(self): m = ReQueue() # no fields to test def test_log_out_message(self): m = LogOut()
def test_invalid_move_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = InvalidMove(move, board) self.assertEqual(move, m.move) self.assertEqual(board, m.board)
def test_your_turn_message(self): move = Move(1, 2, Direction.Positive, Direction.Positive) board = Board([BoardLocation(True, False, True)] * 64) m = YourTurn(move, board) self.assertEqual(move, m.last_move) self.assertEqual(board, m.board)