AI Framework
Play against the computer. Random but legal moves. The AI takes its turn automatically.
Two-player games are fun, but sometimes you want to play solo. This unit adds an AI opponent — a computer player that takes Player 2’s turns automatically.
The AI starts simple: it picks a random empty cell. No strategy, no intelligence, just legal moves. But this framework is the foundation for smarter opponents in later units.
Run It
pasmonext --sna inkwar.asm inkwar.sna

The title screen now offers two options: “1 - TWO PLAYER” or “2 - VS COMPUTER”. Select vs Computer and watch the AI claim cells automatically after each of your moves.
Game Mode Selection
The title screen needs to distinguish between two modes:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
We add a game_mode variable and an ai_timer for the delay before AI moves. The delay makes the game feel more natural — instant AI moves would be jarring.
Reading the Mode Selection
The ZX Spectrum keyboard is read in half-rows. Keys 1-5 share row $F7:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The BIT instruction tests individual bits. Bit 0 is key 1, bit 1 is key 2. When pressed, the bit reads as 0 (active low).
AI Turn Handling
The game loop checks if it’s the AI’s turn:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Three conditions for AI to move:
- Game mode is VS_AI
- Current player is Player 2
- AI timer has expired
The timer creates a half-second pause before each AI move, giving the human time to see what’s happening.
Random Number Generation
The Z80 has a built-in source of randomness — the R register:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The R register increments with every instruction fetch. We mix it with a seed value using addition, rotation, and XOR to produce varied results. Not cryptographically secure, but fine for a game.
Finding an Empty Cell
The AI needs to find a valid move. We start at a random position and scan until we find an empty cell:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Starting at a random position adds variety — without it, the AI would always claim the first available cell. The wrap-around ensures we check every cell even if we start near the end.
Why Random AI First?
Random AI is the simplest possible opponent:
- Always makes legal moves
- Requires minimal code
- Easy to test and debug
- Provides a baseline to improve upon
In upcoming units, we’ll make the AI smarter by prioritising adjacent cells, defending against the human, and targeting strategic positions.
The Complete Code
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Try This: Faster AI
AI_DELAY equ 10 ; Shorter delay (~0.2 sec)
Try This: Instant AI
AI_DELAY equ 1 ; Nearly instant
Be warned — instant AI feels unnatural and can be disorienting.
What You’ve Learnt
- Game modes — Single variable controls two-player vs AI behaviour
- Keyboard row reading — Individual key detection with BIT instruction
- Random numbers — Using R register for pseudo-randomness
- AI framework — Turn detection, delay timer, move execution
What’s Next
In Unit 10, we’ll make the AI smarter by having it prioritise cells adjacent to its existing territory.