Building a rock paper scissors game with webform

Tuesday, December 3, 2024
by Kevin Paxman

This post comes out of wondering how it might be possible to implement game logic in a webform, and discovering that there's a token that will generate a random number from 0 to 2,147,483,647 (with no configurable options to limit the range).

When dealing with a random number of that size, the obvious choice is a 3 value game.

Building out the form

We start with a select list for the user, so they can choose to throw rock, paper, or scissors.

Next, we add a hidden field for the random number, with the random number token ([random:number]) as the default value.

We add three basic HTML fields for each throw the system could make - one for rock, one for paper, and one for scissors.

Now, we need nine more basic HTML fields, for each possible combination of throws, and whether that results in a win, a loss, or a tie.

Finally, we customize the submit button to hide it, since the game will take place entirely on one page.

Adding game logic

We'll add a condition to the user's throw field to disable it if it's filled, since we don't want them to be able to change their mind once they see the system's throw.

Next, we add conditional logic to each of the three system throw fields - all of them need to only be visible once the user's throw is filled in, and we'll add an additional visibility condition based on the value of the random number field.

  • The rock throw will be visible if the number is less than 715827882 (the first third of the random number range).
  • Paper will be visible if the number is between 715827882 and 1431655764 (the middle third)
  • Scissors will be visible if the number is greater than 1431655764 (the final third)

Now, we add similar logic to each of the results fields, making them visible based on what the user threw and what the system threw (based on the random number) and whether that should be a win, a loss, or a tie. Remember that paper beats rock, rock beats scissors, and scissors beats paper, and matching throws are a tie.

It would have been nice to have generic "win", "lose", and "tie" fields, but conditionals don’t support this type of complex options, so we must have separate fields for every possible combination.

This is probably a good point to test your form, trying each throw and refreshing the page until you've seen every possible matchup, to make sure your logic is correct.

Adding a "play again" link

Because most browsers will preserve the form field values when you refresh the page, we'll add another basic HTML field to the page, with the text "play again" linked to the token [current-page:url] (so the link will work regardless of where we place the form). We'll make it visible once the user's throw field is filled.

Our completed game is below.

Play rock paper scissors!

CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

The WCMS throws rock!

The WCMS throws paper!

The WCMS throws scissors!

You win with rock!

The WCMS wins against your rock!

It's a rock vs. rock tie!

You win with paper!

The WCMS wins against your paper!

It's a paper vs. paper tie!

You win with scissors!

The WCMS wins against your scissors!

It's a scissors vs. scissors tie!

What else could you use this for?

You could make a form feel more "conversational" by randomizing some of the responses... you could ask a random different question to each visitor... you even could build out your own game! You could "weight" options by giving some a larger range of numbers and some a smaller range. There's literally over 2 billion things you could do!