Game End Detection
Board full? Someone wins. Compare scores, declare the victor, restart on keypress.
The game has been running forever. Players can claim cells until… when? There’s no ending.
This unit adds proper game end detection. When all 64 cells are claimed, the game determines the winner, displays a victory message, celebrates with a flashing border, then waits for a keypress to restart. A complete game loop.
Run It
pasmonext --sna inkwar.asm inkwar.sna

Play a full game - claim all 64 cells between two players. When the last cell is taken, you’ll see “P1 WINS!”, “P2 WINS!”, or “DRAW!” appear. The border flashes in the winner’s colour. Press any key to play again.
Detecting Game Over
The simplest check: is the board full?
This code sample could not be loaded. The file may be missing or the path may be incorrect.
We already have p1_count and p2_count from the score display. If their sum equals 64, every cell is claimed. The game is over.
This approach reuses existing data. No need for a separate move counter - we derive the answer from state we already track.
Determining the Winner
Three possible outcomes: P1 wins, P2 wins, or draw:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The Z80’s CP instruction compares by subtraction. After cp b:
- Carry set means A < B (p2_count < p1_count → P1 wins)
- Zero set means A = B (draw)
- Neither means A > B (P2 wins)
Each outcome displays a different message in the appropriate colour.
Printing Messages
We need to print null-terminated strings. The print_message routine:
print_message:
; HL = string, B = row, C = column, E = attribute
.pm_loop:
ld a, (hl) ; Get character
or a ; Check for null terminator
jr z, .pm_done
call print_char
inc hl
inc c ; Next column
jr .pm_loop
.pm_done:
; Set attributes for the message area
; ...
The strings are stored in memory:
msg_p1_wins: defb "P1 WINS!", 0
msg_p2_wins: defb "P2 WINS!", 0
msg_draw: defb "DRAW!", 0
The trailing 0 marks the end of each string.
Victory Celebration
Winners deserve fanfare:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The border flashes in the winner’s colour - red for P1, blue for P2, white for a draw. Five quick flashes with black gaps between them. Simple but effective.
Waiting for Input
After showing results, wait for any key:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Two phases:
- Wait for release - If a key is already held from claiming the last cell, wait until it’s released
- Wait for press - Then wait for a new keypress
The CPL instruction inverts A. Keyboard bits are active-low (0 = pressed), so we invert to make pressed keys show as 1s. The HALT saves power while waiting.
Restarting the Game
After wait_for_key, we jump back to start:
jp start ; Restart game
This reinitialises everything: clears the board, resets scores, redraws the screen. A fresh game ready to play.
The Game Loop is Complete
The flow is now:
- Start → Initialise and draw
- Play → Input, validate, claim, update, check end
- End → Show results, celebrate, wait for key
- Restart → Jump to Start
Every game has this structure. What you’ve built is the skeleton that every game builds upon.
The Complete Code
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Try This: Different Victory Messages
msg_p1_wins: defb "RED WINS!", 0
msg_p2_wins: defb "BLUE WINS!", 0
msg_draw: defb "TIE GAME!", 0
Try This: Longer Celebration
.vc_flash:
ld b, 10 ; 10 flashes instead of 5
What You’ve Learnt
- End condition detection - Check when game state reaches a terminal condition
- Score comparison - Use CP and flags to determine greater/less/equal
- Null-terminated strings - Standard way to store variable-length text
- Key debouncing - Wait for release before waiting for press
- Game loop structure - Start → Play → End → Restart
What’s Next
In Unit 7, we’ll add a title screen. The game will start with “INK WAR” and “PRESS ANY KEY”, making it feel like a proper product rather than a demo.