Let's work together!
Like my work? I'm happy to connect.
In this game you are playing versus the computer in a battleship combat.
Your objective is to sink the computer's fleet before it sinks yours.
Each fleet will have eight ships:
When playing you will see two boards:
To attack, click on a square on your opponent's board. The squares can take the following values:
You can track the progress of the game by viewing the ships inventory in the top right corner.
The inventory shows the total number or ships floating with designated ship types.
The second way to track the game by reading the text in the bottom left component that will narrate the updates.
When clicking on Menu the player will be prompted with three options:
The game has five different modes that are explained below:
In this classic game mode, each player has one shot per turn. The user will make the first move.
In this extreme version of the classic game, the ships will move and recover from the shots if they hit but are not sunk within a designated number of turns (dependent on the size of the ship).
In this mode, the user has a specific quantity of bombs (3) that can be used at any point during the game. If a ship is hit by a bomb, it will immediately be sunk.
Rapid fire mode allows the user to choose multiple squares to hit in one turn, with the quantity of available shots equal to the number of ships that the opponent has remaining. The player will make the shots without knowing what impact they had until the end of the turn.
If you miss several shots in a row, computer assist will be enabled to help you to find a target. The likelihood of computer assist hitting a target increases proportionally to the number of misses in a row.
Hanzhao Yu: Game Classes & JUnit Tests, Computer Algorithm Classes
Holland Delany: Game Classes & JUnit Tests, Computer Algorithm Classes, GUI & Resources, Remote Deployment
Jorge Corrales: Game Classes & JUnit Tests
The main method invokes the GUIFrame class, which starts the game.
The GUIFrame class creates the window and menu bar.
The menu bar has the options RESTART, UNHIDE SHIPS, and QUIT.
The GUIFrame class instantiates a GUIPanel.
The GUIPanel class paints the panel for current page (main page or game page).
It also instantiates a GUIMainPage and defines methods to create,
navigate between, and repaint pages.
The GUIMainPage class draws the main (intro) page components.
This includes creating the buttons on the main page
which allow the user to select the game mode.
This class has action listener methods to capture the user game mode selection and
call the method to instantiate the corresponding
BattleShip/BattleshipMode# and GUIGamePage classes.
The GUIGamePage class draws the game page (second page) components.
This includes the user board, computer board, fleet status panels,
and action result panel.
This class uses the GUIGrids class to instantiate the boards.
The GUIGamePage class has methods to update
the text of the panels after each move based on the status of the game.
The GUIGamePage class also has a method to receive mouse events/ capture the selection
when a user clicks on a board square, and
then call the Battleship public void fireTarget(Coordinate coordinate) method on the square.
The GUIGrids class is used to display the game board.
Each square displays an ImageIcon based on status of the square.
Status options are defined in the Status class (see below).
This class defines the methods for a standard game.
This includes methods to create a set of ships,
create the user board and computer board,
play a move/ fire at a target, and get the game status (to be used by the GUI).
The Battleship public void fireTarget(Coordinate coordinate) method plays the user move,
and then immediately calls the AI method to play the computer opponent move.
This class instantiates objects from the following classes - Board, Ship, AI.
All BattleShipMode# classes extend the Battleship class.
This class extends the Battleship class to incorporate "SHIPS ON THE RUN" gameplay.
In the "SHIPS ON THE RUN" mode, the ships move & regenerate
if they are not sunk in time.
This class defines a private boolean shipFlee(Board board, Ship ship) method, and
overrides the Battleship public void fireTarget(Coordinate coordinate) method to incorporate the shipFlee method.
This class extends the Battleship class to incorporate "BOMBS AWAY!" gameplay.
In the "BOMBS AWAY!" mode,
the ships can be sunk with one hit if a bomb is used.
This class defines bomb methods and
overrides the Battleship public void fireTarget(Coordinate coordinate) method to incorporate them.
This class extends the Battleship class to incorporate "RAPID FIRE" gameplay.
In the "RAPID FIRE" mode, the user selects multiple squares to hit on each turn,
where the number of squares the user selects corresponds
to the number of enemy ships left.
This class defines methods for tracking multiple user selected squares,
and overrides the Battleship public void fireTarget(Coordinate coordinate) and public String[] getRoundInfo() methods.
This class extends the Battleship class to incorporate "LUCKY SHOT" gameplay.
In the "LUCKY SHOT" mode,
if the player misses several shots in a row, the
game will try another shot in background that becomes
gradually more likely to hit a target.
If that background shot hits a ship, it replaces the player shot.
This class overrides the Battleship public void fireTarget(Coordinate coordinate) method.
The AI class defines the methods required for the computer opponent to
play a move/ fire at a target.
This includes the public Set
It also includes helper methods to identify possible targets
(priority is given by how many possible ships could be located in a particular square)
and find targets around damaged ships.
The Board class is used to create the board for both the player and computer.
Ships are auto arranged on the board.
This class also contains methods to get information about the status of the board
(the state of the squares and Ships on the board).
This class defines a global usable coordinate.
The coordinate is immutable it is after created.
enum class defining the possible status of a square in the board.
Status options include:
WATER - square that has not been hit, contains water
SHIPINTACT - square that has not been hit, contains ship
SHIPHIT - section of a ship that has been hit, but the ship is still floating
SHIPSUNK - section of a sunk ship
MISS - square that has been hit, contains water
SELECTED_WATER - user selected square, rapid fire game mode only
SELECTED_SHIPINTACT - user selected square, rapid fire game mode only
The Ship class is used to create the ships.
Ships have a size(int), name(string),
and direction(Direction) where it points to.
enum class defining the cardinal directions.
The companion test classes are used to test for
method functionality, state changes, and boundary & invalid input handling.
Java Swing is said to be an old, deprecated technology which can only design desktop apps. Truthfully, for anyone who aims to make a web app, Swing is not a good choice. By nature, Swing has been designed to be run as a desktop application. To access it, you have to setup the JRE on any computer that needs to run it, and it is not supported by modern browsers.
For many years Swing has been the framework of choice for many companies and individuals for creating rich applications. Significant time, money, and effort has already been invested in Swing application development, and many of these applications are essential to their creator’s operations. The Extreme Battleship project was already completed in Swing when I set out to deploy it as a web app.
Nowadays, the Swing framework is becoming a limiting factor, because Swing applications are not able to be used in modern web browsers.
Oracle announced in January 2016 that Applets would be deprecated in Java SE 9, and the technology was removed in Java SE 11. Given that nearly all browser makers were already getting rid of plugin support, you can argue that Oracle really didn’t have any choice but drop the feature. Support for running Applets in browsers is only possible while browser vendors are committed to standards-based plugins.
The argument is that plugins have to connect deeply to the browser’s architecture, and this makes it too difficult to keep everything up to date and secure. In the case of the Java plugin, it was even more complex because of the need to use the JVM etc. to actually run the code. Keeping all of this software up to date was a task beyond most users. So plugins of all types, including Java, had to go.
With the Applet technology support being discontinued, it leaves very few options.
My goal was to display the Swing project in a browser like any Web app. My solution was to use Webswing , which uses a Jetty server to load the JAR and expose it as HTML5 pages. I would recommend the process for others who want to extend the life of their legacy Swing application.
The Swing API is by design cross-platform, which means all interactions with platform dependent features happen through a well-defined minimal interface (java.awt.Toolkit).
Webswing defines a new platform implementation for "Web", which simply turns web browser to a virtual desktop and translates platform specific actions to browser actions in the best possible way.
There are two core actions that every platform has to provide for Swing:
Webswing displays the content in a browser using HTML Canvas and captures keyboard and mouse events in JavaScript to generate Swing input events.
The quick start is simple: download the latest version, extract files, run a script file, and open your browser, it works! Just move your jar in the Webswing folder (or a subfolder) and configure it as a new app in the admin console of the running server. A Docker image is also provided in order to run Webswing in a container, for example on a PaaS like OpenShift or Kubernetes. It is also possible to customize the HTML pages, get stats from the admin console, or integrate it with other systems like nginx, SSL certificates or load-balancers: the excellent documentation gives a lot of information for usage in production.
In order to host the project, I decided to rent a VM on Oracle Cloud Infrastructure, specifically, a Windows Server 2019 Standard Image and VM.Standard.A1.Flex shape for performance and rendering consistency.
As a drawback, every new Webswing session launches a new instance of the app, so developers must set the server with appropriate memory / cpu settings and limit the concurrent sessions. To deal with this constraint, a login, with a limited number of concurrent users, gates the instance.
Now, you can
access
the Java Swing app from any browser, including on mobile devices!
*case sensitive* username=user, password=user
Like my work? I'm happy to connect.