Search code examples
javaoopdesign-patternsminesweeper

Design patterns for minesweeper


I'm trying to create a minesweeper game with design patterns, but I have trouble implementing a creational pattern for the tiles in minesweeper.

In minesweeper, there are 2 types of tiles, the number tile and mines tile. The number tile contains a number or a blank depending on the amount of mines tiles beside them. While the mines tile contain a mine image to load on the tile.

How I approached this is by trying to use a Factory Method for the tiles, here is an example in java.

The abstract class

public abstract class Tile {
    boolean flag = false;
    boolean opened = false;

    abstract void open();

    void flag(){
        // business logic
    }

    boolean checkFlagged(){
        return flag;
    }

    boolean checkOpened(){
        return opened;
    }
}

The NumberTile class

public class NumberTile extends Tile {
    int number;

    @Override
    void open(){
        // business logic
    }
    
    void setNumber(int number){
        this.number = number;
    }

    int getNumber(){
        return number;
    }
}

The MinesTile class

public class MinesTile extends Tile {
    ImageIcon mineImg;

    @Override
    void open(){
        // business logic
        explode();
    }
    
    void explode(){
        // tell main board to end game
    }
    
}

Client Code

Tile numberTile = new NumberTile(); // get and setNumber method will not be accesible
Tile minesTile  = new MinesTile();  // explode method will not be accesible

How do I use the same abstract Tile data type without having the child class methods inaccessible?

If I would abstract all the methods from NumberTile and MinesTile into the abstract class, then they would also have to override methods that won't be used and cause refused bequest.

How do I solve this design pattern problem?


Solution

  • You cannot really solve this, I am not sure on the exact design pattern you're trying to implement as there are many variants. But the only way you can achieve this is by casting.

    Tile someTile = new NumberTile();
    
    if(someTile instanceof NumberTile){
        NumberTile numberTile = (NumberTile) someTile;
        numberTile.getNumber();
    }