← thecodex.expert · The Codex Family of Knowledge
Tier 0 · Absolute Beginner · Go Project

Number Guessing Game

Your very first program with a memory and a decision: the computer picks a secret number, and you guess until you get it. You will learn how a program asks a question, checks an answer, and repeats.

🧠 Teaches how to think spoonfed, every age Last verified:

1 The Problem

We want a tiny game: the computer thinks of a number between 1 and 100, and the player keeps guessing. After each guess the computer says “too high” or “too low” until the player gets it right. Simple — but it teaches the three things every program does: ask, decide, and repeat.

Where this shows up in real life: every time an app checks your password, validates a form, or keeps asking until you give a valid answer, it is doing exactly this — take input, compare it to something, and loop until the condition is met. Learn it here in 15 lines, and you have learned the heartbeat of almost every program.

2 How to Think About It

Before writing any code, picture the game as a loop with a decision inside it. You do not need to know Go yet — you just need to know the shape of what happens:

The plan — in plain English
1. Pick a secret number once, at the start. → 2. Ask the player to guess. → 3. Compare the guess to the secret: lower, higher, or equal? → 4. If not equal, go back to step 2. If equal, celebrate and stop. That is the whole program. Everything below is just saying this in Go.

Too low

Too high

Correct!

Computer picks a secret number 1-100

Ask the player to guess

Is the guess right?

Say 'too low'

Say 'too high'

Show how many guesses it took

Game over

3 The Build — explained part by part

Here is the complete game. Read each part’s plain-English note below it — you should be able to understand the whole program from the notes alone, without knowing any Go in advance.

Goguessing_game.go
package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
)

// playGame is a testable version of the game: give it the secret number and
// a list of guesses, and it returns how many tries it took (0 if the guesses
// never find it).
func playGame(secret int, guesses []int) int {
	for i, guess := range guesses {
		if guess == secret {
			return i + 1
		}
	}
	return 0 // never guessed it
}

func main() {
	// The computer secretly picks a whole number from 1 to 100.
	secretNumber := rand.Intn(100) + 1

	// We count how many guesses the player takes.
	guessesTaken := 0

	reader := bufio.NewReader(os.Stdin)
	fmt.Println("I am thinking of a number between 1 and 100.")

	// Keep asking until the player guesses right.
	for {
		fmt.Print("Your guess: ")
		line, err := reader.ReadString('\n')
		if err != nil {
			return // input closed (e.g. end of file) — stop cleanly
		}
		guess, err := strconv.Atoi(strings.TrimSpace(line))
		if err != nil {
			fmt.Println("Please type a whole number.")
			continue
		}
		guessesTaken++

		if guess < secretNumber {
			fmt.Println("Too low. Try a bigger number.")
		} else if guess > secretNumber {
			fmt.Println("Too high. Try a smaller number.")
		} else {
			fmt.Printf("Correct! You got it in %d guesses.\n", guessesTaken)
			break
		}
	}
}
⚠ No in-browser playground here
Go compiles to a real binary, so unlike the Python version of this project there is no editor above you can run in the browser. Copy the code below and run it on your own machine — it takes seconds once Go is installed.
What each part does — in plain words
rand.Intn(100) + 1 — pick one random whole number from 1 to 100. Intn(100) gives 0–99, so we add 1 to shift the range to 1–100. Modern Go (1.20+) seeds this automatically, so you do not need to seed it by hand.

bufio.NewReader(os.Stdin) — Go reads input in a more explicit way than Python. We wrap standard input in a buffered reader so we can read one full line at a time.

for { ... } — Go has only one loop keyword, for. Written with no condition, it means “repeat forever” — the same job Python’s while True: does.

reader.ReadString('\n') — read everything the player typed, up to and including the Enter key.

strconv.Atoi(strings.TrimSpace(line)) — the input arrives as text with a trailing newline attached. TrimSpace removes it, and Atoi (“ASCII to integer”) turns the text into a number — and returns an error if it cannot, which we check immediately.

if / else if / else — the decision. Go spells the middle case else if (two words, no elif) but the logic is identical to Python’s.

break — exits the for loop the moment the guess is correct, exactly like Python.
Common mistakes — and how to avoid them
✗ Forgetting strings.TrimSpace before strconv.Atoi — the leftover \n from ReadString makes every conversion fail.
✓ Always trim the line before converting it to a number.
✗ Ignoring the error that strconv.Atoi returns — a non-number crashes the program with a panic-free but useless zero value.
✓ Check err != nil and print a friendly message instead, like the code above does.
✗ Calling rand.Intn(100) + 1 inside the loop — it picks a new secret every guess, so you can never win.
✓ Pick the secret once, before the loop starts.
✗ Writing if guess = secretNumber by mistake instead of ==.
✓ Go will not even compile this one — unlike Python, Go refuses to let you use = where a comparison is expected, which catches the bug for you at build time.

