This is the seventh in a series of blog posts I’ve been working on during COVID isolation. It started with the idea of refreshing my systems design and software engineering skills, and grew in the making of it.
Part 1 describes ‘the problem’. A mathematics game designed to help children understand factors and limits which represents the board game Ludo.
Part 2 takes you through the process I followed to break this problem down to understand the constraints and rules that players follow as a precursor to implementation design.
Part 3 shows how the building blocks for the design of the classes and methods are laid out in preparation for understanding each of the functions and attributes needed to encapsulate the game.
In Part 4 we get down to business… producing the game using the programming language PHP with an object orientated approach.
Part 5 stepped it up a notch and walked through a translation of the code to object orientated C++.
Part 6 delves into the world of translating the code into object-orientated Java.
In Part 7 the same code is then translated into Javascript. Read on!
Get in touch on Twitter at @mr_al if you’d like to chat.
Javascript
Available on GitHub at: https://github.com/mr-alistair/ootest-js
So – Java to Javascript – that would be simple, right? It was. By this stage I’d gotten into a rhythm of finding the things that I was going to trip over when changing from language to language and knew to start by experimenting and targeting the areas I’d figured were dramatically different.
Javascript is not Java. If anything, Javascript looks like C++ and PHP had a kid and raised it in a land where they speak HTML. Calling it a ‘script’ is doing it a disservice, though. It can certainly do a lot of the heavy lifting at the ‘front end’ of a web-based system and let PHP and other code handle the ‘back end’. (I haven’t gone into the front end wonders of jsquery or server-side entertainments like node.js here. Maybe one day soonish.) And with modern browsers you have built-in debugging to boot, so that was a bonus.
It was time to consider a different IDE, which had also emerged as a theme of what I was exploring. I went with Visual Studio Code, the street-wise younger sibling of Visual Studio. There were some set-up things which were interesting. Visual Studio Code has a set of plug-in Extensions which provide additional syntax and debugging support, and some run-time libraries for languages that need it. My client browser would execute the Javascript, so VSC needed to know this:
There was also a great Debugger for Chrome (by Microsoft) which helped when stepping through issues within the IDE. All set.
Object Orientated in Javascript
Object Orientated mechanisms in Javascript, for web-based solutions, meant that instead of the standard ‘wrapper’ Class that I’d built to trigger proceedings in other languages (usually a Class named Auto120), I had a HTML file instead. This had two <script> blocks – one to hold the src calls to the three Class modules, and one to execute the game.
Some key differences from the start included:
All variables need to be declared up front as a var , or cannot be referenced without Javascript thinking that it was a procedure call. Like PHP, these variables were loosely typed. The pedant in me usually declared and assigned them a value, such as 0 or “” to remind myself what they were supposed to be.
Where Java required an instance of a Class to be declared by the Class name [i.e. Game thisGame = new Game(); , Javascript needed this to be declared as if it were a variable, i.e. var thisGame = new Game();
In the C++ and Java versions I was used to piping output to the standard terminal output channel; in Javascript it was back to rendering it as HTML. So, it was <br> instead of \n . At least string concatenation was easier, using “+” in the same way as “.” is used in PHP. Standard Javascript ‘document.write’ was used for writing browser output.
Class procedure definitions took me back a step, however, as Javascript reverted to the “this” precursor to identify the ownership of each property or method.
Defining arrays introduced me to the ‘push’ call, which I thought I had put behind me with an ill-fated foray into Assembly language as a teenager. Populating an array of Player Markers became an iteration around:
this.p_pieces.push(new Marker(x_counter));
…where x_counter sequenced from 0 to 4. Yep, we only wanted to deal with Markers 1 to 4, but I cheated and filled in the first array position, 0, as well.
Totally random
A new language to explore meant a new way of figuring out how to generate a random number. For Javascript this ended up being a nesting of two of the implicit Math-class methods – random, and floor.
Math.random will return a floating point value. Multiplying this by the given upper-boundary integer will produce… a larger floating point value. This is great if you want an answer of 4.323 or 2.534 … but I wanted a nice, clean integer between 1 and 6 inclusive. Enter Math.floor which returns the largest integer less than or equal to the current number. Great! As it’s the lower boundary, however, we need to add one to it to bring the lowest possible value up from 0 to 1. So, we end up with:
Presto. One random number between 1 and ‘g_upper’ inclusive.
Back to arrays
Arrays had me pulling my admittedly sparse hair out a few times, particularly where null values or out of bounds results were causing fatal errors. This is where old-school stepping through code during debugs and setting ‘watch’ on variables can be a life saver. I was used to iterating through an array and referencing positions 1 through to 4; most of the arrays I was dealing with expected a value at position 0 as well, otherwise making a reference to the array ‘as a whole’ would trip the wire.
A simple/inelegant fix was to ‘push’ a dummy value to position 0 on the array prior to getting down to business. This value was to be ignored anyway, and for the sake of a few bytes of memory, I was happy.
Two dimensional arrays were just as fun. The breakthrough came when I realised that a two-dimensional array was effectively one array with another array ‘pushed’ into it several times. (My mind keeps thinking of that American culinary delicacy, the Turducken, but we shall not speak of this, here.) So:
…gives us the two dimensional array x_forecast_pointers which, at position 0, has an instance of array x_forecast_internal. A later loop (not shown here) then pushes additional instances into x_forecast_pointer by setting the values within of x_forecast_internal and pushing them into the next available position. I was legitimately surprised that this worked.
When it came to searching for values within an array, I fell back to iterating through the array sequentially. There is an array find() function but, when considering code portability, it is not supported in IE11. Mind you, I’m not particularly supportive of IE11 either, so we’ll call that one a draw.
Making a true independent copy of an array was far easier using the array slice() method, vis:
Walking the talk
So, they were the big-ticket items. Testing the code proved interesting, as with most browser-based renderings one typically must wait for the code to complete before it starts ‘writing’ anything to the document… in this case, the HTML page. It was fortunate that the Visual Studio Code IDE has a built-in console interface that you could output to which helped when it came to stepping through things.
The issue with this is that sometimes code got stuck in a loop (my usual problem of poor punctuation, generally due to missing a bracket on an iterator) and so it appeared to ‘freeze’ after it had flushed output to the first page of so of HTML. Tracing these, particularly with nested conditionals and repeated call-backs is a tedious exercise – it teaches one a wax-on, wax-off lesson about cautious coding, and alcohol consumption while doing so.
The verdict? I didn’t mind JavaScript at all. I gained an improved appreciation of where it ‘sat’ in the big scheme of full-stack development for web-based apps. Down the track I’ll take a closer look at node.js and jsquery, but for now I had another serpent to wrestle with…
NEXT POST… Python! Would this slippery beast prove my undoing? Find out next time…