← All guides
Programming / JavaScript

JavaScript: write a tiny score rule you can test

Use variables, a function, and a duplicate guard to collect three seeds without awarding the same seed twice.

Beginner About 20 min practiceFree guide

First Play Studios · Edition 1 · Updated November 14, 2026

WHAT YOU’LL MAKE OR LEARN

A small score function returns predictable results for valid, duplicate, and invalid collection requests.

Before you start
  • A JavaScript console or local practice file
  • No existing game code is required
In this guide
01

Name the state before writing the function

State is the information your game remembers between actions. This miniature game remembers which of three seeds have been collected. A function handles a request and returns a result the caller can inspect. You can test those rules before adding artwork or buttons.

JavaScript uses let for bindings you may reassign and const for bindings you will not reassign. A const array can still have its contents changed. That distinction matters: keeping the same array binding does not make the contents immutable.

02

Keep the change in one place

Run this self-contained example in a fresh JavaScript session. Each seed has an index from zero to two. The function rejects an invalid index or an already collected seed before changing the array. It derives the score from the array, so there is no separate score variable to drift out of sync.

const seeds = [false, false, false];

function collectSeed(index) {
  if (!Number.isInteger(index) || index < 0 || index >= seeds.length) {
    return { accepted: false, reason: "invalid seed" };
  }
  if (seeds[index]) {
    return { accepted: false, reason: "already collected" };
  }
  seeds[index] = true;
  const score = seeds.filter(Boolean).length;
  return { accepted: true, score, won: score === seeds.length };
}

console.log(collectSeed(1)); // score 1, won false
console.log(collectSeed(1)); // rejected: duplicate
console.log(collectSeed(0)); // score 2, won false
console.log(collectSeed(2)); // score 3, won true
console.log(collectSeed(99)); // rejected: invalid
03

Separate the rule from its presentation

The result object reports what happened. A future button handler could use an accepted result to update text or play a sound. The rule itself does not need to know where that label is or which audio file you chose.

Before adding more features, try to break the assumptions. What happens with -1, 1.5, or the text '1'? The Number.isInteger guard rejects them. This is a design choice: a different system might convert input deliberately, but accidental conversion makes debugging harder. Reloading the practice file starts a new game; this example does not save progress.

TRY IT YOURSELF

Predict five results before running them

  1. Write down the expected output for each of the five example calls.
  2. Run the code in a fresh session and compare every result with your prediction.
  3. Start fresh, collect in another order, and try one duplicate between successful calls.
  4. Add tests for -1, 1.5, and '1'; confirm that none changes a seed.
  5. Explain how a display button could use the return value without becoming the owner of the score.

Check your result.

  • Exactly three different valid indices can be collected.
  • A duplicate or invalid request does not change the state.
  • The winning result appears only after all three distinct seeds are collected.
Guest progress stays in this browser. This records your own practice; it does not automatically test your project.

Common mistakes to watch for.

  • Array indices begin at zero in this example.
  • Rerunning a const declaration in the same console scope can cause a redeclaration error; use a fresh session or file run.
  • A printed correct result is not proof that a later UI or save system is correct.
YOUR PROJECT. YOUR OWN CHATGPT.

Keep the conversation useful.

I’m learning JavaScript with a three-seed collection rule. Walk through my function one request at a time. Ask me to predict state and output before explaining them. Help me add one meaningful edge-case test, and keep DOM updates and persistent saving out of this lesson.

Sources & version notes.

Modern JavaScript (ES2015 or later). The rule example passed 17 local Node result assertions; this does not validate a browser interface or persistent saving.

Further reading from the original documentation:

Practice times are estimates. Software-specific exercises are documentation-based unless their version note says otherwise.
MAKE IT A CONVERSATION

A question or a small win?

Tell the workshop what happened when you tried this guide. Ask for a useful next step, or share something you got working.

See discussions about this guide We’ll include the guide link in your draft. Sign in to post, then add your own question or progress before sharing.
KEEP GOING

One idea leads to another.

Make game rules you can explain and testTurn a big idea into one playable roomFind a bug without changing everythingExplore a learning path