#!/usr/bin/env python
# Tyler Bisk, tjb274
# Final Project
# 12/5/23
import argparse
import json
import os
import subprocess
import time
from datetime import datetime, timedelta
from threading import Thread
from urllib.request import urlopen
import pygame
import pytz
import requests
from PIL import Image
from pygame.locals import *
import matrix
from consts import *
from rgbmatrix import RGBMatrix, RGBMatrixOptions, graphics
from utils import *
global sport, league, team, group
global iteration, in_progress_only
global code_run, in_demo, demo_state
class Score(matrix.Matrix):
def __init__(self, rows, cols, username, gpio_slowdown, brightness):
super(Score, self).__init__(rows, cols, username, gpio_slowdown, brightness)
self.logos_to_invert = ["Iowa Hawkeyes", "Pittsburgh Pirates"]
self.swap_colors = [
"Missouri Tigers",
"Princeton Tigers",
"Carolina Panthers",
"Syracuse Orange",
"Tennessee Titans",
"Tampa Bay Buccaneers",
"Philadelphia Phillies",
"Washington Wizards",
"Nashville Predators",
"Memphis Grizzlies",
"Florida Panthers",
]
self.white_font = [
"New Orleans Saints",
"Charlotte Hornets",
]
def run(self):
global iteration, team, code_run
iteration = 0
#### Display IP Address for 1 second ####
ip = subprocess.run(
"ifconfig | grep 'inet 10'", shell=True, stdout=subprocess.PIPE
).stdout.decode("utf-8")[13:]
ip = ip[0 : ip.find(" ")]
graphics.DrawText(
self.screen, self.small_font, 4, self.matrix.height / 2 + 3, self.white, ip
)
self.screen = self.matrix.SwapOnVSync(self.screen)
time.sleep(1)
#############################################
while code_run:
self.screen.Clear()
if iteration % 8 == 0:
try:
home, away, competition, date, logo = self.get_competition_data()
except Exception as e:
print("could not reach api")
print(e)
iteration = 0
time.sleep(8)
continue
home, away = self.get_team_data(home, away)
self.display_team(home, away, competition, date, logo)
self.screen = self.matrix.SwapOnVSync(self.screen)
iteration = (iteration + 1) % 7200
time.sleep(1)
def more_than_one_in_progress(self, events):
in_progress = 0
for event in events:
status = event["competitions"][0]["status"]["type"]["name"]
if status not in ["STATUS_DELAYED", "STATUS_FINAL", "STATUS_SCHEDULED"]:
in_progress += 1
if in_progress > 1:
return True
return False
def get_competition_data(self):
global sport, league, team, group, iteration
global in_demo, demo_state
URL = "http://site.api.espn.com/apis/site/v2/sports/{}/{}/scoreboard?limit=500&{}".format( # ?dates=20231027"
sport, league, group
)
if in_demo:
sport = "hockey"
league = "mens-college-hockey"
team = "Cornell Big Red"
ds = demo_list[demo_state]
if ds == "PRE GAME":
api = json.loads(
open(
f"/home/{self.username}/scoreboard/sample_jsons/cornellhockeyscheduled.json",
"r",
).read()
)
elif ds == "IN PROGRESS":
api = json.loads(
open(
f"/home/{self.username}/scoreboard/sample_jsons/cornellhockeyprogress.json",
"r",
).read()
)
elif ds == "GOAL":
api = json.loads(
open(
f"/home/{self.username}/scoreboard/sample_jsons/cornellhockeygoal.json",
"r",
).read()
)
elif ds == "POST GAME":
api = json.loads(
open(
f"/home/{self.username}/scoreboard/sample_jsons/cornellhockeyfinal.json",
"r",
).read()
)
else:
api = json.loads(urlopen(URL).read())
rotate = [
"All",
"Top 25",
"Big Ten",
"Ivy League",
"ACC",
"PAC-12",
"SEC",
"Big 12",
]
if team in rotate:
event = api["events"][iteration // 8 % len(api["events"])]
home = event["competitions"][0]["competitors"][0]
away = event["competitions"][0]["competitors"][1]
if in_progress_only and self.more_than_one_in_progress(api["events"]):
print("more than one!")
status = event["competitions"][0]["status"]["type"]["name"]
tries = 0
while status in [
"STATUS_DELAYED",
"STATUS_FINAL",
"STATUS_SCHEDULED",
] and tries < len(api["events"]):
iteration += 8
event = api["events"][iteration // 8 % len(api["events"])]
status = event["competitions"][0]["status"]["type"]["name"]
tries += 1
home = event["competitions"][0]["competitors"][0]
away = event["competitions"][0]["competitors"][1]
# elif final_only # TODO:
else:
found = False
days_ahead = 0
# search in the next week
max_days = 50
while not found and days_ahead < max_days:
# check the current API response for the given team
for event in api["events"]:
home = event["competitions"][0]["competitors"][0]
away = event["competitions"][0]["competitors"][1]
if (
team in home["team"]["displayName"]
or team in away["team"]["displayName"]
or home["team"]["displayName"] in team
or away["team"]["displayName"] in team
):
found = True
break
if not found:
# check the next day to see if team is playing
day = datetime.today() + timedelta(days=days_ahead)
date = day.strftime("%Y%m%d")
if league == "college-football":
# Check teams outside the top 25
group = "enable=groups&groups=80&dates=" + date
elif league == "mens-college-basketball":
group = "enable=groups&groups=50&dates=" + date
else:
group = "dates=" + date
URL = "http://site.api.espn.com/apis/site/v2/sports/{}/{}/scoreboard?limit=500&{}".format( # ?dates=20231027"
sport, league, group
)
api = json.loads(urlopen(URL).read())
days_ahead = days_ahead + 1
if not found:
group = ""
team = "All"
competition = event["competitions"][0]
if home["homeAway"] != "home":
tmp = home
home = away
away = tmp
date = (
datetime.fromisoformat(event["date"][:-1])
.replace(tzinfo=pytz.utc)
.astimezone(pytz.timezone("US/Eastern"))
)
logo = Image.open((f"/home/{self.username}/scoreboard/images/{sport}.png"), "r")
return home, away, competition, date, logo
def get_team_data(self, home, away):
home.setdefault("curatedRank", {"current": 99})
home["curatedRank"].setdefault("current", 99)
away.setdefault("curatedRank", {"current": 99})
away["curatedRank"].setdefault("current", 99)
home.setdefault("records", [{"summary": "0-0"}])
home["records"][0].setdefault("summary", "0-0")
away.setdefault("records", [{"summary": "0-0"}])
away["records"][0].setdefault("summary", "0-0")
home["team"].setdefault("color", "000000")
home["team"].setdefault("alternateColor", "FFFFFF")
home.setdefault("score", 0)
away["team"].setdefault("color", "000000")
away["team"].setdefault("alternateColor", "FFFFFF")
away.setdefault("score", 0)
home["team"].setdefault(
"logo",
"https://secure.espncdn.com/combiner/i?img=/i/teamlogos/default-team-logo-500.png",
)
away["team"].setdefault(
"logo",
"https://secure.espncdn.com/combiner/i?img=/i/teamlogos/default-team-logo-500.png",
)
# convert logo urls to Image
home_logo = Image.open(requests.get(home["team"]["logo"], stream=True).raw)
away_logo = Image.open(requests.get(away["team"]["logo"], stream=True).raw)
# Rank applies for college only
home = TeamData(
home["id"],
home["team"]["displayName"],
home["team"]["shortDisplayName"],
home["team"]["abbreviation"][0:4],
home["curatedRank"]["current"],
"(" + home["records"][0]["summary"] + ")",
home_logo,
home["team"]["color"],
home["team"]["alternateColor"],
home["score"],
)
away = TeamData(
away["id"],
away["team"]["displayName"],
away["team"]["shortDisplayName"],
away["team"]["abbreviation"][0:4],
away["curatedRank"]["current"],
"(" + away["records"][0]["summary"] + ")",
away_logo,
away["team"]["color"],
away["team"]["alternateColor"],
away["score"],
)
# remove parenthesis from records if too long
away.record = away.record[1:-1] if len(away.record) > 7 else away.record
home.record = home.record[1:-1] if len(home.record) > 7 else home.record
if home.name in self.logos_to_invert:
home.logo = self.invert_logo(home.logo)
elif away.name in self.logos_to_invert:
away.logo = self.invert_logo(away.logo)
return home, away
def display_pregame_team(self, home, away, date, logo):
home.logo = self.resize_logo(home.logo, self.matrix.height * 0.625)
away.logo = self.resize_logo(away.logo, self.matrix.height * 0.625)
logo = self.resize_logo(logo, 9)
self.screen.SetImage(
away.logo.convert("RGB"),
self.matrix.height * (5 / 32),
self.matrix.height * (6 / 32),
False,
)
self.screen.SetImage(
home.logo.convert("RGB"),
self.matrix.width - self.matrix.height * (0.625) - 5,
self.matrix.height * (6 / 32),
False,
)
self.screen.SetImage(
logo.convert("RGB"),
self.matrix.width / 2 - 4,
self.matrix.height * 0.5 - 4,
False,
)
if iteration % 8 <= 3 or date.strftime("%-I:%M %p") == "12:00 AM":
date_human_readable = date.strftime("%a %b %-d")
# records
else:
date_human_readable = date.strftime("%-I:%M %p")
# rank
home_detail = ""
away_detail = ""
if iteration % 8 <= 3 or "(0-0)" in home.record or "(0-0)" in away.record:
if home.rank > 0 and home.rank < 26:
home_detail = str(home.rank) + " "
home_detail += home.abbreviation
if away.rank > 0 and away.rank < 26:
away_detail = str(away.rank) + " "
away_detail += away.abbreviation
else:
home_detail = home.record
away_detail = away.record
date_length = len(date_human_readable) * 4
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width / 2 - date_length / 2 + 1,
6,
self.white,
date_human_readable,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75 - len(home_detail) * 4 / 2,
self.matrix.height - 1,
self.white,
home_detail,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.25 - len(away_detail) * 4 / 2,
self.matrix.height - 1,
self.white,
away_detail,
)
return
def display_team_in_progress(self, home, away, competition, status):
hc1 = self.hex_to_rgb(home.color1)
hc2 = self.hex_to_rgb(home.color2)
ac1 = self.hex_to_rgb(away.color1)
ac2 = self.hex_to_rgb(away.color2)
if home.name in self.swap_colors:
tmp = hc1
hc1 = hc2
hc2 = tmp
elif away.name in self.swap_colors:
tmp = ac1
ac1 = ac2
ac2 = tmp
if home.name in self.white_font:
hc2 = self.hex_to_rgb("FFFFFF")
elif away.name in self.white_font:
ac2 = self.hex_to_rgb("FFFFFF")
# change black to white if color 2
if hc2 == (0, 0, 0):
hc2 = (255, 255, 255)
elif ac2 == (0, 0, 0):
ac2 = (255, 255, 255)
hc1 = self.edit_color(hc1, (0, 0, 0), 0.9)
hc2 = self.edit_color(hc2, (255, 255, 255), 0.1)
ac1 = self.edit_color(ac1, (0, 0, 0), 0.9)
ac2 = self.edit_color(ac2, (255, 255, 255), 0.1)
# set defaults for all sports
competition["situation"].setdefault("down", 0)
competition["situation"].setdefault("distance", "")
competition["situation"].setdefault("possessionText", "")
competition["situation"].setdefault("possession", "0")
competition["situation"].setdefault("homeTimeouts", 0)
competition["situation"].setdefault("awayTimeouts", 0)
competition["situation"].setdefault("balls", 0)
competition["situation"].setdefault("strikes", 0)
competition["situation"].setdefault("outs", 0)
competition["situation"].setdefault("onFirst", False)
competition["situation"].setdefault("onSecond", False)
competition["situation"].setdefault("onThird", False)
competition["situation"].setdefault("lastPlay", {"type": {"text": ""}})
competition["situation"].setdefault("lastPlay", {"team": {"id": "0"}})
competition["situation"]["lastPlay"].setdefault("type", {"text": ""})
competition["situation"]["lastPlay"].setdefault("team", {"id": "0"})
competition["situation"]["lastPlay"]["type"].setdefault("text", "")
competition["situation"]["lastPlay"]["team"].setdefault("id", "0")
# Convert period numbers to periods for each sport and league
# OT is sometimes "OT" and sometimes a "5th Quater"
if sport != "baseball":
period = self.ordinal(status["period"])
if period[0] == "O":
period = "OT"
elif sport == "hockey" and int(period[0]) > 3:
period = "OT"
elif (
sport == "basketball"
and league == "mens-college-basketball"
and int(period[0]) > 2
):
period = "OT"
elif int(period[0]) > 4:
period = "OT"
if int(period[0]) > 4:
period = "OT"
else:
period = str(status["period"])
situation = Situation(
period,
status["displayClock"],
""
if competition["situation"]["down"] in [0, -1]
else self.ordinal(competition["situation"]["down"])
+ "+"
+ str(competition["situation"]["distance"]),
competition["situation"]["possessionText"],
competition["situation"]["homeTimeouts"],
competition["situation"]["awayTimeouts"],
competition["situation"]["possession"],
competition["situation"]["balls"],
competition["situation"]["strikes"],
competition["situation"]["outs"],
competition["situation"]["onFirst"],
competition["situation"]["onSecond"],
competition["situation"]["onThird"],
competition["situation"]["lastPlay"],
)
# Blink Team and logo if:
# Touchdown, Field Goal, Safety, Extra Point
# Home run, run scores
# Goal scores
if iteration % 16 < 11 and (
(
sport == "football"
and situation.down_to_go == ""
and situation.last_play["team"]["id"] != "0"
)
or (
sport in ["baseball", "hockey"]
and situation.last_play["scoreValue"] != 0
)
):
if situation.last_play["team"]["id"] == home.id:
team = home
else:
team = away
# Blink
if iteration % 2 == 1:
team.logo = self.resize_logo(team.logo, self.matrix.height * 18 / 32)
self.screen.SetImage(
team.logo.convert("RGB"),
self.matrix.width * 23 / 64,
self.matrix.height * 7 / 32,
False,
)
if sport == "hockey":
text = "GOAL"
elif sport == "baseball":
runs = situation.last_play["scoreValue"]
if runs == 4:
text = "GRAND SLAM"
else:
if "HOME" in situation.last_play["type"]["text"].upper():
text = "HOME RUN"
elif "WALK" in situation.last_play["type"]["text"].upper():
text = "WALK FOR RUN"
elif "STOLE" in situation.last_play["type"]["text"].upper():
text = "STOLE HOME"
else:
text = "RBI"
if runs > 1:
text = (
str(situation.last_play["scoreValue"]) + "-RUN " + text
)
elif (
"TOUCHDOWN" in situation.last_play["type"]["text"].upper()
) or str(situation.last_play["scoreValue"]) == "6":
text = "TOUCHDOWN"
# TODO: 2-Pt conversion succeeded, 2-pt failed, extra point missed, field goal missed,
# all dont fit and need to be abbreviated PAT GOOD, FG GOOD, etc
else:
text = situation.last_play["type"]["text"].upper()
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width / 2 - ((len(text) * 4) / 2 - 1),
6,
self.white,
text,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width / 2 - ((len(team.shortName) * 4) / 2 - 1),
self.matrix.height - 1,
self.white,
team.shortName.upper(),
)
# Just display the teams, scores, boxes, and situation
else:
home.logo = self.resize_logo(home.logo, self.matrix.height * 0.5)
home_logo = Image.new("RGB", home.logo.size, hc1)
home_logo.paste(home.logo, mask=home.logo.split()[3])
away.logo = self.resize_logo(away.logo, self.matrix.height * 0.5)
away_logo = Image.new("RGB", away.logo.size, ac1)
away_logo.paste(away.logo, mask=away.logo.split()[3])
graphics.DrawText(
self.screen,
self.small_font,
(self.matrix.width * 28 / 64 - len(situation.down_to_go) * 4) / 2,
self.matrix.height / 2 + 7,
self.white,
situation.down_to_go,
)
graphics.DrawText(
self.screen,
self.small_font,
(self.matrix.width * 28 / 64 - len(situation.location) * 4) / 2,
self.matrix.height / 2 + 14,
self.white,
situation.location,
)
# Draw boxes
self.DrawBox(
self.matrix.width * 28 / 64,
0,
self.matrix.width,
self.matrix.height // 2 - 1,
graphics.Color(*ac1),
)
self.DrawBox(
self.matrix.width * 28 / 64,
self.matrix.height // 2,
self.matrix.width,
self.matrix.height,
graphics.Color(*hc1),
)
# Display Time Outs Remaining
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
self.matrix.height / 2 - 1,
self.white,
"_" * situation.away_timeouts,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
self.matrix.height - 1,
self.white,
"_" * situation.home_timeouts,
)
# Display logos
self.screen.SetImage(
away_logo.convert("RGB"), self.matrix.width * 29 / 64, 0, False
)
self.screen.SetImage(
home_logo.convert("RGB"),
self.matrix.width * 29 / 64,
self.matrix.height / 2,
False,
)
# Display abbreviations
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
6,
graphics.Color(*ac2),
away.abbreviation,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
self.matrix.height / 2 + 6,
graphics.Color(*hc2),
home.abbreviation,
)
# Display scores
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
12,
graphics.Color(*ac2),
away.score,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.75,
self.matrix.height / 2 + 12,
graphics.Color(*hc2),
home.score,
)
# Display possession (football only)
if situation.possession == away.id:
graphics.DrawText(
self.screen,
self.medium_font,
self.matrix.width - 4,
self.matrix.height * 0.25 + 1,
self.white,
".",
)
elif situation.possession == home.id:
graphics.DrawText(
self.screen,
self.medium_font,
self.matrix.width - 4,
self.matrix.height / 2 + self.matrix.height * 0.25 + 1,
self.white,
".",
)
# move clock to the middle whenever there's no down information
if situation.down_to_go == "":
# move clock down
h = 15
else:
h = 7
# Display clock and period for all sports except baseball
if sport != "baseball":
graphics.DrawText(
self.screen, self.small_font, 8, h, self.white, situation.period
)
graphics.DrawText(
self.screen,
self.small_font,
(self.matrix.width * 28 / 64 - len(situation.clock) * 4) / 2,
h + 7,
self.white,
situation.clock,
)
else:
if "Mid" in status["type"]["detail"]:
graphics.DrawText(
self.screen, self.small_font, 8, h, self.white, "MID"
)
elif "End" in status["type"]["detail"]:
graphics.DrawText(
self.screen, self.small_font, 8, h, self.white, "END"
)
graphics.DrawText(
self.screen,
self.small_font,
8,
h + 7,
self.white,
self.ordinal(int(situation.period)),
)
def display_postgame_team(self, home, away, status, logo):
# Game can be between periods or over. Display "status detail"
home.logo = self.resize_logo(home.logo, self.matrix.height * 0.625)
away.logo = self.resize_logo(away.logo, self.matrix.height * 0.625)
logo = self.resize_logo(logo, 8)
# Display logos
self.screen.SetImage(
away.logo.convert("RGB"),
self.matrix.width * -(1 / 16),
self.matrix.height * 6 / 32 + 1,
False,
)
self.screen.SetImage(
home.logo.convert("RGB"),
self.matrix.width
+ self.matrix.width * (1 / 16)
- self.matrix.height * 0.625,
self.matrix.height * 6 / 32 + 1,
False,
)
self.screen.SetImage(
logo.convert("RGB"),
self.matrix.width / 2 - 4,
self.matrix.height - 9,
False,
)
# Display scores
scoreline = away.score + " " + home.score
# Both scores in range [0, 99]
if len(scoreline) < 6:
length = len(scoreline) * self.score_font_width
graphics.DrawText(
self.screen,
self.score_font,
self.matrix.width / 2 - length / 2,
self.matrix.height / 2 + 5,
self.white,
scoreline,
)
else:
length = len(away.score) * self.small_score_font_width
graphics.DrawText(
self.screen,
self.small_score_font,
self.matrix.width / 2 - length - 1,
self.matrix.height / 2 + 3,
self.white,
away.score,
)
length = len(home.score) * self.small_score_font_width
graphics.DrawText(
self.screen,
self.small_score_font,
self.matrix.width / 2 + 1,
self.matrix.height / 2 + 3,
self.white,
home.score,
)
detail = status["type"]["detail"].upper()
if "END OF 1ST" in detail:
detail = "END Q1"
elif "END OF 3RD" in detail:
detail = "END Q3"
elif "END OF 4TH" in detail:
detail = "END Q4"
if sport == "hockey":
if "END OF 2ND" in detail:
detail = "END P2"
detail = detail.replace("Q", "P")
leng = len(detail)
graphics.DrawText(
self.screen,
self.medium_font,
self.matrix.width / 2 - ((leng * 5) / 2 - 1),
7,
self.white,
detail,
)
if "FINAL" in detail and home.record != "(0-0)" and away.record != "(0-0)":
home_detail = ""
away_detail = ""
if iteration % 8 <= 3 or "(0-0)" in home.record or "(0-0)" in away.record:
if home.rank > 0 and home.rank < 26:
home_detail = str(home.rank) + " "
home_detail += home.abbreviation
if away.rank > 0 and away.rank < 26:
away_detail = str(away.rank) + " "
away_detail += away.abbreviation
else:
home_detail = home.record
away_detail = away.record
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.8 + 1 - len(home_detail) * 4 / 2,
self.matrix.height - 1,
self.white,
home_detail,
)
graphics.DrawText(
self.screen,
self.small_font,
self.matrix.width * 0.2 - len(away_detail) * 4 / 2,
self.matrix.height - 1,
self.white,
away_detail,
)
return
def display_team(self, home, away, competition, date, logo):
status = competition["status"]
if (
status["type"]["name"] == "STATUS_SCHEDULED"
or status["type"]["name"] == "STATUS_DELAYED"
):
self.display_pregame_team(home, away, date, logo)
elif status["type"]["name"] == "STATUS_IN_PROGRESS":
self.display_team_in_progress(home, away, competition, status)
else:
self.display_postgame_team(home, away, status, logo)
return
def scroll(self):
self.screen = self.matrix.CreateFrameCanvas()
font = graphics.Font()
font.LoadFont("fonts/6x13B.bdf")
textColor = graphics.Color(255, 255, 0)
pos = self.screen.width
my_text = "HELLO JFS9"
while True:
self.screen.Clear()
len = graphics.DrawText(self.screen, font, pos, 20, textColor, my_text)
pos -= 1
if pos + len < 0:
pos = self.screen.width
time.sleep(0.05)
self.screen = self.matrix.SwapOnVSync(self.screen)
# parse arguments for given LED matrix
parser = argparse.ArgumentParser(prog="scoreboard")
parser.add_argument("-r", "--rows", default=32)
parser.add_argument("-c", "--columns", default=64)
parser.add_argument("-u", "--username", default="pi")
parser.add_argument("-s", "--gpio_slowdown", default=4)
parser.add_argument("-b", "--brightness", default=80)
args = parser.parse_args()
# Run on Pi TFT
os.putenv("SDL_VIDEODRIVER", "fbcon")
os.putenv("SDL_FBDEV", "/dev/fb0")
# Use the touchscreen
os.putenv("SDL_MOUSEDRV", "TSLIB")
os.putenv("SDL_MOUSEDEV", "/dev/input/touchscreen")
# init pygame
pygame.init()
# hide the mouse
pygame.mouse.set_visible(False)
tft = pygame.display.set_mode((320, 240))
code_run = True
score = Score(
int(args.rows),
int(args.columns),
args.username,
int(args.gpio_slowdown),
int(args.brightness),
)
sport, league, team, in_progress_only, group = read_values(score.username)
time.sleep(0.1)
t1 = Thread(target=score.run)
t1.start()
# set some variables to use later
whte = 255, 255, 255
black = 0, 0, 0
# init the font
font = pygame.font.Font(None, 20)
smal_font = pygame.font.Font(None, 17)
big_font = pygame.font.Font(None, 40)
# init the buttons
start_demo_button = font.render("START DEMO", True, whte)
start_demo_button_rect = start_demo_button.get_rect(center=(320 // 2, 220))
quit_button = font.render("QUIT", True, whte)
quit_button_rect = quit_button.get_rect(center=(int(320 * 0.8), 220))
stop_demo_button = font.render("STOP DEMO", True, whte)
stop_demo_button_rect = stop_demo_button.get_rect(center=(320 // 2, 220))
left_button = big_font.render("<", True, whte)
left_button_rect = left_button.get_rect(center=(20, 240 // 2))
right_button = big_font.render(">", True, whte)
right_button_rect = right_button.get_rect(center=(300, 240 // 2))
up_button = pygame.transform.rotate(right_button, 90)
down_button = pygame.transform.rotate(left_button, 90)
send_parameters_button = font.render("SEND PARAMETERS", True, whte)
send_parameters_button_rect = send_parameters_button.get_rect(center=(320 // 2, 20))
sport_up_rect = up_button.get_rect(center=(int(320 * 0.15), 70))
sport_down_rect = down_button.get_rect(center=(int(320 * 0.15), 170))
league_up_rect = up_button.get_rect(center=(int(320 * 0.35), 70))
league_down_rect = down_button.get_rect(center=(int(320 * 0.35), 170))
team_up_rect = up_button.get_rect(center=(int(320 * 0.75), 70))
team_down_rect = down_button.get_rect(center=(int(320 * 0.75), 170))
# make an inflated rect for larger touch area
start_demo_button_rect_inflated = start_demo_button_rect.inflate(20, 10)
quit_button_rect_inflated = quit_button_rect.inflate(20, 10)
right_button_rect_inflated = right_button_rect.inflate(30, 30)
left_button_rect_inflated = left_button_rect.inflate(30, 30)
sport_up_rect_inflated = sport_up_rect.inflate(30, 30)
sport_down_rect_inflated = sport_down_rect.inflate(30, 30)
league_up_rect_inflated = league_up_rect.inflate(30, 30)
league_down_rect_inflated = league_down_rect.inflate(30, 30)
team_up_rect_inflated = team_up_rect.inflate(30, 30)
team_down_rect_inflated = team_down_rect.inflate(30, 30)
send_parameters_button_rect_inflated = send_parameters_button_rect.inflate(20, 10)
# initialize a clock to set constant fps
clock = pygame.time.Clock()
fps = 10
# def run_pygame(fps):
in_demo = False
sport_state = 0
league_state = 0
league_list = []
team_state = 0
team_list = []
demo_state = 0
while code_run:
tft.fill(black)
# 1. Draw everything according to current state in FSM
if in_demo:
tft.blit(stop_demo_button, stop_demo_button_rect)
tft.blit(left_button, left_button_rect)
tft.blit(right_button, right_button_rect)
demo_text = big_font.render(demo_list[demo_state], True, whte)
tft.blit(demo_text, demo_text.get_rect(center=(int(320 / 2), int(240 / 2))))
else:
tft.blit(send_parameters_button, send_parameters_button_rect)
tft.blit(start_demo_button, start_demo_button_rect)
tft.blit(quit_button, quit_button_rect)
tft.blit(up_button, sport_up_rect)
tft.blit(down_button, sport_down_rect)
tft.blit(up_button, league_up_rect)
tft.blit(down_button, league_down_rect)
tft.blit(up_button, team_up_rect)
tft.blit(down_button, team_down_rect)
sport_text = font.render(sport_list[sport_state], True, whte)
tft.blit(sport_text, sport_text.get_rect(center=(int(320 * 0.15), 120)))
if sport_list[sport_state] == "Hockey":
league_list = hockey_league_list
elif sport_list[sport_state] == "Football":
league_list = football_league_list
elif sport_list[sport_state] == "Basketball":
league_list = basketball_league_list
league_text = font.render(league_list[league_state], True, whte)
tft.blit(league_text, league_text.get_rect(center=(int(320 * 0.35), 120)))
if league_list[league_state] == "NHL":
team_list = nhl_list
elif league_list[league_state] == "NFL":
team_list = nfl_list
elif league_list[league_state] == "NBA":
team_list = nba_list
else:
team_list = ncaa_list
team_text = smal_font.render(team_list[team_state], True, whte)
tft.blit(team_text, team_text.get_rect(center=(int(320 * 0.75), 120)))
# 2. Check if anything was clicked
for event in pygame.event.get():
if event.type == MOUSEBUTTONUP:
pos = pygame.mouse.get_pos()
# see if the click collided with an active button depending on state
if start_demo_button_rect_inflated.collidepoint(pos):
demo_state = 0
iteration = 0
in_demo = not in_demo
if in_demo:
if left_button_rect_inflated.collidepoint(pos):
demo_state = (demo_state - 1) % len(demo_list)
iteration = 0
if right_button_rect_inflated.collidepoint(pos):
demo_state = (demo_state + 1) % len(demo_list)
iteration = 0
else:
if quit_button_rect_inflated.collidepoint(pos):
code_run = False
if sport_up_rect_inflated.collidepoint(pos):
sport_state = (sport_state - 1) % len(sport_list)
league_state = 0
team_state = 0
if sport_down_rect_inflated.collidepoint(pos):
sport_state = (sport_state + 1) % len(sport_list)
league_state = 0
team_state = 0
if league_up_rect_inflated.collidepoint(pos):
league_state = (league_state - 1) % len(league_list)
team_state = 0
if league_down_rect_inflated.collidepoint(pos):
league_state = (league_state + 1) % len(league_list)
team_state = 0
if team_up_rect_inflated.collidepoint(pos):
team_state = (team_state - 1) % len(team_list)
if team_down_rect_inflated.collidepoint(pos):
team_state = (team_state + 1) % len(team_list)
if send_parameters_button_rect_inflated.collidepoint(pos):
sport = sport_list[sport_state].lower()
leaguee = league_list[league_state].lower()
if leaguee == "ncaa":
league = "college-" + sport
elif leaguee == "ncaam":
league = "mens-college-" + sport
elif leaguee == "ncaaw":
league = "womens-college-" + sport
else:
league = leaguee
team = team_list[team_state]
iteration = 0
in_progress_only = True
group = get_group(team, league)
pygame.display.flip()
clock.tick(fps)
pygame.quit()