My current C# project is to create a Battleships program that would allow easy input of grids and on-screen solving.
I find myself strongly preferring online solving of this sort of puzzle to doing it on paper. Conceptis has an online solver, but I wanted to also be able to solve the puzzles in Games in the same manner.
Battleships is a grid-based logic puzzle based on the popular (and more familiar) two-person peg game. In the puzzle, the solver is presented with a square grid with numbers on the side and bottom, and some number of spaces already filled in. The goal is to place the “ships” (listed at the bottom of the grid) in such a way that the number on the sides of the grids represents the number of segments in that row or column, each ship is used once, and no two ships touch each other, even diagonally. The puzzle shown is from the July 2010 issue of Games.
I started with the UI, which is written in WPF/XAML. I knew that this would be significantly more work than my Canfield program. Each grid, as well as the row and column numbers, would need to be clickable, there would need to be an easy way to specific “ship” or “water” for spaces, and the ship pieces would need to automatically change shape based on their neighbors. On the other hand, while Canfield uses uploaded PNG files for the graphics, Battleships uses path files drawn by the program itself.
For the ship pieces, I am using GeometryGroups specified in the Window.Resources of the XAML file.
When I want to use that group in a particular cell, I update it via the C# code.
for (x = 0; x < 10; x++) { for (y = 0; y < 10; y++) { Cells[x, y] = (Path)FindName(string.Format("cell{0}{1}", x, y)); } }
To begin with, I’m programming Battleships at a set 10×10 size, which is the standard for Games magazine; once I’m done, I may double back and include other sizes, or I may move on to other grid-based logic puzzles.
Initially, each cell in the main grid contained just the path piece. Unfortunately, though, cells were only clickable on the visible portion of the path, meaning that empty cells (which contain an empty GeometryGroup) were unclickable. Also, I wanted an internal visible grid of blue lines. So now each cell of the grid contains a grid of its own (implicitly 1×1), which contains a rectangle (for the fill and border) and a path piece.
A ship piece is selected (or cleared) by clicking the left mouse button and a water piece by clicking the right mouse button. I thought about doing a rotation (a left click puts a ship in an empty spot, water in a ship spot, or clears a water spot), but I decided I preferred this method.
To create the map of sample ships at the bottom, I initially tried to scale the playing pieces to 50%, but that didn’t work; when WPF set the pieces next to each other, space was reserved for the full 100% width, leaving large white spaces. I’m sure there’s some method I could have used to get the results I wanted, but I eventually gave up playing with it and created a second set of GeometryGroup elements, scaled down.
I decided to go old school when indicating a cell’s status as either a clue (solid ship, dark blue water) or a guess (gray ship, light blue water). Rather than creating a class with a status attribute, I’m using 1-7 for clue pieces and 11-17 for guess pieces; hence, my code makes liberal use of the % operator. (I also have room in the code for a “commit” status, so that guesses that are firm [11-17] can be visually differentiated from trial-and-error guesses [21-27].)
I’ve programmed the basic UI, although it still needs a little tweaking. To finish up, I also need to program the module that loads in a puzzle (right now, the puzzle is hard-coded, for testing purposes), as well as creating a help file and other minor enhancements.