Machine Coding Problem

Chess Game

maco30maco60macoAllgamesvalidator-strategy-&-command-move-reversal
Commonly Asked By:AmazonMicrosoftRiot Games

Requirements & System Scope

Functional Scope (In-Scope)

  • Grid-Based Piece Movement: Implement standard board cell tracking mapping custom chess piece rules polymorphically.
  • Command-Based Move History: Support undo and redo sequences using a historical moves command log.
  • Collision and Path Checking: Validate moves using linear path scans to verify clear coordinates.
  • Polymorphic Movements: Differentiate piece vectors (Pawn diagonals, Rook straight paths, Bishop diagonals, Knight jumps) systematically.

Explicit Boundaries (Out-of-Scope)

  • No Automatic Chess AI Pruning Engine: Does not write Minimax solvers, alpha-beta weights, or deep-learning moves generators.
  • No Advanced Multi-Room Tournament Matchmaking: Out-of-scope to manage tournament brackets, dynamic ranking databases, or web socket networks.

Class Diagram & Entity Relationships

Structural layout showing pieces and board configurations:

Loading...
  • Polymorphic Chess Piece Abstraction: Piece declares abstract movement signatures, letting pieces override move behaviors independently.
  • Transactional Moves Stack: Move encapsulates start, target, and captured piece states to enable flawless step rollbacks.

Design Patterns & SOLID Principles

  • Polymorphic Strategy Pattern (Movement Vectors): Instead of using ugly switch cases matching piece names to resolve movement boundaries, each piece subclass encapsulates its own validation rules, adhering to the Open-Closed Principle.
  • Command Pattern (Move Reversals): Each player action is encapsulated within a Move object, enabling robust structural undo/redo operations simply.

Core Execution Workflows

Interactive Step Lifecycle

  1. Player invokes move details: playMove(sr, sc, er, ec).
  2. Verify board coordinates and active player turn color.
  3. Delegate checking math to piece subclass: p.isValidMove(er, ec, board.grid).
  4. If move exposes own king to check, abort execution.
  5. Otherwise, instantiate Move containing captured piece info.
  6. Execute grid coordinate updates, push Move to history stack, and alternate player active turn color.

Concurrency & Thread Safety Strategy

For digital matches, multiple fast user input commands could arrive concurrently over websocket lanes:

  • Synchronized Turn Controls: Game session updates run under exclusive player locks, discarding actions from out-of-turn threads.
  • Atomic Board Snapshots: Duplicate board states prior to moves simulations to calculate check exposure securely without polluting live arrays.

Complete Clean Code Blueprint

Robust reference designs in Java and Python:

// โ”€โ”€โ”€ JAVA BLUEPRINT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

enum Color { WHITE, BLACK }

abstract class Piece {
    protected final Color color;
    protected int row;
    protected int col;

    public Piece(Color color, int row, int col) {
        this.color = color;
        this.row = row;
        this.col = col;
    }

    public Color getColor() { return color; }
    public int getRow() { return row; }
    public int getCol() { return col; }
    public void setPosition(int r, int c) { this.row = r; this.col = c; }

    public abstract boolean isValidMove(int targetRow, int targetCol, Piece[][] grid);
}

class Rook extends Piece {
    public Rook(Color color, int r, int c) { super(color, r, c); }

    @Override
    public boolean isValidMove(int tr, int tc, Piece[][] grid) {
        if (row != tr && col != tc) return false;
        if (row == tr) {
            int step = (tc > col) ? 1 : -1;
            for (int curr = col + step; curr != tc; curr += step) {
                if (grid[row][curr] != null) return false;
            }
        } else {
            int step = (tr > row) ? 1 : -1;
            for (int curr = row + step; curr != tr; curr += step) {
                if (grid[curr][col] != null) return false;
            }
        }
        return grid[tr][tc] == null || grid[tr][tc].getColor() != this.color;
    }
}

class Bishop extends Piece {
    public Bishop(Color color, int r, int c) { super(color, r, c); }

    @Override
    public boolean isValidMove(int tr, int tc, Piece[][] grid) {
        if (Math.abs(row - tr) != Math.abs(col - tc)) return false;
        int rowStep = (tr > row) ? 1 : -1;
        int colStep = (tc > col) ? 1 : -1;
        
        int r = row + rowStep;
        int c = col + colStep;
        while (r != tr && c != tc) {
            if (grid[r][c] != null) return false;
            r += rowStep;
            c += colStep;
        }
        return grid[tr][tc] == null || grid[tr][tc].getColor() != this.color;
    }
}

class Knight extends Piece {
    public Knight(Color color, int r, int c) { super(color, r, c); }

    @Override
    public boolean isValidMove(int tr, int tc, Piece[][] grid) {
        int rDiff = Math.abs(row - tr);
        int cDiff = Math.abs(col - tc);
        if (!((rDiff == 2 && cDiff == 1) || (rDiff == 1 && cDiff == 2))) return false;
        return grid[tr][tc] == null || grid[tr][tc].getColor() != this.color;
    }
}

class King extends Piece {
    public King(Color color, int r, int c) { super(color, r, c); }

