A fully OOP, Model-View-Controller (MVC) architecture implementation of the classic Battleship board game, running hosted in Excel, written in VBA to demonstrate the language's little-known OOP capabilities.
Something to play with and have fun with, something to learn with, something to share, something to enhance and extend for fun, because we can, because VBA is fully capable of doing this, and because VBA devs can do open-source on GitHub, too!
For Rubberduck contributors that know C# but don't do any VBA, this makes a decent-sized project to integration-test Rubberduck with. For VBA programmers, it makes a project to study and play with, to see how VBA can be used to write object-oriented code, and how MVC architecture can be leveraged to implement complex but very organized, extensible applications.
Do I need Rubberduck to use this code?
You don't. But you're definitely going to have a much better time with Rubberduck (although.. that's true whether it's this project or any other!), be it only to enjoy navigating all these classes in a treeview with a customized folder hierarchy. You will not be able to run the unit tests without Rubberduck (Assert
calls will fail to resolve), but you can absolutely run and explore this code without the most powerful open-source VBIDE add-in out there. Just know.. you're missing out :)
You need a desktop install of Microsoft Excel with macros enabled. If macros are disabled, the title screen should look like this:
Otherwise, the first step is to pick a UI - at this point there's only a "Worksheet" UI, so you click it and you're taken to the "Game" screen, where you pick the grid you want to play in, knowing that Player 1 always shoots first:
Just implementations of various strategies for winning a Battleship game. For now:
- Random; shoots at random everywhere it can, until all enemy ships are found. Then, the heat is on. Ships may be adjacent.
- FairPlay; shoots at random everywhere it can, until an enemy ship is found. Then proceeds to destroy that ship, then keeps shooting at random until it finds another ship to destroy, until it wins the game. Ships will not be adjacent.
- Merciless; shoots in random-ish patterns targeting the center and/or the edges of the grid, until it finds a ship to sink. Then proceeds to destroy it, then resumes the hunt. Will not shoot a position where the smallest possible ship it's still looking for, wouldn't fit at that position horizontally or vertically. Tends to avoid shooting in positions adjacent to previous known hits if it's not hunting a ship down. Its ships will not be adjacent.
To play the worksheet UI (other implementations may work differently), you can follow the in-game instructions:
To place a ship, select the location of its top-most, left-most position. Click anywhere in the grid to preview; if the preview isn't where you thought it would be, try rotating the ship by right-clicking. Double-click to confirm the position when you're ready to place the next ship - the ships you've placed will appear in the "Fleet Status" box:
Once you've placed all your ships, ...your AI opponent has already done the same and the game is ready for Player 1 to begin:
The goal is to find and sink all enemy ships before they find and sink all of yours.
If you're playing grid 2, you cross your fingers while the AI picks a position to begin the game; if you placed your ships in grid 1, you double-click a cell in grid 2, and then the AI will play.
As the game progresses and you sink enemy ships, specifically which ships you've taken down will appear in the "acquired targets" box under the opponent's grid -
Once a player has found and destroyed all 5 enemy ships, the game ends:
The ships (and their respective length) are:
- Aircraft Carrier (5)
- Battleship (4)
- Submarine (3)
- Cruiser (3)
- Destroyer (2)
Unfortunately, it won't, because of the Win32API calls used in the shape animations and AIPlayer
delays.
If you find a bug, or have a feature request, you will want to open an issue.
If you want to submit a pull request that closes an open issue, you'll need to fork the repository and work off a local clone of the files; open the Battleship.xlsm
file in a desktop install of Microsoft Excel, load the VBE. Add new classes, new test modules and methods, new game modes, AI implementations, a new UI to play with, or enhancements to the WorksheetView
- for best results, regularly export your files to the local git clone directory, commit the set of changes, push them to your fork, and make pull requests that focus on the feature it's for - if your pull request includes Rubberduck unit tests, it's even better!