What if you could add a new chess piece without rewriting your entire game logic?
Why Piece movement rules (polymorphism) in LLD? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine building a chess game by writing separate code for each piece's movement rules everywhere you need them.
For example, when checking if a move is valid, you write different checks for pawns, knights, bishops, and so on, scattered all over your code.
This manual approach is slow and confusing.
Every time you add a new piece or change a rule, you must hunt down all places where movement is checked and update them.
This leads to bugs, duplicated code, and frustration.
Using polymorphism, each piece knows how it moves by itself.
You create a common interface for pieces, and each piece class implements its own movement rules.
This keeps code clean, easy to update, and scalable.
if piece == 'pawn': check_pawn_move() elif piece == 'knight': check_knight_move() // repeated in many places
class Piece: def can_move(self, start, end): pass class Pawn(Piece): def can_move(self, start, end): # pawn move logic pass class Knight(Piece): def can_move(self, start, end): # knight move logic pass
You can add new pieces or change rules easily without breaking existing code.
In a chess app, polymorphism lets you add a new custom piece with unique moves by just creating a new class, without touching the rest of the game logic.
Manual movement checks cause duplicated, hard-to-maintain code.
Polymorphism lets each piece handle its own moves cleanly.
This makes the system scalable and easy to extend.
Practice
Solution
Step 1: Understand polymorphism concept
Polymorphism allows different objects to be treated through a common interface while having their own behavior.Step 2: Apply to piece movement
Each piece class implements its ownmove()method, so no need to check piece type before moving.Final Answer:
It allows each piece to have its own move logic without type checks. -> Option AQuick Check:
Polymorphism = own move logic without type checks [OK]
- Thinking all pieces share the same move logic
- Believing manual type checks are needed
- Confusing polymorphism with inheritance only
Solution
Step 1: Recall method declaration syntax in Python
Instance methods must haveselfas the first parameter.Step 2: Identify correct method signature
def move(self): passcorrectly declares a method withselfand no implementation.Final Answer:
def move(self): pass -> Option BQuick Check:
Method with self parameter = def move(self): pass [OK]
- Omitting self parameter in method
- Using incorrect syntax without def keyword
- Adding unnecessary parameters without context
class Piece:
def move(self):
return "Base move"
class Knight(Piece):
def move(self):
return "L-shaped move"
pieces = [Piece(), Knight()]
for p in pieces:
print(p.move())Solution
Step 1: Understand method overriding
SubclassKnightoverridesmove()to return "L-shaped move".Step 2: Trace the loop output
First object isPiece, prints "Base move"; second isKnight, prints "L-shaped move".Final Answer:
Base move\nL-shaped move -> Option AQuick Check:
Base class and overridden subclass moves printed [OK]
- Assuming base method always runs
- Expecting same output for all pieces
- Confusing method overriding with overloading
class Piece:
def move(self):
pass
class Bishop(Piece):
def move():
print("Diagonal move")
b = Bishop()
b.move()Solution
Step 1: Check method signatures
Bishop.move()lacksselfparameter, so it is not a proper instance method.Step 2: Understand call context
Callingb.move()passesselfautomatically, causing a TypeError due to missing parameter.Final Answer:
Bishop.move() missing self parameter -> Option CQuick Check:
Instance methods must have self parameter [OK]
- Ignoring missing self in subclass method
- Thinking base class method must return value
- Assuming print syntax is wrong
Solution
Step 1: Apply polymorphism design principle
Use a base class with an abstract or emptymove()method to define interface.Step 2: Implement subclasses for each piece
Each piece subclass provides its ownmove()logic, enabling extension without modifying base code.Final Answer:
Create a base Piece class with an abstract move() method; each piece subclass implements move(). -> Option DQuick Check:
Base class + subclass move() = scalable design [OK]
- Using if-else instead of polymorphism
- Relying on global variables for logic
- Putting all move logic in base class only