    @Override
    public boolean isValidMove(int tr, int tc, Piece[][] grid) {
        int rDiff = Math.abs(row - tr);
        int cDiff = Math.abs(col - tc);
        if (rDiff > 1 || cDiff > 1) return false;
        return grid[tr][tc] == null || grid[tr][tc].getColor() != this.color;
    }
}

class Board {
    private final Piece[][] grid = new Piece[8][8];

    public Board() {
        // Initialize base scenario with Kings and pieces
        grid[0][4] = new King(Color.BLACK, 0, 4);
        grid[0][0] = new Rook(Color.BLACK, 0, 0);
        grid[0][2] = new Bishop(Color.BLACK, 0, 2);
        
        grid[7][4] = new King(Color.WHITE, 7, 4);
        grid[7][7] = new Rook(Color.WHITE, 7, 7);
        grid[7][2] = new Bishop(Color.WHITE, 7, 2);
    }

    public Piece getPiece(int r, int c) { return grid[r][c]; }
    public void setPiece(int r, int c, Piece p) { grid[r][c] = p; }
    public Piece[][] getGrid() { return grid; }

    public boolean isKingInCheck(Color kingColor) {
        int kingRow = -1, kingCol = -1;
        for (int r = 0; r < 8; r++) {
            for (int c = 0; c < 8; c++) {
                Piece p = grid[r][c];
                if (p instanceof King && p.getColor() == kingColor) {
                    kingRow = r;
                    kingCol = c;
                    break;
                }
            }
        }

        if (kingRow == -1) return false;

        for (int r = 0; r < 8; r++) {
            for (int c = 0; c < 8; c++) {
                Piece p = grid[r][c];
                if (p != null && p.getColor() != kingColor) {
                    if (p.isValidMove(kingRow, kingCol, grid)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

class Move {
    private final int startRow, startCol, endRow, endCol;
    private final Piece movedPiece, capturedPiece;

    public Move(int sr, int sc, int er, int ec, Piece movedPiece, Piece capturedPiece) {
        this.startRow = sr;
        this.startCol = sc;
        this.endRow = er;
        this.endCol = ec;
        this.movedPiece = movedPiece;
        this.capturedPiece = capturedPiece;
    }

    public void execute(Board board) {
        board.setPiece(startRow, startCol, null);
        board.setPiece(endRow, endCol, movedPiece);
        movedPiece.setPosition(endRow, endCol);
    }

    public void undo(Board board) {
        board.setPiece(startRow, startCol, movedPiece);
        movedPiece.setPosition(startRow, startCol);
        board.setPiece(endRow, endCol, capturedPiece);
    }
}

class ChessGame {
    private final Board board = new Board();
    private final Stack<Move> history = new Stack<>();
    private Color activeTurn = Color.WHITE;
    private final ReentrantLock gameLock = new ReentrantLock();

    public boolean playMove(int sr, int sc, int er, int ec) {
        gameLock.lock();
        try {
            Piece p = board.getPiece(sr, sc);
            if (p == null || p.getColor() != activeTurn) {
                System.out.println("[Move Error] Invalid piece selection or not your turn.");
                return false;
            }

            if (!p.isValidMove(er, ec, board.getGrid())) {
                System.out.println("[Move Error] Invalid move pattern for selected piece.");
                return false;
            }

            // Simulate the move to verify check status
            Piece target = board.getPiece(er, ec);
            Move tempMove = new Move(sr, sc, er, ec, p, target);
            tempMove.execute(board);

            if (board.isKingInCheck(activeTurn)) {
                System.out.println("[Move Rejected] Illegal move! Exposes your own King to Check.");
                tempMove.undo(board); // Rollback
                return false;
            }

            // Move is verified and locked in
            history.push(tempMove);
            System.out.println("[Move Executed] " + p.getClass().getSimpleName() + " from (" + sr + "," + sc + ") to (" + er + "," + ec + ")");
            
            // Check if this move puts opponent in check
            Color opponentColor = (activeTurn == Color.WHITE) ? Color.BLACK : Color.WHITE;
            if (board.isKingInCheck(opponentColor)) {
                System.out.println("[!] Check! " + opponentColor + " King is under attack!");
            }

            activeTurn = opponentColor;
            return true;
        } finally {
            gameLock.unlock();
        }
    }

    public void undo() {
        gameLock.lock();
        try {
            if (!history.isEmpty()) {
                Move move = history.pop();
                move.undo(board);
                activeTurn = (activeTurn == Color.WHITE) ? Color.BLACK : Color.WHITE;
                System.out.println("[Undo Successful] Rollback previous move.");
            } else {
                System.out.println("[Undo Error] No moves recorded in history.");
            }
        } finally {
            gameLock.unlock();
        }
    }

    public Board getBoard() { return board; }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("=== CHESS GAME ENGINE SIMULATION ===");
        ChessGame game = new ChessGame();
        
        // WHITE moves Bishop at (7,2) to (5,0)
        game.playMove(7, 2, 5, 0); 
        
        // BLACK moves Rook at (0,0) to (0,2)
        game.playMove(0, 0, 0, 2);

        // Attempt illegal move that puts own king in check (dummy check)
        System.out.println("Current status OK.");
    }
}

๐Ÿ’ฌReview

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...