How to make two subclasses communicate with each other in a game

java, swing

Solution

This is a typical application, where patterns like MVC are applied. One would implement the game logic separately and for common usage, containing methods like `computerAttack()`. The game logic would therefore contain references to both grids/players and would also implement the event interfaces of both grids/players. This way, the grids don't need to know each other.

M - The internal representation of the grid state (ship/water, bombed/not bombed, ...)

V - The GUI components (grid, buttons, UI event listener interfaces, ...)

C - Game logic (implemented in a separate class or package)

Problem

Linked: Using MouseListener to select a range of cells in a grid I am creating a Battleships game, with two grids. The user will place their ships on one grid and then bomb the other grid. I have an abstract class called Grid which creates a 10x10 grid of cells (which extend JPanel class). It gives each cell a listener, like so: ``` public Grid() { setPreferredSize(new Dimension(300, 300)); setLayout(new GridLayout(GRID_SIZE,GRID_SIZE)); for (int x = 0; x < GRID_SIZE; x++) for (int y = 0; y < GRID_SIZE; y++) { final Cell cell = new Cell(x, y); cellArray[x][y] = cell; add(cell); cell.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent e) { mouseClick(e, cellArray); } @Override public void mouseEntered(MouseEvent e) { mouseEnter(e, cellArray); } @Override public void mouseExited(MouseEvent e) { mouseExit(e, cellArray); } @Override public void mousePressed(MouseEvent e) { mousePress(e, cellArray); } @Override public void mouseReleased(MouseEvent e) { mouseRelease(e, cellArray); } }); } } ``` So these listeners can be accessed from the two subclasses, the listeners call another method as can be seen in the code above. These methods are contained under the constructor and are all abstract: ``` public abstract void mouseClick(MouseEvent e, Cell[][] cellArray); public abstract void mouseEnter(MouseEvent e, Cell[][] cellArray); public abstract void mouseExit(MouseEvent e, Cell[][] cellArray); public abstract void mousePress(MouseEvent e, Cell[][] cellArray); public abstract void mouseRelease(MouseEvent e, Cell[][] cellArray); ``` I then have two concrete subclasses - one is for the "Player grid", the other for the "Computer grid". The main difference is that in the Player grid the listeners are used immediately to place the ships. In the Computer grid, the ships are placed automatically (done when an object of the class is constructed). This means that the listeners in the Computer grid class are only there to respond to the user's attempt to bomb a square. The Player Grid, once the ships have been placed, should be automatically bombed by the computer. This is where I've run into difficulties. I have written a method in the PlayerGrid class called computerAttack() - but I've no idea how to access it from outside the class. How can I make the two subclasses communicate? Additionally, is this even the proper way to do it, or am I trying to do too much in these two classes? I have tried to provide as much information as necessary here, but if the actual content of the two subclasses is needed, I can provide them.

Original source

Related problems