# Task 3: Grid **Depends on:** Task 1, Task 2 ## Context Files - `.dev/2026-05-28-procgen-map-core/spec/design.md` — §4.2 (Grid). - `reikhelm-core/src/geometry.rs` — `Point`, `Rect` (indexing + region iteration). - `reikhelm-core/src/lib.rs` — append the module declaration here. ## Files - Create: `reikhelm-core/src/grid.rs` — generic `Grid`. - Modify: `reikhelm-core/src/lib.rs` — append `pub mod grid;`. ## What to Build A generic, bounds-safe 2D grid (spec §4.2) backed by a flat `Vec` in row-major order. Generic on purpose: it's the map (`Grid`) and also scratch buffers (`Grid`, `Grid`) during generation. All access is bounds-checked — out-of-bounds reads return `None`, out-of-bounds writes are no-ops (never panic). Neighbor queries return only in-bounds points. Derive `Clone, Debug`; derive `Serialize, Deserialize` gated on `T: Serialize/Deserialize`. ## Interface Dependencies - **Consumes:** `Point`, `Rect` from Task 2. - **Produces:** `Grid` with: - `new(width: u32, height: u32, fill: T) -> Self where T: Clone` - `from_fn(width, height, f: impl Fn(Point) -> T) -> Self` - `width() -> u32`, `height() -> u32` - `in_bounds(Point) -> bool` - `get(Point) -> Option<&T>`, `get_mut(Point) -> Option<&mut T>`, `set(Point, T)` (no-op if OOB) - `neighbors4(Point) -> impl Iterator`, `neighbors8(...)` — in-bounds only - `iter() -> impl Iterator` - `iter_rect(Rect) -> impl Iterator` (clipped to bounds) ## Tests - `get`/`set` round-trip for in-bounds points; `set` OOB is a no-op and `get` OOB is `None`. - `neighbors4`/`neighbors8` at a corner return only in-bounds neighbors (3 for corner with 8-conn). - `iter` visits exactly `width * height` cells once each. - `iter_rect` is clipped when the rect extends past the grid edge. - `from_fn` produces values matching the closure at sampled points. ## Success Criteria - [ ] `Grid` exists with all listed methods; OOB access never panics. - [ ] `pub mod grid;` added to `lib.rs`. - [ ] All tests pass: `cargo test -p reikhelm-core grid` ## Commit `"feat(core): generic bounds-safe Grid"`