The knight is a different beast because it does not move orthogonally or diagonally. It can also jump over chess pieces.
Like the rules that we followed earlier to arrive at ORTHOGONAL_POSITIONS and DIAGONAL_POSITIONS, we can similarly arrive at the rules that are required to determine the KNIGHT_POSITIONS tuple. This is defined in 4.04—configurations.py, as follows:
KNIGHT_POSITIONS = ((-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1))
Next, let's override the moves_available method from the Knight class (see code 4.04—piece.py):
class Knight(Piece): def moves_available(self, current_position): model = self.model allowed_moves =  start_position = get_numeric_notation(current_position.upper()) piece = model.get(pos.upper()) ...