Skip to content
Game 5 Unit 13 of 128 1 hr learning time

AI Difficulty Levels

Choose your challenge: Easy (random), Medium (adjacent), or Hard (full strategy).

10% of Ink War

We’ve built three distinct AI behaviours across Units 9-12: random moves, adjacent priority, and full strategy with defense and position bonuses. But players can only face the hardest version. This unit lets them choose their challenge.

The title screen now offers four options. Two-player mode remains, but vs Computer splits into Easy, Medium, and Hard — each using a different AI algorithm.

Run It

pasmonext --sna inkwar.asm inkwar.sna

Unit 13 Title Screen

The new title screen shows all four options. Press 1-4 to select your game mode.

Unit 13 Gameplay

The Three Difficulties

Each difficulty level uses a different cell selection algorithm:

LevelAlgorithmBehaviour
EasyRandomPicks any empty cell at random. No strategy.
MediumAdjacent priorityExpands from existing territory. No defense.
HardFull strategyOffense + defense + position bonuses.

Easy is beatable by anyone. Medium requires some thought. Hard plays optimally within its evaluation limits.

Difficulty Constants

We define the three levels as constants:

The title screen repositions to accommodate four menu options instead of two.

Title Screen Selection

The keyboard reading now checks four keys instead of two:

Keys 1-4 map to bits 0-3 of keyboard row $F7. Each AI option sets both game_mode (to GM_VS_AI) and ai_difficulty (to the appropriate level).

AI Dispatch

The core change is in ai_make_move, which now dispatches based on difficulty:

Three paths:

  • Easy: Calls find_random_empty_cell directly
  • Medium: Calls new find_adjacent_only (AI neighbours only)
  • Hard: Calls find_best_adjacent_cell (full strategy)

Medium Difficulty Algorithm

Medium difficulty uses a simplified version of the scoring algorithm — only AI adjacency, no defense or position bonus:

find_adjacent_only:
            ; ... scan all cells ...
            ; For each empty cell:
            call    count_adjacent_ai   ; Only this - no defense/position
            ; ... keep best score ...

This creates an AI that expands its territory but doesn’t actively block you or prioritise strategic positions.

Why Three Distinct Algorithms?

We could have used probability-based mixing (e.g., Easy = 70% random, 30% strategic). But distinct algorithms are:

  • Simpler to implement — No random number checks per move
  • More predictable — Each level has consistent behaviour
  • Easier to debug — Clear separation of concerns
  • Better learning progression — Players see distinct AI personalities

The algorithms we built in Units 9-12 map naturally to difficulty levels.

The Complete Code

Try This: Add More Levels

You could add intermediate difficulties:

AI_VERY_EASY equ    0   ; Random
AI_EASY      equ    1   ; Adjacent only
AI_MEDIUM    equ    2   ; Adjacent + defense (no position)
AI_HARD      equ    3   ; Full strategy
AI_EXPERT    equ    4   ; Full strategy + look-ahead (future unit)

More keys are available on the same keyboard row (key 5 = bit 4).

Try This: Display Difficulty

Show the current difficulty during gameplay:

; After drawing UI, show difficulty level
ld      a, (ai_difficulty)
; ... display "EASY", "MEDIUM", or "HARD" ...

This reminds players which AI they’re facing.

What You’ve Learnt

  • Menu expansion — Adding options to existing UI
  • Dispatch patterns — Branching based on configuration
  • Code reuse — Leveraging existing algorithms for difficulty
  • Player choice — Giving control over game challenge

What’s Next

In Unit 14, we’ll add sound effects — distinct sounds for claims, errors, and victory to give the game audio feedback.

What Changed

Unit 12 → Unit 13