Skip to content

Commit

Permalink
Bunch of updates
Browse files Browse the repository at this point in the history
* box command can generate multiple box scores in one invocation

* new-game can generate multiple new games

* Add bunts, missed bunts to box score

* Add support for noting courtesy runners, pitching conferences

* Fix catcher's interference

* Allow ground ball double play where first half is unassisted

* Add BG, BP modifiers

* Add T (foul tip), M (missed bunt), L (foul bunt) pitch types

* Add hsub vsub notation
  • Loading branch information
slshen committed May 28, 2024
1 parent 511fdaf commit 53500eb
Show file tree
Hide file tree
Showing 28 changed files with 494 additions and 209 deletions.
81 changes: 81 additions & 0 deletions 20230916-1.gm
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
date: 9/16/23
game: 1
visitorid: pride-jf-16u
home: Ohana Tigers McKay
timelimit: 80m
tournament: Back to School Bash for Cash
---
visitorplays
pitching 1
1 17 BLBSFBFFX S7/L7
2 6 B WP 1-2
... MBFBB W
3 26 CBX 53/G5/B/SH 1-2 2-3
4 11 BFX S8/G1 2-H 3-H
5 3 BB WP 1-2
... BSB W+SB3
6 7 X FC1/BG1/SH B-1 1-2
7 12 BB WP 1-2 2-3 3-H
... SSC K
8 21 CBSBX 43/G4
score 3

9 2 BFFBBB W
10 18 BBBCFB W 1-2
11 00 BBFBFX 9/L9
12 17 BCFFBFC K
13 6 BBX S3/G3/B 1-2 2-3
14 26 FBBBB W 1-2 2-3 3-H
15 11 X S8/G4 B-2 1-3(E8) 2-H 3-H
16 3 BBCBSFS K
score 6

17 7 X S9/G4
18 12 BB WP 1-2
... SSFBS K
19 21 X 63/G6 2-H(E3/TH)
20 2 BX 43/G4
score 7

21 18 X 6/P6
22 00 BX S8/G8
23 17 SBLBX S7/L7 1-2
24 6 B PB 1-2 2-3
... BFFBFB W+WP 2-3 3-H
25 26 CBX FC1/G1 B-1 1-3 3-H
26 11 BX FC4/G4 B-1 1-2(E6) 3-H
27 3 FBFFBS K
28 7 FBBFBB W 1-2 2-3
29 12 CFBBS K
score 10

homeplays
pitching 11
1 1 FSS K
2 17 BFBBCB W
3 11 FCX 9/F9
4 18 BFBBFFB W 1-2
5 5 SX S7/G6 1-3 2-H
6 32 BX E4/P4 B-1 1-3 3-H
alt 4/P4 : bad positioning
7 15 BCX 13/G1
score 2

8 14 BBFBX 9/L9
9 7 SBSBS K
10 16 BSFFBX 53/G5
11 23 CFS K23
12 20 CSS K23
13 1 X 6/P6
score 2

14 17 BFCBX 5/L5
15 11 X H/F7 B-H
16 18 BSX 63/G6
17 5 FX S7/G56
18 32 X E5/G5/TH B-3(E9) 1-H
alt 53/G5 1-2
19 15 X 3/P3
final 4


156 changes: 97 additions & 59 deletions cmd/box.go
Original file line number Diff line number Diff line change
@@ -1,86 +1,124 @@
package cmd

import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/slshen/sb/pkg/boxscore"
"github.com/slshen/sb/pkg/game"
"github.com/slshen/sb/pkg/stats"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)

