I’ve been looking at Elm a bit and thought I’d try my hand at implementing a game to get a feel for it. Only thing is, I’ve run in to the notorious nested record / union types update problem, and looking around I keep seeing people saying ‘flatten your model’ etc., but I’m lacking imagination on how to do this. I was hoping someone here might have a suggestion.
The rules of the game are as follows:
- Two players, although could be more.
- Each has their own 5x5 grid.
- They take it in turns to choose a letter, which both players then proceed to place on their own grid.
- Once both players have filled up their grid with letters, they then find as many words more than three letters long as possible in a set time - say 1 minute.
- 1 point for each letter in each unique word found.
- Player with the most points wins.
The data model seems clear enough to me. Something like:
type alias Player =
{ name: String
, grid: Grid
, words: List String }
type alias Grid = List Cell
type alias Cell =
{ coordinates: Point
, contents: Cell }
type Cell
= EmptyCell
| FullCell String
type alias Point = ( Int, Int )
type Model =
{ players: List Player
, dragging: Bool
, dragStart: Point
, dragEnd: Point }
There’s a bunch of handwaving in there as well - e.g. the dragging stuff captures drag to select words, turn management missing, maybe words is implemented as list of points to guarantee uniqueness etc. but I think that’s enough detail to capture the core issue: what would people suggest to flatten this model and eliminate the nesting of model -> players -> player -> grid -> cells -> cell -> contents.
I’ve written working code for a single grid that manages dragging and stuff, and working on grid -> cells -> cell -> contents is manageable, although clunky, but when I wrap players and a larger model to introduce the other elements, it just seems to get way out of hand.
I would be truly greatful for some insight on how others would tackle this.