Katkat

Design an Extensible Animal-Chess Game Engine

AsanaSoftware Engineer · Technical Screen

Last updated

This question tests your ability to design a decoupled, extensible object-oriented system that separates game state, rule validation, and game flow logic.

Design an Extensible Animal-Chess Engine

Design the core engine for a turn-based board game (e.g., Dou Shou Qi). The engine must be extensible, allowing for future variations in board size, animal types, and specific movement or capture rules without modifying existing engine logic.

Requirements

  1. Immutability: Game state should be immutable. Every move should produce a new state rather than modifying the existing one.
  2. Rule Separation: The logic for checking if a move is valid (e.g., "Can an Elephant capture a Mouse?") must be separated from the board state representation.
  3. Persistence/Replay: The design must support saving the history of moves to reconstruct any previous state deterministically.
  4. Concurrency: Multiple users might be viewing or querying the state simultaneously; ensure the design is thread-safe.

Task

Provide a high-level class structure or pseudo-code showing how the following components interact:

  • GameState: Represents the board and pieces.
  • MoveValidator: A strategy-based interface to validate moves.
  • GameEngine: Orchestrates turns, state transitions, and history.

Example Interface

class Move:
    def __init__(self, piece_id, from_coords, to_coords):
        pass

class GameState:
    # Represents board at a specific point in time
    pass

class GameEngine:
    def apply_move(self, move: Move) -> GameState:
        # 1. Validate move
        # 2. Return new state if valid, else raise exception
        pass

Consider how you would structure the MoveValidator so that adding a new rule (e.g., "a piece cannot move into water") doesn't require editing the GameEngine.

Hints

Hint 1

Use the Strategy design pattern to encapsulate individual movement and capture rules.

Hint 2

Implement the Command pattern for moves to facilitate easy undo/redo functionality and replay logs.

Hint 3

Consider using a 'Factory' or 'Configuration' object to inject specific game rules into the engine at runtime.

Follow-up questions

  • How would you handle a 'capture' rule that is dependent on both the attacking piece and the defensive terrain?
  • If this game were to scale to thousands of simultaneous matches, what state storage strategy would you use to minimize memory footprint?
  • How would you integrate a timeout or clock mechanism into the `GameEngine` without tightly coupling it to the move validation logic?