clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

refactor/root-tui-model
puzzletea / games / rippleeffect / export.go
export.go 1.9K
1package rippleeffect23import (4 "encoding/json"5 "fmt"67 "github.com/FelineStateMachine/puzzletea/game"8)910type Save struct {11 Width int `json:"width"`12 Height int `json:"height"`13 State string `json:"state"`14 Givens string `json:"givens"`15 Cages []Cage `json:"cages"`16 ModeTitle string `json:"mode_title"`17}1819func (m Model) GetSave() ([]byte, error) {20 save := Save{21 Width: m.width,22 Height: m.height,23 State: encodeGrid(m.grid),24 Givens: encodeGrid(m.givens),25 Cages: m.geo.cages,26 ModeTitle: m.modeTitle,27 }28 data, err := json.Marshal(save)29 if err != nil {30 return nil, fmt.Errorf("marshal ripple effect save: %w", err)31 }32 return data, nil33}3435func ImportModel(data []byte) (*Model, error) {36 var save Save37 if err := json.Unmarshal(data, &save); err != nil {38 return nil, fmt.Errorf("unmarshal ripple effect save: %w", err)39 }4041 geo, err := buildGeometry(save.Width, save.Height, save.Cages)42 if err != nil {43 return nil, fmt.Errorf("build ripple effect geometry: %w", err)44 }4546 state, err := parseGrid(save.State, save.Width, save.Height)47 if err != nil {48 return nil, fmt.Errorf("decode ripple effect state: %w", err)49 }50 givens, err := parseGrid(save.Givens, save.Width, save.Height)51 if err != nil {52 return nil, fmt.Errorf("decode ripple effect givens: %w", err)53 }5455 for y := range save.Height {56 for x := range save.Width {57 if givens[y][x] != 0 && state[y][x] != givens[y][x] {58 return nil, fmt.Errorf("given at (%d,%d) does not match current state", x, y)59 }60 if givens[y][x] != 0 && !valueAllowed(geo, givens, point{x: x, y: y}, givens[y][x]) {61 return nil, fmt.Errorf("invalid given at (%d,%d)", x, y)62 }63 }64 }6566 m := &Model{67 width: save.Width,68 height: save.Height,69 geo: geo,70 grid: state,71 initialGrid: cloneGrid(givens),72 givens: givens,73 cursor: game.Cursor{},74 keys: DefaultKeyMap,75 modeTitle: save.ModeTitle,76 }77 m.recompute()78 return m, nil79}