func boxCommand() *cobra.Command {
var (
yamlFormat bool
pdfFormat bool
scoringPlays bool
plays bool
re reArgs
)
c := &cobra.Command{
type boxCmd struct {
*cobra.Command
yamlFormat bool
pdfFormat bool
scoringPlays bool
plays bool
reArgs reArgs
outputDir string
re stats.RunExpectancy
}

func (b *boxCmd) writeBox(g *game.Game, firstGame bool) error {
if b.re == nil {
re, err := b.reArgs.getRunExpectancy()
if err != nil {
return err
}
b.re = re
}
var out io.Writer
if b.outputDir != "" {
base := filepath.Base(g.File.Path)
dot := strings.LastIndexByte(base, '.')
if dot > 1 {
base = base[:dot]
}
path := filepath.Join(b.outputDir, fmt.Sprintf("%s.pdf", base))
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
out = f
} else {
out = os.Stdout
}
if b.pdfFormat {
paps := exec.Command("paps", "--format=pdf", "--font=Courier New 10",
"--left-margin=18", "--right-margin=18", "--top-margin=18", "--bottom-margin=18")
w, err := paps.StdinPipe()
paps.Stdout = out
paps.Stderr = os.Stderr
if err != nil {
return err
}
defer w.Close()
out = w
if err := paps.Start(); err != nil {
return err
}
}
box, err := boxscore.NewBoxScore(g, b.re)
if err != nil {
return err
}
box.IncludeScoringPlays = b.scoringPlays
box.IncludePlays = b.plays
if b.yamlFormat {
dat, err := yaml.Marshal(box)
if err != nil {
return err
}
if _, err := out.Write(dat); err != nil {
return err
}
} else if err := box.Render(out); err != nil {
return err
}
if b.pdfFormat && !firstGame && b.outputDir == "" {
if _, err := out.Write([]byte{'\f'}); err != nil {
return err
}
}
return nil
}

func (b *boxCmd) init() *cobra.Command {
b.Command = &cobra.Command{
Use: "box",
Short: "Generate a box score",
RunE: func(cmd *cobra.Command, args []string) error {
re, err := re.getRunExpectancy()
if err != nil {
return err
}
games, err := game.ReadGameFiles(args)
games, err := game.ReadGames(args)
if err != nil {
return err
}
var out io.Writer
if pdfFormat {
paps := exec.Command("paps", "--format=pdf", "--font=Andale Mono 10",
"--left-margin=18", "--right-margin=18", "--top-margin=18", "--bottom-margin=18")
w, err := paps.StdinPipe()
paps.Stdout = os.Stdout
paps.Stderr = os.Stderr
if err != nil {
return err
}
defer w.Close()
out = w
if err := paps.Start(); err != nil {
return err
}
} else {
out = os.Stdout
}

for i, g := range games {
box, err := boxscore.NewBoxScore(g, re)
if err != nil {
if err := b.writeBox(g, i == 0); err != nil {
return err
}
box.IncludeScoringPlays = scoringPlays
box.IncludePlays = plays
if yamlFormat {
dat, err := yaml.Marshal(box)
if err != nil {
return err
}
if _, err := out.Write(dat); err != nil {
return err
}
} else if err := box.Render(out); err != nil {
return err
}
if i != len(games)-1 {
if _, err := out.Write([]byte{'\f'}); err != nil {
return err
}
}
}
return nil
},
}
c.Flags().BoolVar(&yamlFormat, "yaml", false, "")
c.Flags().BoolVar(&pdfFormat, "pdf", false, "Run paps to convert output to pdf")
c.Flags().BoolVar(&scoringPlays, "scoring", false, "Include scoring plays in box")
c.Flags().BoolVar(&plays, "plays", false, "Include play by play in box")
re.registerFlags(c.Flags())
return c
flags := b.Flags()
flags.BoolVar(&b.yamlFormat, "yaml", false, "")
flags.BoolVar(&b.pdfFormat, "pdf", false, "Run paps to convert output to pdf")
flags.BoolVar(&b.scoringPlays, "scoring", false, "Include scoring plays in box")
flags.BoolVar(&b.plays, "plays", false, "Include play by play in box")
flags.StringVar(&b.outputDir, "outdir", "", "Write individual box scores to this directory")
b.reArgs.registerFlags(flags)
return b.Command
}

func boxCommand() *cobra.Command {
var b boxCmd
return b.init()
}
Loading

0 comments on commit 53500eb

Please sign in to comment.