Claiming Cells
Press Space to claim territory. Cells turn your colour. Take turns with a friend.
The board is ready. Now it’s time to claim it.
This unit adds the core gameplay: press Space to claim the cell under your cursor. The cell turns your colour. Then it’s the other player’s turn. Two players, one keyboard, taking turns until the board is full.
Run It
Assemble and run:
pasmonext --tapbas inkwar.asm inkwar.tap

The board looks the same as before - but now press Space.
The cell under your cursor turns red (bright red, actually). A short rising tone plays. Move the cursor and press Space again - now it turns blue. You’re Player 2.
Keep pressing Space. Red, blue, red, blue. The board fills up with colour.
Hand the keyboard to a friend. Now you’re playing Ink War.
Try This: Change Player Colours
Edit P1_ATTR and P2_ATTR to use different colours:
P1_ATTR equ %01100000 ; Yellow paper + BRIGHT
P2_ATTR equ %01011000 ; Cyan paper + BRIGHT
Remember the colour values:
- 0 = black, 1 = blue, 2 = red, 3 = magenta
- 4 = green, 5 = cyan, 6 = yellow, 7 = white
The PAPER bits are 5-3, so shift your colour left by 3. Yellow (6) becomes 110 in bits 5-3, plus BRIGHT (bit 6) = %01110000… wait, that’s white. Let me recalculate.
Actually: %01100000 = BRIGHT + paper 4 (green). For yellow: %01110000 = BRIGHT + paper 6. Try different combinations and see what looks good.
Try This: Change the Sound
Make the claim sound descending instead of ascending:
sound_claim:
ld hl, 100 ; Starting pitch (higher)
ld b, 20
.loop:
; ... same tone generation ...
; Decrease pitch (add to delay)
ld de, 20
add hl, de ; Changed from sbc to add
djnz .loop
ret
Or make it longer, shorter, different starting pitch. The beeper is primitive but expressive.
What You’ve Learnt
- Game state arrays -
defs 64, 0reserves 64 bytes initialised to zero - Turn-based logic - Track current player, switch after valid moves
- Input validation - Check cell state before allowing claims
- XOR toggling -
xor 3switches between 1 and 2 - Beeper sound - Toggle bit 4 of port $FE at varying speeds for pitch
What’s Next
In Unit 3, you’ll customise the game’s appearance - different colours, different cursor style, making it your own. You’ll learn exactly how attribute bytes work by changing them.
What Changed
We added three things:
- Board state - An array tracking who owns each cell
- Claiming - Press Space to take ownership
- Turn switching - Players alternate automatically
Player Colours
Each player gets a distinct colour:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Player 1 is red (%01010000), Player 2 is blue (%01001000). Both use BRIGHT for vivid colours that stand out from the white empty cells.
The cursor attributes (P1_CURSOR, P2_CURSOR) combine the player colour with FLASH, so when you move onto your own cell, it still flashes.
Game State
We need to remember who owns each cell:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The board_state array has 64 bytes - one per cell. Each byte is:
0= empty1= Player 1 (red)2= Player 2 (blue)
The current_player variable tracks whose turn it is, starting with Player 1.
Initialisation
At startup, we clear the board and set Player 1 to go first:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
The djnz loop writes zero to all 64 cells. Simple and fast.
Trying to Claim
When you press Space, we check if the claim is valid:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
If the cell isn’t empty (or a / ret nz), we ignore the press. No stealing opponent cells - not yet, anyway.
The player switch uses a clever trick: xor 3 toggles between 1 and 2. Binary 01 XOR 11 = 10, and 10 XOR 11 = 01.
The Claim Itself
This code sample could not be loaded. The file may be missing or the path may be incorrect.
Two things happen:
- We store the player number in
board_state - We change the attribute colour on screen
The array index is row * 8 + col. We calculate it using shifts: add a, a three times multiplies by 8.
Sound Feedback
A claim should feel satisfying:
This code sample could not be loaded. The file may be missing or the path may be incorrect.
This generates a rising tone by decreasing the delay between speaker toggles. The Spectrum’s beeper is just a single bit - toggle it fast for high pitch, slow for low pitch.
The speaker is bit 4 of port $FE (the same port as border colour). We alternate between $10 (speaker on) and $00 (speaker off).
The Complete Code
This code sample could not be loaded. The file may be missing or the path may be incorrect.