Skip to content

Commit

Permalink
Merge pull request #492 from MLB-LED-Scoreboard/dev
Browse files Browse the repository at this point in the history
Release v6.5.0
  • Loading branch information
ty-porter authored Jul 20, 2023
2 parents c5160bc + 9c84a79 commit 14373af
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ A default `config.json.example` file is included for reference. Copy this file t
### Additional Features
* Runs/Hits/Errors - Runs are always shown on the games screen, but you can enable or adjust spacing of a "runs, hits, errors" display. Take a look at the [coordinates readme file](/coordinates/README.md) for details.

* Pitch Data - Pitch data can be shown on the game screen, See the [coordinates readme file](/coordinates/README.md) for details. In addition, the Short and Long pitch description can be changed in data/pitches.py
* Pitch Data - Pitch data can be shown on the game screen, See the [coordinates readme file](/coordinates/README.md) for details. In addition, the `short` and `long` pitch description can be changed in data/pitches.py

### Flags

Expand Down
7 changes: 6 additions & 1 deletion colors/scoreboard.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,15 @@
"g": 255,
"b": 255
},
"strikeout": {
"play_result": {
"r": 255,
"g": 235,
"b": 59
},
"strikeout": {
"r": 255,
"g": 0,
"b": 0
}
},
"batter_count": {
Expand Down
2 changes: 1 addition & 1 deletion coordinates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The layout can have a couple of different states where things are rendered diffe
## Pitch Data
* `enabled` (true/false) turn feature on/off
* `mph` (true/false) When rendering pitch speed add mph after (99 mph)
* `desc_length` (Short/Long) The short or long pitch type description, you can change both the short and long description to your liking in data/pitches as long as you do not change the index value.
* `desc_length` (short/long) The short or long pitch type description, you can change both the short and long description to your liking in data/pitches as long as you do not change the index value.

## Updates
The software develops and releases features with full support for the default layouts, so custom layouts may look unsatisfactory if you update to later versions of the scoreboard. If you as a user decide to create a custom layout file, you are responsible for tweaking the coordinates to your liking with each update.
Expand Down
14 changes: 11 additions & 3 deletions coordinates/w128h32.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
"y": 50,
"enabled": false,
"mph": false,
"desc_length": "Short"
"desc_length": "short"
},
"pitch_count": {
"font_name": "4x6",
Expand All @@ -184,8 +184,16 @@
},
"loop": 64,
"strikeout": {
"x": 84,
"y": 30
"x": 60,
"y": 30,
"desc_length": "short",
"enabled": true
},
"play_result": {
"x": 60,
"y": 30,
"desc_length": "short",
"enabled": true
}
},
"pregame": {
Expand Down
14 changes: 11 additions & 3 deletions coordinates/w128h64.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"y": 50,
"enabled": true,
"mph": true,
"desc_length": "Long"
"desc_length": "long"
},
"pitch_count": {
"font_name": "4x6",
Expand All @@ -146,8 +146,16 @@
},
"loop": 68,
"strikeout": {
"x": 32,
"y": 60
"x": 16,
"y": 60,
"desc_length": "long",
"enabled": true
},
"play_result": {
"x": 16,
"y": 60,
"desc_length": "long",
"enabled": true
}
},
"batter_count": {
Expand Down
14 changes: 11 additions & 3 deletions coordinates/w192h64.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"y": 50,
"enabled": true,
"mph": true,
"desc_length": "Long"
"desc_length": "long"
},
"pitch_count": {
"font_name": "4x6",
Expand All @@ -146,8 +146,16 @@
},
"loop": 68,
"strikeout": {
"x": 32,
"y": 60
"x": 16,
"y": 60,
"desc_length": "long",
"enabled": true
},
"play_result": {
"x": 16,
"y": 60,
"desc_length": "long",
"enabled": true
}
},
"batter_count": {
Expand Down
12 changes: 10 additions & 2 deletions coordinates/w32h32.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
"y": 50,
"enabled": false,
"mph": false,
"desc_length": "Short"
"desc_length": "short"
},
"pitch_count": {
"font_name": "4x6",
Expand All @@ -165,7 +165,15 @@
"loop": 16,
"strikeout": {
"x": 33,
"y": 33
"y": 33,
"desc_length": "short",
"enabled": false
},
"play_result": {
"x": 33,
"y": 33,
"desc_length": "short",
"enabled": false
}
},
"batter_count": {
Expand Down
14 changes: 12 additions & 2 deletions coordinates/w64h32.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
"y": 50,
"enabled": false,
"mph": false,
"desc_length": "Short"
"desc_length": "short"
},
"pitch_count": {
"x": 1,
Expand All @@ -142,8 +142,18 @@
"strikeout": {
"x": 15,
"y": 29,
"font_name": "5x7"
"font_name": "5x7",
"desc_length": "short",
"enabled": true
},
"play_result": {
"x": 15,
"y": 29,
"font_name": "5x7",
"desc_length": "short",
"enabled": true
}

},
"batter_count": {
"x": 34,
Expand Down
12 changes: 10 additions & 2 deletions coordinates/w64h64.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
"y": 50,
"enabled": false,
"mph": false,
"desc_length": "Short"
"desc_length": "short"
},
"pitch_count": {
"font_name": "4x6",
Expand All @@ -141,7 +141,15 @@
"loop": 64,
"strikeout": {
"x": 31,
"y": 36
"y": 36,
"desc_length": "short",
"enabled": true
},
"play_result": {
"x": 31,
"y": 36,
"desc_length": "short",
"enabled": true
}
},
"pregame": {
Expand Down
37 changes: 37 additions & 0 deletions data/plays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
SINGLE = "single"
DOUBLE = "double"
TRIPLE = "triple"
HOME_RUN = "home_run"

WALK = "walk"
INTENTIONAL_WALK = "intent_walk"
HIT_BY_PITCH = "hit_by_pitch"

STRIKEOUT = "strikeout"
STRIKEOUT_ALT = "strike_out"
STRIKEOUT_LOOKING = "strikeout_looking"

ERROR = "error"
FIELDERS_CHOICE = "fielders_choice"

HITS = [SINGLE, DOUBLE, TRIPLE]

WALKS = [WALK, INTENTIONAL_WALK, HIT_BY_PITCH]

OTHERS = [ERROR, FIELDERS_CHOICE]

STRIKEOUTS = [STRIKEOUT, STRIKEOUT_ALT, STRIKEOUT_LOOKING]

PLAY_RESULTS = {
SINGLE: {"short": "1B", "long": "Single"},
DOUBLE: {"short": "2B", "long": "Double"},
TRIPLE: {"short": "3B", "long": "Triple"},
WALK: {"short": "BB", "long": "Walk"},
INTENTIONAL_WALK: {"short": "IBB", "long": "Int. Walk"},
STRIKEOUT: {"short": "K", "long": "K"},
STRIKEOUT_ALT: {"short": "K", "long": "K"},
STRIKEOUT_LOOKING: {"short": "ꓘ", "long": "ꓘ"},
HIT_BY_PITCH: {"short": "HBP", "long": "Hit Bttr"},
ERROR: {"short": "E", "long": "Error"},
FIELDERS_CHOICE: {"short": "FC", "long": "Fielder's Chc"},
}
8 changes: 8 additions & 0 deletions data/scoreboard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from data.scoreboard.outs import Outs
from data.scoreboard.pitches import Pitches
from data.scoreboard.team import Team
from data import plays



class Scoreboard:
Expand Down Expand Up @@ -41,6 +43,12 @@ def strikeout(self):

def strikeout_looking(self):
return self.play_result == "strikeout_looking"

def hit(self):
return self.play_result in plays.HITS

def walk(self):
return self.play_result in plays.WALKS

def get_text_for_reason(self):
if self.note:
Expand Down
62 changes: 40 additions & 22 deletions renderers/games/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@
from data.scoreboard.bases import Bases
from data.scoreboard.inning import Inning
from data.scoreboard.pitches import Pitches
from data.plays import PLAY_RESULTS

from renderers import scrollingtext
from renderers.games import nohitter


def render_live_game(canvas, layout: Layout, colors: Color, scoreboard: Scoreboard, text_pos, animation_time):
pos = 0

if scoreboard.inning.state == Inning.TOP or scoreboard.inning.state == Inning.BOTTOM:

pos = _render_at_bat(
canvas,
layout,
colors,
scoreboard.atbat,
text_pos,
scoreboard.strikeout(),
scoreboard.strikeout_looking(),
(animation_time // 6) % 2,
scoreboard.pitches,
)
canvas,
layout,
colors,
scoreboard.atbat,
text_pos,
scoreboard.play_result,
(animation_time // 6) % 2,
scoreboard.pitches
)

# Check if we're deep enough into a game and it's a no hitter or perfect game
should_display_nohitter = layout.coords("nohitter")["innings_until_display"]
Expand All @@ -38,6 +37,7 @@ def render_live_game(canvas, layout: Layout, colors: Color, scoreboard: Scoreboa
_render_bases(canvas, layout, colors, scoreboard.bases, scoreboard.homerun(), (animation_time % 16) // 5)

_render_inning_display(canvas, layout, colors, scoreboard.inning)

else:
_render_inning_break(canvas, layout, colors, scoreboard.inning)
_render_due_up(canvas, layout, colors, scoreboard.atbat)
Expand All @@ -46,24 +46,41 @@ def render_live_game(canvas, layout: Layout, colors: Color, scoreboard: Scoreboa


# --------------- at-bat ---------------
def _render_at_bat(canvas, layout, colors, atbat: AtBat, text_pos, strikeout, looking, animation, pitches: Pitches):
def _render_at_bat(canvas, layout, colors, atbat: AtBat, text_pos, play_result, animation, pitches: Pitches):
plength = __render_pitcher_text(canvas, layout, colors, atbat.pitcher, pitches, text_pos)
__render_pitch_text(canvas, layout, colors, pitches)
__render_pitch_count(canvas, layout, colors, pitches)
if strikeout:
results = list(PLAY_RESULTS.keys())
if play_result in results and __should_render_play_result(play_result, layout):
if animation:
__render_strikeout(canvas, layout, colors, looking)
__render_play_result(canvas, layout, colors, play_result)
return plength
else:
blength = __render_batter_text(canvas, layout, colors, atbat.batter, text_pos)
return max(plength, blength)


def __render_strikeout(canvas, layout, colors, looking):
coords = layout.coords("atbat.strikeout")
color = colors.graphics_color("atbat.strikeout")
font = layout.font("atbat.strikeout")
text = "ꓘ" if looking else "K"
def __should_render_play_result(play_result, layout):
if "strikeout" in play_result:
coords = layout.coords("atbat.strikeout")
else:
coords = layout.coords("atbat.play_result")
return coords["enabled"]


def __render_play_result(canvas, layout, colors, play_result):
if "strikeout" in play_result:
color = colors.graphics_color("atbat.strikeout")
coords = layout.coords("atbat.strikeout")
font = layout.font("atbat.strikeout")
else:
color = colors.graphics_color("atbat.play_result")
coords = layout.coords("atbat.play_result")
font = layout.font("atbat.play_result")
try:
text = PLAY_RESULTS[play_result][coords["desc_length"].lower()]
except KeyError:
return
graphics.DrawText(canvas, font["font"], coords["x"], coords["y"], color, text)


Expand Down Expand Up @@ -123,9 +140,9 @@ def __render_pitch_text(canvas, layout, colors, pitches: Pitches):
mph = " "
if coords["mph"]:
mph = "mph "
if coords["desc_length"] == "Long":
if coords["desc_length"].lower() == "long":
pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type_long
elif coords["desc_length"] == "Short":
elif coords["desc_length"].lower() == "short":
pitch_text = str(pitches.last_pitch_speed) + mph + pitches.last_pitch_type
else:
pitch_text = ""
Expand Down Expand Up @@ -242,6 +259,7 @@ def __fill_out_circle(canvas, out, color):

# --------------- inning information ---------------
def _render_inning_break(canvas, layout, colors, inning: Inning):

text_font = layout.font("inning.break.text")
num_font = layout.font("inning.break.number")
text_coords = layout.coords("inning.break.text")
Expand Down
2 changes: 1 addition & 1 deletion renderers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def __draw_game(self):
self.data.scrolling_finished = True

else: # draw a live game
if scoreboard.homerun() or scoreboard.strikeout():
if scoreboard.homerun() or scoreboard.strikeout() or scoreboard.hit() or scoreboard.walk():
self.animation_time += 1
else:
self.animation_time = 0
Expand Down
Loading

0 comments on commit 14373af

Please sign in to comment.