4 Test & Prove Each Part

How do we know the game works without playing it a hundred times by hand? We write small tests — each one checks one rule and proves it. Go’s built-in testing package is the standard way to do this, no extra install required.

Guessing the secret on the first try counts as 1 try
When the answer is the third guess, it correctly returns 3
If the player never guesses it, we get a clean result — not a crash
The secret number is always between 1 and 100, every single time
Goguessing_game_test.go
package main

import (
	"math/rand"
	"testing"
)

func TestCorrectFirstTry(t *testing.T) {
	if got := playGame(42, []int{42}); got != 1 {
		t.Errorf("playGame(42, [42]) = %d; want 1", got)
	}
}

func TestTakesThreeTries(t *testing.T) {
	if got := playGame(50, []int{10, 90, 50}); got != 3 {
		t.Errorf("playGame(50, [10 90 50]) = %d; want 3", got)
	}
}

func TestNeverGuesses(t *testing.T) {
	if got := playGame(7, []int{1, 2, 3}); got != 0 {
		t.Errorf("playGame(7, [1 2 3]) = %d; want 0 (never found)", got)
	}
}

func TestSecretIsInRange(t *testing.T) {
	for i := 0; i < 1000; i++ {
		n := rand.Intn(100) + 1
		if n < 1 || n > 100 {
			t.Fatalf("secret %d out of range 1-100", n)
		}
	}
}

Run them with go test -v ./.... Each test sets up a tiny situation and checks the result with a plain if and t.Errorf — Go’s tests are just functions named TestXxx that take a *testing.T. Green means the rule holds; a failing test prints exactly what it expected and what it got.

5 The Interface

Even a tiny program has an interface — the way a person interacts with it. Here is its contract, documented plainly, the same way a professional would describe any tool.

INPUTYour guessa whole number 1–100, typed by the player
What it expects
A number like 42, typed and then Enter pressed.
OUTPUTFeedbackone of three replies
What it returns
"Too low. Try a bigger number."
"Too high. Try a smaller number."
"Correct! You got it in N guesses."

6 Run It & Automate It

Save the code as guessing_game.go and run it with go run guessing_game.go — Go compiles and executes in one step, no separate build needed while you are experimenting.

Run it locally
go run guessing_game.go
Then type a number, press Enter, and follow the “too high / too low” hints until you win.

A CI tool like Jenkins runs go test automatically whenever the code changes — every line below has a plain explanation.

What you should see when it works
Terminala real run
I am thinking of a number between 1 and 100.
Your guess: 50
Too high. Try a smaller number.
Your guess: 25
Too low. Try a bigger number.
Your guess: 37
Too high. Try a smaller number.
Your guess: 31
Correct! You got it in 4 guesses.
If it breaks — how to fix it
🚨 The program prints “Please type a whole number.” even for digits.
Check for stray spaces, or that you pressed Enter (not just typed and left the cursor there) — ReadString('\n') waits for the newline.
🚨 The game never ends, even when I guess right.
Your break is missing or in the wrong branch. It must run in the else case, when the guess equals the secret.
🚨 go: command not found
Go is not installed, or not on your PATH. Install it from go.dev/dl and reopen your terminal.
GroovyJenkinsfile
// Jenkinsfile — runs the tests automatically every time the code changes.
pipeline {
    agent any                                  // run on any available machine

    stages {
        stage('Get the code') {
            steps { checkout scm }             // download the latest code
        }
        stage('Set up Go') {
            steps {
                sh 'go version'                                 // confirm Go is installed
                sh 'test -f go.mod || go mod init guessing_game'  // create a module if none exists
            }
        }
        stage('Run the tests') {
            steps {
                sh 'go vet ./...'                    // catch obvious mistakes before running
                sh 'go test -v ./...'                // run every test, show each result
            }
        }
    }

    post {
        success { echo 'All tests passed.' }
        failure { echo 'A test failed — look above.' }
    }
}
🎯 Try this next — make it yours

You have the working game. Now make it yours — each of these adds one new idea:

  1. Limit the guesses. Give the player only 7 tries, then reveal the answer. (Teaches: counting toward a limit.)
  2. Let them play again. After winning, ask “Play again? (y/n)” and restart if yes. (Teaches: an outer loop.)
  3. Make invalid input impossible to miss. Print the valid range again whenever Atoi fails. (Teaches: friendlier error handling.)
  4. Make the computer guess your number. Flip the roles — the computer guesses and you say higher/lower. (Teaches: binary search thinking.)
What you learned
You just learned the three pillars every program is built on: input (reading a line with bufio), decisions (if / else if / else), and loops (for + break). You also met Go’s error-checking style — instead of exceptions, functions like Atoi hand back an error value you check yourself — and how go test proves your code works. Related reference: Control Flow, Error Handling & the Standard Library.