Andrew Martin
Andrew Martin

Reputation: 5741

How to correctly model a Battleships Game in Java

I am trying to create a Battleships game for a 'Games' project my group is doing at university. I've never really used GUIs before, with almost all my output previously being in the Eclipse console.

To begin with, I created a GUI class, which is effectively my "runner" class. It loads up a JFrame.
I have a second class, GUIGrid, which sets a dimension for the two game boards that will be displayed and uses nested for loops to create the grid from GUICells.
This contains listeners etc to detect what the mouse is doing and stores the x and y coordinates of each cell. I have run a little piece of test code so I can click anywhere on either grid and a popup tells me exactly which coordinates that cell is.

In addition to these classes, I have a Ship class, with five subclasses for types of ship and a Player class, with stores the player's name and create an array of Ship objects for them to use.

Finally, I have my logic classes. I have a GridLogic class and a CellLogic class. The former uses nested for loops to create a 2D array of CellLogic objects. The CellLogic class then stores things like coordinates and information on whether the cell has been attacked.

My question (at last!) is - is this the correct way to model the system? When I look at the CellLogic and CellGUI classes, they seem to have fairly similar stuff. Additionally, although I can make the GUI respond to mouse clicks, I am really struggling to connect the GUI to the Logic. For example, I have no idea how to add ships onto the grid and then store which positions store ships in the 2D array. Without posting copious amounts of code, I was hoping someone would be able to tell me if I'm at least on the right track, or if I've separated the system out too much.

Upvotes: 3

Views: 4291

Answers (4)

tgkprog
tgkprog

Reputation: 4598

I guess you wont get one answer here but this is my take. MVC obviously. In particular I would keep the main GUI one class (JFrame, menus etc). Would keep the board in another. It would use the Cells & Ships to draw itself. Cells would contain information (their x,y, which ship is on them and whether bombed or not), ship class would have its type, from x,y and to x,y, image to render. Then you can have a bomb image that is partially transparent so the ship can be seen below it.

Board would draw squares, ships and then finally bombs over them.

Instead of a pop up, helps to have a debug frame, where you can show (on labels) some key information; besides the running log

Controller would be the BattleShip class with some help from the model : cells and ships. Keep the communication, who played, where etc seperate -> talks to Board via interfaces so can change that to say a web one with a new view.

Upvotes: 1

Joop Eggen
Joop Eggen

Reputation: 109557

Model-View-Controller with listeners and such. If you look into JavaFX (which intends to follow up Java Swing) it has simpler "built-in" change listeners. Also there are a couple of nice styling and animation effects available without much programming.

The rest seems fine. Step back on inheritance. You might implement a feature lookup/discovery model:

public interface FlightCapable { }
public class X {
    public T lookup(Class<T> intface) { }
}
FlightCapable fc = x.lookup(FlightCapable.class);
if (fc != null)
    fc.fly();  // Instead of x.fly();

This highly decouples.

Upvotes: 0

Kai
Kai

Reputation: 39641

The tendency of over-using sub-classing is very common to university projects. Subclassing is a thing which mostly is avoided today. In your example there won't be a real benefit of using sub-classes for ship types. A better design would be to just use a Ship class which has an enum ShipType. This will also make the evaluation easier later.

To answer your comment: Well your approach misses some kind of GridModel which contains the 2D grid and the Player objects (all game data). This GridModel is known in GridGUI and GridLogic. The GridLogic modifies the GridModel and tells the GridGui to repaint the changed model. The GridGUI doesn't modify the model it just informs the GridLogic that a click at the grid-coordinate x, y happened. Then it's on the logic to modify the model and let the GUI refresh itself. See the Model-View-Controller-Pattern for more details.

Upvotes: 2

wrm
wrm

Reputation: 1908

the separation sounds good though i think, it could be made more clear. using the MVC pattern, you can clearly define the model (ships and grid), the controllers(your logic) and the view (the jframe that draws the grid).

Now basically, the model dont know anything else, the controller knows view and model and the view knows how to draw model and calls controller as reaction on user input. That is: user clicks, the view just calls a controller with the coordinates and the event that happened. This controller now modifies the grid and issues a redraw.

So in my pov, you probably dont need a cellGUI class, just a view that draws everything (though, you could model it like this if you store x,y in cellgui classes...). But you dont need a celllogic class. you need a "higher" controller that knows, how to modify the whole grid and what happens, if there is already something and so on.

Upvotes: 3

Related Questions