Adventures in Random

Or how there are patterns in everything.

Having embarked on my first tentative steps into front-end development, the hours of bootcamp labs, lectures and lessons soon adding up; until one inoccuous looking lab appeared — “JavaScript Project Mode” — What was this?

A short brief: Find a public API and build something on a single page using it. There were a few more caveats but it was certainly sounding simple enough. I chose to enter “Project Mode” by taking some time to think about what was both a challenge and within my novice grip; and while idly playing a memory matching game with my daughter, inspiration struck.

Memory matching games where pairs of objects are laid out and covered up and you have to pick the correct pairs, engaging fun for my two year old, a challenging project in the making for me.

Ace Rimmer — What a guy!

Breaking apart the idea I made myself a shopping list of things to find, an API which could provide pictures, a means to build some cards on the screen, shuffle the pictures, make the cards clickable, cheer when they are all matched, and as Ace Rimmer once said “Smoke me a kipper, I’ll be back for breakfast.”.

A topical reference and much like the misadventures of the crew of Red Dwarf, what sounded oh so simple turned out to be a touch more challenging.

Starting the build

The ideation and exploration phase

A cornerstone of my first forrays into front-end development were DOM manipulation, and creating items on a webpage in a dynamic and responsive fashion. So creating some rough “playing cards” sounded like a good starting point. This was indeed correct. However, little div-boxes with the numbers 1 through 8 on them wasn’t the most engaging of games to play.

Time to hit the search engines, and seek out some public API’s, there are some fantastic people who update and maintain various repo’s on GitHub with links to API which are free to use (for educational purposes of course!), it was while searching for picture led API’s when I answered my own question — where do you find pictures in the offline world? — my initial thoughts led me to Art Galleries, I had a look at API’s belonging to the Met and the art institue of Chicago both of who have a fantastic collection of images and and well documented API’s. It was at this point my lovely two year old barged into my office and wanted to know what I was doing, and why was I looking at pictures that were (her opinion not mine) boring.

So I did what any self-respecting parent who wanted to carry on with their work would do, and asked, “Well Dotts, what would you find interesting?” Quick as a flash, I had my answer: Pokepines, after clarifying that she did indeed mean Pokémon, I guess I had to look for a different sort of API to comply with her request. Thankfully there is a fantastic Poké-community and the API is brilliantly supported at pokeapi.co. A quick peruse of the API documentation and I had approx 1100 Pokémon and their images just a GET request away.
Or so I thought…

The pokeapi is a superb resource and a GET request for Pokémon to the API returns the first 20 of 1100 or so. The first issue that I came across was that the resulting JSONified response looked like this for each Pokémon:

{name: "pikachu", url: "https://pokeapi.co/api/v2/pokemon/25/"}

Which (if you follow the link above!) is indeed the name of a pokemon and a URL to which can receive another JSON response for the individual Pokémon which has a lot more detail, in this instance, about our friend Pikachu. Taking this starting API was a lot like being given access to a fancy car, with one caveat, you need to make your own key to get the performance you want.

Some tinkering with game formats and board sizes later, I’d created some rules for my game, and crafted the code to fill out a game board with a set of eight pairs of Pokémon randomly selected from the first 151 Pokémon (which aficianado’s will remember fondly from Red, Blue and maybe Yellow if you liked #25 a lot).

let randomPokemonId = function(){
return Math.floor(Math.random() * 151)
}

Superb stuff!

Random (or is it?)

The “is it actually random?” phase

With my beautiful game board packed full of cards with different Pokémon on I did what any feature tester would do, and pressed f5 to refresh the game board to see if it was giving the same pattern of cards to match each time. It didn’t appear to be. The underlying gameDeck array looks a bit like this:

gameArray = [...randomPokemonArray, ...randomPokemonArray]

The gameArray when console.logged, was giving a list of eight pokemon and then a second one in identical positions. While the code was working as I expected, the gameboard displayed on screen was a lot different to the array.

I finished quite late on my testing so went to bed happy that my array was truly random. (narrator — it was not). With hindsight applied, I was accessing the array at peak US and EU times which led to different latencies on the GET requests for each card, which meant some rendered faster than others and gave the illusion of randomness. The following morning (a Saturday about 4am EST) this became apparent. My once random array was pairs of cards in almost identical places, not once, twice… ten times in a row. This must be one of them challenges I mentioned earlier.

To work around this issue, naive me thought this would be a simple process, use an Array.prototype.shuffle() function and the board I just created could be shuffled and dealt out as quickly and smoothly as a game of poker in Vegas. As all new to framework coders do, I searched MDN for the documentation.

As my good friend Gru (see pic) discovered — there is no native array.shuffle() command in JavaScript. Oh beans.

As I scratched my head and broadened my search from the MDN documentation to google search and stack overflow I came across the Fisher-Yates (or Knuth) method to shuffle an array.

The Fisher-Yates method is widely regarded as the best way to shuffle an array in JavaScript. Essentially, it works from the end of the array and swaps the last element with a random element in the proceeding part of the array e.g. if there array.length was 10 , the item at [9] would swap places with an element in positions [0] — [8], the shuffle utilses a while loop to count down the array, and s the element now in [9] had already been shuffled, it now starts from position [8], and follow the same pattern until [0] is reached this results in the contents of the array being shuffled.

Having done this and run the debugging code in my functions, I was confident that I had a shuffled array, see the logged arrays in the gist below which I took as confirmation:

If you look closely though, some Magmar remain in situ, Moltres has found another one to stand next to, which when put into the game board may result in a ‘predictable’ pattern for that game round.

The gameArray is random, it might not look it, but it is, and that is the beauty of the human brain. We will always seek to apply order to what we see through finding patterns. Even when you know the subject is truly random. However you can end up with instances like this(!):

A seemingly not random pokemon board with numerous repeats
A seemingly not random pokemon board with numerous repeats
It is random I promise!

Here is a link to my github repo for this project :- here!

I also made a feature demo video which is available:- here!

Feel free to get in touch about the build, I’d love to hear your thoughts.

Former tech banker, now aspiring software engineer. Feel free to get in touch.