Skip to content
CS 233 // Spimbot
Pages

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

#
  1. Write the puzzle's index to CURRENT_PUZZLE. Puzzles are numbered from 0 in request order, so AVAIL_PUZZLES - 1 is the latest.
  2. Write the address of the solution to SUBMIT_SOLUTION: num_rows * num_cols bytes, row by row, each a press amount from 0 to num_colors - 1.
  3. Read MMIO_STATUS. OK means the bot got its 4 paint. Each puzzle pays once.