loading...
Cover image for Learning Algorithms Through Games

Learning Algorithms Through Games

babak profile image Babak ・2 min read

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 by:

babak profile

Babak

@babak

Twitter @babakness https://twitter.com/babakness

Discussion

markdown guide