Confidently Incorrect - Navigating Battleships

Bradley Hill - Apr 16 - - Dev Community

Confidently Incorrect since 1987

Background

So I started The Odin Project a while ago now...at least a year now, with a big slow-down during the 9 months of my studies with Ada Tech School, but I have since returned to The Odin project with gusto, and would like to take the time to discuss my latest mini-project, the last suggested project for the part of The Odin Project curriculum regarding JavaScript.

Here is the GitHub link to the project: Battleships

Now I have been using TypeScript for many months now and see no reason not to use TypeScript to complete the JavaScript projects, nothing like type safety for improving the quality of my code, and the Intellisense improvements certainly make it more pleasing to work with in VSCode.

There is a full description of the objectives to be met during the project, and we are tasked with writing our code practising Test-Driven Development, and Object Orientated Programming.

So what will we be needing for this project? Ships, of course! And a Player object too, not to mention a Gameboard object to put our Ships on, and our Players to have one each. Then a GameLoop to manage the game logic, of course.

Let's not forget the TDD, so I guess a folder full of our test suites as well(I'm using Jest for testing). And of course a CSS file for styling, HTML file and a script file for the DOM manipulation, got to try and maintain a good separation of concerns! So eventually I ended up with a nice little architecture like this:

List of directories and files in my finished project

And with a month or so of on and off working on the program, with various distractions, not least of which has been the job hunt, I have ended up with a game that looks like this:

Simple layout of two 10x10 grids and space for a list of missed attack and hit co-ordinates

Now evidently I am no genius when it comes to the visual design, but I am happy with the simplicity and the colours, all the important information is readily visible to the player, and a simple dropdown selector for changing the difficulty (we will talk about that later, oh yes!) and space for the moves made by both players.

Using TDD, or how I learned to love tests.

Now I have been introduced to testing in my studies, found them interesting but didn't have much use at the time for them, and with the time pressures of our group projects there was little wiggle room for writing tests... More's the pity, it seems.

Test suite report showing all tests passing

Now, it definitely took me a little while to wrap my brain around the change in thinking that TDD requires. Testing something....before there is something to test? Seems madness, illogical, putting the cart in front of the horse.... But it really helps! The process is often described as Red, Green, Refactor.

  • Red: Write a test. The most simple basic test you can think of. You need an object back from a function, great. Test that it returns an object. No more. No less. This test will fail (Comes back red when you run your automated testing library npm test for this project), because we have nothing for it to test. Well, we can fix that....

  • Green: Write the code to pass the test. Now stop for a second, and go back and read that first sentence. Write the code to pass the test. No more than that. So your test is checking that your function returns an object? Write the function, return an object. Stop. No more than is necessary to pass the test. This definitely resulted in me back tracking and deleting some code I had enthusiastically carried on typing with after writing enough to pass the test, but honestly it's probably the key part of the process.

  • Refactor: After your test is passing (run your test suites, see that glorious green of victory!) time to go back and refactor the test, or in my case write a new test, that will test the next part of the function that you require.

This process helps writing tighter, cleaner code, with each addition to the code being focused and minimal, and whilst considering what test to write it gives you direction and centres attention on the necessary.

Could be better

Boy is there room for improvement......

Screenshot of the game being played, various hits and misses displayed on the grids

Whilst I am happy (enough) with the project to consider it finished personally, there are many things which could be improved and implemented.

Screenshot of the console declaring the game over

A better Game Over/ You Won message. This would probably be better handled similarly to the introductory message, with an HTML element that is displayed depending on the end of game state. Honestly, the only reason I haven't done this was my rush to be done with the project.

Screenshot displaying the Introduction to the game Overlay

Taking a broader view of the code base, I have received some very useful feedback from the user u/jambalaya004 on Reddit, that I will list here, as it seems to me to be very good feedback for me to take onboard.

  1. Methods nested inside objects : It makes the code harder to read, and any future updating of the code would quickly become a spaghetti nightmare. Splitting up the functions and adding them to the objects by reference would be cleaner and easier to modify in the future.

This is the largest change I think I need to bear in mind, I would much rather my code be easy to read for when I return to it in the future, or it gets passed to another person to modify. I may return to the project in the coming weeks and attempt to refactor it in this respect, although for now I must return to the job hunt for now.

  1. Typescript Interfaces : They suggested that I move all the Interfaces out from each file and containing them within a src/models directory. This is just a simple and elegant change, I feel a bit stupid for no thinking of it myself. I can then just import the interfaces to where they are needed and improves the organisation of the project.

  2. If, If, If, If : Nested if statements, I myself thought that there was too much nesting of If statements even as I was writing the code. They point out it adds complexity (the Enemy of clean code) and complicates testing (I definitely experienced some of this). So I will be doing some research and learning on how to invert if statements and other ways to reduce code paths and nesting.

  3. let should not be my default but const : Something I am trying to shift away from is my instinctive defaulting to declare my variables with let and using const to make immutable what doesn't need to change. Definitely good advice and something I could improve on in this project.

To conclude

I am pleased with this project, it definitely has taken effort on my part and I have learnt some good practising that I look forward to using going forward. I also can see more clearly the good habits I want to try and instil now before the bad habits set in.

There were frustrations and compromises and victories, but little by little I can see my progress, and I still enjoy the act of overcoming these new challenges and learning more and more. Each day is another little lesson. I look forward to continuing with The Odin Project and the next challenges, but in the meantime I must return to looking for my alternance (apprenticeship) and maybe a small personal project before launching into the next part of the curriculum.

Until next time, be safe and stay happy, thank you for taking the time to read my little Project review.

. . . . . . . . . .