def test_board_location(self):
     loc = BoardLocation(True, True, False)
     self.assertEqual(loc.to_bytes(), b"\x06")
     self.assertEqual(loc.to_bytes(), BoardLocation.from_bytes(loc.to_bytes()).to_bytes())
     self.assertEqual(loc.used, True)
     self.assertEqual(loc.promoted, True)
     self.assertEqual(loc.owner, False)
 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 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_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)