OOD

Minesweeper Game


import java.io.*;
import java.util.*;


public class MS {
    // Minesweeper is a game where mines are hidden in a grid of squares.
// Revealed squares have numbers telling you how many mines touch the square.
// You can use the number clues to solve the game by opening all of the unrevealed squares.
// If you click on a mine you lose the game!

// Your implementation should support:
// 1. Generating a board of ROWS x COLUMNS size
// 2. Randomly placing a set of NUM_MINES mines
// 3. Printing the board state
// 4. Clicking a cell
//   - This should reveal the number of mines that touch the square.
//   - If a mine is clicked, the game is over.
//     All remaining mines should be revealed.
//   - Clicking on an empty cell (a cell with no adjacent mines)ok
//     should reveal all adjacent cells until a cell bordering a mine
//     is reached.

// Revealed squares that have no adjacent mines: 0
// Revealed squares that have adjacent mines: numbers 1 - 8
// Unrevealed cells: '-'
// Revealed mines: 'X'

// Example:

// ROWS = 5
// COLUMNS = 5
// NUM_MINES = 4
// // exampleMineLocations = [[0, 1], [2, 0], [4, 0], [4, 4]]
// // [row, column]

// printBoard()
// Output:
// ['-','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']

// click(0, 0)
// printBoard()
// Output:
// ['1','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']
// ['-','-','-','-','-']

// click(0, 4)
// printBoard()
// Output:
// ['1','-','1','0','0']
// ['-','2','1','0','0']
// ['-','1','0','0','0']
// ['-','2','0','1','1']
// ['-','1','0','1','-']

// click(2, 0)
// printBoard()
// Output:
// ['1','X','1','0','0']
// ['-','2','1','0','0']
// ['X','1','0','0','0']
// ['-','2','0','1','1']
// ['X','1','0','1','X']


    /*
     * Click `Run` to execute the snippet below!
     */

    /*
     * To execute Java, please define "static void main" on a class
     * named Solution.
     *
     * If you need more classes, simply define them inline.
     */

        public static void main(String[] args) {

            Minesweeper minesweeper = new Minesweeper(5, 5, 3);
            System.out.println("Initial Board:");
            minesweeper.print();

            // Simulated clicks
            System.out.println("\nClick (0,0):");
            minesweeper.click(0, 0);

            System.out.println("\nClick (1,1):");
            minesweeper.click(1, 1);

            System.out.println("\nClick (2,2):");
            minesweeper.click(2, 2);

            System.out.println("\nClick (4,4):");
            minesweeper.click(4, 4); // might be a mine

            System.out.println("\nClick (3,0):");
            minesweeper.click(3, 0);
        }

        static class Minesweeper {
            String[][] grid;
            String[][] mineGrid;
            int[][] dirs = {
                    {1,0}, {0,1}, {-1,0}, {0,-1},
                    {1,1}, {-1,1}, {1,-1}, {-1,-1}
            };
            Minesweeper(int rows, int cols, int mineCount) {
                this.grid = new String[rows][cols];
                for (String[] r : grid) {
                    Arrays.fill(r, "-");
                }
                this.mineGrid = new String[rows][cols];
                for (String[] r : mineGrid) {
                    Arrays.fill(r, "-");
                }
                this.generateMines(mineCount);
                this.preProcess();
            }

            public void click(int row, int col) {
                if (!inbound(row, col)) {
                    System.out.println("Invalid coordinate");
                    return;
                }
                if (mineGrid[row][col].equals("X")) {
                    System.out.println("Game over");
                    grid = mineGrid;
                } else if (hasAdjacentMine(row, col)) {
                    grid[row][col] = mineGrid[row][col];
                } else {
                    dfs(row, col);
                }
                print();
            }

            void dfs(int row, int col) {
                grid[row][col] = mineGrid[row][col];
                for (int[] dir : dirs) {
                    int newRow = row + dir[0];
                    int newCol = col + dir[1];
                    if (inbound(newRow, newCol)
                            && !mineGrid[newRow][newCol].equals("X")
                            && grid[newRow][newCol].equals("-")
                            && !hasAdjacentMine(newRow, newCol)) {
                        dfs(newRow, newCol);
                    }
                }
            }

            private boolean hasAdjacentMine(int row, int col) {
                for (int[] dir : dirs) {
                    int newRow = row + dir[0];
                    int newCol = col + dir[1];
                    if (inbound(newRow, newCol) && mineGrid[newRow][newCol].equals("X")) {
                        return true;
                    }
                }
                return false;
            }

            public void print() {
                System.out.println("Grid:");
                for (String[] row : grid) {
                    for (String c : row) System.out.print(c + ',');
                    System.out.println();
                }

//                System.out.println("Mine Grid:");
//                for (String[] row : mineGrid) {
//                    for (String c : row) System.out.print(c + ',');
//                    System.out.println();
//                }
            }

