anchor.diff:          Board:Board
           Score:int }
   
  +    /// This is usually a function that produces (pseudo) random colors.
  +    /// It can also be used to create a specific initial board position.
  +    type StoneGenerator = unit-> CellState
  +
       type GameConfig = {
           NumberOfColumns:int
           NumberOfRows:int
  -        MaxNumberOfColors:int }
  -
  -    type StoneGenerator = (int -> CellState)
  +        StoneGenerator:StoneGenerator }
   
       type SameGameApi = {
  -        NewGame: StoneGenerator -> GameConfig -> Game option
  +        NewGame: GameConfig -> Game option
           Play: Game -> Position -> Game }
   
   module SameGameDomain =
  
positive.code: let rec updateUi game =
      let boardElement = document.getElementById("sg-board") :?> HTMLDivElement
      let scoreElement = document.getElementById ("sg-score") :?> HTMLDivElement
  
      let addListeners maxColIndex maxRowIndex  =
          [0..maxColIndex] |> List.iter (fun x ->
              [0..maxRowIndex] |> List.iter (fun y -> 
                  let cellId = sprintf "cell-%d-%d" x y
                  let el = document.getElementById(cellId) :?> HTMLButtonElement
                  el.addEventListener_click((fun _ -> 
                      let game = play game (x,y)
                      updateUi game; null))))
      
      match game with
      | Some (InProgress gs) -> 
  
negative.code:         scoreElement.innerText <- sprintf "No more moves. Your final score is %i point(s)." gs.Score
      | _ -> boardElement.innerText <- "Sorry, an error occurred while rendering the board."
  
  // no fable support for System.Int32.Parse
  let strToInt (str:string) =
      [for c in str -> c] 
  