Skip to content

Commit

Permalink
Add pitch-related fields to cwsub.
Browse files Browse the repository at this point in the history
This adds to cwsub all of the fields in cwevent related to pitches - the count, the pitch sequence up to the sub, and
the cwevent extended fields which tabulate counts of pitches in the plate appearance up to that point.
  • Loading branch information
tturocy committed Mar 19, 2024
1 parent 0e22640 commit 72ce601
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 6 deletions.
53 changes: 52 additions & 1 deletion doc/cwsub.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ in-game player substitutions. It is designed to be used in conjunction
with :program:`cwevent` to mitigate a blind spot in the
existing tools.

:program:`cwsub` outputs up to ten pieces of
:program:`cwsub` outputs up to 25 pieces of
information about each substitution. All are included by default; which
ones are generated is controlled by the -f switch.

The fields have the same interpretation those with the same name in
:program:`cwevent`. That is to say, you can think of :program:`cwsub` as
extending :program:`cwevent` by treating substitutions as events in
their own right. In particular, the count and pitch counts are cumulative
counts for the plate appearance up to the point of the substitution.

.. list-table:: cwevent standard field numbers
:header-rows: 1
:widths: 5,20,10
Expand Down Expand Up @@ -49,5 +55,50 @@ ones are generated is controlled by the -f switch.
* - 9
- Event number
- ``EVENT_ID``
* - 10
- Balls
- ``BALLS_CT``
* - 11
- Strikes
- ``STRIKES_CT``
* - 12
- Pitch sequence
- ``PITCH_SEQ_TX``
* - 13
- number of balls in plate appearance
- ``PA_BALL_CT``
* - 14
- number of called balls in plate appearance
- ``PA_CALLED_BALL_CT``
* - 15
- number of intentional balls in plate appearance
- ``PA_INTENT_BALL_CT``
* - 16
- number of pitchouts in plate appearance
- ``PA_PITCHOUT_BALL_CT``
* - 17
- number of pitches hitting batter in plate appearance
- ``PA_HITBATTER_BALL_CT``
* - 18
- number of other balls in plate appearance
- ``PA_OTHER_BALL_CT``
* - 19
- number of strikes in plate appearance
- ``PA_STRIKE_CT``
* - 20
- number of called strikes in plate appearance
- ``PA_CALLED_STRIKE_CT``
* - 21
- number of swinging strikes in plate appearance
- ``PA_SWINGMISS_STRIKE_CT``
* - 22
- number of foul balls in plate appearance
- ``PA_FOUL_STRIKE_CT``
* - 23
- number of balls in play in plate appearance
- ``PA_INPLAY_STRIKE_CT``
* - 24
- number of other strikes in plate appearance
- ``PA_OTHER_STRIKE_CT``


149 changes: 144 additions & 5 deletions src/cwtools/cwsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@
extern int ascii;

/* Fields to display (-f) */
int fields[10] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
int fields[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
};

int max_field = 9;
int max_field = 24;

char program_name[20] = "cwsub";

Expand Down Expand Up @@ -137,6 +139,128 @@ DECLARE_FIELDFUNC(cwsub_event_number)
gameiter->state->event_count : gameiter->state->event_count + 1);
}

/* Field 10 */
DECLARE_FIELDFUNC(cwsub_balls)
{
if (strlen(gameiter->event->count) >= 2 &&
gameiter->event->count[0] != '?' &&
gameiter->event->count[1] != '?') {
return sprintf(buffer, "%c", gameiter->event->count[0]);
}
else {
return sprintf(buffer, "0");
}
}

/* Field 11 */
DECLARE_FIELDFUNC(cwsub_strikes)
{
if (strlen(gameiter->event->count) >= 2 &&
gameiter->event->count[0] != '?' &&
gameiter->event->count[1] != '?') {
return sprintf(buffer, "%c", gameiter->event->count[1]);
}
else {
return sprintf(buffer, "0");
}
}

/* Field 12 */
DECLARE_FIELDFUNC(cwsub_pitches)
{
/* This bit of code wipes out leading whitespace, which bevent
* does not include in its output */
char *foo = gameiter->event->pitches;
while (foo && isspace(*foo)) {
foo++;
}
return sprintf(buffer, (ascii) ? "\"%s\"" : "%-20s", foo);
}

