Hex Minesweeper
ABOUT THIS PROJECT
Minesweeper, but every cell has six neighbors.
A team project for CS 3110, Cornell's data structures and functional programming course. Moving minesweeper from a square grid to a hexagonal one sounds cosmetic and is not: Adjacency, the flood fill that opens empty regions, and the coordinate system all have to be rebuilt, and doing it in OCaml means doing it without mutable state to fall back on.
Hexagonal coordinates
Implemented axial to pixel conversion for flat-top hexagons, y = size * sqrt(3) * (r + q/2), along with the vertex calculation used to draw each cell. Getting that formula right is what fixed the horizontal alignment of the entire board; the version before it looked correct in isolation and drifted further out the wider the board got.
Adjacency over six neighbours
Six neighbours instead of eight changes the counting and the flood fill more than you would expect, because the offsets differ depending on the row and none of the square-grid shortcuts carry over. Tiles with no adjacent mines correctly render as blank rather than as a zero, which matters because a zero reads as information the player then has to unlearn.
Drawing the board
Filled and outlined hexagon rendering built on top of the vertex calculation, drawn against a defined set of color constants rather than literals scattered through the drawing code, so the whole scheme changes from one place.
Property-based tests
QCheck tests with oracles across every module, 31 tests passing, and Bisect coverage above 80%. The oracle approach is the point: rather than assert on hand-picked boards, the tests generate boards and compare behavior against a reference implementation, which catches adjacency and flood-fill bugs that example-based tests walk straight past.