puzzle team project

Hex Minesweeper

image coming soon key art

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 with a team meant agreeing on interfaces first and testing each module against the others.

Hexagonal coordinates, both directions

Wrote the GUI module: axial to pixel for flat-top hexagons, x = size * 3/2 * q and y = size * sqrt(3) * (r + q/2), plus the six-vertex calculation the filled and outlined cells are drawn from. Getting the y term right is what fixed the horizontal alignment of the whole board; the version before it looked correct in isolation and drifted further out the wider the board got. Clicks go the other way through pixel_to_axial: convert to fractional axial, derive the third cube axis, round all three, and correct whichever axis has the largest rounding error so q + r + s stays zero, which is what keeps a click on a cell edge from landing in the wrong hex.

image coming soon hex coordinates

Difficulty as config

The UI and board sizes were hardcoded, so I moved them into a config.json parsed by Yojson into typed records: colors, display, gameplay, and easy, medium and hard settings of board radius and mine percentage. It loads lazily, falls back to a default config when the file is missing, and reports a Json_error rather than crashing. A start screen picks the difficulty, and the random map generation reads its radius and mine count from that record instead of from constants scattered through the generator.

image coming soon difficulty menu

A hint power-up

Added a hint tile type to the board: is_hint_powerup and revealed_by_hint fields on the tile record, placement through the same random coordinate picker the mines use, and its own colors in the GUI. Revealing a mine through a hint does not lose the game, and the numbers on tiles adjacent to a hint render in blue so the player can tell hinted information from earned information.

image coming soon hint tile

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. The coordinate round trip, pixel to axial and back, is one of the generated properties.

image coming soon test run