Kyle Shevlin

Software Engineer
January 28, 2022
0 strokes bestowed

The Simulation Pattern

edit

Disclaimer: If this pattern has an established name, let me know. I'll update the article to reflect that.

In December, I participated in Advent of Code. It was mostly fun, but I did have some extremely difficult days. If you follow me on Twitter, you know of my travails with day 19. Oof.

That said, there was a common pattern I used to solve several of the puzzles that I want to share with you. I call it the "simulation pattern" and if I hadn't tried to learn the tiniest amount of game dev a few years back, I may have never learned it. Thus, I want to pass it on to you in the hopes you find it useful.

What is a simulation?

A "simulation", in my own words, is where we create some conditions and store some state, and then add a tick method to advance that state to the next discrete increment. Conway's Game of Life is an excellent example of a simulation and I encourage you to take this pattern and try to build Conway's Game of Life with it when you're done reading this post.

The pieces of the pattern

In its most basic form, a simulation is a closure which exposes a tick method to advance to the next state. Using a factory function, it looks like this:

function createSimulation(initialState) {
  let state = initialState

  return {
    tick() {
      // Add functionality to update state
    },
    getState() {
      return state
    },
  }
}

const sim = createSimulation()
sim.tick()
sim.getState()

We create a function that holds our state in closure. We add functionality in our exposed tick method to advance the state, and we create a way to access the current state with getState. All simulations are some variation of this pattern.

Let's create a simple example to demonstrate this. All of us have to deal with money in some capacity, so a loan payoff calculator can be a useful tool to have. We can create a simulation that takes in a principal, an interestRate, and expose a tick method that receives a payment to determine how many payments are necessary to pay off a loan.

First, let's create our factory function:

function createLoanPayoffSimulation(principal, interestRate) {
  let total = principal

  return {
    tick(payment) {
      const interest = total * interestRate

      if (payment <= interest) {
        throw new Error('Impossible to pay off loan. Increase payment amount.')
      }

      const diff = interest - payment
      total += diff

      return this
    },
    getTotal() {
      return total
    },
  }
}

// Dividing by 12 gives us a monthly interest rate
const sim = createLoanPayoffSimulation(10000, 0.05 / 12)

Now that we have our simulation, we can create a function that uses a simulation to determine how many payments are needed to payoff the loan.

function getTotalPayments(payoffSimulation, payment) {
  let payments = 0
  let paid = false

  while (!paid) {
    payoffSimulation.tick(payment)
    payments++

    const total = payoffSimulation.getTotal()
    paid = total <= 0
  }

  return payments
}

console.log(getTotalPayments(sim, 500)) // 21

We can pass different simulations with different conditions into getTotalPayments to solve other loan payoff scenarios.

Now that you've seen the basics, give it a try on some other problems. Or try it on an Advent of Code problem, like this one.

You can also use generator functions to create a similar effect, just with next as the method instead of tick. The difference being that you yield the next state with each run of the function. I make a loan payment calculator in that post as well, so you can hopefully compare the two.


Finished reading?

Here are a few options for what to do next.

Like
Liked the post? Click the beard up to 50 times to show it
Share
Sharing this post on Twitter & elsewhere is a great way to help me out
Support
Was this post valuable to you? Make a donation to show it
Make a Donation
Kofi logo

Related Posts:
What is a Closure?Generator Functions
Tags
JavaScriptComputer Science

Kyle Shevlin's face, which is mostly a beard with eyes
Kyle Shevlin is a software engineer who specializes in JavaScript, React and front end web development.

Let's talk some more about JavaScript, React, and software engineering.

I write a newsletter to share my thoughts and the projects I'm working on. I would love for you to join the conversation. You can unsubscribe at any time.

Just Enough Functional Programming Logo
Just Enough Functional Programming

Check out my courses!

Liked the post? You might like my courses, too. Click the button to view this course or go to Courses for more information.
I would like give thanks to those who have contributed fixes and updates to this blog. If you see something that needs some love, you can join them. This blog is open sourced at https://github.com/kyleshevlin/blog
alexloudenjacobwsmithbryndymentJacobMGEvanseclectic-codingjhsukgcreativeerikvorhesHaroenvmarktnoonandependabotmarcuslyonsbrentmclarkfederico-fiorinimedayzDoNormalFanchGadjonoahmateenbrandonpittman
©2022 Kyle Shevlin. All Rights Reserved.