needmoreeasy EN 한국어
Learn

75 — Game: a simple opponent

★★★★★ (5/5)game & strategy
Prerequisites
26 — Adventure, 10 — Random
You will end up with
a take-away game where the computer follows a winning strategy

A game opponent needs a rule, not just luck. In Nim, players take 1 to 3 stones from a pile; the one forced to take the last stone loses. The computer can play a strategy that keeps a winning position — and a fair mode that just rolls the dice.

Steps

  1. Start a pile and explain the rule:

    pile = 12
    show f"The pile has {pile} stones. Take 1, 2, or 3."
    
    run it →
  2. A move removes stones: pile = pile - taken. The game ends when the pile reaches 0 — the player who took the last stone loses:

    while pile > 0:
        ask take, "How many (1-3)? "
        taken = int(take)
        if taken < 1 or taken > 3:
            show "Take 1, 2, or 3."
            continue
        pile = pile - taken
    
    run it →

    continue skips the computer's turn and asks again for a valid number.

  3. The computer's strategy: after your move, the pile is n. If the computer leaves a pile of n % 4 stones... no — taking n % 4 stones (when it is not 0) leaves a multiple of 4, a losing position for you. When n % 4 is 0, any move gives you a winning position, so the computer takes a random 1-3 in that fair mode:

    move = pile % 4
    if move == 0:
        move = random_number(1, 3)
    pile = pile - move
    
    run it →
  4. The full game. Save nim.nme:

    # nim.nme — take 1-3 stones; the last stone loses.
    # Run: nme r nim
    
    use random latest
    
    pile = 12
    show f"The pile has {pile} stones. Take 1, 2, or 3."
    
    while pile > 0:
        ask take, "Your turn — how many (1-3)? "
        taken = int(take)
        if taken < 1 or taken > 3:
            show "Take 1, 2, or 3."
            continue
        pile = pile - taken
        if pile == 0:
            show "You took the last stone. You lose!"
            break
        move = pile % 4
        if move == 0:
            move = random_number(1, 3)
        pile = pile - move
        show f"Computer takes {move}. Pile is now {pile}."
        if pile == 0:
            show "The computer took the last stone. You win!"
    
    run it →
  5. Run it with the player taking 2, then 2, then 1:

    printf '2\n2\n1\n' | nme r nim
    
    The pile has 12 stones. Take 1, 2, or 3.
    Your turn — how many (1-3)? Computer takes 2. Pile is now 8.
    Your turn — how many (1-3)? Computer takes 2. Pile is now 4.
    Your turn — how many (1-3)? Computer takes 3. Pile is now 0.
    The computer took the last stone. You win!
    

    pile % 4 leaves a multiple of 4 after the computer's move, which is exactly why the strategy works.

Try it yourself

Change the starting pile to 15 and play again: the strategy still wins unless the random fair mode helps you. Add a best counter of how many games you win.

What you learned

  • % (modulo) tells you the remainder — the key to the Nim strategy.
  • continue skips to the next loop turn for an invalid move.
  • A strategy is just a rule computed from the game state.
  • A random fallback keeps the opponent honest when the strategy can't win.

This page on GitHub