Learning Algorithms Through Games
Babak
Posted on January 7, 2020
I'm studying algorithms through games. I recently re-created one of those number slider games. As a kid, I remember getting these free puzzles from the flight crew.
See the code here:
https://github.com/babakness/number-slider
Algorithm
Making this game presents a number of neat challenges. The key algorithm to making this work is, given a matrix of numbers with size N*M, and empty piece, E; move each piece from a select piece P0 toward E.
Suppose we number each piece adjacent to P0 in an increasing fashion, ie P1, P2, ...Pn until we reach the empty square E. After the move, Pn will occupy the position of E, and each piece before it will move likewise until P0 is in the position of P1.
Finally, after P0 moves, the piece E is placed in its prior position.
Game Design
This game can be thought of as breaking down following the MVC structure. The main algorithms can be thought of as the Model, and the code manipulates the DOM as the Controller. Finally, the html page and the styles involved can be considered the View.
I use these names loosely, the essential idea is to break up our code into just enough abstractions to organize our code; but not so many as to create confusion.
Vanilla JS
No frameworks! The game uses the DOM API directly. It can be a good review of how to use regular DOM and CSS animations to achieve game play animations.
Useful functions
Some pretty nice functions came out of this.
Here is a function that throttles calls to an async function--only allowing the function to be called again after it has completed it task.
/**
* HOF to prevent calls to an async function before it resolves
* @param fn async function to throttle until resolve
*/
function throttleAsyncCalls<A,B>(
fn: (...args: A[]) => Promise<B>
) {
let wait = false
return async function( ...args: A[] ) {
if( wait === true ) {
return
}
wait = true
let result = await fn( ...args )
wait = false
return result
}
}
How about this one, it dispatches a mouse click when you click "enter" on an element. This is useful for a11y.
/**
* When enter is pressed on an element, dispatch a click event on that element
* @param event Keyboard Event
*/
function routeEnterToClick( event: KeyboardEvent ) {
let mouseClick = new MouseEvent( 'click', { bubbles: true } )
if( event.key.toLowerCase() === 'enter' ) {
event.target.dispatchEvent( mouseClick )
}
}
And much more 😁
Play around!
Have fun!
https://number-slider.algogames.dev
Follow me on Twitter at Babakness.
Posted on January 7, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.