            private void preProcess() {
                for (int x = 0; x < mineGrid.length; x++) {
                    for (int y = 0; y < mineGrid[0].length; y++) {
                        if (mineGrid[x][y] != "-") continue;
                        // get number of neighbor mines
                        int val = 0;
                        for (int[] d : dirs) {
                            int nX = d[0] + x;
                            int nY = d[1] + y;
                            if (inbound(nX, nY) && mineGrid[nX][nY].equals("X")) val++;
                        }
                        mineGrid[x][y] = String.valueOf(val);
                    }
                }
            }

            private void generateMines(int count) {
                Random rand = new Random();
                int i = 0;
                while (i < count) {
                    int x = rand.nextInt(this.grid.length);
                    int y = rand.nextInt(this.grid[0].length);
                    if (inbound(x, y) && !mineGrid[x][y].equals("X")) {
                        mineGrid[x][y] = "X";
                        i++;
                    }
                }
            }

            private boolean inbound(int x, int y) {
                return x >= 0 && x < grid.length && y >= 0 && y < grid[0].length;
            }
        }
}

Elevator

Design an elevator control system for a building with M elevators and N floors. The system should handle:

  • Requests from outside (up/down buttons on each floor)

  • Requests from inside (floor buttons inside each elevator)

  • Elevator movement, state management, and load handling

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

public class ElevatorSystem {

    class Elevator {
        int id;
        int currentFloor;
        Direction direction;
        ElevatorState state;
        TreeSet<Integer> requests = new TreeSet<>();

        Elevator(int id) {
            this.id = id;
            this.currentFloor = 0;
            this.direction = Direction.IDLE;
            this.state = ElevatorState.IDLE;
        }

        void moveOneFloor() {
            synchronized (this) {
                if (requests.isEmpty()) {
                    direction = Direction.IDLE;
                    state = ElevatorState.IDLE;
                    return;
                }

                int targetFloor = direction == Direction.UP ? requests.first() : requests.last();

                if (currentFloor == targetFloor) {
                    System.out.println("Elevator " + id + " stopping at floor " + currentFloor);
                    requests.remove(currentFloor);
                    state = ElevatorState.STOPPED;
                    updateDirection(); // may go idle
                } else {
                    state = ElevatorState.MOVING;
                    if (currentFloor < targetFloor) {
                        currentFloor++;
                        direction = Direction.UP;
                    } else if (currentFloor > targetFloor) {
                        currentFloor--;
                        direction = Direction.DOWN;
                    }
                    System.out.println("Elevator " + id + " moved to floor " + currentFloor);
                }
            }
        }

        void addRequest(int floor) {
            synchronized (this) {
                requests.add(floor);
                updateDirection();
            }
        }

        private void updateDirection() {
            if (requests.isEmpty()) {
                state = ElevatorState.IDLE;
                direction = Direction.IDLE;
            } else if (currentFloor < requests.first()) {
                state = ElevatorState.MOVING;
                direction = Direction.UP;
            } else if (currentFloor > requests.last()) {
                state = ElevatorState.MOVING;
                direction = Direction.DOWN;
            } else {
                // Between floors or already at target
                state = ElevatorState.MOVING;
                direction = (direction == Direction.UP) ? Direction.UP : Direction.DOWN;
            }
        }
    }

    enum Direction {
        UP, DOWN, IDLE
    }

    enum ElevatorState {
        MOVING, STOPPED, IDLE
    }

    List<Elevator> elevators;

    public ElevatorSystem(int numberOfElevators) {
        this.elevators = new ArrayList<>();
        for (int i = 0; i < numberOfElevators; i++) {
            elevators.add(new Elevator(i));
        }
    }

    public synchronized Elevator assignElevator(int requestFloor, Direction direction) {
        Elevator best = null;
        int minDistance = Integer.MAX_VALUE;
        for (Elevator e : elevators) {
            if (e.direction == direction || e.state == ElevatorState.IDLE) {
                int distance = Math.abs(requestFloor - e.currentFloor);
                if (distance < minDistance) {
                    best = e;
                    minDistance = distance;
                }
            }
        }
        return best;
    }

    public synchronized void requestPickup(int floor, Direction direction) {
        Elevator best = assignElevator(floor, direction);
        if (best != null) {
            best.addRequest(floor);
            System.out.println("Assigned elevator " + best.id + " to floor " + floor + " (" + direction + ")");
        }
    }

    public void step() {
        for (Elevator e : elevators) {
            e.moveOneFloor();
        }
    }

    public void status() {
        for (Elevator e : elevators) {
            System.out.println("Elevator " + e.id +
                    " at floor " + e.currentFloor +
                    " going " + e.direction +
                    " state: " + e.state +
                    " queue: " + e.requests);
        }
    }

    public static void main(String[] args) {
        ElevatorSystem system = new ElevatorSystem(2);

        system.requestPickup(3, Direction.UP);
        system.requestPickup(0, Direction.UP);
        system.elevators.get(0).addRequest(5); // simulate inside elevator button press

        for (int i = 0; i < 10; i++) {
            System.out.println("\nStep " + i);
            system.step();
            system.status();
        }
    }
}

Last updated

Was this helpful?