Paint and puzzles
Paint
#A bot starts with the paint its mode gives and holds at most 65,535. Each trail tile costs 1 paint, and each solved puzzle pays 4, up to that limit.
Boards
#Puzzles are Lights Out boards with 2 or 3 colors. Each cell holds a value from 0 to num_colors - 1. Pressing a cell by an amount adds that amount, modulo num_colors, to the cell and to its up, down, left and right neighbors. A solution gives one press amount per cell that turns every cell to 0.
For example, on a 3-color board, pressing the middle cell by 2 changes these cells:
Before Added After
0 0 0 0 2 0 0 2 0
0 1 0 2 2 2 2 0 2
0 0 0 0 2 0 0 2 0
The middle cell becomes (1 + 2) mod 3 = 0.
| Colors | Board sizes (num_rows by num_cols) |
|---|---|
| 2 | 12 by 4, 15 by 4, 16 by 4, 6 by 5, 13 by 5, 5 by 6 |
| 3 | 7 by 3, 12 by 3, 13 by 3, 11 by 5 |
Every board has a solution.
Requesting a puzzle
#Write the address of a 268-byte, word-aligned buffer to REQUEST_PUZZLE. An accepted request sets MMIO_STATUS to OK and adds 1 to AVAIL_PUZZLES. A bot can request 2,000 puzzles in a match. Later requests get TOO_MANY_PUZZLES, and a bad buffer gets BAD_ADDRESS.
The puzzle arrives 1,000 to 5,000 cycles after the request, or after the bot's previous puzzle arrives if that is later. The game then writes it to the start of the buffer, whether or not the bot has interrupts enabled, and raises the REQUEST_PUZZLE interrupt. The game writes these fields:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | num_rows |
| 4 | 4 | num_cols |
| 8 | 4 | num_colors |
| 12 | num_rows * num_cols |
The board, row by row: cell (row, col) is the byte at 12 + row * num_cols + col |
Solving
#- Write the puzzle's index to
CURRENT_PUZZLE. Puzzles are numbered from 0 in request order, soAVAIL_PUZZLES - 1is the latest. - Write the address of the solution to
SUBMIT_SOLUTION:num_rows * num_colsbytes, row by row, each a press amount from 0 tonum_colors - 1. - Read
MMIO_STATUS.OKmeans the bot got its 4 paint. Each puzzle pays once.