From 07f0d270e8633dd8b59c409ae42474aed7cc60d4 Mon Sep 17 00:00:00 2001 From: Broderick Westrope Date: Wed, 21 Aug 2024 17:37:46 +1000 Subject: [PATCH] feat: implement sprint game mode --- cmd/tetrigo/subcommands.go | 16 ++++++++++------ internal/tui/common/mode.go | 2 ++ internal/tui/menu/model.go | 7 ++----- internal/tui/single/model.go | 23 ++++++++++++++++++++--- internal/tui/starter/model.go | 6 +++--- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/cmd/tetrigo/subcommands.go b/cmd/tetrigo/subcommands.go index 975049f..d2c5e84 100644 --- a/cmd/tetrigo/subcommands.go +++ b/cmd/tetrigo/subcommands.go @@ -23,14 +23,18 @@ type PlayCmd struct { } func (c *PlayCmd) Run(globals *GlobalVars) error { - switch c.GameMode { - case "marathon": - return launchStarter(globals, common.ModeUltra, common.NewSingleInput(common.ModeMarathon, c.Level, c.Name)) - case "ultra": - return launchStarter(globals, common.ModeUltra, common.NewSingleInput(common.ModeUltra, c.Level, c.Name)) - default: + singlePlayerModes := map[string]common.Mode{ + "marathon": common.ModeMarathon, + "sprint": common.ModeSprint, + "ultra": common.ModeUltra, + } + + mode, ok := singlePlayerModes[c.GameMode] + if !ok { return fmt.Errorf("invalid game mode: %s", c.GameMode) } + + return launchStarter(globals, mode, common.NewSingleInput(common.ModeMarathon, c.Level, c.Name)) } type LeaderboardCmd struct { diff --git a/internal/tui/common/mode.go b/internal/tui/common/mode.go index c505578..b0fb59f 100644 --- a/internal/tui/common/mode.go +++ b/internal/tui/common/mode.go @@ -27,6 +27,7 @@ type Mode int const ( ModeMenu = Mode(iota) ModeMarathon + ModeSprint ModeUltra ModeLeaderboard ) @@ -34,6 +35,7 @@ const ( var modeToStrMap = map[Mode]string{ ModeMenu: "Menu", ModeMarathon: "Marathon", + ModeSprint: "Sprint", ModeUltra: "Ultra", ModeLeaderboard: "Leaderboard", } diff --git a/internal/tui/menu/model.go b/internal/tui/menu/model.go index d85c929..0e2444a 100644 --- a/internal/tui/menu/model.go +++ b/internal/tui/menu/model.go @@ -41,7 +41,7 @@ func NewModel(_ *common.MenuInput) *Model { nameInput := textinput.NewModel("Enter your name", 20, 20) modePicker := hpicker.NewModel([]hpicker.KeyValuePair{ {Key: "Marathon", Value: common.ModeMarathon}, - // {Key: "Sprint (40 Lines)", Value: "sprint"}, + {Key: "Sprint (40 Lines)", Value: common.ModeSprint}, {Key: "Ultra (Time Trial)", Value: common.ModeUltra}, }) levelPicker := hpicker.NewModel(nil, hpicker.WithRange(1, 15)) @@ -167,10 +167,7 @@ func (m Model) startGame() (tea.Cmd, error) { } switch mode { - case common.ModeMarathon: - in := common.NewSingleInput(mode, level, playerName) - return common.SwitchModeCmd(mode, in), nil - case common.ModeUltra: + case common.ModeMarathon, common.ModeSprint, common.ModeUltra: in := common.NewSingleInput(mode, level, playerName) return common.SwitchModeCmd(mode, in), nil case common.ModeMenu, common.ModeLeaderboard: diff --git a/internal/tui/single/model.go b/internal/tui/single/model.go index c0aa1db..763f174 100644 --- a/internal/tui/single/model.go +++ b/internal/tui/single/model.go @@ -19,6 +19,10 @@ import ( "github.com/charmbracelet/lipgloss" ) +const ( + timerUpdateInterval = time.Millisecond * 13 +) + var _ tea.Model = &Model{} type Model struct { @@ -59,16 +63,29 @@ func NewModel(in *common.SingleInput, cfg *config.Config) (*Model, error) { MaxLevel: cfg.MaxLevel, IncreaseLevel: true, EndOnMaxLevel: cfg.EndOnMaxLevel, - GhostEnabled: cfg.GhostEnabled, + + GhostEnabled: cfg.GhostEnabled, + } + m.gameStopwatch = stopwatch.NewWithInterval(timerUpdateInterval) + case common.ModeSprint: + gameIn = &single.Input{ + Level: in.Level, + MaxLevel: cfg.MaxLevel, + IncreaseLevel: true, + + MaxLines: 40, + EndOnMaxLines: true, + + GhostEnabled: cfg.GhostEnabled, } - m.gameStopwatch = stopwatch.NewWithInterval(time.Millisecond * 13) + m.gameStopwatch = stopwatch.NewWithInterval(timerUpdateInterval) case common.ModeUltra: gameIn = &single.Input{ Level: in.Level, GhostEnabled: cfg.GhostEnabled, } m.useTimer = true - m.gameTimer = timer.NewWithInterval(time.Minute*2, time.Millisecond*13) + m.gameTimer = timer.NewWithInterval(time.Minute*2, timerUpdateInterval) case common.ModeMenu, common.ModeLeaderboard: return nil, fmt.Errorf("invalid single player game mode: %v", in.Mode) default: diff --git a/internal/tui/starter/model.go b/internal/tui/starter/model.go index 1843320..775094e 100644 --- a/internal/tui/starter/model.go +++ b/internal/tui/starter/model.go @@ -107,12 +107,12 @@ func (m *Model) setChild(mode common.Mode, switchIn common.SwitchModeInput) erro return ErrInvalidSwitchModeInput } m.child = menu.NewModel(menuIn) - case common.ModeMarathon, common.ModeUltra: - ultraIn, ok := switchIn.(*common.SingleInput) + case common.ModeMarathon, common.ModeSprint, common.ModeUltra: + singleIn, ok := switchIn.(*common.SingleInput) if !ok { return ErrInvalidSwitchModeInput } - child, err := single.NewModel(ultraIn, m.cfg) + child, err := single.NewModel(singleIn, m.cfg) if err != nil { return err }