1package nurikabe23import (4 "github.com/FelineStateMachine/puzzletea/game"5)67// screenToGrid converts terminal screen coordinates to grid cell coordinates.8// Returns (col, row, ok) where ok is false if click landed outside a cell.9func (m *Model) screenToGrid(screenX, screenY int) (col, row int, ok bool) {10 return m.screenToGridAt(screenX, screenY, false)11}1213func (m *Model) screenToGridDrag(screenX, screenY int) (col, row int, ok bool) {14 return m.screenToGridAt(screenX, screenY, true)15}1617func (m *Model) screenToGridAt(screenX, screenY int, includeSeparators bool) (col, row int, ok bool) {18 ox, oy := m.cachedGridOrigin()19 return game.DynamicGridScreenToCell(20 game.DynamicGridMetrics{21 Width: m.width,22 Height: m.height,23 CellWidth: cellWidth,24 },25 ox,26 oy,27 screenX,28 screenY,29 includeSeparators,30 )31}3233func (m *Model) cachedGridOrigin() (x, y int) {34 if m.originValid {35 return m.originX, m.originY36 }37 x, y = m.gridOrigin()38 m.originX, m.originY = x, y39 m.originValid = true40 return x, y41}4243func (m *Model) gridOrigin() (x, y int) {44 title := game.TitleBarView("Nurikabe", m.modeTitle, m.solved)45 grid := gridView(*m)46 return game.DynamicGridOrigin(m.termWidth, m.termHeight, m.View(), title, grid)47}