diff --git a/main.go b/main.go index 84f1f31..1c3f822 100644 --- a/main.go +++ b/main.go @@ -3,116 +3,18 @@ package main import ( "fmt" "os" - "strconv" - "time" sim "git.saintnet.tech/stryan/spacetea/simulator" - "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" ) -var style = lipgloss.NewStyle(). - Width(24). - Align(lipgloss.Center). - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("63")) - -type model struct { - s *sim.Simulator - input textinput.Model -} -type beat struct{} - var simulator *sim.Simulator -func heartbeat() tea.Cmd { - return tea.Tick(time.Second, func(time.Time) tea.Msg { - return beat{} - }) -} -func initialModel() model { - ti := textinput.New() - ti.Placeholder = "input command" - ti.CharLimit = 156 - ti.Width = 20 - - return model{ - s: simulator, - input: ti, - } -} -func (m model) Init() tea.Cmd { - return tea.Batch(textinput.Blink, heartbeat()) -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.Type { - case tea.KeyCtrlC: - m.s.Stop() - return m, tea.Quit - case tea.KeyEnter: - m.s.Input(m.input.Value()) - m.input.Reset() - return m, nil - case tea.KeyRight: - m.s.Input("right") - return m, nil - case tea.KeyLeft: - m.s.Input("left") - return m, nil - case tea.KeyUp: - m.s.Input("up") - return m, nil - case tea.KeyDown: - m.s.Input("down") - return m, nil - case tea.KeyCtrlF: - if m.input.Focused() { - m.input.Blur() - } else { - m.input.Focus() - } - return m, nil - case tea.KeyRunes: - if !m.input.Focused() { - switch msg.String() { - case "g": - m.s.Input("get") - case "p": - var res []string - for k, _ := range m.s.Player.Resources { - res = append(res, strconv.Itoa(k)) - } - return newPlaceModel(res, nil), nil - } - return m, nil - } - } - case beat: - //heartbeat - return m, heartbeat() - } - m.input, cmd = m.input.Update(msg) - return m, cmd - -} - -func (m model) View() string { - var render string - display := lipgloss.JoinHorizontal(0, style.Render(m.s.Place.String()), style.Render(fmt.Sprintf("Player\n%v", m.s.Player.String()))) - render = fmt.Sprintf("%v\n%v\n%v\n", style.Render(fmt.Sprintf("Current Time: %v", strconv.Itoa(m.s.Time))), display, style.Render(m.input.View())) - return render -} - func main() { simulator = sim.NewSimulator() simulator.Start() - - if err := tea.NewProgram(initialModel(), tea.WithAltScreen()).Start(); err != nil { + parent := parent{initMainscreen()} + if err := tea.NewProgram(parent).Start(); err != nil { fmt.Printf("Uh oh, there was an error: %v\n", err) os.Exit(1) } diff --git a/mainscreen.go b/mainscreen.go new file mode 100644 index 0000000..762ad27 --- /dev/null +++ b/mainscreen.go @@ -0,0 +1,122 @@ +package main + +import ( + "fmt" + "strconv" + "time" + + sim "git.saintnet.tech/stryan/spacetea/simulator" + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +var style = lipgloss.NewStyle(). + Width(24). + Align(lipgloss.Center). + BorderStyle(lipgloss.NormalBorder()). + BorderForeground(lipgloss.Color("63")) + +type model struct { + s *sim.Simulator + input textinput.Model + next string +} + +type beat struct{} +type simCmd string + +func heartbeat() tea.Cmd { + return tea.Tick(time.Second*1, func(time.Time) tea.Msg { + return beat{} + }) +} + +func (m model) simCommand() tea.Msg { + if m.next != "" { + tmp := m.next + m.next = "" + return simCmd(tmp) + } + return nil +} +func initMainscreen() model { + ti := textinput.New() + ti.Placeholder = "input command" + ti.CharLimit = 156 + ti.Width = 20 + + return model{ + s: simulator, + input: ti, + } +} +func (m model) Init() tea.Cmd { + return heartbeat() +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + switch msg := msg.(type) { + case beat: + //heartbeat + return m, heartbeat() + case placeMsg: + simc := fmt.Sprintf("place %v", string(msg)) + m.s.Input(simc) + return m, nil + case tea.KeyMsg: + switch msg.Type { + case tea.KeyCtrlC: + m.s.Stop() + return m, tea.Quit + case tea.KeyEnter: + m.s.Input(m.input.Value()) + m.input.Reset() + return m, nil + case tea.KeyRight: + m.s.Input("right") + return m, nil + case tea.KeyLeft: + m.s.Input("left") + return m, nil + case tea.KeyUp: + m.s.Input("up") + return m, nil + case tea.KeyDown: + m.s.Input("down") + return m, nil + case tea.KeyCtrlF: + if m.input.Focused() { + m.input.Blur() + } else { + m.input.Focus() + } + return m, nil + case tea.KeyRunes: + if !m.input.Focused() { + switch msg.String() { + case "g": + m.s.Input("get") + case "p": + var res []string + for k := range m.s.Player.Resources { + res = append(res, strconv.Itoa(k)) + } + return newPlaceModel(res, nil), nil + } + return m, nil + } + } + } + m.input, cmd = m.input.Update(msg) + return m, cmd + +} + +func (m model) View() string { + var render string + display := lipgloss.JoinHorizontal(0, style.Render(m.s.Place.String()), style.Render(fmt.Sprintf("Player\n%v", m.s.Player.String()))) + render = fmt.Sprintf("%v\n%v\n%v\n", style.Render(fmt.Sprintf("Current Time: %v", strconv.Itoa(m.s.Time))), display, style.Render(m.input.View())) + return render +} diff --git a/parent.go b/parent.go new file mode 100644 index 0000000..4b462c6 --- /dev/null +++ b/parent.go @@ -0,0 +1,19 @@ +package main + +import tea "github.com/charmbracelet/bubbletea" + +type parent struct { + current tea.Model +} + +func (m parent) Init() tea.Cmd { + return tea.Batch(m.current.Init(), tea.EnterAltScreen) +} + +func (m parent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + return m.current.Update(msg) +} + +func (m parent) View() string { + return m.current.View() +} diff --git a/place.go b/place.go index ba44478..61a6757 100644 --- a/place.go +++ b/place.go @@ -1,8 +1,6 @@ package main import ( - "log" - "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" ) @@ -19,6 +17,13 @@ type placeModel struct { list list.Model } +type placeMsg string + +func (p placeModel) buildPlaceMsg() tea.Msg { + i := p.list.SelectedItem().(item) + return placeMsg(i.Title()) +} + func newPlaceModel(entries []string, m tea.Model) placeModel { var p placeModel items := []list.Item{} @@ -50,11 +55,9 @@ func (p placeModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "ctrl-c": return p, tea.Quit case "esc": - return initialModel(), nil + return initMainscreen(), nil case "enter": - cur := p.list.SelectedItem() - log.Println(cur.FilterValue()) - return initialModel(), nil + return initMainscreen(), p.buildPlaceMsg } } diff --git a/simulator/plant.go b/simulator/plant.go index c6d7c42..303f837 100644 --- a/simulator/plant.go +++ b/simulator/plant.go @@ -6,13 +6,26 @@ import ( //Plant is a plant that grows per tick type Plant struct { - kind int - value int + kind int + value int + growth int +} + +func newPlant(k int) *Plant { + return &Plant{ + kind: k, + value: 0, + growth: 0, + } } //Tick one iteration func (p *Plant) Tick() { - p.value++ + p.growth++ + if p.growth > 10 { + p.value++ + p.growth = 0 + } } //Get produced plant diff --git a/simulator/simulator.go b/simulator/simulator.go index 620682b..7feaa72 100644 --- a/simulator/simulator.go +++ b/simulator/simulator.go @@ -1,6 +1,8 @@ package simulator import ( + "strconv" + "strings" "time" ) @@ -17,7 +19,7 @@ type Simulator struct { func NewSimulator() *Simulator { pod := newPod() player := NewPlayer() - pod.Place(&Plant{1, 0}, 4, 4) + pod.Place(newPlant(1), 4, 4) pod.Tiles[0][0].User = player return &Simulator{pod, NewPlayer(), 0, 0, 0, make(chan bool)} } @@ -35,7 +37,8 @@ func (s *Simulator) Stop() { //Input sends a command to the simulator func (s *Simulator) Input(cmd string) { cur := s.Place.Tiles[s.Px][s.Py] - switch cmd { + cmdS := strings.Split(cmd, " ") + switch cmdS[0] { case "get": if cur.Maker != nil { prod := cur.Maker.Get() @@ -43,6 +46,18 @@ func (s *Simulator) Input(cmd string) { s.Player.Resources[prod.Kind] = s.Player.Resources[prod.Kind] + prod.Value } } + case "place": + if len(cmdS) < 2 { + return + } + item := cmdS[1] + if item == strconv.Itoa(1) { + res := s.Place.Place(newPlant(1), s.Px, s.Py) + if res { + s.Player.Resources[1] = s.Player.Resources[1] - 1 + } + } + case "left": res := s.Place.MovePlayer(s.Px, s.Py, s.Px, s.Py-1) if res {