This is the fourth 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.

Get in touch on Twitter at @mr_al if you’d like to chat.


PHP

Available on GitHub at: https://github.com/mr-alistair/ootest-php

Run time version is found at: https://alistairlloyd.com/ootest/php/

My wife runs her own web site design business. (check out Mara Communications if you’re interested… she’s very good!) As a result, PHP is the language I’ve been the ‘most’ exposed to over the last few years. So, it made sense for me to use this to write and test the code following the groundwork of design.

I had dabbled in procedural PHP, mainly making WordPress plugins to add functionality or alter other developers’ plugins over time. This was my first foray into coding in an object orientated method with this language.

I’d cut my teeth of my brother’s 1kb RAM Sinclair ZX81 in the early 1980s, upon which I taught myself BASIC in a relatively constrained yet entertaining technology environment. As a result, and with that raw grounding, I did my PHP development without any fancy IDEs and coded it directly into text files using my web server’s code editor.

This is the coding equivalent of whittling a full chess set out of rough wood pieces on your back porch. It’s slow, a bit messy, and if you don’t watch what you’re doing you’re likely to take head of a Knight off and be left with a messy HTTP 500 error. Nevertheless, it gave me a safe environment to test the integrity of my logic and design, piece at a time.

They say no battle plan survives first contact with the enemy, and that applies to converting an on-paper design to code. Ask any Business Analyst who has faced down an Engineer/Programmer querying the “what ifs…” assumptions and the “we’d never thought of that…” scenarios. You’d think that when you are both the analyst and the engineer that these conversations would take place relatively quickly. Nope. Cognitive bias – particularly in one’s own design – is a terrible thing to wrestle with.

I like PHP. There, I’ve said it. Its grammar is neat, it has well-ordered brackets to contain functions, it is ambivalent to variable declaration, and has beautiful array handling. Sure, it’s not the fastest interpreted language around, and requires it’s own platform (in my case, Apache on Linux, rendering output as HTML), but it provided a safe proving ground for converting the design to working code.

Array Handling

I mentioned the array handling, as this would be highlighted in later version in different languages. For the coding, iterating through arrays to determine if pieces were to be chosen, set aside or targeted required a set of temporary (dummy) array sets to be established which mimicked the live set.

In PHP the easiest way of knocking these out was using ‘unset’ to remove an array element while keeping the rest around it. ‘array_values’ could then be used to populate and tidy a new array with the same contents, and ‘array_rand’ would return a populated element at random. ‘in_array’ would return a Boolean indicating existence of an integer in the array – we didn’t need to know which one it was, just that it existed. Perfect.

Figure 1 – PHP Auto120, extract from Game class, showing use of unset and array_values when determining which Player Marker to move.

Loop de loop, and loose typing

for’ loops in PHP also give you want you ask for. From 1 to less-than-or-equal-to 4? Yep, I can do that. (Remembering, like most languages, the first array element starts at 0 (zero) which I chose to ignore for simplicity… until it came back to bite me later.)

Figure 2 – for loop iterating through the four Markers for a Player and setting a flag if a ‘magic number’ is found.

PHP’s loose typing of variables came in handy when concatenating and writing log strings. Got a mix of strings and integers?  Yep, I can deal with that. Need to force it into a format?  Nah, don’t worry. All good.

Iterative Build

Testing the PHP code happened in sprints. Once the ‘Marker’ and ‘Player’ classes were defined, I coded the ‘Game’ class in stages and progressively added to the game-play as I went. Each scenario threw up different challenges, particularly when ensuring that the logic of what pieces were being targeted and moved were valid. For example, when using ‘array_values’ to copy remaining values to an array, it, of course, compresses values back to the smallest footprint, thus preserving memory.

In this scenario an array of ‘Marker’ objects that is attached to a ‘Player’, containing the locations of the four pieces ( (and including array position 0) may look like so {0,3,24,15,30} but when ‘penultimate’ numbers are knocked out and the array is copied, it presents as {0,3,15}. So, I had to ensure that the copied arrays had a reference to the ‘Marker’ number and location, plus a flag to indicate if it was to be ignored.

‘Marker’ and ‘Player’ were described with public methods, so in the ‘Game’ class I could call the methods directly by referencing the ‘Player’ and the ‘Marker’ methods and objects, such as: 

$g_player[$x_counter]->p_pieces[$x_piece_pointer]->m_get_status()

…to get the playable status of Player “$x_counter“’s Marker number “$p_piece_pointer“.

Similarly, the location of a ‘Marker’ was frequently requested through a similar call:

$g_player[$x_counter]->p_pieces[$x_piece_pointer]->m_get_location()

When fully functional, each game typically has over 100 ‘moves’, so a fair amount of information was written out to the log. I did consider writing some code to display a visual representation of the board as it would appear after the end of each move, but given that I was playing around with a text-only representation I’ll preserve that for Version 2.

What I did find useful was building code into the calling routine to loop through each ‘Player’ and display their ‘Marker’ locations on the board, which was useful in tracking and debugging.

PHP did offer the advantage of including standard HTML colour tags in the output, though. So, I had some fun with colour-coding various status lines, which helped highlight interesting logical choices and twists and turns of the game. In this, you can see how the algorithm is choosing penultimate and factor numbers.

Figure 3 – PHP Auto120 run-time output following a successful game.
Figure 4 – PHP Auto120 run-time output mid-game, showing logging of movements including ‘bumping’ opposition pieces, forfeits for rolling a 1, and successfully reaching Position 120.
Figure 5 – PHP Auto120 run-time output, showing the decision making logging walking through seeking a) a penultimate ‘magic number’, a factor ‘magic number’, and then finding a target opposition piece to hit and bump.

So, I’d moved from concept to design to working code. It ran, it produced consistent results, and much had been discovered along the way which fleshed out the on-paper design.

NEXT POST… C++, dusting off some old knowledge and skills to the same problem using different tools…