From 47e8f504e560d320cd2cab460a7d0797340853fe Mon Sep 17 00:00:00 2001 From: Sam Shen Date: Tue, 22 Oct 2024 19:49:37 -0700 Subject: [PATCH] Minor fixes --- TODO.md | 2 ++ pkg/game/gamemachine.go | 8 ++++---- pkg/gamefile/file.go | 37 ++++++++++++++++++++----------------- pkg/gamefile/lexer.go | 2 +- pkg/gamefile/newgame.go | 18 ++++++++++++++++++ pkg/gamefile/parser_test.go | 4 ++-- pkg/ui/ui.go | 7 ++++--- 7 files changed, 51 insertions(+), 27 deletions(-) diff --git a/TODO.md b/TODO.md index b3cce99..3f5ef5a 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,5 @@ +* Implment sub, hsub, vsub + * Verify stats for games in tests * Check for runners advancing past other runners, disappearing runners diff --git a/pkg/game/gamemachine.go b/pkg/game/gamemachine.go index 06d4ebc..3906a19 100644 --- a/pkg/game/gamemachine.go +++ b/pkg/game/gamemachine.go @@ -284,7 +284,7 @@ func (m *gameMachine) handlePlayCode(play gamefile.Play, state *State) error { } state.Complete = true state.recordOut() - return m.handleCaughtStealing(play, state, pp, CaughtStealing, NoError) + return m.handleCaughtStealing(play, state, pp, NoError) case pp.playIs("K+PO%($$)") || pp.playIs("K+PO%(E$)"): from := pp.playMatches[0] if !(from == "1" || from == "2" || from == "3") { @@ -502,9 +502,9 @@ func (m *gameMachine) handlePlayCode(play gamefile.Play, state *State) error { fieldingError := FieldingError{ Fielder: pp.getFielder(1), } - return m.handleCaughtStealing(play, state, pp, PickedOff, fieldingError) + return m.handleCaughtStealing(play, state, pp, fieldingError) case pp.playIs("CS%($$)") || pp.playIs("CS%($$$)") || pp.playIs("CS%($$$$)"): - return m.handleCaughtStealing(play, state, pp, CaughtStealing, NoError) + return m.handleCaughtStealing(play, state, pp, NoError) case pp.playIs("FLE$"): state.Play = Play{ Type: FoulFlyError, @@ -549,7 +549,7 @@ func (m *gameMachine) handleGroundBallDoublePlay(play gamefile.Play, state *Stat return nil } -func (m *gameMachine) handleCaughtStealing(play gamefile.Play, state *State, pp playCodeParser, playType PlayType, fieldingError FieldingError) error { +func (m *gameMachine) handleCaughtStealing(play gamefile.Play, state *State, pp playCodeParser, fieldingError FieldingError) error { to := pp.playMatches[0] if !(to == "2" || to == "3" || to == "H") { return fmt.Errorf("illegal caught stealing base code %s", pp.playCode) diff --git a/pkg/gamefile/file.go b/pkg/gamefile/file.go index 9bd82a7..1e3231a 100644 --- a/pkg/gamefile/file.go +++ b/pkg/gamefile/file.go @@ -39,25 +39,28 @@ type Property struct { type Event struct { Pos Position - Alternative *Alternative `parser:"'alt' @@ (NL|EOF)"` - Pitcher string `parser:"| ('pitcher'|'pitching') @Token (NL|EOF)"` - RAdjRunner Numbers `parser:"| 'radj' @Token"` - RAdjBase string `parser:" @Token (NL|EOF)"` - Score string `parser:"| 'score' @Token (NL|EOF)"` - Final string `parser:"| 'final' @Token (NL|EOF)"` - HSubEnter string `parser:"| 'hsub' @Token"` - HSubFor string `parser:" 'for' @Token (NL|EOF)"` - VSubEnter string `parser:"| 'vsub' @Token"` - VSubFor string `parser:" 'for' @Token (NL|EOF)"` - Play *ActualPlay `parser:"| @@"` - Afters []*After `parser:" @@*"` - Comment string `parser:" @Comment? (NL|EOF)"` - Empty bool `parser:"| @NL"` + Alternative *Alternative `parser:"'alt' @@ (NL|EOF)"` + Pitcher string `parser:"| ('pitcher'|'pitching') @Token (NL|EOF)"` + RAdjRunner Numbers `parser:"| 'radj' @Token"` + RAdjBase string `parser:" @Token (NL|EOF)"` + Score string `parser:"| 'score' @Token (NL|EOF)"` + Final string `parser:"| 'final' @Token (NL|EOF)"` + Sub *LineupChange `parser:"| @@"` + Play *ActualPlay `parser:"| @@"` + Afters []*LineupChange `parser:" @@*"` + Comment string `parser:" @Comment? (NL|EOF)"` + Empty bool `parser:"| @NL"` } -type After struct { +type LineupChange struct { CourtesyRunner *string `parser:"'cr' @Token"` Conference *bool `parser:"| @'conf'"` + SubEnter string `parser:"| 'sub' @Token"` + SubExit string `parser:"| 'for' @Token"` + HSubEnter string `parser:"| 'hsub' @Token"` + HSubExit string `parser:" 'for' @Token (NL|EOF)"` + VSubEnter string `parser:"| 'vsub' @Token"` + VSubExit string `parser:" 'for' @Token (NL|EOF)"` } type Play interface { @@ -220,7 +223,7 @@ func (f *File) writeEvents(w io.Writer, name string, events []*Event) { f.writeCodeAdvancesComment(w, play.Code, play.Advances, event.Afters, event.Comment) case event.Alternative != nil: alt := event.Alternative - fmt.Fprintf(w, " alt") + fmt.Fprintf(w, " alt ") f.writeCodeAdvancesComment(w, alt.Code, alt.Advances, nil, alt.Comment) case event.Pitcher != "": fmt.Fprintf(w, "pitching %s\n", event.Pitcher) @@ -235,7 +238,7 @@ func (f *File) writeEvents(w io.Writer, name string, events []*Event) { fmt.Fprintln(w) } -func (f *File) writeCodeAdvancesComment(w io.Writer, code string, advances []string, afters []*After, comment string) { +func (f *File) writeCodeAdvancesComment(w io.Writer, code string, advances []string, afters []*LineupChange, comment string) { fmt.Fprintf(w, "%s", code) for _, adv := range advances { fmt.Fprintf(w, " %s", adv) diff --git a/pkg/gamefile/lexer.go b/pkg/gamefile/lexer.go index f70cb3b..9652076 100644 --- a/pkg/gamefile/lexer.go +++ b/pkg/gamefile/lexer.go @@ -24,7 +24,7 @@ var gameFileDef = lexer.MustStateful( rule("comment", `//.*[\n\r]`, nil), }, "PA": { - rule("Advance", `[Bb123][-Xx][123H]([^ \t\n\r]*)`, nil), + rule("Advance", `[Bb123][-Xx][123Hh]([^ \t\n\r]*)`, nil), rule("colon", `(:|--)[ \t]*`, lexer.Push("PAComment")), rule("NL", `[\n\r]`, lexer.Pop()), rule("Token", `[^ \t\n\r]+`, nil), diff --git a/pkg/gamefile/newgame.go b/pkg/gamefile/newgame.go index a5afa23..34854ae 100644 --- a/pkg/gamefile/newgame.go +++ b/pkg/gamefile/newgame.go @@ -47,6 +47,24 @@ func (f *File) WriteNewGame(nextDay bool) (*File, error) { }) } } + ng.HomeEvents = []*Event{ + {Pitcher: "0"}, + {Play: &ActualPlay{ + PlateAppearance: "1", + Batter: "1", + PitchSequence: ".", + Code: "NP", + }}, + } + ng.VisitorEvents = []*Event{ + {Pitcher: "0"}, + {Play: &ActualPlay{ + PlateAppearance: "1", + Batter: "1", + PitchSequence: ".", + Code: "NP", + }}, + } if err := ng.Validate(); err != nil { return nil, err } diff --git a/pkg/gamefile/parser_test.go b/pkg/gamefile/parser_test.go index cb3b614..10c428f 100644 --- a/pkg/gamefile/parser_test.go +++ b/pkg/gamefile/parser_test.go @@ -40,7 +40,7 @@ func TestParser(t *testing.T) { event = events[3] assert.Equal("9", *event.Afters[0].CourtesyRunner) event = events[20] - assert.Equal("3", event.VSubEnter) - assert.Equal("2", event.VSubFor) + assert.Equal("3", event.Sub.VSubEnter) + assert.Equal("2", event.Sub.VSubExit) } } diff --git a/pkg/ui/ui.go b/pkg/ui/ui.go index 8ef0a03..3f49669 100644 --- a/pkg/ui/ui.go +++ b/pkg/ui/ui.go @@ -376,14 +376,15 @@ func (ui *UI) newGame(gamePath string) { if newGamePath == "" { newGamePath = path.Join(path.Dir(gamePath), time.Now().Format(gamefile.GameDateFormat)+"-1.gm") } + ui.homePlays.SetText("", false) + ui.visitorPlays.SetText("", false) ui.parseGame(newGamePath) } func (ui *UI) save() { text := ui.getGameText() var canonName string - gf, _ := gamefile.ParseString(ui.path, text) - if gf != nil { + if gf, err := gamefile.ParseString(ui.path, text); err == nil { gm, _ := game.NewGame(gf) if gm != nil && gm.GetDate().Unix() != 0 && gm.Number != "" { canonName = fmt.Sprintf("%s-%s.gm", gm.GetDate().Format("20060102"), gm.Number) @@ -400,7 +401,7 @@ func (ui *UI) save() { if canonName != "" { ui.path = path.Join(path.Dir(ui.path), canonName) } - f, err := os.CreateTemp(path.Dir(ui.path), fmt.Sprintf("%s*", ui.path)) + f, err := os.CreateTemp(path.Dir(ui.path), fmt.Sprintf("%s*", path.Base(ui.path))) if err != nil { msg := fmt.Sprintf("cannot save %s [yellow:red]%s", ui.path, err.Error()) ui.messages.SetText(msg)