Last time we implemented the ending of the game, and cleaned up the code a bit.
In this post we’ll look into an enhancement that allows us to change the size of the game, some more refactoring and bug fixes. At the end of this post we’ll be at the point where we have a playable game.
Altering the Game Size
One feature we’d like to add is the ability to play variable size of the Mancala game. We treat the total number of cells as the “size” of the game. Since each player has the same number of cells, this needs to be an even number, and cells are split evenly between players.
The next commit adds this feature:
The implementation is pretty straightforward. Instead of having a constant (CELL_COUNT
) in the controller module (game.js
), we pass a parameter in the constructor (game.js
, line 3), that is then fed to the Board
data structure. The Board
class already had this parameter, so it was already ready to work with any size, and did not assume a constant size.
What remains is simply having a way for the user to specify this. I decided to go with a simple URL parameter. This is simple enough to pass. So resolveGameSize
in index.html
(lines 15-27) takes care of reading the parameter from the URL query string and validating it. We then initialize the MancalaGame
instance with this number (index.html
line 12).
Again, Some Cleanup
The next two commits are really about a small but important refactoring. We’re encapsulating the board drawing in a class that takes care of all the drawing business, essentially encapsulating how the board is drawn and the user interaction with the board. The changes in drawing.js
is mostly re-organization of different functions into class method (the BoardUI
class). The more interesting part is how it’s actually used:
The controller now doesn’t maintain a pointer to the canvas instance. Instead, it works through API provided by the BoardUI
class, which is at a higher level of abstraction – initializeBoardDrawing
, drawBoardState
, toggleHighlights
. The motivation here is really better encapsulation of the UI implementation.
The last commit for today takes care of one bug fix – making sure we skip the opponent’s mancala when making a move:
There’s nothing too fancy here. The gist of the fix is in lines 17-19 in the MancalaGame
class1.
Incorporating this fix, however, prompted me to extract the calculation of the target cells to a different function (_calculateTargetCellsForMove
), so the playCell
function remains at the same level of abstraction, and is still readable2.
And We’re Done …
At this point, one should be able to build the code (npm run build
) and point his browser to the resulting index.html
. Look for it in the dist
directory.
A working version of the game is available here, embedded here for your convenience:
Admittedly, it’s not much to look in terms of UI design. But it’s a simple game we did in a few hours time, and it works. If you followed along so far, give yourself a pat on the shoulder.
… But Wait, There’s More
The story of how to create a simple game is pretty much done. But there’s more that can be said and done here, more features to build, tweaks to do.
Concrete examples for more directions include better UI design, more features (undo/redo, saving game states, showing a log, etc.). I welcome any more suggestions, and of course pull requests.
If you look at the repo, you’ll see that I went in another direction for enhancement. I was more interested in incorporating bots (“AI”) into the game as a feature; so you could play against a bot, or even have two bots play against each other. Stay tuned for more on that front.