/* Field 13 */
DECLARE_FIELDFUNC(cwsub_pitches_balls)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_thrown));
}

/* Field 14 */
DECLARE_FIELDFUNC(cwsub_pitches_balls_called)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_called));
}

/* Field 15 */
DECLARE_FIELDFUNC(cwsub_pitches_balls_intentional)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_intentional));
}

/* Field 16 */
DECLARE_FIELDFUNC(cwsub_pitches_balls_pitchout)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_pitchout));
}

/* Field 17 */
DECLARE_FIELDFUNC(cwsub_pitches_balls_hit_batter)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_hit_batter));
}

/* Field 18 */
DECLARE_FIELDFUNC(cwsub_pitches_balls_other)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_ball_other));
}

/* Field 19 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_thrown));
}

/* Field 20 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes_called)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_called));
}

/* Field 21 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes_swinging)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_swinging));
}

/* Field 22 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes_foul)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_foul));
}

/* Field 23 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes_inplay)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_inplay));
}

/* Field 24 */
DECLARE_FIELDFUNC(cwsub_pitches_strikes_other)
{
return sprintf(buffer, (ascii) ? "%d" : "%02d",
cw_pitch_count_pitches(gameiter->event->pitches, cw_pitch_strike_other));
}

static field_struct field_data[] = {
{ cwsub_game_id, "GAME_ID", "game id" },
{ cwsub_inning, "INN_CT", "inning" },
Expand All @@ -147,7 +271,22 @@ static field_struct field_data[] = {
{ cwsub_position, "SUB_FLD_CD", "fielding position" },
{ cwsub_removed_player, "REMOVED_ID", "removed player" },
{ cwsub_removed_position, "REMOVED_FLD_CD", "position of removed player" },
{ cwsub_event_number, "EVENT_ID", "event number" }
{ cwsub_event_number, "EVENT_ID", "event number" },
{ cwsub_balls, "BALLS_CT", "balls" },
{ cwsub_strikes, "STRIKES_CT", "strikes" },
{ cwsub_pitches, "PITCH_SEQ_TX", "pitch sequence" },
{ cwsub_pitches_balls, "PA_BALL_CT", "number of balls thrown in plate appearance" },
{ cwsub_pitches_balls_called, "PA_CALLED_BALL_CT", "number of called balls in plate appearance" },
{ cwsub_pitches_balls_intentional, "PA_INTENT_BALL_CT", "number of intentional balls in plate appearance" },
{ cwsub_pitches_balls_pitchout, "PA_PITCHOUT_BALL_CT", "number of pitchouts in plate appearance" },
{ cwsub_pitches_balls_hit_batter, "PA_HITBATTER_BALL_CT", "number of pitches hitting batter in plate appearance" },
{ cwsub_pitches_balls_other, "PA_OTHER_BALL_CT", "number of other balls in plate appearance" },
{ cwsub_pitches_strikes, "PA_STRIKE_CT", "number of strikes thrown in plate appearance" },
{ cwsub_pitches_strikes_called, "PA_CALLED_STRIKE_CT", "number of called strikes in plate appearance" },
{ cwsub_pitches_strikes_swinging, "PA_SWINGMISS_STRIKE_CT", "number of swinging strikes in plate appearance" },
{ cwsub_pitches_strikes_foul, "PA_FOUL_STRIKE_CT", "number of foul balls in plate appearance" },
{ cwsub_pitches_strikes_inplay, "PA_INPLAY_STRIKE_CT", "number of balls in play in plate appearance" },
{ cwsub_pitches_strikes_other, "PA_OTHER_STRIKE_CT", "number of other strikes in plate appearance" }
};

void
Expand All @@ -164,7 +303,7 @@ cwsub_process_game(CWGame *game, CWRoster *_visitors, CWRoster *_home)
comma = 0;
strcpy(output_line, "");
buf = output_line;
for (i = 0; i < 10; i++) {
for (i = 0; i <= max_field; i++) {
if (fields[i]) {
if (ascii && comma) {
*(buf++) = ',';
Expand Down

0 comments on commit 72ce601

Please sign in to comment.