diff --git a/TechDocs/game_scheduling_feature.md b/TechDocs/game_scheduling_feature.md index ec6f25b..52569a6 100644 --- a/TechDocs/game_scheduling_feature.md +++ b/TechDocs/game_scheduling_feature.md @@ -11,3 +11,1577 @@ CFBGameRequest Struct NFLGameRequest Struct ## Endpoints + +- CreateCFBGameRequest +- CreateNFLPreseasonRequest +- AcceptCFBGameRequest +- RejectCFBGameRequest +- ProcessCFBGameRequest +- VetoCFBGameRequest +- AcceptNFLGameRequest +- RejectNFLGameRequest +- ProcessNFLGameRequest +- VetoNFLGameRequest + +## Cron Jobs + +- GenerateRequiredAnnualGames +- GenerateCFBConferenceSchedule +- GenerateRemainingCFBOOCGames +- GenerateRemainingCFBSpringGames +- GenerateNFLSchedule (complete?) +- GenerateRemainingNFLPreseasonGames + +## NFL Schedule Generation + +- Has already been complete. Moving on. + +## CFB Required Annual Games + +- Use the CollegeRivals struct which should now have information as far as required annual games for participation for each team. These games should be created before putting together the conference schedule. Each rivalry can have special rules as far as when the game is played, which timeslot, and whether the game is neutral site or not. Some rivalry games are additionally conference matchups and non-conference matchups. This will impact both OOC generation and conference generation. + +## Generate CFB Conference Schedule + +- Generate a full conference schedule for every CFB conference (non-independents) in preparation of the upcoming season. Annual rivalry games should be generated by this point and will consist of matchups that are both out of conference games and conference matchups. +- Each conference has a different amount of teams and has their own set of rules as far as scheduling matchups. For example, the Big Ten has 18 teams and the ACC has 17 teams. There are going to be different rules as far as scheduling games go. SEC and Big 12 have 16 teams, Pac-12 has 8 teams, Sunbelt has 14 teams (two divions of 7 teams), AAC has around 14 teams, and multiple conferences with 13, 12, 11, 10, 9, 8, 7, and 6 teams. +- We want to be able to make a conference schedule for a season where we ensure that teams are playing opponents - some similar and some different - and we should keep track of the non-annual conference opponents they faced in the last 4 seasons and whether they played on the road or at home. Ideally we want to make sure that each team plays all of their other conference members at least once or twice within a four season span. This will be easier with smaller conferences, difficult with larger ones. +- When creating the functions for creating matchups and weekly slates for different sized conferences, use as much context from the existing annual games created & the team's conference opponent history in previous seasons. If there are already certain rivalry games scheduled and existing, we should make sure that we can build a weekly slate around those scheduled games and opponents that week. So if a potential weekly slate of games for the SEC has Tennessee vs Alabama, that should always be considered for the Week 8 slate because the rivalry game must always be during week 8 of the season (according to the rivalry record). +- Regarding when these games are scheduled, teams are only allowed zero to one games per week. We ideally want to keep conference matchups between weeks 4 through 12 of the regular season. If these rules cannot be met, we can expand the range to between weeks 0 and 13. Week 14 should be reserved only for certain rivalry matchups. +- There are going to be some cases where every conference team won't be able to match with another conference team member in a given week. That is okay, and if that's the case, as mentioned in the last bullet point, we can schedule out those conference games in weeks 0 through 13 if needed. +- Each team's conference schedule should have an even number of home and away games. If there needs to be an uneven split, please ensure that a team that has the lower amount of home games in the previous season has the expected number of home games in the current season. + +# Big 12 Conference Rules + +#### 1. Teams & Pod Structure + +The 16 teams are divided into **4 pods of 4 teams each**. Pod membership determines the majority of scheduling logic. + +| Pod | Teams | +| ---------- | ---------------------------------------------- | +| **Red** | Arizona, Arizona State, BYU, Utah | +| **Yellow** | Texas Tech, TCU, Houston, Baylor | +| **Green** | Kansas, Kansas State, Oklahoma State, Colorado | +| **Orange** | West Virginia, UCF, Cincinnati, Iowa State | + +--- + +#### 2. Annual Rivalry Registry + +Four matchups are **hardcoded** and must occur every season regardless of rotation or scheduling constraints. Each rivalry pair shares a pod. + +``` +RIVALRY_REGISTRY = { + (BYU, Utah), + (Arizona, Arizona State), + (Baylor, TCU), + (Kansas, Kansas State) +} +``` + +- Home/away **flips on a 2-year cycle** for each rivalry game. +- Each rivalry game is always assigned to **Week 9** (the final conference game of the season) and cannot be moved. + +--- + +#### 3. Game Count Per Season + +| Category | Games | +| -------------------------- | ----- | +| Pod games (intra-pod) | 3 | +| Non-pod conference games | 6 | +| **Total conference games** | **9** | + +--- + +#### 4. Pod Games (3 games) + +Each team plays every other team in its pod once per season — 3 games total, since there are 4 teams per pod. + +##### 4a. Home/Away Rotation + +- Home and away assignments within the pod **flip every 2 years**. +- If Team A hosted Team B in Year 1, Team A visits Team B in Year 2. + +##### 4b. Game Ordering Within Pod Games + +Pod games are split into two groups for scheduling purposes: + +- **The Rivalry Game** — The team's designated matchup from the `RIVALRY_REGISTRY`. Always scheduled **last (Week 9)**. +- **The Other 2 Pod Games** — Scheduled in Weeks 7 and 8, in any order. + +--- + +#### 5. Non-Pod Conference Games (6 games) + +Each team plays 6 opponents drawn from outside its pod (i.e., from the other 3 pods), rotating on a **4-year cycle**. + +##### 5a. Rotation Structure + +- Each team plays **2 opponents from each of the other 3 pods** per season (2 × 3 = 6 games). +- Over 4 years, every team cycles through all 12 non-pod opponents, with home/away varying by year. + +##### 5b. Cross-Pod Matchup Pairs + +Cross-pod opponents are **pre-assigned pairs** defined in a rotation table. These pairs are fixed; only the home/away location changes across the 4-year cycle. + +##### 5c. 4-Year Cycle + +Non-pod games repeat in a 4-year pattern (Year 1 → Year 2 → Year 3 → Year 4 → repeat). The rotation table must be enumerated explicitly, as it cannot be derived algorithmically without knowing the initial cross-pod pair assignments. + +--- + +#### 6. Weekly Scheduling Order + +The 9 conference games for each team are ordered as follows: + +| Weeks | Games | Constraints | +| ----- | ----------------------- | --------------------------------------------------------- | +| 4–10 | 6 non-pod games | Randomly mixed; no more than **2 consecutive away games** | +| 10–12 | 2 non-rivalry pod games | Any order | +| 13/14 | Rivalry game | Always last; non-negotiable | + +##### 6a. Consecutive Away Game Constraint + +When shuffling the 6 non-pod games into Weeks 1–6, the scheduler must ensure: + +``` +max_consecutive_away_games ≤ 2 +``` + +--- + +#### 7. Summary Formula (Pseudocode) + +``` +RIVALRY_REGISTRY = { + (BYU, Utah), (Arizona, ArizonaState), + (Baylor, TCU), (Kansas, KansasState) +} + +for each team T in season Y: + + // Step 1: Identify rivalry game (always Week 9) + rival = lookup_rival(T, RIVALRY_REGISTRY) + → guaranteed annual + → home/away = flip(Y, rival) + + // Step 2: Identify remaining pod games (Weeks 7–8) + other_pod_games = intra_pod_opponents(T) - {rival} + → 2 games + → home/away = flip(Y, opponent) + + // Step 3: Pull non-pod games from rotation table (Weeks 1–6) + non_pod_games = lookup(T, Y, cross_pod_rotation_table) + → 6 opponents + → home/away pre-assigned by rotation table + + // Step 4: Build the full 9-game schedule + schedule = [ + shuffle(non_pod_games, constraint: max_consecutive_away ≤ 2), // Weeks 1–6 + other_pod_games[0], // Week 7 + other_pod_games[1], // Week 8 + rival // Week 9 (locked) + ] +``` + +--- + +#### 8. Constraints Summary + +| Rule | Constraint | +| ---------------------- | -------------------------------------------------- | +| Total conference games | Exactly 9 | +| Pod games | Exactly 3 (all intra-pod opponents) | +| Non-pod games | Exactly 6 (2 per opposing pod) | +| Non-pod game rotation | 4-year repeating cycle | +| Home/away (pod) | Flips every 2 years | +| Home/away (non-pod) | Defined by 4-year rotation table | +| Rivalry game placement | Always Week 9; never moved | +| Consecutive away games | Maximum 2 in a row (Weeks 1–6 only) | +| Annual rivalries | All 4 rivalry pairs must be scheduled every season | + +# SEC Conference Football Scheduling Rules + +## 1. Teams + +The SEC consists of **16 teams**: + +| Team | Out-of-Conference Week 14 Rival | +| ----------------- | ------------------------------- | +| Alabama | — | +| Arkansas | — | +| Auburn | — | +| Florida | Florida State | +| Georgia | Georgia Tech | +| Kentucky | Louisville | +| LSU | — | +| Mississippi State | — | +| Missouri | — | +| Oklahoma | — | +| Ole Miss | — | +| South Carolina | Clemson | +| Tennessee | — | +| Texas | — | +| Texas A&M | — | +| Vanderbilt | — | + +--- + +## 2. Season Structure + +| Parameter | Value | +| -------------------------- | ---------------------------------- | +| Total regular season weeks | 15 (Week 0 – Week 14) | +| Total games per team | 12 | +| Conference games per team | 9 | +| Minimum OOC games per team | 3 | +| Bye weeks per team | 3 (free floating, no restrictions) | + +--- + +## 3. Guaranteed Annual Matchups + +Each team has exactly **3 guaranteed conference matchups** that occur every season. These are fixed opponents — only home/away location rotates on a 2-year flip cycle. + +| Matchup | Week 14 Locked? | +| ------------------------------- | --------------- | +| Alabama vs Auburn | ✅ Yes | +| Alabama vs Tennessee | No | +| Alabama vs Mississippi State | No | +| Arkansas vs LSU | ✅ Yes | +| Arkansas vs Missouri | No | +| Arkansas vs Texas | No | +| Auburn vs Georgia | No | +| Auburn vs Vanderbilt | No | +| Florida vs Georgia | No | +| Florida vs South Carolina | No | +| Florida vs Kentucky | No | +| Georgia vs South Carolina | No | +| Kentucky vs Tennessee | No | +| Kentucky vs South Carolina | No | +| LSU vs Ole Miss | No | +| LSU vs Texas A&M | No | +| Mississippi State vs Vanderbilt | No | +| Mississippi State vs Ole Miss | ✅ Yes | +| Missouri vs Oklahoma | ✅ Yes | +| Missouri vs Texas A&M | No | +| Oklahoma vs Texas | No | +| Oklahoma vs Ole Miss | No | +| Tennessee vs Vanderbilt | ✅ Yes | +| Texas vs Texas A&M | ✅ Yes | + +### 3a. Guaranteed Matchup Registry Per Team + +| Team | Guaranteed Opponents | +| ----------------- | ------------------------------------ | +| Alabama | Auburn, Tennessee, Mississippi State | +| Arkansas | LSU, Missouri, Texas | +| Auburn | Alabama, Georgia, Vanderbilt | +| Florida | Georgia, South Carolina, Kentucky | +| Georgia | Auburn, Florida, South Carolina | +| Kentucky | Florida, Tennessee, South Carolina | +| LSU | Arkansas, Ole Miss, Texas A&M | +| Mississippi State | Alabama, Vanderbilt, Ole Miss | +| Missouri | Arkansas, Oklahoma, Texas A&M | +| Oklahoma | Missouri, Texas, Ole Miss | +| Ole Miss | LSU, Mississippi State, Oklahoma | +| South Carolina | Florida, Georgia, Kentucky | +| Tennessee | Alabama, Kentucky, Vanderbilt | +| Texas | Arkansas, Oklahoma, Texas A&M | +| Texas A&M | LSU, Missouri, Texas | +| Vanderbilt | Auburn, Mississippi State, Tennessee | + +### 3b. Home/Away Rotation + +- Home and away assignments for guaranteed matchups **flip on a 2-year cycle**. +- If Team A hosts Team B in Year 1, Team A visits Team B in Year 2. + +--- + +## 4. Week 14 Rules + +Week 14 is a **hard lock** for all 16 teams. No flexible or non-rivalry conference game may be placed in Week 14. + +| Team Type | Week 14 Assignment | +| ------------------------------------------- | ---------------------------------- | +| Teams with a locked conference rivalry game | Play their designated rivalry game | +| Teams with a locked OOC rivalry game | Play their out-of-conference rival | +| All other teams | Bye week | + +### 4a. Week 14 Locked Games + +| Game | Type | +| ----------------------------- | ------------------ | +| Alabama vs Auburn | Conference rivalry | +| LSU vs Arkansas | Conference rivalry | +| Texas vs Texas A&M | Conference rivalry | +| Ole Miss vs Mississippi State | Conference rivalry | +| Missouri vs Oklahoma | Conference rivalry | +| Tennessee vs Vanderbilt | Conference rivalry | +| Georgia vs Georgia Tech | OOC rivalry | +| South Carolina vs Clemson | OOC rivalry | +| Florida vs Florida State | OOC rivalry | +| Kentucky vs Louisville | OOC rivalry | + +--- + +## 5. Flexible Conference Games (6 games) + +Each team plays **6 flexible conference games** per season drawn from their 12 non-guaranteed opponents, rotating on a **4-year cycle**. + +### 5a. Non-Guaranteed Opponent Pool + +Each team has exactly **12 non-guaranteed opponents** (15 total conference members minus 3 guaranteed annual opponents). + +### 5b. 4-Year Rotation Cycle + +The 12 non-guaranteed opponents are split into two groups of 6 and played in the following pattern: + +| Year | Opponents Played | Home/Away | +| ------ | ------------------------ | ------------------- | +| Year 1 | Group A (Opponents 1–6) | Per rotation table | +| Year 2 | Group B (Opponents 7–12) | Per rotation table | +| Year 3 | Group A (Opponents 1–6) | Flipped from Year 1 | +| Year 4 | Group B (Opponents 7–12) | Flipped from Year 2 | + +- Every non-guaranteed opponent is played **at least once within a 4-year cycle**. +- Every non-guaranteed opponent is played **exactly twice** over the full 4-year cycle — once at home, once away. +- Group A and Group B assignments are **pre-defined in the rotation table** and cannot be derived algorithmically without the initial assignment. + +### 5c. Flexible Game Scheduling Constraints + +- Flexible games may be scheduled in **any open week between Week 0 and Week 13**. +- Flexible games may **not** be scheduled in Week 14. +- There are no restrictions on consecutive away games for flexible games. +- Bye weeks float freely with no placement restrictions. + +--- + +## 6. Game Count Summary Per Season + +| Category | Games | +| --------------------------- | ----------- | +| Guaranteed conference games | 3 | +| Flexible conference games | 6 | +| Out-of-conference games | 3 (minimum) | +| **Total** | **12** | + +--- + +## 7. Summary Formula (Pseudocode) + +``` +GUARANTEED_REGISTRY = { + (Alabama, Auburn), (Alabama, Tennessee), (Alabama, MississippiState), + (Arkansas, LSU), (Arkansas, Missouri), (Arkansas, Texas), + (Auburn, Georgia), (Auburn, Vanderbilt), + (Florida, Georgia), (Florida, SouthCarolina), (Florida, Kentucky), + (Georgia, SouthCarolina), + (Kentucky, Tennessee), (Kentucky, SouthCarolina), + (LSU, OleMiss), (LSU, TexasAM), + (MississippiState, Vanderbilt), (MississippiState, OleMiss), + (Missouri, Oklahoma), (Missouri, TexasAM), + (Oklahoma, Texas), (Oklahoma, OleMiss), + (Tennessee, Vanderbilt), + (Texas, TexasAM) +} + +WEEK14_CONFERENCE_LOCKS = { + (Alabama, Auburn), + (LSU, Arkansas), + (Texas, TexasAM), + (OleMiss, MississippiState), + (Missouri, Oklahoma), + (Tennessee, Vanderbilt) +} + +WEEK14_OOC_LOCKS = { + (Georgia, GeorgiaTech), + (SouthCarolina, Clemson), + (Florida, FloridaState), + (Kentucky, Louisville) +} + +for each team T in season Y: + + // Step 1: Identify the 3 guaranteed conference games + guaranteed_games = lookup_guaranteed(T, GUARANTEED_REGISTRY) + → 3 opponents + → home/away = flip(Y, opponent) + + // Step 2: Lock Week 14 + if T in WEEK14_CONFERENCE_LOCKS: + week14_game = lookup_week14_conference(T) + guaranteed_games.lock(week14_game, week=14) + else if T in WEEK14_OOC_LOCKS: + week14_game = lookup_week14_ooc(T) + // scheduled as OOC game, not conference + else: + week14 = BYE + + // Step 3: Pull flexible conference games from rotation table + flexible_games = lookup(T, Y, rotation_table) + → 6 opponents + → Group A in Years 1 & 3, Group B in Years 2 & 4 + → home/away flipped between Year 1/3 and Year 2/4 + + // Step 4: Schedule OOC games (minimum 3) + ooc_games = schedule_ooc(T) + → minimum 3 games + → float freely in Weeks 0–13 + + // Step 5: Build full 12-game schedule across Weeks 0–14 + all_games = guaranteed_games + flexible_games + ooc_games + → 12 games total + → float freely in Weeks 0–13 (Week 14 already locked above) + → remaining open weeks = bye weeks (3 total, no restrictions) +``` + +--- + +## 8. Constraints Summary + +| Rule | Constraint | +| --------------------------- | --------------------------------------------------------- | +| Total games per season | Exactly 12 | +| Conference games | Exactly 9 (3 guaranteed + 6 flexible) | +| OOC games | Minimum 3 | +| Bye weeks | Exactly 3; float freely, no restrictions | +| Guaranteed matchups | All 24 pairs must be scheduled every season | +| Home/away (guaranteed) | Flips every 2 years | +| Flexible game rotation | 4-year cycle; Groups A & B defined by rotation table | +| Home/away (flexible) | Flips between Year 1↔3 and Year 2↔4 | +| Non-guaranteed opponents | Every opponent played at least once per 4-year cycle | +| Week 14 | Hard lock for all 16 teams; no flexible games permitted | +| Week 14 (conference rivals) | 6 designated rivalry games always played in Week 14 | +| Week 14 (OOC rivals) | Florida, Georgia, Kentucky, South Carolina play OOC rival | +| Week 14 (all others) | Bye week | + +# Big Ten Football Scheduling Algorithm — Rules & Constraints + +## Overview + +This document defines the rules, constraints, and logic required to algorithmically generate a valid Big Ten Conference football schedule across an 18-team, no-division format. The schedule operates on a **5-year rolling cycle** and must satisfy both hard constraints (non-negotiable) and soft constraints (preferred but flexible). + +--- + +## Conference Structure + +- **Total Teams:** 18 +- **Conference Games Per Team Per Season:** 9 +- **Total Conference Games Per Season:** 81 (18 × 9 ÷ 2) +- **Total Possible Unique Pairings:** 153 (18 × 17 ÷ 2) +- **Divisional Format:** None +- **Scheduling Cycle:** 5 years + +--- + +## Season Week Definitions + +| Week Range | Description | +| -------------- | ------------------------------------------------------------------------------------ | +| Weeks 0–3 | Non-conference games only | +| **Weeks 4–12** | **Primary conference game window** | +| Week 13 | Overflow conference window (used only if Weeks 4–12 cannot accommodate all matchups) | +| **Week 14** | **Reserved for annual protected rivalry games** | + +> **Note:** The algorithm should attempt to schedule all 9 conference games within Weeks 4–12 first. If the full slate cannot be accommodated within that window, Week 13 becomes available as an overflow slot. Week 14 is exclusively reserved for protected rivalry matchups and may not be used for rotating conference games. + +--- + +## Protected Annual Rivalries + +The following matchups are locked into the schedule every season and are treated as pre-filled, non-negotiable slots before any other scheduling logic runs. + +### Week 14 Rivalry Games + +These games are traditionally played in the final week of the regular season: + +| Matchup | Week | +| ----------------------------- | ---- | +| Michigan vs. Ohio State | 14 | +| Iowa vs. Nebraska | 14 | +| Minnesota vs. Wisconsin | 14 | +| Indiana vs. Purdue | 14 | +| Illinois vs. Northwestern | 14 | +| Illinois vs. Purdue | 14 | +| Maryland vs. Rutgers | 14 | +| Penn State vs. Michigan State | 14 | +| UCLA vs. USC | 14 | + +### Mid-Season Fixed Rivalry Games + +These games have traditional scheduling placements within the regular season and should be treated as fixed week assignments by the algorithm: + +| Matchup | Traditional Week | +| --------------------------- | ---------------- | +| Oregon vs. Washington | 8 | +| Michigan vs. Michigan State | 8 | +| Iowa vs. Wisconsin | 10 | +| Iowa vs. Minnesota | 8 | +| Nebraska vs. Minnesota | 6 | + +> **Note:** Additional mid-season rivalry games with established traditional weeks should be added to this table as they are identified. The algorithm must treat these week assignments as locked and plan all other rotating matchups around them. + +--- + +## Hard Constraints + +### (Rules that must never be violated) + +**H1 — Game Count** +Each team must play exactly 9 conference games per season. No more, no fewer. + +**H2 — No Repeat Opponents in a Single Season** +No team may play the same opponent more than once within the same season. + +**H3 — One Game Per Week Per Team** +No team may appear in more than one game in any given week. + +**H4 — Protected Rivalries Are Always Scheduled** +All protected rivalry matchups defined above must appear in every season's schedule without exception. + +**H5 — Protected Rivalry Weeks Are Locked** +Week 14 rivalry games must always be scheduled in Week 14. Mid-season fixed rivalry games must always be scheduled in their designated traditional week. These slots are immovable. + +**H6 — Conference Games Within Designated Windows** +All conference games must fall within Weeks 4–14. Non-conference games occupy Weeks 0–3. No conference game may be scheduled outside this range. + +**H7 — Opponent Coverage Within 5-Year Cycle** +Every team must face every other conference opponent **at least twice** within any rolling 5-year window — once as the home team and once as the away team. + +**H8 — Maximum Repeat Frequency** +No two non-protected-rivalry teams may play each other more than **3 times** within any 5-year window. + +**H9 — Home/Away Balance Per Season** +Each team must play either 4 home and 5 away conference games, or 5 home and 4 away conference games in a given season. A team may not play more than 5 home or more than 5 away conference games in a single season. + +**H10 — Home/Away Reciprocity Within Cycle** +If Team A hosts Team B in a given year, Team B must host Team A before those two teams meet again in the same home/away configuration. + +--- + +## Soft Constraints + +### (Preferred outcomes the algorithm optimizes for) + +**S1 — Avoid Back-to-Back Repeat Matchups** +Non-protected-rivalry teams should not play each other in consecutive seasons unless no valid alternative exists. + +**S2 — Distribute Strong Opponents Evenly** +The algorithm should avoid scheduling multiple historically competitive opponents in the same 2-week window for any given team where possible. + +**S3 — Primary Window Usage** +The algorithm should fill as many conference game slots as possible within Weeks 4–12 before utilizing Week 13 as overflow. + +**S4 — Home/Away Cycle Completion** +Over the 5-year cycle, the algorithm should aim to have every team host and visit every other team at least once, beyond just satisfying H7. + +**S5 — Season-to-Season Home/Away Alternation** +If Team A hosted Team B last season, the algorithm should prefer scheduling the return game (Team B hosting Team A) within the next 1–2 seasons rather than waiting until the end of the cycle. + +--- + +## Cycle Tracking Requirements + +The algorithm must maintain a persistent memory of the following data points across all 5 years in the active cycle: + +- **Matchup history:** Every pairing that has occurred, including year and home/away assignment +- **Home/away ledger:** For each team pair, which team has hosted and how many times within the cycle +- **Play count per pair:** How many times two teams have met within the rolling 5-year window +- **Coverage gaps:** Which team pairs have not yet met within the current cycle, flagged for priority scheduling in upcoming seasons + +At the start of each new season, the algorithm ingests the prior seasons' data and uses coverage gaps and home/away imbalances as weighted inputs when selecting rotating matchups. + +--- + +## Scheduling Execution Order + +The algorithm should process the schedule in the following order each season: + +1. **Lock protected rivalry games** — Pre-fill all annual rivalry matchups into their designated weeks +2. **Identify coverage gaps** — Flag team pairs that have not yet met or are behind on home/away reciprocity within the current 5-year window +3. **Prioritize gap matchups** — Assign gap pairings first when filling rotating conference slots +4. **Fill remaining slots** — Complete each team's 9-game slate using valid pairings that satisfy all hard constraints +5. **Score against soft constraints** — Among valid options, prefer combinations that score highest on soft constraint objectives +6. **Validate the full schedule** — Run a final pass confirming every hard constraint is satisfied before the schedule is finalized +7. **Update cycle ledger** — Record all matchups, home/away assignments, and play counts for use in future seasons + +--- + +## Edge Cases & Notes + +- **Illinois plays two protected rivals (Northwestern and Purdue).** This leaves Illinois with only 7 rotating slots per season rather than 8. The algorithm must account for this reduced flexibility. +- **Indiana and Purdue are a protected pair. Purdue is also protected with Illinois.** Purdue therefore has two protected games per season, same as Illinois. +- **Michigan State is protected with Michigan.** Michigan also plays Ohio State. Michigan therefore has two protected games per season as well. +- If the 5-year cycle ends and a team pair still has not met twice due to scheduling constraints, that pair must be treated as a **Priority 1** gap at the start of the next cycle. +- The algorithm should flag any season where a team is forced to play 3 non-protected-rivalry opponents within a single 5-year window and log it for review, even if it does not violate H8. + +# ACC Conference Football Scheduling Rules + +## Effective: 2027 Season Onward + +--- + +## 1. Teams + +The ACC consists of **17 football-playing members**: + +| Team | Primary Conf. Rival(s) | Week 14 Assignment | +| -------------- | --------------------------- | ------------------------ | +| Boston College | Syracuse | vs Syracuse (conf) | +| California | Stanford | vs Stanford (conf) | +| Clemson | Georgia Tech | vs South Carolina (OOC) | +| Duke | UNC, NC State, Wake Forest | vs UNC (conf) | +| Florida State | Miami | vs Florida (OOC) | +| Georgia Tech | Clemson | vs Georgia (OOC) | +| Louisville | Pittsburgh | vs Kentucky (OOC) | +| Miami | Florida State | Bye (hard default) | +| NC State | UNC, Duke, Wake Forest | Bye (hard default) | +| North Carolina | Duke, NC State, Wake Forest | vs Duke (conf) | +| Pittsburgh | Louisville | vs West Virginia (OOC) | +| SMU | — | Bye (hard default) | +| Stanford | California | vs California (conf) | +| Syracuse | Boston College | vs Boston College (conf) | +| Virginia | Virginia Tech | vs Virginia Tech (conf) | +| Virginia Tech | Virginia | vs Virginia (conf) | +| Wake Forest | UNC, Duke, NC State | Bye (hard default) | + +--- + +## 2. Season Structure + +| Parameter | Value | +| -------------------------- | ------------------------------------- | +| Total regular season weeks | 15 (Week 0 – Week 14) | +| Conference games per team | 8 or 9 (see Section 6) | +| OOC games | Managed externally by user/simulation | +| Conference game window | Week 0 – Week 13 (primary) | +| Week 14 | Hard lock (see Section 5) | + +--- + +## 3. Guaranteed Annual In-Conference Matchups + +The following in-conference matchups occur **every season** regardless of rotation. These are treated as **variables** — the list below reflects the assumed default set and can be updated without changing the underlying scheduling rules. + +### 3a. Guaranteed Matchup Registry + +| Matchup | Notes | +| -------------------------- | ------------------------------------------- | +| California vs Stanford | Geographic/historic rivalry; Week 14 locked | +| Clemson vs Georgia Tech | Annual ACC rivalry | +| Florida State vs Miami | Annual ACC rivalry | +| Louisville vs Pittsburgh | Annual ACC rivalry | +| Syracuse vs Boston College | Annual ACC rivalry | +| Virginia vs Virginia Tech | Annual ACC rivalry; Week 14 locked | +| UNC vs Duke | Tobacco Road | +| UNC vs NC State | Tobacco Road; Week 14 locked | +| UNC vs Wake Forest | Tobacco Road | +| Duke vs NC State | Tobacco Road | +| Duke vs Wake Forest | Tobacco Road | +| NC State vs Wake Forest | Tobacco Road | + +> **Note:** The Tobacco Road group (UNC, Duke, NC State, Wake Forest) all play each other annually — 3 guaranteed in-conference games each. If scheduling constraints make this impossible in a future season, the minimum requirement is that **UNC, Duke, and NC State** always play each other (2 guaranteed games each for those three; Wake Forest drops to 2 as well in that scenario). + +### 3b. Guaranteed Matchup Count Per Team + +| Team | Guaranteed In-Conf Opponents | Count | +| -------------- | ---------------------------- | ----- | +| Boston College | Syracuse | 1 | +| California | Stanford | 1 | +| Clemson | Georgia Tech | 1 | +| Duke | UNC, NC State, Wake Forest | 3 | +| Florida State | Miami | 1 | +| Georgia Tech | Clemson | 1 | +| Louisville | Pittsburgh | 1 | +| Miami | Florida State | 1 | +| NC State | UNC, Duke, Wake Forest | 3 | +| North Carolina | Duke, NC State, Wake Forest | 3 | +| Pittsburgh | Louisville | 1 | +| SMU | — | 0 | +| Stanford | California | 1 | +| Syracuse | Boston College | 1 | +| Virginia | Virginia Tech | 1 | +| Virginia Tech | Virginia | 1 | +| Wake Forest | UNC, Duke, NC State | 3 | + +> **Note on SMU:** SMU has no designated guaranteed in-conference rival. All 9 of SMU's conference opponents in a 9-game season are drawn from the flexible rotation pool. + +### 3c. Home/Away Rotation + +- Home and away assignments for guaranteed matchups **flip on a 2-year cycle**. +- If Team A hosts Team B in Year 1, Team A visits Team B in Year 2. + +--- + +## 4. Flexible Conference Games + +Each team's remaining conference games beyond their guaranteed matchups are drawn from a **pre-assigned rotation table**. + +### 4a. Flexible Game Slots Per Season + +| Team | Guaranteed Games (G) | Flexible Slots (9 - G) | Non-Guaranteed Pool Size | +| ----------------------------------------------------- | -------------------- | ---------------------- | ------------------------ | +| Tobacco Road teams (Duke, UNC, NC State, Wake Forest) | 3 | 6 | 12 | +| Teams with 1 guaranteed rival | 1 | 8 | 14 | +| SMU | 0 | 9 | 16 | + +### 4b. Rotation Table Model + +Because the ACC's 17-team structure creates asymmetric guaranteed matchup counts, a **universal fixed-year cycle does not apply equally to all teams**. Instead, each team maintains a **pre-assigned rotation table** built around the following principle: + +> Every non-guaranteed conference opponent must be played **at least once within a defined rotation window**, with home/away alternating across appearances. + +The rotation window per team is determined as follows: + +| Flexible Slots/Season | Non-Guaranteed Pool | Rotation Window | +| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------- | +| 6 (Tobacco Road) | 12 opponents | 4 years (6×4=24 slots = 12 opponents × 2 plays each) ✅ | +| 8 (1 guaranteed rival) | 14 opponents | Managed via rotation table; all 14 opponents seen within 2 seasons, full home/away cycle completes in 4 seasons | +| 9 (SMU) | 16 opponents | Managed via rotation table; all 16 opponents seen within 2 seasons | + +### 4c. Rotation Table Construction Rules + +When building or updating the rotation table for a given team: + +1. Split the non-guaranteed opponent pool into two equal (or near-equal) halves — **Group A** and **Group B** +2. In **odd-numbered cycle years** (Year 1, Year 3), play Group A opponents +3. In **even-numbered cycle years** (Year 2, Year 4), play Group B opponents +4. Home/away assignments **flip between Year 1↔Year 3** and **Year 2↔Year 4** +5. For teams with odd-sized pools (e.g. 14 or 16 opponents), one opponent per cycle year may appear in both groups — this opponent is played in back-to-back years before the home/away flip + +### 4d. Flexible Game Scheduling Window + +- Flexible conference games may be scheduled in **any open week between Week 0 and Week 13** +- Flexible conference games may **not** be scheduled in Week 14 unless the Week 14 overflow rule is triggered (see Section 5c) +- There are no restrictions on consecutive away games or bye week placement + +--- + +## 5. Week 14 Rules + +Week 14 operates as a **hard lock** for all 17 teams. Assignments fall into four categories: + +### 5a. Confirmed In-Conference Week 14 Games + +| Matchup | Type | +| --------------------------- | ------------------ | +| California vs Stanford | Conference rivalry | +| Virginia vs Virginia Tech | Conference rivalry | +| UNC vs North Carolina State | Conference rivalry | +| Syracuse vs Boston College | Conference rivalry | + +### 5b. Confirmed OOC Week 14 Games + +| Team | OOC Opponent | +| ------------- | -------------- | +| Florida State | Florida | +| Clemson | South Carolina | +| Georgia Tech | Georgia | +| Louisville | Kentucky | +| Pittsburgh | West Virginia | + +### 5c. Hard Bye — Week 14 + +The following teams are assigned a **bye in Week 14 by default**: + +- Miami +- NC State +- SMU +- Wake Forest + +> **Overflow Rule:** If any of these four teams cannot fulfill their full conference game requirement between Weeks 0–13 due to scheduling constraints, one flexible conference game may be moved into Week 14 as a last resort. This should be treated as an exception, not standard practice. + +--- + +## 6. The 8-Game Schedule Rule (17-Team Accommodation) + +Because the ACC has 17 members, **one team per season plays 8 conference games** instead of 9. All other teams play 9 conference games. + +### 6a. Selection Process + +1. Maintain a **selection tracker dictionary** keyed by team name, storing the most recent season in which that team was assigned the 8-game schedule +2. At the start of each season's scheduling process, identify all teams that have **never been selected** or were **selected least recently** +3. From that pool, select one team **at random** +4. Record the selected team and the current season year in the tracker + +### 6b. Tracker Format + +``` +8_GAME_TRACKER = { + "Boston College": null, // null = never selected + "California": null, + "Clemson": null, + "Duke": null, + "Florida State": null, + "Georgia Tech": null, + "Louisville": null, + "Miami": null, + "NC State": null, + "North Carolina": null, + "Pittsburgh": null, + "SMU": null, + "Stanford": null, + "Syracuse": null, + "Virginia": null, + "Virginia Tech": null, + "Wake Forest": null +} +``` + +### 6c. Selection Algorithm + +``` +function select_8_game_team(tracker, current_season): + + // Step 1: Find the minimum last-selected season across all teams + // (null counts as the lowest possible value — never selected) + never_selected = [team for team in tracker if tracker[team] is null] + + if never_selected is not empty: + selected = random_choice(never_selected) + + else: + // All teams have been selected at least once + // Find the team(s) selected longest ago + oldest_season = min(tracker.values()) + eligible = [team for team in tracker if tracker[team] == oldest_season] + selected = random_choice(eligible) + + // Step 2: Update tracker + tracker[selected] = current_season + + return selected +``` + +### 6d. Tracking Notes + +- Tracking begins with the **2027 season** (first full 9-game format season) +- The 2026 transition season is **not counted** toward the tracker +- After all 17 teams have been selected once (~17 seasons), the tracker continues — teams are always selected based on who was picked **least recently** +- A team selected for an 8-game schedule **drops one flexible game slot** for that season only; their guaranteed matchups remain unchanged + +--- + +## 7. Game Count Summary Per Season + +| Category | Standard Team | 8-Game Team | +| -------------------------- | --------------------- | ------------------ | +| Guaranteed in-conf games | G (variable per team) | G (unchanged) | +| Flexible conf games | 9 - G | 8 - G | +| **Total conference games** | **9** | **8** | +| OOC games | Managed externally | Managed externally | + +--- + +## 8. Summary Formula (Pseudocode) + +``` +// --- REGISTRIES (treated as variables / inputs) --- + +GUARANTEED_CONF_REGISTRY = { + (California, Stanford), + (Clemson, GeorgiaTech), + (FloridaState, Miami), + (Louisville, Pittsburgh), + (Syracuse, BostonCollege), + (Virginia, VirginiaTech), + (UNC, Duke), (UNC, NCState), (UNC, WakeForest), + (Duke, NCState), (Duke, WakeForest), + (NCState, WakeForest) +} + +WEEK14_CONF_LOCKS = { + (California, Stanford), + (Virginia, VirginiaTech), + (UNC, Duke), + (Syracuse, BostonCollege) +} + +WEEK14_OOC_LOCKS = { + FloridaState: Florida, + Clemson: SouthCarolina, + GeorgiaTech: Georgia, + Louisville: Kentucky, + Pittsburgh: WestVirginia +} + +WEEK14_HARD_BYE = { Miami, NCState, SMU, WakeForest } + // overflow rule: may use Week 14 if Weeks 0-13 cannot fulfill schedule + +ROTATION_TABLE = { ... } // pre-assigned per team, per season year + +8_GAME_TRACKER = { team: last_selected_season | null } + + +// --- PER-SEASON SCHEDULING --- + +for each season Y: + + // Step 1: Select the 8-game team for this season + eight_game_team = select_8_game_team(8_GAME_TRACKER, Y) + + for each team T: + + conf_game_target = (8 if T == eight_game_team else 9) + + // Step 2: Assign guaranteed in-conference games + guaranteed_games = lookup_guaranteed(T, GUARANTEED_CONF_REGISTRY) + → home/away = flip(Y, opponent) // 2-year cycle + + // Step 3: Pull flexible games from rotation table + flexible_count = conf_game_target - len(guaranteed_games) + flexible_games = lookup_rotation(T, Y, ROTATION_TABLE, flexible_count) + → home/away defined by rotation table + → all non-guaranteed opponents seen at least once per rotation window + + // Step 4: Lock Week 14 + if T in WEEK14_CONF_LOCKS: + week14 = lookup_week14_conf(T) // in-conference game + else if T in WEEK14_OOC_LOCKS: + week14 = WEEK14_OOC_LOCKS[T] // OOC game (scheduled externally) + else if T in WEEK14_HARD_BYE: + week14 = BYE // default; overflow exception applies + else: + week14 = BYE + + // Step 5: Schedule all conference games in Weeks 0–13 + all_conf_games = guaranteed_games + flexible_games + schedule = place_games(all_conf_games, window=Week0..Week13) + → no placement restrictions beyond window + → bye weeks float freely + + // Step 6: Apply Week 14 + schedule[14] = week14 +``` + +--- + +## 9. Constraints Summary + +| Rule | Constraint | +| --------------------------- | ------------------------------------------------------------------------------------- | +| Total conference games | 9 per team (8 for one designated team per season) | +| Guaranteed in-conf matchups | All registry pairs play every season | +| Home/away (guaranteed) | Flips every 2 years | +| Flexible game rotation | Pre-assigned rotation table; all non-guaranteed opponents seen within rotation window | +| Home/away (flexible) | Alternates across rotation cycle appearances | +| Conference game window | Weeks 0–13 (primary) | +| Week 14 | Hard lock for all 17 teams | +| Week 14 (conf rivalry) | California/Stanford, Virginia/VT, UNC/Duke, Syracuse/BC always play in Week 14 | +| Week 14 (OOC rivalry) | Florida State, Clemson, Georgia Tech, Louisville, Pitt play OOC rival in Week 14 | +| Week 14 (hard bye) | Miami, NC State, SMU, Wake Forest default to bye; overflow exception allowed | +| 8-game team selection | Random from least-recently-selected pool; tracked from 2027 onward | +| 8-game tracker reset | Never resets — always selects least recently chosen team | +| Tobacco Road minimum | UNC, Duke, NC State always play each other even if 4-way group cannot be fulfilled | +| SMU | No guaranteed rival; all conference games drawn from rotation table | + +# American Athletic Conference (The American) Football Scheduling Rules + +--- + +## 1. Teams + +The American Athletic Conference consists of **14 football-playing members**: + +| Team | Guaranteed In-Conf Rival | Week 14 Assignment | +| ------------- | ------------------------ | ---------------------- | +| Army | Navy | vs Navy (conf) | +| ECU | — | Bye (default) | +| FAU | — | Bye (default) | +| Memphis | UAB | vs UAB (conf) | +| UNC Charlotte | — | Bye (default) | +| Navy | Army | vs Army (conf) | +| North Texas | — | Bye (default) | +| Rice | — | Bye (default) | +| Temple | — | Bye (default) | +| Tulane | — | vs Southern Miss (OOC) | +| Tulsa | — | Bye (default) | +| UAB | Memphis | vs Memphis (conf) | +| USF | — | vs UCF (OOC) | +| UTSA | — | vs Texas State (OOC) | + +--- + +## 2. Season Structure + +| Parameter | Value | +| -------------------------- | ------------------------------------------ | +| Total regular season weeks | 15 (Week 0 – Week 14) | +| Conference games per team | 8 | +| Conference game window | Week 0 – Week 13 (primary) | +| Week 14 | Hard lock for all 14 teams (see Section 5) | +| Week 15 | Does not exist in this scheduling system | +| OOC games | Managed externally by user/simulation | +| Bye weeks | Float freely; no placement restrictions | + +--- + +## 3. Guaranteed Annual In-Conference Matchups + +The following in-conference matchups occur **every season** regardless of rotation. These are treated as **variables** — the list below reflects the assumed default set and can be updated without changing the underlying scheduling rules. + +### 3a. Guaranteed Matchup Registry + +| Matchup | Week 14 Locked? | Notes | +| -------------- | --------------- | --------------------------------------------------------------- | +| Army vs Navy | ✅ Yes | Traditionally Week 15; moved to Week 14 for simulation purposes | +| Memphis vs UAB | ✅ Yes | Battle for the Bones | + +### 3b. Guaranteed Matchup Count Per Team + +| Team | Guaranteed In-Conf Opponents | Count | +| ------------- | ---------------------------- | ----- | +| Army | Navy | 1 | +| ECU | — | 0 | +| FAU | — | 0 | +| Memphis | UAB | 1 | +| UNC Charlotte | — | 0 | +| Navy | Army | 1 | +| North Texas | — | 0 | +| Rice | — | 0 | +| Temple | — | 0 | +| Tulane | — | 0 | +| Tulsa | — | 0 | +| UAB | Memphis | 1 | +| USF | — | 0 | +| UTSA | — | 0 | + +### 3c. Home/Away Rotation + +- Home and away assignments for guaranteed matchups **flip on a 2-year cycle**. +- If Team A hosts Team B in Year 1, Team A visits Team B in Year 2. + +--- + +## 4. Flexible Conference Games + +Each team's remaining conference games beyond their guaranteed matchups are drawn from a **pre-assigned rotation table**, cycling through all non-guaranteed conference opponents over a 4-year window. + +### 4a. Flexible Game Slots Per Season + +| Team Type | Guaranteed Games (G) | Flexible Slots (8 - G) | Non-Guaranteed Pool Size | +| -------------------------------------------------------- | -------------------- | ---------------------- | ------------------------ | +| Teams with 1 guaranteed rival (Army, Navy, Memphis, UAB) | 1 | 7 | 12 | +| Teams with no guaranteed rival (all others) | 0 | 8 | 13 | + +### 4b. 4-Year Rotation Cycle + +All non-guaranteed opponents must be played **at least twice within a 4-year cycle** — once at home and once away. The rotation is structured as follows: + +| Year | Opponents Played | Home/Away | +| ------ | ---------------- | ------------------- | +| Year 1 | Group A | Per rotation table | +| Year 2 | Group B | Per rotation table | +| Year 3 | Group A | Flipped from Year 1 | +| Year 4 | Group B | Flipped from Year 2 | + +### 4c. Group Assignment + +The non-guaranteed opponent pool for each team is split into **Group A** and **Group B** via the pre-assigned rotation table: + +| Team Type | Pool Size | Group A | Group B | Extra Slots/Cycle | +| ------------------- | ------------ | ----------- | -------------------- | ------------------------------------- | +| 1 guaranteed rival | 12 opponents | 6 opponents | 6 opponents | 4 extra slots (can revisit opponents) | +| 0 guaranteed rivals | 13 opponents | 7 opponents | 6 opponents (or 6/7) | 6 extra slots (can revisit opponents) | + +> **Note on Extra Slots:** Because flexible slots per cycle exceed the minimum needed to play everyone twice, extra slots are filled by **revisiting opponents** from the current cycle year's group. Priority for revisits is given to opponents not yet seen in the current season or opponents with a home/away imbalance. + +### 4d. Rotation Table Construction Rules + +When building or updating the rotation table for a given team: + +1. Split the non-guaranteed opponent pool into two equal (or near-equal) halves — **Group A** and **Group B** +2. Assign Group A to **odd cycle years** (Year 1, Year 3) +3. Assign Group B to **even cycle years** (Year 2, Year 4) +4. Home/away assignments **flip between Year 1↔Year 3** and **Year 2↔Year 4** +5. Fill any remaining flexible slots in a given season with revisit opponents drawn from the current year's group, prioritizing home/away balance + +### 4e. Flexible Game Scheduling Window + +- Flexible conference games may be scheduled in **any open week between Week 0 and Week 13** +- Flexible conference games may **not** be scheduled in Week 14 unless the overflow rule is triggered (see Section 5c) +- Bye weeks float freely with no placement restrictions + +--- + +## 5. Week 14 Rules + +Week 14 operates as a **hard lock** for all 14 teams. No flexible conference game may be placed in Week 14 unless the overflow exception applies. + +### 5a. In-Conference Week 14 Hard Locks + +| Matchup | Type | +| -------------- | ----------------------------------------- | +| Army vs Navy | Conference rivalry | +| Memphis vs UAB | Conference rivalry (Battle for the Bones) | + +### 5b. OOC Week 14 Hard Locks + +| Team | OOC Opponent | Notes | +| ------ | ------------- | ------------------- | +| Tulane | Southern Miss | Battle for the Bell | +| USF | UCF | OOC rivalry | +| UTSA | Texas State | OOC rivalry | + +### 5c. Hard Bye — Week 14 + +The following teams are assigned a **bye in Week 14 by default**: + +| Team | +| ------------- | +| ECU | +| FAU | +| UNC Charlotte | +| North Texas | +| Rice | +| Temple | +| Tulsa | + +> **Overflow Rule:** If any of these teams cannot fulfill their full 8-game conference requirement between Weeks 0–13 due to scheduling constraints, one flexible conference game may be moved into Week 14 as a last resort. This should be treated as an exception, not standard practice. + +--- + +## 6. Game Count Summary Per Season + +| Category | Teams w/ 1 Guaranteed Rival | Teams w/ 0 Guaranteed Rivals | +| -------------------------- | --------------------------- | ---------------------------- | +| Guaranteed in-conf games | 1 | 0 | +| Flexible conf games | 7 | 8 | +| **Total conference games** | **8** | **8** | +| OOC games | Managed externally | Managed externally | + +> **Note:** Every team in the American plays exactly **8 conference games** every season. There is no odd-team accommodation rule. + +--- + +## 7. Summary Formula (Pseudocode) + +``` +// --- REGISTRIES (treated as variables / inputs) --- + +GUARANTEED_CONF_REGISTRY = { + (Army, Navy), // Week 14 locked — Army vs Navy + (Memphis, UAB) // Week 14 locked — Battle for the Bones +} + +WEEK14_CONF_LOCKS = { + (Army, Navy), + (Memphis, UAB) +} + +WEEK14_OOC_LOCKS = { + Tulane: SouthernMiss, // Battle for the Bell + USF: UCF, + UTSA: TexasState +} + +WEEK14_HARD_BYE = { + ECU, FAU, UNCCharlotte, NorthTexas, Rice, Temple, Tulsa +} +// Overflow rule: may use Week 14 if Weeks 0–13 cannot fulfill schedule + +ROTATION_TABLE = { ... } // pre-assigned per team, per season year + + +// --- PER-SEASON SCHEDULING --- + +for each season Y: + + for each team T: + + conf_game_target = 8 // all teams play exactly 8 conference games + + // Step 1: Assign guaranteed in-conference games + guaranteed_games = lookup_guaranteed(T, GUARANTEED_CONF_REGISTRY) + → 0 or 1 opponent + → home/away = flip(Y, opponent) // 2-year cycle + + // Step 2: Pull flexible games from rotation table + flexible_count = conf_game_target - len(guaranteed_games) + flexible_games = lookup_rotation(T, Y, ROTATION_TABLE, flexible_count) + → Group A in Years 1 & 3; Group B in Years 2 & 4 + → home/away flipped between Year 1↔3 and Year 2↔4 + → extra slots filled by revisit opponents from current group + + // Step 3: Lock Week 14 + if T in WEEK14_CONF_LOCKS: + week14 = lookup_week14_conf(T) // in-conference rivalry game + else if T in WEEK14_OOC_LOCKS: + week14 = WEEK14_OOC_LOCKS[T] // OOC game (scheduled externally) + else: + week14 = BYE // default; overflow exception applies + + // Step 4: Schedule all conference games in Weeks 0–13 + all_conf_games = guaranteed_games + flexible_games + schedule = place_games(all_conf_games, window=Week0..Week13) + → no placement restrictions beyond window + → bye weeks float freely + + // Step 5: Apply Week 14 + schedule[14] = week14 +``` + +--- + +## 8. Constraints Summary + +| Rule | Constraint | +| --------------------------- | ------------------------------------------------------------------------------ | +| Total conference games | Exactly 8 per team, every season | +| Odd-team accommodation | None required (14 teams divides evenly) | +| Guaranteed in-conf matchups | All registry pairs play every season | +| Home/away (guaranteed) | Flips every 2 years | +| Flexible game rotation | Pre-assigned rotation table; 4-year cycle | +| Non-guaranteed opponents | Every opponent played at least twice per 4-year cycle (once home, once away) | +| Home/away (flexible) | Flips between Year 1↔3 and Year 2↔4 | +| Extra rotation slots | Filled by revisit opponents; prioritize home/away balance | +| Conference game window | Weeks 0–13 (primary) | +| Week 14 | Hard lock for all 14 teams | +| Week 14 (conf rivalry) | Army/Navy and Memphis/UAB always play in Week 14 | +| Week 14 (OOC rivalry) | Tulane, USF, UTSA play OOC rival in Week 14 | +| Week 14 (hard bye) | ECU, FAU, Charlotte, North Texas, Rice, Temple, Tulsa default to bye | +| Overflow rule | Bye teams may use Week 14 as last resort if Weeks 0–13 cannot fulfill schedule | +| Week 15 | Does not exist in this scheduling system | + +# Pac 12 Conference Scheduling Rules + +- Because the Pac 12 has 8 teams, we should go with a round robin schedule for the Pac 12. Each team will face all 7 other conference opponents and schedule 5 out of conference games. + +## Pac 12 Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Boise State vs Fresno State | 14 | Conference rivalry (Battle of the Milk Can) | +| SDSU vs Fresno State | 4 | Conference rivalry (Battle For the Old Oil Can) | +| Oregon State vs Wazzu | 13 | Conference rivalry (Pac-2 Rivalry) | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Colorado State vs Wyoming | 13 | Border War | +| Washington vs Wazzu | 14 | Apple Cup | +| Oregon State vs Oregon | 14 | Civil War | +| Texas State vs UTSA | 14 | I-35 Rivalry | +| Fresno State vs San Jose State | 2 | Battle for the Valley | +| Utah State vs Wyoming | 1 | Bridger's Battle | + +# Mountain West Conference Scheduling Rules + +- The Mountain West will have ten football conference members in 2027 and beyond and will have a round robin schedule, but will only play 8 conference members each season rather than 9. This means each team will have 4 OOC matchups and 8 conference matchups each season. It is expected that each team will play each other conference member in a home-and-away series at least once within a 4 year span. + +## MWC Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| UNLV vs Nevada | 14 | Fremont Cannon | +| Wyoming vs Hawaii | 13 | Paniolo Trophy | +| Hawaii vs San Jose State | 4 | Dick Tomey Legacy Trophy | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Colorado State vs Wyoming | 3 | Border War | +| Fresno State vs San Jose State | 2 | Battle for the Valley | +| Utah State vs Wyoming | 1 | Bridger's Battle | +| North Dakota State vs South Dakota State | 1 | Dakota Marker | +| Northern Illinois vs Ball State | 14 | Bronze Stalk Trophy | + +# Mid-American Conference (MAC) Scheduling Rules + +- The MAC will use a pod-based protected rivalry system scheduling format for its conference schedule. Teams will be divided into 4 pods of 3 teams each (The only exclusion is Pod 1, which as 4 because of UMass), and each team will be guaranteed to face the other 2 teams in its pod every season. Every team in the MAC will be guaranteed to face every other team in the MAC at least once every 4 years. + The pods are as follows: + | Pod | School 1 | School 2 | School 3 | + | --- | -------- | -------- | -------- | + | 1 | Akron | Buffalo | Kent State | | UMass + | 2 | Ball State | Miami (OH) | Ohio | + | 4 | Bowling Green | Sacramento State | Toledo | + | 3 | CMU | EMU | WMU | + +## MAC Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Akron vs Kent State | 14 | Wagon Wheel | +| Bowling Green vs Kent State | Any | Anniversary Award | +| Bowling Green vs Toledo | 14 | Battle of I-75 | +| CMU vs WMU | 14 | Victory Cannon | +| CMU vs EMU | Any | Michigan MAC Trophy | +| EMU vs WMU | Any | Michigan MAC Trophy | +| Buffalo vs UMass | 14 | Flagship Cup | +| Miami (OH) vs Ohio | 14 | Battle of the Bricks | +| Miami (OH) vs Ball State | Any | Red Bird Rivalry | +| Sacramento State vs Ball State | 13 | Battle for the SAC | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Northern Illinois vs Ball State | 14 | Battle for the Bronze Stalk | + +# Sun Belt Conference Scheduling Rules + +- For the Sun belt conference schedule - Every season a team plays all 6 of the division team members and then 2 teams from the other division. Keep track of previous conference games and which teams played which interdivision members when selecting the two cross-division opponents that each team must play in the season. + +# Conference USA Scheduling Rules + +- Conference USA is a 10 team conference that plays an 8 game conference schedule. This means each team will miss playing a conference opponent each season. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 3 times in a 4 year span. Of those three times, at least once should be at home and at least once should be away. + +## Conference USA Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Middle Tennessee vs Western Kentucky | 13 | 100 Miles of Hate | + +# Notre Dame Rules + +- Notre Dame is an independent team that is not beholden to a conference. Notre Dame traditionally has some rivalry games that need to be played every season. The next section details these OOC rivalry games. + +## Notre Dame Rivalries + +The following out of conference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Notre Dame vs Michigan | Any | Michigan-Notre Dame Rivalry | +| Notre Dame vs USC | If season is an even year, Week 4; otherwise, week 13 | Jeweled Shilllelagh | +| Notre Dame vs Stanford | If season is an odd year, Week 4; otherwise, week 13 | Stanford-Notre Dame Rivalry | +| Notre Dame vs Navy | 0 | Navy-Notre Dame Rivalry | +| Notre Dame vs Michigan State | 2 | Battle for the Megaphone | +| Notre Dame vs Boston College | 3 | Ireland Trophy | + +# Big Sky Scheduling Rules + +- Big Sky Confernece is a 13 team conference that plays an 8 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## Big Sky Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Cal Poly vs UC Davis | 12 | Battle for the Golden Horseshoe | +| Eastern Washington vs Montana | 12 | EWU-UM Governor's Cup | +| Eastern Washington vs Portland State | 13 | Dam Cup | +| Idaho vs Idaho State | 13 | Battle of the Domes | +| Idaho vs Montana | 8 | Little Brown Stein | +| Montana vs Montana State | 13 | Brawl of the Wild | +| Southern Utah vs Northern Arizona | 12 | Grand Canyon Rivalry | +| Southern Utah vs Weber State | 5 | Beehive Bowl | +| Southern Utah vs Utah Tech | 8 | Battle of the Ax | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Sacramento State vs UC Davis | 14 | Causeway Classic | + +# MVFC Scheduling Rules + +- The MVFC is a 9 team conference that plays an 8 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## MVFC Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| South Dakota vs South Dakota State | 11 | South Dakota Showdown | +| North Dakota vs South Dakota | 8 | Sitting Bull Trophy | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Eastern Illinois vs Illinois State | 3 | Mid-America Classic | +| Drake vs Northern Iowa | 3 | Drake-Northern Iowa Rivalry | + +# CAA Scheduling Rules + +- The CAA is a 13 team conference that plays an 8 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## CAA Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Albany vs Stony Brook | 12 | Albany-Stony Brook Rivalry | +| Maine vs New Hampshire | 13 | Battle for the Brice-Cowell Musket | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Hampton vs Howard | 3 | The Real HU | +| Hampton vs Norfolk State | 11 | Battle for the Bay | +| Towson vs Morgan State | 11 | The Battle for Greater Baltimore | +| North Carolina A&T vs North Carolina Central | 3 | NCAT-NCCU Rivalry | +| North Carolina A&T vs South Carolina State | 11 | NCAT-SCST Rivalry | +| Dartmouth vs New Hampshire | 14 | Dartmouth vs New Hampshire | + +# MEAC Scheduling Rules + +- The MEAC is a 6 team conference that plays a 5 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## MEAC Rivalries + +Because the MEAC runs as a 6 team conference, each team is expected to play all of their opponents in a given season. It does not matter which week a rivalry takes place. + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Hampton vs Howard | 3 | The Real HU | +| Hampton vs Norfolk State | 11 | Battle for the Bay | +| Towson vs Morgan State | 11 | The Battle for Greater Baltimore | +| North Carolina A&T vs North Carolina Central | 3 | NCAT-NCCU Rivalry | +| North Carolina A&T vs South Carolina State | 11 | NCAT-SCST Rivalry | + +# Southland Conference Scheduling Rules + +- The Southland Conference is a 10 team conference that plays an 8 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## Southland Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Stephen F. Austin vs Northwestern State | 12 | Chief Caddo | +| Lamar vs McNeese | 12 | Battle of the Border | +| Northwestern State vs McNeese | 4 | NWST-MCN rivalry | +| Northwestern State vs Nicholls | 8 | NSU Challenge | +| Northwestern State vs Southeastern Louisiana | 8 | NWST-SELA Rivalry | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| McNeese vs Central Arkansas | 2 | Red Beans and Rice Bowl | + +# Ivy League Scheduling Rules + +- The Ivy League is an 8 team conference that plays a 7 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## Ivy League Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Harvard vs Yale | 14 | The Game | +| Penn vs Princeton | 14 | Battle for the P | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Dartmouth vs New Hampshire | 14 | Dartmouth vs New Hampshire | +| Columbia vs Fordham | 14 | Liberty Cup | +| Brown vs Rhode Island | 3 | Brown-Rhode Island | +| Colgate vs Cornell | 3 | Colgate-Cornell | +| Yale vs LeHigh | 3 | Yank Townsend Trophy | + +# Southern Conference Scheduling Rules + +- The Southern Conference is a 10 team conference that plays a 9 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## Southern Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| VMI vs The Citadel | 13 | Military Classic of the South | +| The Citadel vs Furman | 10 | The Citadel-Furman | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| William & Mary vs VMI | 3 | VMI-William & Mary | +| Richmond vs VMI | 1 | VMI-Richmond | +| Charlston Southern vs The Citadel | 1 | The Citadel-Charleston Southern | + +# OVC-Big South Football Conference Scheduling Rules + +- The Southern Conference is an 8 team conference that plays a 7 game conference schedule. When creating the round-robin schedule, please keep track of the amount of times each team has played their conference opponents over the last four seasons. At most, a team should have faced all of their conference opponents at least 2 times in a 4 year span. Of those two times, at least once should be at home and at least once should be away. + +## OVC-Big South Football Conference Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Tennessee State vs UT Martin | 10 | Sgt. York Trophy | +| Western Illinois vs Eastern Illinois | 12 | East vs West Classic | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Jackson State vs Tennessee State | 3 | Southern Heritage Classic | +| Tennessee Tech vs UT Martin | 9 | Sgt. York Trophy | +| Tennessee Tech vs Tennessee State | 8 | Sgt. York Trophy | + +# Southwestern Athletic Conference (SWAC) Scheduling Rules + +- The Southern Conference is a 12 team conference that plays an 8 game conference schedule consisting of five divisional matches and three cross-divisional games. Teams rotate cross-division opponents every two years. + +## Southwestern Athletic Conference (SWAC) Rivalries + +The following intraconference games should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Florida A&M vs Jackson State | 1 | The Orange Blossom Classic | +| Texas Southern vs Prairie View A&M | 1 | Labor Day Classic | +| Grambling State vs Prairie View A&M | 4 | State Fair Classic | +| Alabama A&M vs Alabama State | 10 | Magic City Classic | +| Bethune Cookman vs Florida A&M | 13 | Florida Classic | +| Grambling State vs Southern | 13 | Bayou Classic | +| Mississippi Valley State vs Jackson State | 13 | Mississippi Classic | + +The following interconference rivalry games (OOC) should be played within the designated week: +| Matchup | Week | Type | +| ---------------------------- | -------------- | ----------------------------------------------- | +| Jackson State vs Tennessee State | 3 | Southern Heritage Classic | + +# Remaining Conferences + +The remaining conferences not covered (Pioneer League, NEC, UAC, etc.) Should take a generic conference format. +For the Pioneer League with 11 members, each team should face at most 9 conference opponents per year. At most, they should face every conference opponent at least twice within a four year span, with at least a home and away game for each opponent. + +The NEC will have 9 conference members. Each team will have an 8-game conference schedule with a balanced number of home and away games. Each team is expected to play all conference members each year with at least a home-and-away series complete every two years. + +The UAC has 8 conference members. Each team will have a 7-game conference schedule, with a balanced number of home and away games if possible. Each team is expected to play all conference members each year with at least a home-and-away series complete every two years. + +# Endpoints + +## CreateCFBGameRequest + +This is a POST request where the user sends a CFBGameRequest struct and creates an entry into the Database. + +## CreateNFLGameRequest + +This is a POST request where the user sends an NFLGameRequest struct and creates an entry into the Database. + +## AcceptCFBGameRequest + +This is a GET request where the user sends a request ID, which toggles the Request as ACCEPTED and saves. Use the gamerequest function Accepted(). We should check the SendingTeamID on whether the college team that sent the request is a user team. If they are a user team, send a notification to the team's Coach that the request was accepted. + +## RejectCFBGameRequest + +This is a GET request where the user sends a request ID, and then deletes the record from the DB. We should check the SendingTeamID on whether the college team that sent the request is a user team. If they are a user team, send a notification to the team's Coach that the request was rejected. + +## ProcessCFBGameRequest + +This is a GET request that passes the GameRequest ID and then creates a new CollegeGame record from the existing GameRequestID. Fetch for all stadiums & create a Stadium Map by ID; pass the ArenaID into the map to ensure that we're using the correct stadium data for the game. + +## VetoCFBGameRequest + +This is a GET request that fetches for a GameRequest record and then deletes it. Fetch for the College Teams using the SendingTeamID and the ReceivingTeamID and for each of those teams that is a user team, send a notification indicating that the game request was vetoed. + +## AcceptNFLGameRequest + +This is a GET request where the user sends a request ID, which toggles the Request as ACCEPTED and saves. Use the gamerequest function Accepted(). We should check the SendingTeamID on whether the NFL team that sent the request is a user team. If they are a user team, send a notification to the team's Owner that the request was accepted. + +## RejectNFLGameRequest + +This is a GET request where the user sends a request ID, and then deletes the record from the DB. We should check the SendingTeamID on whether the college team that sent the request is a user team. If they are a user team, send a notification to the team's Owner that the request was rejected. + +## ProcessNFLGameRequest + +This is a GET request that passes the GameRequest ID and then creates a new NFLGame record from the existing GameRequestID. Fetch for all stadiums & create a Stadium Map by ID; pass the ArenaID into the map to ensure that we're using the correct stadium data for the game. + +## VetoNFLGameRequest + +This is a GET request that fetches for a GameRequest record and then deletes it. Fetch for the NFL Teams using the SendingTeamID and the ReceivingTeamID and for each of those teams that is a user team, send a notification indicating that the game request was vetoed. diff --git a/controller/BootstrapController.go b/controller/BootstrapController.go index 75599ff..2585995 100644 --- a/controller/BootstrapController.go +++ b/controller/BootstrapController.go @@ -81,7 +81,7 @@ func BootstrapSchedulingData(w http.ResponseWriter, r *http.Request) { username := vars["username"] collegeID := vars["collegeID"] seasonID := vars["seasonID"] - data := managers.GetCollegePollsBootstrap(username, collegeID, seasonID) + data := managers.GetSchedulePageBootstrap(username, collegeID, seasonID) bootstrapData, err := easyjson.Marshal(data) if err != nil { log.Printf("Failed to encode JSON response: %v", err) diff --git a/controller/SchedulerController.go b/controller/SchedulerController.go new file mode 100644 index 0000000..f3e0f25 --- /dev/null +++ b/controller/SchedulerController.go @@ -0,0 +1,136 @@ +package controller + +import ( + "encoding/json" + "net/http" + + "github.com/CalebRose/SimFBA/managers" + "github.com/CalebRose/SimFBA/structs" + "github.com/gorilla/mux" +) + +func TestCFBScheduler(w http.ResponseWriter, r *http.Request) { + managers.BaseGenerateCFBSchedule(true) + json.NewEncoder(w).Encode(true) +} + +// CreateCFBGameRequest accepts a CFBGameRequest body and persists it. +func CreateCFBGameRequest(w http.ResponseWriter, r *http.Request) { + var request structs.CFBGameRequest + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + managers.CreateCFBGameRequest(request) + json.NewEncoder(w).Encode(true) +} + +// AcceptCFBGameRequest marks the request as accepted. +func AcceptCFBGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.AcceptCFBGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// RejectCFBGameRequest deletes the request. +func RejectCFBGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.RejectCFBGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// ProcessCFBGameRequest converts an accepted request into a CollegeGame record. +func ProcessCFBGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.ProcessCFBGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// VetoCFBGameRequest deletes the request via admin veto. +func VetoCFBGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.VetoCFBGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// CreateNFLGameRequest accepts an NFLGameRequest body and persists it. +func CreateNFLGameRequest(w http.ResponseWriter, r *http.Request) { + var request structs.NFLGameRequest + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + managers.CreateNFLGameRequest(request) + json.NewEncoder(w).Encode(true) +} + +// AcceptNFLGameRequest marks the NFL request as accepted. +func AcceptNFLGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.AcceptNFLGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// RejectNFLGameRequest deletes the NFL request. +func RejectNFLGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.RejectNFLGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// ProcessNFLGameRequest converts an accepted NFL request into an NFLGame record. +func ProcessNFLGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.ProcessNFLGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// VetoNFLGameRequest deletes the NFL request via admin veto. +func VetoNFLGameRequest(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + requestID := vars["requestID"] + if len(requestID) == 0 { + panic("User did not provide a requestID") + } + managers.VetoNFLGameRequest(requestID) + json.NewEncoder(w).Encode(true) +} + +// SwapCFBHomeAndAwayTeams accepts a gameID and swaps the home and away teams for that game. +func SwapCFBHomeAndAwayTeams(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + gameID := vars["gameID"] + if len(gameID) == 0 { + panic("User did not provide a gameID") + } + managers.SwapCFBGameHomeAndAwayTeams(gameID) + json.NewEncoder(w).Encode(true) +} diff --git a/data/2027/college_teams_csv.csv b/data/2027/college_teams_csv.csv new file mode 100644 index 0000000..10ed822 --- /dev/null +++ b/data/2027/college_teams_csv.csv @@ -0,0 +1,271 @@ +id,team_name,mascot,team_abbr,coach,city,state,country,stadium,stadium_capacity,record_attendance,enrollment,first_played,conference_id,conference,division_id,division,program_prestige,academic_prestige,facilities,color_one,color_two,color_three,is_fbs,overall_grade,offense_grade,defense_grade,special_teams_grade,players_progressed,recruits_added,stadium_id,discord_id,penalty_marks,is_active,created_at,updated_at,deleted_at,jersey_type,last_login,abbreviation,league_id,arena_id,arena,arena_capacity,goalie_grade,is_user_coached,is_club,professional_prestige,traditions,atmosphere,academics,conference_prestige,coach_rating,season_momentum +1,"Air Force",Falcons,USAF,IrishGang,"Colorado Springs",Colorado,USA,"Falcon Stadium",46692,56409,4304,1955,11,"Mountain West",0,Mountain,0,0,0,#a6a6a8,#00308f,,1,C,C,C,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-03 17:31:15.142",NULL,0,"2026-05-03 17:31:14.956",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +2,Akron,Zips,AKRN,AI,Akron,Ohio,USA,"InfoCision Stadium-Summa Field",30000,27881,19200,0,10,MAC,0,,0,0,0,#002147,#918b4c,,1,C,C,C,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.228",NULL,0,"2025-09-29 23:27:50.534",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +3,Alabama,"Crimson Tide",BAMA,thatfunk,Tuscaloosa,Alabama,USA,"Bryant-Denny Stadium",101821,65535,38500,1892,7,SEC,0,,0,0,0,#9e1b32,#FFFFFF,,1,A,A-,A+,A-,1,1,0,<@267540431670083595>,0,1,"0000-00-00 00:00:00.000","2026-05-06 12:41:15.636",NULL,0,"2026-05-06 12:41:15.519",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +4,"Appalachian State",Mountaineers,APST,Mightydog135,Boone,"North Carolina",USA,"Kidd Brewer Stadium",30000,35126,19100,1928,12,"Sun Belt",15,East,0,0,0,#222222,#ffcc00,,1,A-,A-,A-,B-,1,1,0,<@714184832040566800>,1,1,"0000-00-00 00:00:00.000","2026-05-05 20:45:36.173",NULL,0,"2026-05-05 20:45:36.083",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +5,Arizona,Wildcats,ZONA,AI,Tucson,Arizona,USA,"Arizona Stadium",56029,59920,45200,1899,5,"Big 12",0,,0,0,0,#AB0520,#0C234B,,1,C,C-,C,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.335",NULL,0,"2025-12-10 17:54:05.813",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +6,"Arizona State","Sun Devils",AZST,AI,Tempe,Arizona,USA,"Sun Devil Stadium, Frank Kush Field",56232,65535,51800,1896,5,"Big 12",0,,0,0,0,#990033,#FFB310,,1,D+,D,D+,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.371",NULL,0,"2025-07-26 05:26:35.195",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +7,Arkansas,Razorbacks,ARK,bbigguns92,Fayetteville,Arkansas,USA,"Donald W. Reynolds Razorback Stadium, Frank Broyles Field",72000,65535,27800,1894,7,SEC,0,,0,0,0,#9D2235,#FFFFFF,,1,C-,C,D,C,1,1,0,<@1086029345904152576>,0,1,"0000-00-00 00:00:00.000","2026-04-28 13:15:31.984",NULL,0,"2026-04-28 13:15:31.853",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +8,"Arkansas State","Red Wolves",ARST,FrankNoGamin,Jonesboro,Arkansas,USA,"Centennial Bank Stadium",30964,31243,22000,1911,12,"Sun Belt",16,West,0,0,0,#cc092f,#000000,#FFFFFF,1,C,C+,C-,D-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-30 16:18:45.242",NULL,0,"2026-04-30 16:18:44.997",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +9,Army,"Black Knights",ARMY,failedchompers,"West Point","New York",USA,"Blaik Field at Michie Stadium",38000,42765,4300,1890,8,American,0,,0,0,0,#000000,#d3bc8d,,1,C+,C,B-,B-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-30 23:38:36.920",NULL,0,"2026-04-30 23:38:36.573",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +10,Auburn,Tigers,AUB,AI,Auburn,Alabama,USA,"Pat Dye Field at Jordan-Hare Stadium",87451,65535,30400,1892,7,SEC,0,,0,0,0,#0C2340,#F26522,,1,C,C,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.519",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +11,"Ball State",Cardinals,BALL,npklemm,Muncie,Indiana,USA,"Scheumann Stadium",22500,23861,22500,1924,10,MAC,0,,0,0,0,#BA0C2F,#FFFFFF,,1,A,A-,A+,A-,1,1,0,<@183396307107315712>,1,1,"0000-00-00 00:00:00.000","2026-05-06 12:29:16.360",NULL,0,"2026-05-06 12:29:16.207",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +12,Baylor,Bears,BAYL,Vivid,Waco,Texas,USA,"McLane Stadium",45140,49875,17200,1899,5,"Big 12",0,,0,0,0,#fecb00,#003015,,1,C+,C,B-,C,1,1,0,<@413018867468599297>,0,1,"0000-00-00 00:00:00.000","2026-05-04 16:45:48.529",NULL,0,"2026-05-04 16:45:48.422",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +13,"Boise State",Broncos,BOIS,cubansdoitbest,Boise,Idaho,USA,"Albertsons Stadium",36387,36864,25500,1933,6,Pac-12,0,,0,0,0,#09347A,#F1632A,,1,D+,C,D,D,1,1,0,<@1213600182545940553>,0,1,"0000-00-00 00:00:00.000","2026-05-06 04:45:44.733",NULL,0,"2026-05-06 04:45:44.617",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +14,"Boston College",Eagles,BC,Fireballer34,"Chestnut Hill",Massachusetts,USA,"Alumni Stadium",44500,44500,14700,1893,3,ACC,0,,0,0,0,#910039,#B38F59,,1,B+,B+,B,B,1,1,0,<@1388666260979585116>,2,1,"0000-00-00 00:00:00.000","2026-05-06 11:05:28.960",NULL,0,"2026-05-06 11:05:28.788",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +15,"Bowling Green",Falcons,BGSU,PoopyRhinoPickle,"Bowling Green",Ohio,USA,"Doyt L. Perry Stadium",24000,33527,23000,1919,10,MAC,0,,0,0,0,#4F2C1D,#FE5000,,1,A+,A+,A+,A-,1,1,0,<@408137883984199691>,0,1,"0000-00-00 00:00:00.000","2026-05-05 12:52:31.260",NULL,0,"2026-05-05 12:52:31.025",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +16,Buffalo,Bulls,BUFF,AI,Buffalo,"New York",USA,"UB Stadium",29013,29795,31500,1894,10,MAC,0,,0,0,0,#FFFFFF,#005bbb,,1,C-,C,D,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.739",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +17,BYU,Cougars,BYU,Spoof,Provo,Utah,USA,"LaVell Edwards Stadium",63470,65535,33600,1922,5,"Big 12",0,,0,0,0,#002255,#FFFFFF,,1,A,A+,A-,B+,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 07:39:20.344",NULL,0,"2026-05-06 07:39:20.281",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +18,California,"Golden Bears",CAL,believer,Berkeley,California,USA,"California Memorial Stadium",62717,65535,42500,1882,3,ACC,0,,0,0,0,#041E42,#FFC72C,,1,C,C,C,C+,1,1,0,<@267537915003928576>,0,1,"0000-00-00 00:00:00.000","2026-05-05 23:53:30.317",NULL,0,"2026-05-05 23:53:30.213",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +19,"Central Michigan",Chippewas,CMU,AI,"Mount Pleasant",Michigan,USA,"Kelly/Shorts Stadium",30255,35127,21700,1896,10,MAC,0,,0,0,0,#ffc82e,#6a0032,,1,C-,C,D,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.849",NULL,0,"2026-04-11 03:27:20.414",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +20,Charlotte,49ers,CHAR,AI,Charlotte,"North Carolina",USA,"McColl-Richardson Field at Jerry Richardson Stadium",15314,17444,29700,2013,8,American,0,East,0,0,0,#046a38,#FFFFFF,,1,C,C,C,B-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.885",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +21,Cincinnati,Bearcats,CINC,AI,Cincinnati,Ohio,USA,"Nippert Stadium",40000,40124,46000,1885,5,"Big 12",0,,0,0,0,#E00122,#000000,,1,C,C,C,C,1,1,0,,2,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.921",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +22,Clemson,Tigers,CLEM,AI,Clemson,"South Carolina",USA,"Frank Howard Field at Clemson Memorial Stadium",81500,65535,25000,1896,3,ACC,0,,0,0,0,#522D80,#F56600,,1,C,C,C,B,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:57.961",NULL,0,"2026-03-25 13:18:20.594",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +23,"Coastal Carolina",Chanticleers,CCU,Iied,Conway,"South Carolina",USA,"Brooks Stadium",20000,15991,10600,2003,12,"Sun Belt",15,East,0,0,0,#000000,#CFB87C,#A2A4A3,1,C+,B-,C,B,1,1,0,<@200111154482249728>,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:56:55.663",NULL,0,"2026-05-06 13:56:55.389",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +24,Colorado,Buffaloes,COLO,Bingo415,Boulder,Colorado,USA,"Folsom Field",50183,54972,33200,1890,5,"Big 12",0,,0,0,0,#000000,#CFB87C,#A2A4A3,1,A-,A-,A-,A,1,1,0,<@274190160365879297>,0,1,"0000-00-00 00:00:00.000","2026-05-05 20:49:36.325",NULL,0,"2026-05-05 20:49:36.147",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +25,"Colorado State",Rams,CSU,Bellwood,"Fort Collins",Colorado,USA,"Sonny Lubick Field at Canvas Stadium",41200,41000,33800,1890,6,Pac-12,0,,0,0,0,#1E4D2B,#C8C372,,1,A-,A-,B+,A-,1,1,0,<@339796149022097409>,2,1,"0000-00-00 00:00:00.000","2026-05-06 00:45:14.618",NULL,0,"2026-05-06 00:45:14.504",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +26,Duke,"Blue Devils",DUKE,Viselli,Durham,"North Carolina",USA,"Brooks Field at Wallace Wade Stadium",40000,57500,15900,1888,3,ACC,0,,0,0,0,#001A57,#FFFFFF,,1,C,C,C-,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 14:05:29.053",NULL,0,"2026-05-06 14:05:28.928",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +27,"East Carolina",Pirates,ECU,SeanH,Greenville,"North Carolina",USA,"Bagwell Field at Dowdy-Ficklen Stadium",50000,51082,29100,1932,8,American,0,,0,0,0,#592A8A,#FDC82F,,1,C,C+,C,A-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.143",NULL,0,"2026-03-10 01:27:43.689",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +28,"Eastern Michigan",Eagles,EMU,fjames92,Ypsilanti,Michigan,USA,"Rynearson Stadium",30200,26188,20300,1891,10,MAC,0,,0,0,0,#006633,#FFFFFF,,1,D+,C-,D,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.180",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +29,FIU,Panthers,FIU,AI,Miami,Florida,USA,"Riccardo Silva Stadium",23500,22682,56800,2002,9,C-USA,0,,0,0,0,#081E3F,#B6862C,,1,D+,D+,D+,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.228",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +30,Florida,Gators,FLA,Weeze,Gainesville,Florida,USA,"Steve Spurrier-Florida Field at Ben Hill Griffin Stadium",88548,65535,56100,1906,7,SEC,0,,0,0,0,#0021a5,#FA4616,,1,B,B,A-,C,1,1,0,<@373546175363809284>,0,1,"0000-00-00 00:00:00.000","2026-05-06 00:09:07.277",NULL,0,"2026-05-06 00:09:06.765",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +31,"Florida Atlantic",Owls,FAU,Haschdei,"Boca Raton",Florida,USA,"FAU Stadium",30000,29103,30800,2001,8,American,0,East,0,0,0,#003366,#CC0000,,1,D+,D+,D,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.318",NULL,0,"2026-04-18 18:02:45.746",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +32,"Florida State",Seminoles,FSU,LyonsinLex,Tallahassee,Florida,USA,"Bobby Bowden Field at Doak S. Campbell Stadium",79560,65535,41900,1947,3,ACC,0,,0,0,0,#782F40,#CEB888,,1,B,B,B,B,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-06 11:19:51.200",NULL,0,"2026-05-06 11:19:51.160",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +33,"Fresno State",Bulldogs,FRES,chaserck,Fresno,California,USA,"Bulldog Stadium at Jim Sweeney Field",41031,42881,25000,1921,6,Pac-12,0,,0,0,0,#C41230,#002C76,,1,C-,C-,C-,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-03 20:25:48.237",NULL,0,"2026-05-03 20:25:48.072",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +34,Georgia,Bulldogs,UGA,Sarge,Athens,Georgia,USA,"Sanford Stadium",92746,65535,38200,1892,7,SEC,0,,0,0,0,#DA291C,#000000,,1,A-,A-,A-,B-,1,1,0,<@248312577677983744>,1,1,"0000-00-00 00:00:00.000","2026-05-05 04:31:30.624",NULL,0,"2026-05-05 04:31:30.530",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +35,"Georgia Southern",Eagles,GASO,Pookers,Statesboro,Georgia,USA,"Allen E. Paulson Stadium",25000,25735,26400,1924,12,"Sun Belt",15,East,0,0,0,#011e41,#FFFFFF,,1,D,C-,D-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.478",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +36,"Georgia State",Panthers,GAST,RiRi,Atlanta,Georgia,USA,"Georgia State Stadium",25000,24333,52800,2010,12,"Sun Belt",15,East,0,0,0,#0039A6,#FFFFFF,,1,B-,B-,B-,C+,1,1,0,<@546556994795077673>,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:05:23.517",NULL,0,"2026-05-06 13:05:23.447",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +37,"Georgia Tech","Yellow Jackets",GT,ATonOfLaw,Atlanta,Georgia,USA,"Bobby Dodd Stadium at Historic Grant Field",55000,60316,32700,1892,3,ACC,0,,0,0,0,#C59353,#FFFFFF,,1,B+,A-,B+,A-,1,1,0,<@750492519971946536>,0,1,"0000-00-00 00:00:00.000","2026-05-04 05:50:07.963",NULL,0,"2026-05-04 05:50:07.791",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +38,Hawaii,"Rainbow Warriors",HAWI,AI,Honolulu,Hawai'i,USA,"Aloha Stadium",50000,50000,17700,1909,11,"Mountain West",0,Best,0,0,0,#024731,#FFFFFF,#000000,1,D+,C-,D,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.598",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +39,Houston,Cougars,UHOU,mahrowkeen,Houston,Texas,USA,"John O'Quinn Field at TDECU Stadium",40000,42159,42700,1946,5,"Big 12",0,,0,0,0,#C92839,#FFFFFF,,1,A,A+,A,A-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-06 03:02:14.455",NULL,0,"2026-05-06 03:02:14.288",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +40,Illinois,"Fighting Illini",ILLI,nemolee.exe,"Urbana Champaign",Illinois,USA,"Memorial Stadium",60670,65535,51200,1890,4,"Big Ten",0,,0,0,0,#e04e39,#13294b,,1,A,A,A,A,1,1,0,<@201184790458793991>,0,1,"0000-00-00 00:00:00.000","2026-05-06 04:53:05.280",NULL,0,"2026-05-06 04:53:05.197",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +41,Indiana,Hoosiers,IND,AI,Bloomington,Indiana,USA,"Memorial Stadium",52959,56223,43700,1887,4,"Big Ten",0,,0,0,0,#EEEDEB,#990000,,1,B,C+,A-,B+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.729",NULL,0,"2026-03-30 14:16:32.445",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +42,Iowa,Hawkeyes,IOWA,Angus,"Iowa City",Iowa,USA,"Kinnick Stadium",70585,65535,33000,1889,4,"Big Ten",0,,0,0,0,#000000,#FFE100,,1,D,D+,D-,C+,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 11:59:43.873",NULL,0,"2026-05-06 11:59:43.798",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +43,"Iowa State",Cyclones,IAST,bananabreadbitch,Ames,Iowa,USA,"Jack Trice Stadium",61500,61500,33400,1892,5,"Big 12",0,,0,0,0,#a6192e,#FDC82F,,1,D,D,D+,F,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.809",NULL,0,"2026-04-16 03:06:39.621",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +44,Kansas,Jayhawks,KANS,bundy,Lawrence,Kansas,USA,"David Booth Kansas Memorial Stadium",50071,52530,27700,1890,5,"Big 12",0,,0,0,0,#0051BA,#E8000D,,1,A-,A,A-,A-,1,1,0,<@255505163148591114>,0,1,"0000-00-00 00:00:00.000","2026-05-05 20:33:42.610",NULL,0,"2026-05-05 20:33:42.441",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +45,"Kansas State",Wildcats,KSST,Image_f3quet,Manhattan,Kansas,USA,"Bill Snyder Family Football Stadium",50000,53811,21700,1896,5,"Big 12",0,,0,0,0,#512888,#FFFFFF,,1,D+,C,D,F,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-30 03:40:35.108",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +46,"Kent State","Golden Flashes",KENT,Groobs03,Kent,Ohio,USA,"Dix Stadium",25000,27363,39300,1920,10,MAC,0,,0,0,0,#002664,#EAAB00,,1,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:58.940",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +47,Kentucky,Wildcats,UKEN,Ezaco,Lexington,Kentucky,USA,"Kroger Field at C.M. Newton Grounds",61000,65535,29200,1881,7,SEC,0,,0,0,0,#0033A0,#FFFFFF,,1,C,C,D+,C-,1,1,0,<@232929647325741056>,1,1,"0000-00-00 00:00:00.000","2026-05-06 12:09:48.349",NULL,0,"2026-05-06 12:09:48.177",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +48,Liberty,Flames,LU,TCM12,Lynchburg,Virginia,USA,"Arthur L. Williams Stadium",25000,22551,15000,1973,9,C-USA,0,,0,0,0,#002D62,#C41230,,1,C-,D,C,D+,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.021",NULL,0,"2026-04-16 15:17:45.625",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +49,Louisiana,"Ragin' Cajuns",ULL,AI,Lafayette,Louisiana,USA,"Cajun Field",41426,41357,19200,1902,12,"Sun Belt",16,West,0,0,0,#ce181e,#FFFFFF,,1,C,C-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.058",NULL,0,"2025-08-09 13:04:50.795",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +50,"Louisiana Monroe",Warhawks,ULM,HAFFnHAFF,Monroe,Louisiana,USA,"Joe Aillet Stadium",28562,28714,8800,1951,12,"Sun Belt",16,West,0,0,0,#800029,#bd955a,,1,C-,D,D+,B-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-01 18:16:22.280",NULL,0,"2026-05-01 18:16:22.203",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +51,"Louisiana Tech",Bulldogs,LT,Swipet,Ruston,Louisiana,USA,"JPS Field at Malone Stadium",30427,31175,12400,1901,12,"Sun Belt",16,,0,0,0,#003087,#CB333B,,1,C,C,C,D,1,1,0,<@259820256090914816>,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.131",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +52,Louisville,Cardinals,LOU,AI,Louisville,Kentucky,USA,"Cardinal Stadium",61000,55632,22600,1910,3,ACC,0,,0,0,0,#AD0000,#000000,,1,C-,C-,C-,F,1,1,0,,2,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.169",NULL,0,"2025-07-28 07:38:29.278",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +53,LSU,Tigers,LSU,alderreinwald@gmail.com,"Baton Rouge",Louisiana,USA,"Tiger Stadium",102321,65535,30800,1893,7,SEC,0,,0,0,0,#582c83,#ffc72c,,1,C,C,C,D,1,1,0,,2,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.208",NULL,0,"2025-07-26 04:55:43.837",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +54,Marshall,"Thundering Herd",MRSH,Newkbomb,Huntington,"West Virginia",USA,"Joan C. Edwards Stadium",38019,41382,13200,1895,12,"Sun Belt",15,East,0,0,0,#006140,#FFFFFF,,1,B+,A-,B+,A-,1,1,0,<@959669041553879060>,0,1,"0000-00-00 00:00:00.000","2026-05-05 20:46:50.182",NULL,0,"2026-05-05 20:46:50.037",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +55,Maryland,Terrapins,UMD,tommygunner,"College Park",Maryland,USA,"Capital One Field at Maryland Stadium",51802,58973,41200,1888,4,"Big Ten",0,,0,0,0,#c8102e,#FFFFFF,#000000,1,B+,A-,B+,B+,1,1,0,<@485860762238189579>,1,1,"0000-00-00 00:00:00.000","2026-05-06 02:56:13.000",NULL,0,"2026-05-06 02:56:12.698",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +56,Memphis,Tigers,MEMP,AI,Memphis,Tennessee,USA,"Liberty Bowl Memorial Stadium",62380,65535,21500,1912,8,American,0,,0,0,0,#0D3182,#888C8F,,1,C,C,C+,D-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.318",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +57,"Miami (FL)",Hurricanes,MIAF,Dearden,"Coral Gables",Florida,USA,"Hard Rock Stadium",65326,65535,17300,1926,3,ACC,0,,0,0,0,#005030,#f47321,,1,C,D,B-,B,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.355",NULL,0,"2026-04-08 21:21:29.284",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +58,"Miami (OH)",RedHawks,MIAO,AI,Oxford,Ohio,USA,"Fred C. Yager Stadium",24286,30087,24300,1888,10,MAC,0,,0,0,0,#B61E2E,#FFFFFF,,1,C,C,C,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.391",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +59,Michigan,Wolverines,MICH,subsequent,"Ann Arbor",Michigan,USA,"Michigan Stadium",107601,65535,46000,1879,4,"Big Ten",0,,0,0,0,#ffcb05,#00274c,,1,C,C,C,C-,1,1,0,<@189543659912298497>,1,1,"0000-00-00 00:00:00.000","2026-05-06 13:19:58.921",NULL,0,"2026-05-06 13:19:58.881",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +60,"Michigan State",Spartans,MIST,jedibob5,"East Lansing",Michigan,USA,"Spartan Stadium",75005,65535,50300,1885,4,"Big Ten",0,,0,0,0,#18453B,#FFFFFF,,1,B,B+,B,B,1,1,0,<@97161779242627072>,0,1,"0000-00-00 00:00:00.000","2026-05-05 23:49:18.413",NULL,0,"2026-05-05 23:49:18.180",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +61,"Middle Tennessee","Blue Raiders",MTSU,AI,Murfreesboro,Tennessee,USA,"Johnny Red Floyd Stadium",31000,30502,21900,1911,9,C-USA,0,,0,0,0,#0066CC,#FFFFFF,,1,D,D,D-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.547",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +62,Minnesota,"Golden Gophers",MINN,Minnow,Minneapolis,Minnesota,USA,"TCF Bank Stadium",50805,54147,47800,1882,4,"Big Ten",0,,0,0,0,#7a0019,#ffcc33,,1,A-,A,A-,A-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 01:18:48.160",NULL,0,"2026-05-06 01:18:47.455",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +63,"Mississippi State",Bulldogs,MSST,AI,Starkville,Mississippi,USA,"Davis Wade Stadium at Scott Field",61337,62945,22200,1895,7,SEC,0,,0,0,0,#660000,#FFFFFF,,1,B-,B-,B-,B,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-23 21:45:57.651",NULL,0,"2026-04-23 21:18:54.808",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +64,Missouri,Tigers,MIZZ,AI,Columbia,Missouri,USA,"Faurot Field at Memorial Stadium",71168,65535,30000,1890,7,SEC,0,,0,0,0,#000000,#F1B82D,,1,C,C-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.665",NULL,0,"2026-02-24 15:48:13.359",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +65,Navy,Midshipmen,NAVY,Syndakyt,Annapolis,Maryland,USA,"Navy-Marine Corps Memorial Stadium",34000,37970,4600,1879,8,American,0,,0,0,0,#00205b,#c5b783,,1,A,A,A,B+,1,1,0,<@264660416930512896>,0,1,"0000-00-00 00:00:00.000","2026-05-02 02:04:51.553",NULL,0,"2026-05-02 02:04:51.487",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +66,"NC State",Wolfpack,NCST,Matty460,Raleigh,"North Carolina",USA,"Wayne Day Family Field at Carter-Finley Stadium",57583,57583,35500,1892,3,ACC,0,,0,0,0,#CC0000,#FFFFFF,,1,B,B+,B,B-,1,1,0,<@329591013364465664>,1,1,"0000-00-00 00:00:00.000","2026-05-06 13:23:33.029",NULL,0,"2026-05-06 13:23:32.827",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +67,Nebraska,Cornhuskers,NEB,alexfall862,Lincoln,Nebraska,USA,"Memorial Stadium, Tom Osborne Field",85458,65535,25800,1890,4,"Big Ten",0,,0,0,0,#e41c38,#fdf2d9,,1,A-,A-,A-,A-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:40:34.927",NULL,0,"2026-05-06 13:40:34.644",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +68,Nevada,"Wolf Pack",NEV,AI,Reno,Nevada,USA,"Mackay Stadium",26000,33391,21600,1896,11,"Mountain West",0,Best,0,0,0,#003366,#807f84,,1,C,C,C,C,1,1,0,,3,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.809",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +69,"New Mexico",Lobos,UNM,DarthJarJar,Albuquerque,"New Mexico",USA,"Dreamstyle Stadium",39224,44760,26300,1892,11,"Mountain West",0,Mountain,0,0,0,#B71234,#C3C8C8,,1,C,C,C,C,1,1,0,<@412617956762058762>,0,1,"0000-00-00 00:00:00.000","2026-05-06 06:04:47.938",NULL,0,"2026-05-06 06:04:47.825",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +70,"New Mexico State",Aggies,NMSU,Rabbit,"Las Cruces","New Mexico",USA,"Aggie Memorial Stadium",30343,32993,21900,1893,9,C-USA,0,,0,0,0,#8c0b42,#FFFFFF,,1,C,C,D,B,1,1,0,<@960254290335768596>,3,1,"0000-00-00 00:00:00.000","2026-04-20 18:00:59.883",NULL,0,"2026-03-26 21:26:55.196",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +71,"North Carolina","Tar Heels",UNC,Tryggr,"Chapel Hill","North Carolina",USA,"Kenan Memorial Stadium",51000,62000,29800,1888,3,ACC,0,,0,0,0,#7BAFD4,#FFFFFF,,1,A-,A,A,B-,1,1,0,<@490628797566287874>,0,1,"0000-00-00 00:00:00.000","2026-05-06 04:02:15.795",NULL,0,"2026-05-06 04:02:14.781",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +72,"North Texas","Mean Green",UNT,EmeraldSeasSunshine,Denton,Texas,USA,"Apogee Stadium",30850,28075,39400,1913,8,American,0,West,0,0,0,#00853E,#FFFFFF,,1,C,C,C,D,1,1,0,<@1072231722210574367>,0,1,"0000-00-00 00:00:00.000","2026-05-05 04:00:21.895",NULL,0,"2026-05-05 04:00:21.814",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +73,"Northern Illinois",Huskies,NIU,Ape,DeKalb,Illinois,USA,"Brigham Field at Huskie Stadium",23595,28221,20000,1899,11,"Mountain West",0,,0,0,0,#ba0c2f,#000000,,1,B+,A-,B+,B+,1,1,0,<@183014755819192321>,1,1,"0000-00-00 00:00:00.000","2026-05-02 01:14:58.215",NULL,0,"2026-05-02 01:14:58.103",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +74,Northwestern,Wildcats,NW,AI,Evanston,Illinois,USA,"Ryan Field",47130,55752,21200,1876,4,"Big Ten",0,,0,0,0,#4E2A84,#FFFFFF,,1,D,D,D,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.051",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +75,"Notre Dame","Fighting Irish",ND,LordLittlebutt,"South Bend",Indiana,USA,"Notre Dame Stadium",77622,65535,12300,1887,13,Independent,0,,0,0,0,#0C2340,#C99700,,1,A-,A,A-,B+,1,1,0,<@339001227062935553>,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:25:19.557",NULL,0,"2026-05-06 13:25:19.313",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +76,Ohio,Bobcats,OHIO,"Traith Kreios",Athens,Ohio,USA,"Peden Stadium",24000,25893,34900,1894,10,MAC,0,,0,0,0,#00694E,#FFFFFF,,1,C,C,C,C+,1,1,0,<@311215081902047234>,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.141",NULL,0,"2025-11-12 02:16:52.336",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +77,"Ohio State",Buckeyes,OHST,Piercewise1,Columbus,Ohio,USA,"Ohio Stadium",104944,65535,68100,1889,4,"Big Ten",0,,0,0,0,#bb0000,#666666,,1,B,B,B+,B-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 12:45:51.707",NULL,0,"2026-05-06 12:45:51.628",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +78,Oklahoma,Sooners,OKLA,Amhaja,Norman,Oklahoma,USA,"Gaylord Family - Oklahoma Memorial Stadium at Owen Field",86112,65535,28500,1895,7,SEC,0,,0,0,0,#841617,#FDF9D8,,1,B,B+,B,B,1,1,0,<@697155660088999997>,0,1,"0000-00-00 00:00:00.000","2026-05-04 17:23:01.127",NULL,0,"2026-05-04 17:23:01.029",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +79,"Oklahoma State",Cowboys,OKST,ohyeahtt,Stillwater,Oklahoma,USA,"Boone Pickens Stadium",60218,60218,25300,1901,5,"Big 12",0,,0,0,0,#FF7300,#000000,,1,A-,A-,B+,B,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-02 08:42:35.764",NULL,0,"2026-05-02 08:42:35.666",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +80,"Old Dominion",Monarchs,ODU,AI,Norfolk,Virginia,USA,"Foreman Field at S. B. Ballard Stadium",20118,20118,25000,2009,12,"Sun Belt",15,East,0,0,0,#05344C,#7c878e,#92c1e9,1,D+,C,D,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.295",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +81,"Ole Miss",Rebels,MISS,SlapYourBasil,Oxford,Mississippi,USA,"Vaught-Hemingway Stadium at Hollingsworth Field",64038,65535,23200,1890,7,SEC,0,,0,0,0,#00205b,#c8102e,,1,A,A,A,A,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-21 17:12:22.091",NULL,0,"2026-04-21 17:12:22.020",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +82,Oregon,Ducks,OREG,Dida28,Eugene,Oregon,USA,"Autzen Stadium",54000,60055,22700,1894,4,"Big Ten",0,,0,0,0,#FEE123,#154733,,1,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-05 21:34:31.089",NULL,0,"2026-05-05 21:34:30.894",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +83,"Oregon State",Beavers,ORST,AI,Corvallis,Oregon,USA,"Reser Stadium",45674,46469,30900,1893,6,Pac-12,0,,0,0,0,#C34500,#000000,,1,C,C,C,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.418",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +84,"Penn State","Nittany Lions",PNST,Rocketcan,"University Park",Pennsylvania,USA,"Beaver Stadium",106572,65535,46600,1881,4,"Big Ten",0,,0,0,0,#041e42,#FFFFFF,,1,C-,D+,C-,C+,1,1,0,<@211521230266695680>,1,1,"0000-00-00 00:00:00.000","2026-04-28 06:03:54.958",NULL,0,"2026-04-28 06:03:54.727",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +85,Pittsburgh,Panthers,PITT,TheLiberator,Pittsburgh,Pennsylvania,USA,"Heinz Field",68400,65535,28600,1890,3,ACC,0,,0,0,0,#1c2957,#cdb87d,,1,C,C,C,B-,1,1,0,,2,1,"0000-00-00 00:00:00.000","2026-05-06 12:04:32.176",NULL,0,"2026-05-06 12:04:31.706",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +86,Purdue,Boilermakers,PURD,AI,"West Lafayette",Indiana,USA,"Ross-Ade Stadium",57236,65535,43400,1887,4,"Big Ten",0,,0,0,0,#000000,#CEB888,,1,B,A-,B-,A,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-22 21:06:57.607",NULL,0,"2026-03-25 07:02:29.490",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +87,Rice,Owls,RICE,bardloff,Houston,Texas,USA,"Rice Stadium",47000,65535,7100,1912,8,American,0,West,0,0,0,#002469,#5e6062,,1,B,B,B,B,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-04 17:34:47.580",NULL,0,"2026-05-04 17:34:47.393",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +88,Rutgers,"Scarlet Knights",RUTG,Kirby,Piscataway,"New Jersey",USA,"High Point Solutions Stadium",52454,53737,70900,1869,4,"Big Ten",0,,0,0,0,#d21034,#FFFFFF,,1,B,B,A-,C,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-04 10:15:37.593",NULL,0,"2026-05-04 10:15:37.395",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +89,"San Diego State",Aztecs,SDSU,Jumbo,"San Diego",California,USA,"Snapdragon Stadium",35000,34046,34900,1921,6,Pac-12,0,,0,0,0,#C41230,#000000,,1,C,C-,C-,B,1,1,0,<@276508819067109386>,0,1,"0000-00-00 00:00:00.000","2026-04-30 01:17:39.739",NULL,0,"2026-04-30 01:17:39.451",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +90,"San Jose State",Spartans,SJSU,Chandler1,"San Jose",California,USA,"CEFCU Stadium",30456,31681,32800,1892,11,"Mountain West",0,Best,0,0,0,#0055A2,#FFFFFF,#E5A823,1,C+,B-,B-,D+,1,1,0,<@171374943341248512>,0,1,"0000-00-00 00:00:00.000","2026-04-29 17:31:57.087",NULL,0,"2026-04-29 17:31:56.485",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +91,SMU,Mustangs,SMU,AI,"University Park",Texas,USA,"Gerald J. Ford Stadium",32000,35481,11800,1915,3,ACC,0,,0,0,0,#354ca1,cd2027,,1,C-,D+,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.712",NULL,0,"2026-01-26 15:15:14.116",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +92,"South Alabama",Jaguars,USA,jgreene816,Mobile,Alabama,USA,"Ladd-Peebles Stadium",40000,38129,15100,2009,12,"Sun Belt",16,West,0,0,0,#00205B,#FFFFFF,#BF0D3E,1,C,B-,C-,D,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.749",NULL,0,"2025-11-26 14:48:21.265",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +93,"South Carolina",Gamecocks,SOCA,Dearden,Columbia,"South Carolina",USA,"Williams-Brice Stadium",80250,65535,50100,1892,7,SEC,0,,0,0,0,#73000A,#000000,,1,B-,B-,C+,B,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 11:47:18.836",NULL,0,"2026-05-06 11:47:18.555",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +94,"South Florida",Bulls,USF,iToxickiddy,Tampa,Florida,USA,"Raymond James Stadium",65857,65535,50700,1997,8,American,0,,0,0,0,#006747,#CFC493,,1,C,C,C,C+,1,1,0,<@1071609080235425875>,1,1,"0000-00-00 00:00:00.000","2026-05-05 19:42:21.908",NULL,0,"2026-05-05 19:42:21.663",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +95,"Southern Miss","Golden Eagles",USM,TuscanSota,Hattiesburg,Mississippi,USA,"Carlisle-Faulkner Field at M.M. Roberts Stadium",36000,36641,14500,1912,12,"Sun Belt",16,West,0,0,0,#000000,#FDC737,,1,B-,B,B-,B-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:29:40.132",NULL,0,"2026-05-06 13:29:39.883",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +96,Stanford,Cardinal,STAN,"Ricky Campbell",Stanford,California,USA,"Stanford Stadium",50424,51607,16500,1891,3,ACC,0,,0,0,0,#8C1515,#FFFFFF,,1,A,A+,A-,B+,1,1,0,<@413503799957782528>,0,1,"0000-00-00 00:00:00.000","2026-05-06 00:38:01.881",NULL,0,"2026-05-06 00:38:01.708",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +97,Syracuse,Orange,CUSE,taffyowner,Syracuse,"New York",USA,"Carrier Dome",49250,50564,22900,1889,3,ACC,0,,0,0,0,#D44500,#FFFFFF,,1,C,C-,C,C-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-04-25 19:33:47.907",NULL,0,"2026-04-25 19:33:47.591",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +98,TCU,"Horned Frogs",TCU,DangerZoneh,"Fort Worth",Texas,USA,"Amon G. Carter Stadium",45000,50307,10400,1896,5,"Big 12",0,,0,0,0,#4d1979,#FFFFFF,,1,D,C-,D-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:00.971",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +99,Temple,Owls,TEMP,SandyToez,Philadelphia,Pennsylvania,USA,"Lincoln Financial Field",68532,65535,40000,1894,8,American,0,,0,0,0,#990033,#FFFFFF,,1,B+,A-,B,B-,1,1,0,<@236518428435808256>,1,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.009",NULL,0,"2026-04-18 15:03:14.028",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +100,Tennessee,Volunteers,TENN,tsweezy,Knoxville,Tennessee,USA,"Neyland Stadium",102455,65535,28900,1891,7,SEC,0,,0,0,0,#FF8200,#FFFFFF,,1,A+,A+,A+,A+,1,1,0,<@451922899646021643>,0,1,"0000-00-00 00:00:00.000","2026-05-06 03:30:42.849",NULL,0,"2026-05-06 03:30:42.707",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +101,Texas,Longhorns,TEX,Dean,Austin,Texas,USA,"Darrell K Royal-Texas Memorial Stadium",100119,65535,51800,1893,7,SEC,0,,0,0,0,#BF5700,#FFFFFF,,1,C+,C,B,C-,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-05 09:14:08.059",NULL,0,"2026-05-05 09:14:07.812",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +102,"Texas A&M",Aggies,TAMU,jaknib,"College Station",Texas,USA,"Kyle Field",102733,65535,69400,1894,7,SEC,0,,0,0,0,#500000,#FFFFFF,,1,B,B,B,B,1,1,0,<@787256171618107413>,1,1,"0000-00-00 00:00:00.000","2026-05-06 13:00:22.723",NULL,0,"2026-05-06 13:00:22.267",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +103,"Texas State",Bobcats,TXST,AI,"San Marcos",Texas,USA,"Jim Wacker Field at Bobcat Stadium",30000,33006,38800,1904,6,Pac-12,0,,0,0,0,#501214,#8D734A,,1,C,C,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-30 15:45:33.168",NULL,0,"2026-04-23 02:13:57.747",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +104,"Texas Tech","Red Raiders",TTU,rcarlson77,Lubbock,Texas,USA,"Jones AT&T Stadium",60862,61836,38200,1925,5,"Big 12",0,,0,0,0,#CC0000,#000000,,1,C,C,C,B-,1,1,0,,2,1,"0000-00-00 00:00:00.000","2026-05-06 13:05:12.949",NULL,0,"2026-05-06 13:05:12.813",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +105,Toledo,Rockets,TLDO,ArmTheSharks,Toledo,Ohio,USA,"Glass Bowl",26248,36852,23100,1917,10,MAC,0,,0,0,0,#ffce00,#002569,,1,D+,D,C-,D,1,1,0,<@136156829158866945>,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.236",NULL,0,"2026-01-06 07:37:21.028",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +106,Troy,Trojans,TROY,AI,Troy,Alabama,USA,"Veterans Memorial Stadium at Larry Blakeney Field",30402,29013,18100,1909,12,"Sun Belt",16,East,0,0,0,#862633,#8a8d8f,#000000,1,D-,D,F,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.273",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +107,Tulane,"Green Wave",TLNE,kgreene829,"New Orleans",Louisiana,USA,"Barry B. Benson Field at Yulman Stadium",30000,30000,14100,1893,8,American,0,,0,0,0,#005837,#0082ba,,1,A,A-,A+,A+,1,1,0,<@564457558241312796>,0,1,"0000-00-00 00:00:00.000","2026-05-05 15:41:30.081",NULL,0,"2026-05-05 15:41:29.960",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +108,Tulsa,"Golden Hurricane",TULS,acewulf,Tulsa,Oklahoma,USA,"Skelly Field at H. A. Chapman Stadium",30000,47350,4300,1895,8,American,0,,0,0,0,#002d72,#c5b783,#c8102e,1,A,A+,A,A,1,1,0,<@197912142135951360>,0,1,"0000-00-00 00:00:00.000","2026-05-06 12:13:18.545",NULL,0,"2026-05-06 12:13:18.374",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +109,UAB,Blazers,UAB,jared2001usa,Birmingham,Alabama,USA,"Legion Field Stadium",71594,45212,21900,1991,8,American,0,West,0,0,0,#CC0000,#000000,,1,D,C-,D-,C,1,1,0,<@249652864606011419>,0,1,"0000-00-00 00:00:00.000","2026-04-30 14:31:24.587",NULL,0,"2026-04-30 14:31:24.453",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +110,UCF,Knights,UCF,AI,Orlando,Florida,USA,"Bounce House",44206,48453,68600,1979,5,"Big 12",0,,0,0,0,#000000,#BA9B37,,1,D,D,D,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.421",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +111,UCLA,Bruins,UCLA,jmjacobs,"Los Angeles",California,USA,"Rose Bowl Stadium",90888,65535,45400,1919,4,"Big Ten",0,,0,0,0,#0072ce,#ffc72c,,1,A-,A,B+,B-,1,1,0,<@256580232230862848>,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:22:52.688",NULL,0,"2026-05-06 13:22:52.589",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +112,UConn,Huskies,CONN,AI,Storrs,Connecticut,USA,"Pratt & Whitney Stadium at Rentschler Field",40000,42704,32200,1896,13,Independent,0,,0,0,0,#000E2F,#FFFFFF,,1,C-,C-,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.494",NULL,0,"2026-01-16 17:25:07.373",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +113,UMass,Minutemen,MASS,AI,Amherst,Massachusetts,USA,"Warren McGuirk Alumni Stadium",17000,17000,30600,1879,10,MAC,0,,0,0,0,#881c1c,#FFFFFF,,1,D,D-,D+,D-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.530",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +114,UNLV,Rebels,UNLV,Jitters,"Las Vegas",Nevada,USA,"Allegient Stadium",65000,54541,30500,1968,11,"Mountain West",0,Best,0,0,0,#B10202,#666666,,1,A,A+,A+,B+,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-06 06:35:58.997",NULL,0,"2026-05-06 06:35:58.835",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +115,USC,Trojans,USC,Dr_Novella,"Los Angeles",California,USA,"Los Angeles Memorial Coliseum",77500,65535,45700,1888,4,"Big Ten",0,,0,0,0,#990000,#FFCC00,,1,B+,B+,B,A-,1,1,0,<@462474852780081153>,1,1,"0000-00-00 00:00:00.000","2026-05-06 00:03:52.753",NULL,0,"2026-05-06 00:03:52.698",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +116,UTEP,Miners,UTEP,AI,"El Paso",Texas,USA,"Sun Bowl Stadium",51500,53415,25100,1914,11,"Mountain West",0,,0,0,0,#000000,#997F3D,,1,D+,C-,D,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.650",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +117,UTSA,Roadrunners,UTSA,Dakotagreer,"San Antonio",Texas,USA,Alamodome,65000,56743,30700,2011,8,American,0,West,0,0,0,#0c2340,#FFFFFF,#f15a22,1,C-,D+,C,C,1,1,0,<@698723172932911135>,3,1,"0000-00-00 00:00:00.000","2026-04-22 01:11:55.862",NULL,0,"2026-04-22 01:11:55.742",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +118,Utah,Utes,UTAH,SageBow,"Salt Lake City",Utah,USA,"Rice-Eccles Stadium",45807,46768,33000,1892,5,"Big 12",0,,0,0,0,#CC0000,#FFFFFF,,1,A,A,A,A-,1,1,0,<@186563319103094784>,0,1,"0000-00-00 00:00:00.000","2026-05-06 13:29:54.518",NULL,0,"2026-05-06 13:29:54.193",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +119,"Utah State",Aggies,UTST,Ewade,Logan,Utah,USA,"Merlin Olsen Field at Maverik Stadium",25513,33119,29400,1892,6,Pac-12,0,,0,0,0,#9D968D,#FFFFFF,#0F2439,1,C,C-,B-,C,1,1,0,<@852750683081408584>,1,1,"0000-00-00 00:00:00.000","2026-05-02 22:01:35.341",NULL,0,"2026-05-02 22:01:35.160",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +120,Vanderbilt,Commodores,VAND,ChizDippler,Nashville,Tennessee,USA,"Vanderbilt Stadium",40350,41448,13100,1890,7,SEC,0,,0,0,0,#000000,#997F3D,,1,C,C,C,B+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:01.797",NULL,0,"2026-03-06 05:46:02.102",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +121,Virginia,Cavaliers,UVA,Wahoo,Charlottesville,Virginia,USA,"David A. Harrison III Field at Scott Stadium",61500,64947,24400,1888,3,ACC,0,,0,0,0,#fa4616,#041e42,,1,D+,D+,D+,C,1,1,0,<@417934198997909504>,1,1,"0000-00-00 00:00:00.000","2026-05-05 01:20:24.307",NULL,0,"2026-05-05 01:20:24.212",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +122,"Virginia Tech",Hokies,VT,DramaticBacon,Blacksburg,Virginia,USA,"Worsham Field at Lane Stadium",66233,65535,33400,1892,3,ACC,0,,0,0,0,#660000,#FF6600,,1,B,B-,B+,B+,1,1,0,,1,1,"0000-00-00 00:00:00.000","2026-05-01 13:34:57.693",NULL,0,"2026-05-01 13:34:57.628",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +123,"Wake Forest","Demon Deacons",WAKE,Qupax,Winston-Salem,"North Carolina",USA,"BB&T Field",31500,37623,8100,1888,3,ACC,0,,0,0,0,#000000,#9E7E38,,1,C,C,C,C,1,1,0,<@303297964183388160>,1,1,"0000-00-00 00:00:00.000","2026-04-30 18:36:43.165",NULL,0,"2026-04-30 18:36:42.979",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +124,Washington,Huskies,WASH,CoachCartier,Seattle,Washington,USA,"Alaska Airlines Field at Husky Stadium",70500,65535,47900,1889,4,"Big Ten",0,,0,0,0,#363c74,#e8d3a2,,1,B+,A-,B+,B+,1,1,0,<@789037297248239687>,1,1,"0000-00-00 00:00:00.000","2026-05-02 19:46:08.895",NULL,0,"2026-05-02 19:46:08.800",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +125,"Washington State",Cougars,WAST,chadbird,Pullman,Washington,USA,"Martin Stadium",32248,40306,30600,1893,6,Pac-12,0,,0,0,0,#981e32,#5e6a71,,1,A,A,A,A,1,1,0,<@557651507663863826>,0,1,"0000-00-00 00:00:00.000","2026-05-06 12:26:36.759",NULL,0,"2026-05-06 12:26:36.701",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +126,"West Virginia",Mountaineers,WVU,smackemz3,Morgantown,"West Virginia",USA,"Mountaineer Field at Milan Puskar Stadium",60000,65535,30000,1891,5,"Big 12",0,,0,0,0,#002855,#EAAA00,,1,A,A+,A,B+,1,1,0,<@277181463927980043>,0,1,"0000-00-00 00:00:00.000","2026-05-06 12:43:57.706",NULL,0,"2026-05-06 12:43:57.569",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +127,"Western Kentucky",Hilltoppers,WKU,AI,"Bowling Green",Kentucky,USA,"L. T. Smith Stadium at Jimmy Feix Field",22113,23252,20300,1913,9,C-USA,0,,0,0,0,#B01E24,#FFFFFF,,1,C,C,C,B-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.060",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +128,"Western Michigan",Broncos,WMU,Jieret,Kalamazoo,Michigan,USA,"Waldo Stadium",30200,36361,22900,1905,10,MAC,0,,0,0,0,#6c4023,#b5a167,,1,A+,A+,A+,A-,1,1,0,<@197683852242714624>,0,1,"0000-00-00 00:00:00.000","2026-05-06 10:49:35.728",NULL,0,"2026-05-06 10:49:35.588",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +129,Wisconsin,Badgers,WISC,JC,Madison,Wisconsin,USA,"Camp Randall Stadium",80321,65535,44400,1889,4,"Big Ten",0,,0,0,0,#c5050c,#FFFFFF,,1,A-,A-,A-,A-,1,1,0,<@372791539019153409>,0,1,"0000-00-00 00:00:00.000","2026-05-06 11:45:50.302",NULL,0,"2026-05-06 11:45:50.204",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +130,Wyoming,Cowboys,WYOM,AI,Laramie,Wyoming,USA,"Jonah Field at War Memorial Stadium",29181,34745,12400,123,11,"Mountain West",0,Mountain,0,0,0,#492f24,#ffc425,,1,D,C-,F,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.175",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +131,"James Madison",Dukes,JMU,SaltyMetrics,Harrisonburg,Virginia,USA,"Bridgeforth Stadium",24877,26159,21496,2023,12,"Sun Belt",15,,0,0,0,#450084,#CBB677,,1,B+,B+,B+,A-,1,1,0,<@1091450857922510917>,0,1,"0000-00-00 00:00:00.000","2026-05-04 17:48:14.865",NULL,0,"2026-05-04 17:48:14.813",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +132,"Jacksonville State",Gamecocks,JST,AI,Jacksonville,Alabama,USA,"Burgess-Snow Field at JSU Stadium",24000,23692,8067,2023,9,C-USA,0,,0,0,0,#CC0000,#FFFFFF,,1,C-,C-,D+,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.249",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +133,"Sam Houston State",Bearkats,SHSU,AI,Huntsville,Texas,USA,"Bowers Stadium",12593,16148,21679,2023,9,C-USA,0,,0,0,0,#FFFFFF,#F56423,,1,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.286",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +134,"Kennesaw State",Owls,KNSW,AI,Kennesaw,Georgia,USA,"Fifth Third Bank Stadium",8318,9506,41181,2023,9,C-USA,0,,0,0,0,#0B1315,#FDBB30,,1,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.323",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +135,"Youngstown State",Penguins,YSU,AI,Youngstown,OH,USA,"Stambaugh Stadium",20630,20630,12155,2023,14,MVFC,0,,0,0,0,#C8102E,#3D3C3C,#000000,0,D+,C,D,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.360",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +136,"Indiana State",Sycamores,INST,AI,"Terre Haute",IN,USA,"Memorial Stadium",12764,0,12144,2023,14,MVFC,0,,0,0,0,#0142BC,#FFFFFF,,0,D+,D-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.396",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +137,"Illinois State",Redbirds,ILST,AI,Normal,IL,USA,"Hancock Stadium",13391,0,20635,2023,14,MVFC,0,,0,0,0,#CE1126,#F9DD16,#FFFFFF,0,D+,D,C,F,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.435",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +138,"Missouri State",Bears,MOST,AI,Springfield,MO,USA,"Robert W. Plaster Stadium",17500,0,23502,2023,9,C-USA,0,,0,0,0,#5E0009,#FFFFFF,#000000,1,D+,C-,D+,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.472",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +139,"Murray State",Racers,MUR,AI,Murray,KY,USA,"Roy Stewart Stadium",16800,0,9427,2023,14,MVFC,0,,0,0,0,#ECAC00,#002144,#FFFFFF,0,C-,D,C,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.509",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +140,"Northern Iowa",Panthers,UNI,AI,"Cedar Falls",IA,USA,UNI-Dome,16324,0,10497,2023,14,MVFC,0,,0,0,0,#4B116F,#FFCC00,,0,D+,D+,D+,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.546",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +141,"Southern Illinois",Salukis,SIU,AI,Carbondale,IL,USA,"Saluki Stadium",15000,15276,11366,2023,14,MVFC,0,,0,0,0,#FFFFFF,#720000,#000000,0,D,D-,C,F,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.582",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +142,"North Dakota","Fighting Hawks",UND,AI,"Grand Forks",ND,USA,"Alerus Center",12283,0,13876,2023,14,MVFC,0,,0,0,0,#009A44,#AAAEAD,#000000,0,D,D-,D,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.619",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +143,"North Dakota State",Bison,NDSU,"Devin Atwater",Fargo,ND,USA,Fargodome,19000,0,12242,2023,11,"Mountain West",0,,0,0,0,#0A5640,#FFC72A,,1,D,D,D,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-29 22:25:50.697",NULL,0,"2026-04-29 22:25:50.539",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +144,"South Dakota State",Jackrabbits,SDST,AI,Brookings,SD,USA,"Dana J. Dykhouse Stadium",19340,0,11331,2023,14,MVFC,0,,0,0,0,#0033A0,#FFD100,,0,C,C,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.693",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +145,"South Dakota",Coyotes,SDAK,AI,Vermillion,SD,USA,DakotaDome,9100,0,9856,2023,14,MVFC,0,,0,0,0,#AD0000,#B4B4B4,#000000,0,C-,D+,C,D-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.730",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +146,"Western Illinois",Leathernecks,WIU,AI,Macomb,IL,USA,"Hanson Field",16368,0,6170,2023,20,"Big South-OVC",0,,0,0,0,#663399,#FFCC00,,0,C-,D,C,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.767",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +147,Bucknell,Bisons,BUCK,AI,Lewisburg,PA,USA,"Christy Mathewson-Memorial Stadium",13100,0,3650,2023,15,Patriot,0,,0,0,0,#E87722,#003865,#FFFFFF,0,D+,D-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.806",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +148,Colgate,Raiders,COLG,AI,Hamilton,NY,USA,"Andy Kerr Stadium",10221,0,2837,2023,15,Patriot,0,,0,0,0,#821019,#E10028,#000000,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.842",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +149,"Holy Cross",Crusaders,HC,AI,Worcester,MA,USA,"Fitton Field",23500,27000,3174,2023,15,Patriot,0,,0,0,0,#602D89,#FFFFFF,#000000,0,D,D+,D,F,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.881",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +150,Lafayette,Leopards,LAF,AI,Easton,PA,USA,"Fisher Stadium",13132,21000,2382,2023,15,Patriot,0,,0,0,0,#A8996E,#98002E,#FFFFFF,0,D+,D,D+,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:02.917",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +151,Lehigh,"Mountain Hawks",LEH,AI,Bethlehem,PA,USA,"Goodman Stadium",16000,0,5047,2023,15,Patriot,0,,0,0,0,#E51937,#653600,#653600,0,C-,C,D+,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.010",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +152,Fordham,Rams,FOR,AI,Bronx,NY,USA,"Jack Coffey Field",7000,8220,8220,2023,15,Patriot,0,,0,0,0,#860038,#FFFFFF,,0,C-,C-,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.046",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +153,Georgetown,Hoyas,GEOT,AI,Washington,DC,USA,"Cooper Field",3750,7433,7433,2023,15,Patriot,0,,0,0,0,#041E42,#8D817B,,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.084",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +154,"UC Davis",Aggies,UCD,AI,Davis,CA,USA,"UC Davis Health Stadium",10743,0,38369,2023,16,"Big Sky",0,,0,0,0,#B3A369,#002855,,0,C,B-,C,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.120",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +155,"Cal Poly",Mustangs,CP,AI,"San Luis Obispo",CA,USA,"Alex G. Spanos Stadium",11075,0,21812,2023,16,"Big Sky",0,,0,0,0,#003831,#FFE395,#000000,0,C,C-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.156",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +156,"Eastern Washington",Eagles,EWU,"David VanHousen",Cheney,WA,USA,"Roos Field",8600,11702,12607,2023,16,"Big Sky",0,,0,0,0,#FFFFFF,#A10022,#000000,0,C,C,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.195",NULL,0,"2026-02-16 14:30:19.288",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +157,Idaho,Vandals,IDHO,AI,Moscow,ID,USA,"Kibbie Dome",16000,19878,11814,2023,16,"Big Sky",0,,0,0,0,#B3A369,#EAAB00,#B3A369,0,B-,B-,B-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.231",NULL,0,"2026-04-07 20:27:53.796",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +158,"Idaho State",Bengals,IDST,AI,Pocatello,ID,USA,"Holt Arena",12000,13895,12805,2023,16,"Big Sky",0,,0,0,0,#FF671F,#000000,,0,B,B,B+,C+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.268",NULL,0,"2026-04-07 22:42:34.712",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +159,Montana,Grizzlies,MONT,AI,Missoula,MT,USA,"Washington-Grizzly Stadium",25217,26856,10104,2023,16,"Big Sky",0,,0,0,0,#999999,#660033,,0,C-,D+,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.305",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +160,"Montana State",Bobcats,MTST,AI,Bozeman,MT,USA,"Bobcat Stadium",20767,22037,16766,2023,16,"Big Sky",0,,0,0,0,#00205B,#B9975B,,0,C,C,D+,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.343",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +161,"Northern Arizona",Lumberjacks,NAU,AI,Flagstaff,AZ,USA,"Walkup Skydome",11230,0,22791,2023,16,"Big Sky",0,,0,0,0,#FFD200,#003466,,0,C,C,C-,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.380",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +162,"Northern Colorado",Bears,UNCO,AI,Greeley,CO,USA,"Nottingham Field",8533,0,12862,2023,16,"Big Sky",0,,0,0,0,#013C65,#F6B000,,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.417",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +163,"Portland State",Vikings,PRST,AI,Portland,OR,USA,"Hillsboro Stadium",7600,10000,27285,2023,16,"Big Sky",0,,0,0,0,#373A36,#154734,#FFFFFF,0,D+,C-,D+,F,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.454",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +164,"Sacramento State",Hornets,SSU,AI,Sacramento,CA,USA,"Hornet Stadium",21195,23073,31181,2023,10,MAC,0,,0,0,0,#043927,#C4B581,,1,C,C,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.492",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +165,"Weber State",Wildcats,WEB,AI,Ogden,UT,USA,"Stewart Stadium",17312,0,27465,2023,16,"Big Sky",0,,0,0,0,#4B2682,#A1A1A4,,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.530",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +166,Brown,Bears,BRWN,AI,Providence,RI,USA,"Brown Stadium",20000,0,7043,2023,17,"Ivy League",0,,0,0,0,#4E3629,#7C2529,#000000,0,C,C,C,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.568",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +167,Columbia,Lions,COLU,AI,"New York",NY,USA,"Lawrence A. Wien Stadium",17000,0,6398,2023,17,"Ivy League",0,,0,0,0,#9BCBEB,#003865,#FFFFFF,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.606",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +168,Cornell,"Big Red",COR,AI,Ithaca,NY,USA,"Schoellkopf Field",21500,0,15043,2023,17,"Ivy League",0,,0,0,0,#B31B1B,#5E3920,#000000,0,D+,C-,D,B,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.655",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +169,Dartmouth,"Big Green",DART,AI,Hanover,NH,USA,"Memorial Field",11000,0,4495,2023,17,"Ivy League",0,,0,0,0,#046A38,#000000,#FFFFFF,0,C,C,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.695",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +170,Pennsylvania,Quakers,PENN,AI,Philadelphia,PA,USA,"Franklin Field",52958,0,10019,2023,17,"Ivy League",0,,0,0,0,#990000,#011F5B,#FFFFFF,0,D,D,C-,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.741",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +171,Harvard,Crimson,HARV,AI,Cambridge,MA,USA,"Harvard Stadium",30323,0,6788,2023,17,"Ivy League",0,,0,0,0,#A41034,#000000,#B6B6B6,0,D,D-,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.777",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +172,Princeton,Tigers,PRIN,AI,Princeton,NJ,USA,"Princeton Stadium",27773,27800,5428,2023,17,"Ivy League",0,,0,0,0,#FF671F,#000000,,0,C,C-,C,D+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.816",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +173,Yale,Bulldogs,YALE,AI,"New Haven",CT,USA,"Yale Bowl",61446,0,6092,2023,17,"Ivy League",0,,0,0,0,#00356B,#FFFFFF,,0,C,C,C,C+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.852",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +174,Furman,Paladins,FUR,AI,Greenville,SC,USA,"Paladin Stadium",16000,0,2629,2023,18,SoCon,0,,0,0,0,#201547,#582C83,#A7A8AA,0,C,C-,C,C+,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.889",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +175,Samford,Bulldogs,SAM,AI,Homewood,AL,USA,"Seibert Stadium",6700,11000,5729,2023,18,SoCon,0,,0,0,0,#002649,#C4161D,,0,D+,D-,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.926",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +176,"The Citadel",Bulldogs,CIT,AI,Charleston,SC,USA,"Johnson Hagood Stadium",22342,22342,3693,2023,18,SoCon,0,,0,0,0,#3975B7,#1F3A60,#FFFFFF,0,C,C,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.962",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +177,Wofford,Terriers,WOF,AI,Spartanburg,SC,USA,"Gibbs Stadium",13000,0,1773,2023,18,SoCon,0,,0,0,0,#886E4C,#FFFFFF,#C7B37F,0,C-,D,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:03.999",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +178,Chattanooga,Mocs,UTC,AI,Chattanooga,TN,USA,"Finley Stadium",20412,0,11728,2023,18,SoCon,0,,0,0,0,#00386B,#E0AA0F,#ADAFAA,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.035",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +179,"East Tennessee State",Buccaneers,ETSU,AI,"Johnson City",TN,USA,"William B. Greene Jr. Stadium",7694,10594,9151,2023,18,SoCon,0,,0,0,0,#041E42,#FFC72C,,0,D,D-,D,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.072",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +180,"Western Carolina",Catamounts,WCU,AI,Cullowhee,NC,USA,"EJ Whitmire Stadium",13742,0,12243,2023,18,SoCon,0,,0,0,0,#592C88,#C1A875,,0,C,C,D,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.113",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +181,Mercer,Bears,MER,AI,Macon,GA,USA,"Five Star Stadium",10200,12712,9026,2023,18,SoCon,0,,0,0,0,#F76800,#000000,,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.149",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +182,VMI,Keydets,VMI,AI,Lexington,VA,USA,"Foster Stadium",10000,0,1772,2023,18,SoCon,0,,0,0,0,#A71F23,#FFD520,#000000,0,C,C,C-,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.185",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +183,Grambling,Tigers,GRAM,AI,Grambling,LA,USA,"Eddie G. Robinson Memorial Stadium",19600,0,5438,2023,19,SWAC,18,West,0,0,0,#EAA921,#000000,,0,D+,D,C-,D-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.226",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +184,Bethune-Cookman,Wildcats,BCU,AI,"Daytona Beach",FL,USA,"Daytona Stadium",15000,0,2901,2023,19,SWAC,17,East,0,0,0,#F2A900,#6F263D,#000000,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.263",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +185,"Prairie View A&M",Panthers,PV,AI,"Prairie View",TX,USA,"Blackshear Field",15000,0,9350,2023,19,SWAC,18,West,0,0,0,#330066,#FFCC33,#FFCC33,0,C,C-,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.300",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +186,"Alcorn State",Braves,ALCN,AI,Lorman,MS,USA,"Spinks-Casem Stadium",22500,0,3523,2023,19,SWAC,18,West,0,0,0,#CE8E00,#4B306A,,0,D+,D+,C-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.337",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +187,Southern,Jaguars,SOU,AI,"Baton Rouge",LA,USA,"A.W. Mumford Stadium",28500,0,7140,2023,19,SWAC,18,West,0,0,0,#FFCE34,#58B6E7,#FFFFFF,0,C,C,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.373",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +188,"Alabama A&M",Bulldogs,AAMU,AI,Huntsville,AL,USA,"Louis Crews Stadium",21000,0,6172,2023,19,SWAC,17,East,0,0,0,#660000,#FFFFFF,,0,C,C,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.434",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +189,"Arkansas-Pine Bluff","Golden Lions",UAPB,AI,"Pine Bluff",AR,USA,"Simmons Bank Field",16000,0,2498,2023,19,SWAC,18,West,0,0,0,#EEB310,#E31837,#FFFFFF,0,D+,D,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.471",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +190,"Florida A&M",Rattlers,FAMU,AI,Tallahassee,FL,USA,"Bragg Memorial Stadium",2550,33954,9626,2023,19,SWAC,17,East,0,0,0,#EE7624,#1B5633,#231F20,0,C-,D,C,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.508",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +191,"Alabama State",Hornets,ALST,AI,Montgomery,AL,USA,"New ASU Stadium",26500,0,4190,2023,19,SWAC,17,East,0,0,0,#000000,#C99700,,0,C-,D+,C,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.547",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +192,"Texas Southern",Tigers,TXSO,AI,Houston,TX,USA,"PNC Stadium",22039,20197,7524,2023,19,SWAC,18,West,0,0,0,#7C183E,#9DA6AB,#FFFFFF,0,D+,C-,D,C-,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.585",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +193,"Mississippi Valley State","Delta Devils",MSVU,AI,"Itta Bena",MS,USA,"Rice-Totten Stadium",10000,0,2147,2023,19,SWAC,17,East,0,0,0,#00703C,#E51937,#000000,0,D,C-,D-,C,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.621",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +194,"Jackson State",Tigers,JXST,AI,Jackson,MS,USA,"Mississippi Veterans Memorial Stadium",62500,62512,7080,2023,19,SWAC,17,East,0,0,0,#002147,#008ED6,#FFFFFF,0,D+,C-,D,D,1,1,0,,0,1,"0000-00-00 00:00:00.000","2026-04-20 18:01:04.661",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +195,"Charleston Southern",Buccaneers,CHSO,AI,"Bules Creek",NC,USA,"Buccaneer Field",10000,4000,0,2027,20,"Big South-OVC",0,,0,0,0,#A8996E,#002855,#ffffff,0,C,C,C,C,1,1,220,,0,1,"2024-04-22 21:02:42.811","2026-04-20 18:01:04.705",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +196,"Eastern Illinois",Panthers,EIU,AI,Charleston,IL,USA,"O'Brien Field",10000,10000,0,2027,20,"Big South-OVC",0,,0,0,0,#919295,#004b83,#ffffff,0,C,C,C,C,1,1,221,,0,1,"2024-04-22 21:02:43.708","2026-04-20 18:01:04.742",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +197,Gardner-Webb,"Runnin' Bulldogs",WEBB,AI,"Boiling Springs",NC,USA,"Ernest W. Spangler Stadium",10000,7800,0,2027,20,"Big South-OVC",0,,0,0,0,#BF2F37,#ffffff,#ffffff,0,C,C+,C,C,1,1,222,,0,1,"2024-04-22 21:02:44.594","2026-04-20 18:01:04.781",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +198,Lindenwood,Lions,LIN,AI,"St. Charles",MO,USA,"Hunter STadium",10000,7450,0,2027,20,"Big South-OVC",0,,0,0,0,#B5A36A,#101820,#ffffff,0,C,C-,C,C,1,1,223,,0,1,"2024-04-22 21:02:45.490","2026-04-20 18:01:04.817",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +199,"Southeast Missouri State",Redhawks,SEMO,AI,"Cape Girardeau",MO,USA,"Houck Stadium",10000,11015,0,2027,20,"Big South-OVC",0,,0,0,0,#000000,#C8102E,#ffffff,0,C,C,C-,C,1,1,224,,0,1,"2024-04-22 21:02:46.367","2026-04-20 18:01:04.854",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +200,"Tennessee State",Tigers,TNST,AI,Nashville,TN,USA,"Hale Stadium",10000,10000,0,2027,20,"Big South-OVC",0,,0,0,0,#00539F,#ffffff,#ffffff,0,C,C,C,C+,1,1,225,,1,1,"2024-04-22 21:02:47.251","2026-04-20 18:01:04.893",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +201,"Tennessee Tech","Golden Eagles",TNTC,AI,Cookeville,TN,USA,"Tucker Stadium",10000,16500,0,2027,18,SoCon,0,,0,0,0,#4f2984,#FFDD00,#ffffff,0,C-,D+,C,D-,1,1,226,,0,1,"2024-04-22 21:02:48.158","2026-04-20 18:01:04.932",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +202,"UT Martin",Skyhawks,UTM,AI,Martin,TN,USA,"Graham Stadium",10000,7500,0,2027,20,"Big South-OVC",0,,0,0,0,#f79728,#002a5b,#ffffff,0,C-,C,D+,C,1,1,227,,0,1,"2024-04-22 21:02:49.060","2026-04-20 18:01:04.969",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +203,Albany,"Great Danes",ALB,GhostBlade,Albany,NY,USA,"Tom & Mary Casey Stadium",10000,8500,0,2027,21,CAA,0,,0,0,0,#461660,#eeb211,#FFFFFF,0,C-,C-,C,C-,1,1,228,,0,1,"2024-04-22 21:02:49.954","2026-04-20 18:01:05.010",NULL,0,"2026-02-12 20:59:07.207",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +204,Bryant,Bulldogs,BRY,AI,Smithfield,RI,USA,"Beirne Stadium",10000,5500,0,2027,21,CAA,0,,0,0,0,#b4975b,#000000,#c9bb8c,0,C,C,C,B-,1,1,229,,0,1,"2024-04-22 21:02:50.845","2026-04-20 18:01:05.048",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +205,Campbell,"Fighting Camels",CAMP,AI,"Buies Creek",NC,USA,"Barker-Lane Stadium",10000,5500,0,2027,21,CAA,0,,0,0,0,#f58025,#231f20,#ffffff,0,C-,C-,C-,D+,1,1,230,,0,1,"2024-04-22 21:02:51.721","2026-04-20 18:01:05.084",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +206,Delaware,"Fighting Blue Hens",DEL,Osu,Newark,DE,USA,"Delaware Stadium",10000,18500,0,2027,9,C-USA,0,,0,0,0,#00539f,#FFDD31,#ffffff,1,C,C,B-,D,1,1,231,<@485314920083095575>,0,1,"2024-04-22 21:02:52.610","2026-04-20 18:01:05.125",NULL,0,"2025-11-12 01:05:58.594",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +207,Elon,Phoenix,ELON,AI,Elon,NC,USA,"Rhodes Stadium",10000,11250,0,2027,21,CAA,0,,0,0,0,#73000a,#b59a57,#ffffff,0,D+,D,C,C-,1,1,232,,0,1,"2024-04-22 21:02:53.493","2026-04-20 18:01:05.162",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +208,Hampton,Pirates,HAMP,AI,Hampton,VA,USA,"Armstrong Stadium",10000,10000,0,2027,21,CAA,0,,0,0,0,#ffffff,#0060A9,#ffffff,0,C,C,C,C,1,1,233,,0,1,"2024-04-22 21:02:54.373","2026-04-20 18:01:05.204",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +209,Maine,Blackbears,ME,AI,Orono,ME,USA,"Harold Alfond Sports Stadium",10000,8419,0,2027,21,CAA,0,,0,0,0,#003263,#B0D7FF,#908C89,0,C,C,C,C,1,1,234,,0,1,"2024-04-22 21:02:55.268","2026-04-20 18:01:05.243",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +210,Monmouth,Hawks,MONM,AI,"West Long Branch",NJ,USA,"Kessler Field",10000,4600,0,2027,21,CAA,0,,0,0,0,#041E42,#53565A,#ffffff,0,C,C,C,C,1,1,235,,0,1,"2024-04-22 21:02:56.187","2026-04-20 18:01:05.280",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +211,"New Hampshire",Wildcats,UNH,AI,Durham,NH,USA,"Wildcat Stadium",10000,11015,0,2027,21,CAA,0,,0,0,0,#041e42,#BBBCBC,#FFFFFF,0,C,C,C,C+,1,1,236,,0,1,"2024-04-22 21:02:57.077","2026-04-20 18:01:05.317",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +212,"North Carolina A&T",Aggies,NCAT,AI,Greensboro,NC,USA,"Truist Stadium",10000,21500,0,2027,21,CAA,0,,0,0,0,#f3b237,#003d6d,#ffffff,0,C,C,D,C,1,1,237,,0,1,"2024-04-22 21:02:57.968","2026-04-20 18:01:05.354",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +213,"Rhode Island",Rams,URI,AI,Kingston,RI,USA,"Meade Stadium",10000,6580,0,2027,21,CAA,0,,0,0,0,#68abe8,#002147,#ffffff,0,C,D,C,C,1,1,238,,0,1,"2024-04-22 21:02:58.839","2026-04-20 18:01:05.391",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +214,Richmond,Spiders,RICH,AI,Richmond,VA,USA,"E. Claiborne Robins Stadium",10000,8700,0,2027,15,Patriot,0,,0,0,0,#000066,#990000,#ffffff,0,D,D+,D,C,1,1,239,,0,1,"2024-04-22 21:02:59.727","2026-04-20 18:01:05.428",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +215,"Stony Brook",Seawolves,STBK,AI,"Stony Brook",NY,USA,"Kenneth P. LaValle Stadium",10000,12300,0,2027,21,CAA,0,,0,0,0,#990000,#16243e,#828282,0,C,C,C,C-,1,1,240,,0,1,"2024-04-22 21:03:00.594","2026-04-20 18:01:05.464",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +216,Towson,Tigers,TOW,AI,Towson,MD,USA,"Johnny Unitas Stadiumn",10000,11198,0,2027,21,CAA,0,,0,0,0,#FFBB00,#3C3C3C,#ffffff,0,C,C,C,C,1,1,241,,0,1,"2024-04-22 21:03:01.479","2026-04-20 18:01:05.501",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +217,Villanova,Wildcats,VILL,AI,Philadelphia,PA,USA,"Villanova Stadium",10000,12500,0,2027,15,Patriot,0,,0,0,0,#00205b,#13b5ea,#ffffff,0,C,C,C,C,1,1,242,,0,1,"2024-04-22 21:03:02.368","2026-04-20 18:01:05.539",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +218,"William & Mary",Tribe,W&M,AI,Williamsburg,VA,USA,"Water J. Zable Stadium",10000,12259,0,2027,15,Patriot,0,,0,0,0,#115740,#F0B323,#ffffff,0,C,C,C+,D,1,1,243,,0,1,"2024-04-22 21:03:03.281","2026-04-20 18:01:05.576",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +219,Merrimack,Warriors,MRMK,AI,"North Andover",MA,USA,"Duane Stadium",10000,4000,0,2027,22,Independent,0,,0,0,0,#003768,#fdb813,#ffffff,0,C,C,C,C,1,1,244,,0,1,"2024-04-22 21:03:04.177","2026-04-20 18:01:05.614",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +220,"Sacred Heart",Pioneers,SHU,dotNectar,Fairfield,CT,USA,"Campus Field",10000,3334,0,2027,21,CAA,0,,0,0,0,#ce1141,#b1b3b6,#ffffff,0,C,C,C,C,1,1,245,,0,1,"2024-04-22 21:03:05.068","2026-05-05 18:44:53.364",NULL,0,"2026-05-05 18:44:53.290",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +221,"Delaware State",Hornets,DSU,AI,Dover,DE,USA,"Alumni Stadium",10000,7193,0,2027,23,MEAC,0,,0,0,0,#EE3124,#72CDF4,#ffffff,0,C-,C,C-,C-,1,1,246,,0,1,"2024-04-22 21:03:05.959","2026-04-20 18:01:05.692",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +222,Howard,Bison,HOW,AI,Washington,DC,USA,"William H. Greene Stadium",10000,10000,0,2027,23,MEAC,0,,0,0,0,#e51937,#003a63,#ffffff,0,C,C+,C,D,1,1,247,,0,1,"2024-04-22 21:03:06.848","2026-04-20 18:01:05.728",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +223,"Morgan State",Bears,MORG,AI,Baltimore,MD,USA,"Hughes Stadium",10000,10000,0,2027,23,MEAC,0,,0,0,0,#1b4383,#f47937,#ffffff,0,C,C,C,C,1,1,248,,0,1,"2024-04-22 21:03:07.734","2026-04-20 18:01:05.770",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +224,"Norfolk State",Spartans,NORF,AI,Norfolk,VA,USA,"William "Dick" Price Stadium",10000,30000,0,2027,23,MEAC,0,,0,0,0,#F3D03E,#007A53,#ffffff,0,C,C,C,C,1,1,249,,0,1,"2024-04-22 21:03:08.617","2026-04-20 18:01:05.807",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +225,"North Carolina Central",Eagles,NCCU,AI,Durham,NC,USA,"O'Kelly-Riddick Stadium",10000,10000,0,2027,23,MEAC,0,,0,0,0,#880023,#8e9093,#ffffff,0,C,C,C,C+,1,1,250,,0,1,"2024-04-22 21:03:09.489","2026-04-20 18:01:05.843",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +226,"South Carolina State",Bulldogs,SCST,AI,Orangeburg,SC,USA,"Oliver C. Dawson Stadium",10000,20000,0,2027,23,MEAC,0,,0,0,0,#001A72,#862633,#ffffff,0,C,C+,C,B-,1,1,251,,0,1,"2024-04-22 21:03:10.391","2026-04-20 18:01:05.880",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +227,"Central Connecticut","Blue Devils",CCSU,AI,"New Britain",CT,USA,"Arute Field",10000,5500,0,2027,24,NEC,0,,0,0,0,#00539b,#ffffff,#ffffff,0,C,C,C,D,1,1,252,,0,1,"2024-04-22 21:03:11.284","2026-04-20 18:01:05.916",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +228,Duquesne,Dukes,DUQ,AI,Pittsburgh,PA,USA,"Arthur J. Rooney Athletic Field",10000,2200,0,2027,24,NEC,0,,0,0,0,#041E42,#BA0C2F,#ffffff,0,D+,D,C,D+,1,1,253,,0,1,"2024-04-22 21:03:12.173","2026-04-20 18:01:05.953",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +229,LIU,Sharks,LIU,AI,Brooklyn,NY,USA,"Bethpage Federal Credit Union Stadium",10000,6000,0,2027,24,NEC,0,,0,0,0,#69B3E7,#FFC72C,#ffffff,0,C,C,C,C+,1,1,254,,1,1,"2024-04-22 21:03:13.062","2026-04-20 18:01:05.989",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +230,Mercyhurst,Lakers,MRCY,AI,Erie,PA,USA,"Saxon Stadium",10000,2300,0,2027,24,NEC,0,,0,0,0,#07594D,#182752,#ffffff,0,C,C,C-,C,1,1,255,,0,1,"2024-04-22 21:03:14.064","2026-04-20 18:01:06.032",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +231,"Robert Morris",Colonials,RMU,AI,"Moon Township",PA,USA,"Joe Walton Stadium",10000,3000,0,2027,24,NEC,0,,0,0,0,#14234b,#a6192e,#ffffff,0,C,C,C,C,1,1,256,,0,1,"2024-04-22 21:03:14.946","2026-04-20 18:01:06.071",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +232,"Saint Francis","Red Flash",SFPA,AI,Loretto,PA,USA,"DeGol Field",10000,3450,0,2027,22,Independent,0,,0,0,0,#bd1f25,#8e908f,#ffffff,0,C-,D+,C,C-,1,1,257,,0,1,"2024-04-22 21:03:15.838","2026-04-20 18:01:06.109",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +233,Stonehill,Skyhawks,STO,AI,Easton,MA,USA,"W.B. Mason Stadium",10000,2400,0,2027,24,NEC,0,,0,0,0,#2F2975,#FFFFFF,#ffffff,0,C,C,D+,C,1,1,258,,0,1,"2024-04-22 21:03:16.707","2026-04-20 18:01:06.146",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +234,Wagner,Seahawks,WAG,AI,"Staten Island",NY,USA,"Wagner College Stadium",10000,3500,0,2027,24,NEC,0,,0,0,0,#00483a,#b9bbbd,#ffffff,0,D,D-,D+,C,1,1,259,,0,1,"2024-04-22 21:03:17.604","2026-04-20 18:01:06.184",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +235,Butler,Bulldogs,BUT,AI,Indianapolis,IN,USA,"Bud and Jackie Sellick Bowl",10000,7500,0,2027,25,Pioneer,0,,0,0,0,#13294b,#747678,#ffffff,0,C,C,C+,C,1,1,260,,0,1,"2024-04-22 21:03:18.478","2026-04-20 18:01:06.220",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +236,Davidson,Wildcats,DAV,AI,Davidson,NC,USA,"Richardson Stadium",10000,4741,0,2027,25,Pioneer,0,,0,0,0,#ac1a2f,#000000,#ffffff,0,C,C,C,C,1,1,261,,0,1,"2024-04-22 21:03:19.373","2026-04-20 18:01:06.257",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +237,Dayton,Flyers,DAY,AI,Dayton,OH,USA,"Welcome Stadium",10000,11000,0,2027,25,Pioneer,0,,0,0,0,#CE1141,#004B8D,#ffffff,0,C,C,C,C,1,1,262,,1,1,"2024-04-22 21:03:20.249","2026-04-20 18:01:06.294",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +238,Drake,Bulldogs,DRKE,AI,"Des Moines",IA,USA,"Drake Stadium",10000,14557,0,2027,25,Pioneer,0,,0,0,0,#004477,#999999,#ffffff,0,C,C,C-,C,1,1,263,,0,1,"2024-04-22 21:03:21.156","2026-04-20 18:01:06.330",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +239,Marist,"Red Foxes",MRST,AI,Poughkeepsie,NY,USA,"Leonidoff Field",10000,5000,0,2027,25,Pioneer,0,,0,0,0,#C8102E,#b2b2b2,#ffffff,0,C,C,C,C,1,1,264,,0,1,"2024-04-22 21:03:22.049","2026-04-20 18:01:06.367",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +240,"Morehead State",Eagles,MORE,AI,Morehead,KY,USA,"Jayne Stadium",10000,10000,0,2027,25,Pioneer,0,,0,0,0,#005EB8,#FFCF00,#ffffff,0,C,C,C,D,1,1,265,,0,1,"2024-04-22 21:03:22.933","2026-04-20 18:01:06.404",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +241,Presbyterian,"Blue Hose",PRE,AI,Clinton,SC,USA,"Bailey Memorial Stadium",10000,6500,0,2027,25,Pioneer,0,,0,0,0,#0060A9,#9D2235,#ffffff,0,C,C-,C,C,1,1,266,,0,1,"2024-04-22 21:03:23.821","2026-04-20 18:01:06.441",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +242,"San Diego",Torreros,USD,AI,"San Diego",CA,USA,"Torero Stadium",10000,6000,0,2027,25,Pioneer,0,,0,0,0,#002868,#84bce8,#FFFFFF,0,C,C-,C,C-,1,1,267,,0,1,"2024-04-22 21:03:24.693","2026-04-20 18:01:06.477",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +243,"St. Thomas",Tommies,STMN,AI,"Saint Paul",MN,USA,"O'Shaughnessy Stadium",10000,5025,0,2027,25,Pioneer,0,,0,0,0,#FFFFFF,#512773,#ffffff,0,C,C,C-,C,1,1,268,,0,1,"2024-04-22 21:03:25.601","2026-04-20 18:01:06.513",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +244,Stetson,Hatters,STET,AI,DeLand,FL,USA,"Spec Martin Memorial Stadium",10000,6000,0,2027,25,Pioneer,0,,0,0,0,#00523E,#FFFFFF,#3B8729,0,C,C,C,C-,1,1,269,,0,1,"2024-04-22 21:03:26.474","2026-04-20 18:01:06.602",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +245,Valparaiso,Beacons,VAL,AI,Valparaiso,IN,USA,"Brown Field",10000,5000,0,2027,25,Pioneer,0,,0,0,0,#381e0e,#ffcc00,#613318,0,C-,C,D,C,1,1,270,,0,1,"2024-04-22 21:03:27.372","2026-04-20 18:01:06.640",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +246,"Houston Christian",Huskies,HCU,AI,Houston,TX,USA,"Husky Stadium",10000,5000,0,2027,26,Southland,0,,0,0,0,#1c4e9d,#f3652c,#ffffff,0,C-,D+,C,C,1,1,271,,0,1,"2024-04-22 21:03:28.249","2026-04-20 18:01:06.676",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +247,"Incarnate Word",Cardinals,UIW,AI,"San Antonio",TX,USA,"Gayle and Tom Benson Stadium",10000,6000,0,2027,26,Southland,0,,0,0,0,#cb333b,#000000,#ffffff,0,C,C,C-,C,1,1,272,,0,1,"2024-04-22 21:03:29.134","2026-04-20 18:01:06.713",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +248,Lamar,Cardinals,LAM,AI,Beaumont,TX,USA,"Provost Umphrey Stadium",10000,16000,0,2027,26,Southland,0,,0,0,0,#dc0032,#ffffff,#ffffff,0,C,C,C,D,1,1,273,,0,1,"2024-04-22 21:03:30.007","2026-04-20 18:01:06.752",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +249,McNeese,Cowboys,MCN,AI,"Lake Charles",LA,USA,"Cowboy Stadium",10000,17610,0,2027,26,Southland,0,,0,0,0,#00529b,#ffd204,#ffffff,0,C,C,C,C+,1,1,274,,0,1,"2024-04-22 21:03:30.908","2026-04-20 18:01:06.789",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +250,Nicholls,Colonels,NICH,AI,Thibodaux,LA,USA,"Manning Field at John L. Guidry Stadium",10000,10500,0,2027,26,Southland,0,,0,0,0,#ae132a,#72808a,#ffffff,0,C-,D+,C,D,1,1,275,,1,1,"2024-04-22 21:03:31.813","2026-04-20 18:01:06.826",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +251,"Northwestern State",Demons,NWST,AI,Natchitotches,LA,USA,"Harry Turpin Stadium",10000,15971,0,2027,26,Southland,0,,0,0,0,#663399,#ffffff,#ffffff,0,C,C,C,C,1,1,276,,0,1,"2024-04-22 21:03:32.719","2026-04-20 18:01:06.864",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +252,"SE Louisiana",Lions,SELA,AI,Hammond,LA,USA,"Strawberry Stadium",10000,7408,0,2027,26,Southland,0,,0,0,0,#006341,#eaaa00,#ffffff,0,D+,C-,D,C-,1,1,277,,0,1,"2024-04-22 21:03:33.617","2026-04-20 18:01:06.900",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +253,"East Texas A&M",Lions,ETAM,AI,Commerce,TX,USA,"Ernest Hawkins Field at Memorial Stadium",10000,11582,0,2027,26,Southland,0,,0,0,0,#00386C,#F1B20F,#FFFFFF,0,C,C,C,C,1,1,278,,0,1,"2024-04-22 21:03:34.500","2026-04-20 18:01:06.937",NULL,0,"2025-07-25 18:35:07.235",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +254,"UT Rio Grande Valley",Vaqueros,RGV,AI,Edinburg,TX,USA,"Robert and Janet Vackar Stadium",10000,9735,0,2027,26,Southland,0,,0,0,0,#FFA300,#0C2340,#ffffff,0,C,C,D,D+,1,1,279,,0,1,"2024-04-22 21:03:35.408","2026-04-20 18:01:06.974",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +255,"Abilene Christian",Wildcats,ACU,AI,Abilene,TX,USA,"Anthony Field at Wildcat Stadium",10000,12000,0,2027,27,UAC,0,,0,0,0,#4f2170,#FFFFFF,,0,C,C,C,C,1,1,280,,0,1,"2024-04-22 21:03:36.299","2026-04-20 18:01:07.011",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +256,"Austin Peay",Governors,APSU,AI,Clarksville,TN,USA,"Fortera Stadium",10000,10100,0,2027,27,UAC,0,,0,0,0,#C41E3A,#ffffff,#000000,0,C,C,C,C,1,1,281,,0,1,"2024-04-22 21:03:37.199","2026-04-20 18:01:07.047",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +257,"Central Arkansas",Bears,CARK,AI,Conway,AR,USA,"Estes Stadium",10000,10000,0,2027,27,UAC,0,,0,0,0,#4f2d7f,#818a8f,#000000,0,C,C,C,C,1,1,282,,0,1,"2024-04-22 21:03:38.085","2026-04-20 18:01:07.085",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +258,"Eastern Kentucky",Colonels,EKU,AI,Richmond,KY,USA,"Roy Kidd Stadium",10000,20000,0,2027,27,UAC,0,,0,0,0,#8a0039,#ffffff,#000000,0,C,C,C,C,1,1,283,,0,1,"2024-04-22 21:03:38.958","2026-04-20 18:01:07.122",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +259,"North Alabama",Lions,UNA,AI,Florence,AL,USA,"Braly Municipal Stadium",10000,14215,0,2027,27,UAC,0,,0,0,0,#46166B,#DB9F11,#5F6062,0,C,C,C-,D+,1,1,284,,0,1,"2024-04-22 21:03:39.866","2026-04-20 18:01:07.158",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +260,"Southern Utah",Thunderbirds,SUU,AI,"Cedar City",UT,USA,"Eccles Coliseum",10000,8500,0,2027,16,"Big Sky",0,,0,0,0,#C41425,#000000,#ffffff,0,C,C,C,C-,1,1,285,,0,1,"2024-04-22 21:03:40.741","2026-04-20 18:01:07.413",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +261,"Stephen F. Austin",Lumberjacks,SFA,AI,Nacogdoches,TX,USA,"Homer Bryce Stadium",10000,14575,0,2027,26,Southland,0,,0,0,0,#613393,#ffffff,#ffffff,0,C,C,C,C,1,1,286,,0,1,"2024-04-22 21:03:41.628","2026-04-20 18:01:07.449",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +262,"Tarleton State",Texans,TAR,AI,Stephenville,TX,USA,"Memorial Stadium",10000,24000,0,2027,27,UAC,0,,0,0,0,#ffffff,#4f2d7f,#ffffff,0,C,C-,C,C,1,1,287,,0,1,"2024-04-22 21:03:42.523","2026-04-20 18:01:07.486",NULL,0,"2025-10-14 14:34:45.406",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +263,"Utah Tech",Trailblazers,UTU,AI,"St. George",UT,USA,"Greater Zion STadium",10000,10000,0,2027,16,"Big Sky",0,,0,0,0,#BA1C21,#0C233F,#ffffff,0,C,C,C,C,1,1,288,,0,1,"2024-04-22 21:03:43.419","2026-04-20 18:01:07.530",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +264,"West Georgia",Wolves,UWG,AI,Carrollton,GA,USA,"University Stadium",10000,10000,0,2027,27,UAC,0,,0,0,0,#0656A5,#DA2128,#FFFFFF,0,C,C,C+,C,1,1,289,,0,1,"2024-04-22 21:03:44.345","2026-04-20 18:01:07.566",NULL,0,"2025-09-03 21:54:32.865",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +265,"Chicago State",Cougars,CHST,,Chicago,IL,USA,"SeatGeek Stadium",20000,20000,0,2027,24,NEC,0,,0,0,0,#006666,#000000,#ffffff,0,F,F,F,F,1,1,290,,0,1,"2025-09-22 16:52:47.224","2026-04-20 18:01:07.603",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +266,"New Haven",Chargers,NHU,,"New Haven",CT,USA,"Ralph F. DellaCamera Stadium",5000,5000,0,2027,24,NEC,0,,0,0,0,#004B8D,#FFC423,#ffffff,0,,,,,1,1,291,,0,1,"2025-09-22 16:52:48.121","2026-04-20 18:01:07.640",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +267,Guam,Tritons,UOG,AI,Mangilao,GM,USA,"National Football Stadium",1000,0,0,2027,22,Independent,0,,0,0,0,#046A38,#FFFFFF,#FFFFFF,0,,,,,0,0,292,,0,1,"2026-05-05 18:38:07.382","2026-05-05 18:38:07.382",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +268,"American Samoa",Kingfishers,SAMO,AI,"Pago Pago",AS,USA,"Veterans Memorial Stadium",1000,0,0,2027,22,Independent,0,,0,0,0,#fde5c3,#bc3714,#FFFFFF,0,,,,,0,0,293,,0,1,"2026-05-05 18:38:07.931","2026-05-05 18:38:07.931",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +269,"West Florida",Argonauts,UWF,AI,Pensacola,FL,USA,"Darrell Gooden Stadium",7500,0,0,2027,27,UAC,0,,0,0,0,#007DC3,#00B085,#ffffff,0,,,,,0,0,294,,0,1,"2026-05-05 18:38:08.483","2026-05-05 18:38:08.483",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL +270,Marquette,"Golden Eagles",MARQ,AI,Milwaukee,WI,USA,"Marquette Stadium",24000,0,0,2027,22,Independent,0,,0,0,0,#003366,#ffcc00,#ffffff,0,,,,,0,0,295,,0,1,"2026-05-05 18:38:09.033","2026-05-05 18:38:09.033",NULL,0,"0000-00-00 00:00:00.000",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL diff --git a/data/2027/rivalries.csv b/data/2027/rivalries.csv new file mode 100644 index 0000000..ee4be9f --- /dev/null +++ b/data/2027/rivalries.csv @@ -0,0 +1,326 @@ +id,rivalry_name,trophy_name,team_one_id,team_name,team_two_id,team_name,team_one_priority,team_two_priority,is_annual_rivalry,conference_id,preferred_week,is_neutral_site,stadium_id +1,,"Commander in Chief's Trophy",1,"Air Force",65,Navy,5,5,0,0,0,0,0 +2,,,1,"Air Force",25,"Colorado State",4,4,0,0,0,0,0 +3,,,1,"Air Force",38,Hawaii,4,4,0,11,0,0,0 +4,,"Wagon Wheel",2,Akron,46,"Kent State",5,5,1,10,14,0,0 +5,"Steel Tire",,2,Akron,135,"Youngstown State",3,5,0,0,0,0,0 +6,"Third Saturday in October",,100,Tennessee,3,Alabama,5,5,1,7,8,0,0 +7,"Iron Bowl",,3,Alabama,10,Auburn,5,5,1,7,14,0,0 +8,"Houndstooth Hoedown",,3,Alabama,84,"Penn State",1,1,0,0,0,0,0 +9,,,3,Alabama,30,Florida,2,2,0,7,0,0,0 +10,,,3,Alabama,34,Georgia,3,3,0,7,0,0,0 +11,,,3,Alabama,22,Clemson,3,3,0,0,0,0,0 +12,,,3,Alabama,37,"Georgia Tech",1,2,0,0,0,0,0 +13,"Magic City Classic",,188,"Alabama A&M",191,"Alabama State",5,5,1,19,10,0,0 +14,"Empire Clash","The Golden Apple Trophy",203,Albany,215,"Stony Brook",4,4,1,21,12,0,0 +15,"Soul Bowl",,186,"Alcorn State",194,"Jackson State",4,4,0,19,0,0,0 +16,"Deeper Than Hate",,4,"Appalachian State",35,"Georgia Southern",5,5,1,12,14,0,0 +17,"Old Mountain Feud",,4,"Appalachian State",54,Marshall,5,5,1,12,13,0,0 +18,"Battle for the Old Mountain Jug",,4,"Appalachian State",180,"Western Carolina",4,5,0,0,0,0,0 +19,"Duel in the Desert","Territorial Cup",5,Arizona,6,"Arizona State",5,5,1,5,14,0,0 +20,,,5,Arizona,69,"New Mexico",1,2,0,0,0,0,0 +21,,,7,Arkansas,104,"Texas Tech",1,1,0,0,0,0,0 +22,"Battle Line Rivalry","Battle Line Trophy",64,Missouri,7,Arkansas,2,2,1,7,11,0,0 +23,,,7,Arkansas,101,Texas,5,4,1,7,9,0,0 +24,"Southwest Classic",,7,Arkansas,102,"Texas A&M",5,5,0,7,0,0,0 +25,"Paint Bucket Bowl",,8,"Arkansas State",56,Memphis,2,1,0,0,0,0,0 +26,,,8,"Arkansas State",50,"Louisiana Monroe",4,4,1,12,4,0,0 +27,,"Commander in Chief's Trophy",9,Army,65,Navy,5,5,1,8,14,0,0 +28,,"Commander in Chief's Trophy",9,Army,1,"Air Force",5,5,1,0,3,0,0 +29,,,9,Army,75,"Notre Dame",3,2,0,0,0,0,0 +30,,,10,Auburn,30,Florida,2,2,0,7,0,0,0 +31,,,10,Auburn,100,Tennessee,2,2,0,7,0,0,0 +32,,,10,Auburn,22,Clemson,2,2,0,0,0,0,0 +33,"Deep South's Oldest Rivalry",,10,Auburn,34,Georgia,5,5,1,7,5,0,0 +34,,,10,Auburn,107,Tulane,1,2,0,0,0,0,0 +35,,"Bronze Stalk Trophy",11,"Ball State",73,"Northern Illinois",5,5,1,0,14,0,0 +36,"Blue Key Victory Bell",,11,"Ball State",136,"Indiana State",3,5,0,0,0,0,0 +37,,,12,Baylor,39,Houston,2,3,0,5,0,0,0 +38,"The Revivalry",,12,Baylor,98,TCU,5,5,1,5,14,0,0 +39,"BuTT Bowl",,12,Baylor,104,"Texas Tech",4,4,0,5,0,0,0 +40,"Battle of the Brazos",,12,Baylor,102,"Texas A&M",4,2,0,0,0,0,0 +41,,,12,Baylor,101,Texas,4,2,0,0,0,0,0 +42,"Florida Classic",,184,Bethune-Cookman,190,"Florida A&M",5,5,1,19,13,0,0 +43,,,13,"Boise State",33,"Fresno State",4,4,1,6,14,0,0 +44,,,13,"Boise State",68,Nevada,5,4,0,0,0,0,0 +45,,,13,"Boise State",157,Idaho,3,5,0,0,0,0,0 +46,,"O'Rourke-McFadden Trophy",14,"Boston College",22,Clemson,4,4,0,3,0,0,0 +47,,,14,"Boston College",85,Pittsburgh,3,3,0,3,0,0,0 +48,,,14,"Boston College",97,Syracuse,4,4,1,3,14,0,0 +49,,,14,"Boston College",122,"Virginia Tech",4,4,0,3,0,0,0 +50,,,14,"Boston College",149,"Holy Cross",1,5,0,0,0,0,0 +51,"Holy War","Ireland Trophy",14,"Boston College",75,"Notre Dame",5,4,1,0,3,0,0 +52,,,14,"Boston College",113,UMass,1,3,0,0,0,0,0 +53,,"Anniversary Award",15,"Bowling Green",46,"Kent State",5,5,1,10,12,0,0 +54,,,15,"Bowling Green",105,Toledo,4,4,1,10,14,0,0 +55,,"Governor's Cup",166,Brown,213,"Rhode Island",3,5,1,0,3,0,0 +56,,"Hoosier Helmet Trophy",235,Butler,245,Valparaiso,4,4,0,25,0,0,0 +57,"The Old Wagon Wheel",,17,BYU,119,"Utah State",3,4,0,0,0,0,0 +58,"Bear Brawl",,18,California,111,UCLA,4,4,0,0,0,0,0 +59,"Battle for the Golden Horseshoe","The Golden Horseshoe",155,"Cal Poly",154,"UC Davis",4,4,1,16,12,0,0 +60,"The Big Game","Stanford Axe",18,California,96,Stanford,5,5,1,3,14,0,0 +61,"Red Beans and Rice Bowl","50 Pound Iron Pot",257,"Central Arkansas",249,McNeese,4,4,1,0,3,0,0 +62,,"Michigan MAC Trophy",19,"Central Michigan",28,"Eastern Michigan",5,5,1,10,9,0,0 +63,,"Michigan MAC Trophy",19,"Central Michigan",128,"Western Michigan",5,5,1,10,14,0,0 +64,,,21,Cincinnati,110,UCF,3,3,0,5,0,0,0 +65,,,21,Cincinnati,126,"West Virginia",3,2,0,5,0,0,0 +66,"The Keg of Nails",,21,Cincinnati,52,Louisville,3,3,0,0,0,0,0 +67,"Victory Bell",,21,Cincinnati,58,"Miami (OH)",2,3,0,0,0,0,0 +68,,,21,Cincinnati,56,Memphis,1,1,0,0,0,0,0 +69,,,22,Clemson,32,"Florida State",4,4,0,3,0,0,0 +70,,,22,Clemson,37,"Georgia Tech",4,5,1,3,8,0,0 +71,"Textile Bowl",,22,Clemson,66,"NC State",3,4,0,3,0,0,0 +72,,,23,"Coastal Carolina",48,Liberty,5,5,0,0,0,0,0 +73,,,148,Colgate,168,Cornell,5,5,1,0,3,0,0 +74,"Rumble in the Rockies",,24,Colorado,118,Utah,4,4,1,5,12,0,0 +75,,,24,Colorado,45,"Kansas State",3,4,0,5,0,0,0 +76,"Rocky Mountain Showdown",,25,"Colorado State",24,Colorado,3,5,1,0,1,0,0 +77,"Border War",,25,"Colorado State",130,Wyoming,5,5,1,0,3,0,0 +78,,"Liberty Cup",167,Columbia,152,Fordham,2,3,1,0,14,0,0 +79,,,168,Cornell,169,Dartmouth,3,3,0,17,0,0,0 +80,,"Trustees' Cup",168,Cornell,170,Pennsylvania,3,3,0,17,0,0,0 +81,,,169,Dartmouth,171,Harvard,4,2,0,17,0,0,0 +82,"Granite Bowl",,169,Dartmouth,211,"New Hampshire",3,3,1,0,14,0,0 +83,,,237,Dayton,238,Drake,3,5,0,25,0,0,0 +84,"Battle of the Blue",,206,Delaware,217,Villanova,4,4,0,0,0,0,0 +85,,,206,Delaware,151,Lehigh,2,4,0,0,0,0,0 +86,"Route 1 Rivalry",,206,Delaware,221,"Delaware State",4,5,1,0,1,0,0 +87,,,206,Delaware,218,"William & Mary",2,3,0,0,0,0,0 +88,,,238,Drake,140,"Northern Iowa",5,5,1,0,3,0,0 +89,"Tobacco Road","Victory Bell",26,Duke,71,"North Carolina",5,5,1,3,8,0,0 +90,"Tobacco Road",,26,Duke,66,"NC State",4,4,1,3,10,0,0 +91,"Tobacco Road",,26,Duke,123,"Wake Forest",3,4,0,3,0,0,0 +92,,,27,"East Carolina",54,Marshall,2,3,0,0,0,0,0 +93,"Battle of the Bluegrass",,258,"Eastern Kentucky",127,"Western Kentucky",5,5,0,0,0,0,0 +94,,"Old Hawg Rifle",258,"Eastern Kentucky",240,"Morehead State",3,3,0,0,0,0,0 +95,,"The Dam Cup",156,"Eastern Washington",163,"Portland State",4,4,1,16,13,0,0 +96,,"The Governor's Cup",156,"Eastern Washington",159,Montana,3,3,1,16,12,0,0 +97,"Shula Bowl",,31,"Florida Atlantic",29,FIU,5,5,1,0,14,0,0 +98,,"Okefenokee Oar",30,Florida,34,Georgia,4,4,1,7,4,1,203 +99,,,30,Florida,47,Kentucky,3,4,1,7,5,0,0 +100,,,30,Florida,53,LSU,2,2,0,7,0,0,0 +101,,,30,Florida,100,Tennessee,3,3,0,7,0,0,0 +102,,,30,Florida,57,"Miami (FL)",5,5,0,0,0,0,0 +103,,,32,"Florida State",30,Florida,5,5,1,0,14,0,0 +104,,"Florida Cup",32,"Florida State",57,"Miami (FL)",5,5,1,3,12,0,0 +105,,"Jefferson-Eppes Trophy",32,"Florida State",121,Virginia,3,4,0,3,0,0,0 +106,,"Ram-Crusader Cup",152,Fordham,149,"Holy Cross",5,5,1,15,5,0,0 +107,,,33,"Fresno State",38,Hawaii,2,2,0,0,0,0,0 +108,,,33,"Fresno State",89,"San Diego State",3,3,1,6,4,0,0 +109,,,33,"Fresno State",90,"San Jose State",4,4,1,0,2,0,0 +110,,,174,Furman,177,Wofford,5,5,0,18,0,0,0 +111,,,34,Georgia,93,"South Carolina",4,4,1,7,6,0,0 +112,,,34,Georgia,100,Tennessee,3,3,0,7,0,0,0 +113,,,34,Georgia,22,Clemson,4,4,0,0,0,0,0 +114,"Clean, Old-Fashioned Hate",,34,Georgia,37,"Georgia Tech",5,5,1,0,14,0,0 +115,"Modern Day Hate",,36,"Georgia State",35,"Georgia Southern",5,5,1,12,13,0,0 +116,,,37,"Georgia Tech",122,"Virginia Tech",3,3,0,3,0,0,0 +117,"Bayou Classic",,183,Grambling,187,Southern,4,2,1,19,13,0,0 +118,"State Fair Classic",,183,Grambling,185,"Prairie View A&M",4,4,1,19,4,0,0 +119,"Battle of the Bay",,208,Hampton,224,"Norfolk State",3,3,1,0,11,0,0 +120,"The Real HU",,208,Hampton,222,Howard,5,5,1,0,3,0,0 +121,,,171,Harvard,170,Pennsylvania,2,3,0,17,0,0,0 +122,,,171,Harvard,172,Princeton,2,3,0,17,0,0,0 +123,"The Game",,171,Harvard,173,Yale,5,5,1,17,14,0,0 +124,"Dick Tomey Legacy Game",,38,Hawaii,90,"San Jose State",4,4,1,11,4,0,0 +125,,,38,Hawaii,130,Wyoming,1,1,1,11,13,0,0 +126,,,39,Houston,104,"Texas Tech",2,2,0,5,0,0,0 +127,,,39,Houston,87,Rice,2,2,0,0,0,0,0 +128,,,39,Houston,91,SMU,2,2,0,0,0,0,0 +129,,,39,Houston,108,Tulsa,2,1,0,0,0,0,0 +130,,,222,Howard,223,"Morgan State",3,3,1,23,4,0,0 +131,"Battle of the Domes","The Potato State Trophy",157,Idaho,158,"Idaho State",5,5,1,16,13,0,0 +132,,"Little Brown Stein",157,Idaho,159,Montana,3,2,1,16,8,0,0 +133,,,40,Illinois,41,Indiana,2,2,0,4,0,0,0 +134,,"Land of Lincoln Trophy",40,Illinois,74,Northwestern,5,5,1,4,14,0,0 +135,,Illibuck,40,Illinois,77,"Ohio State",3,2,0,4,0,0,0 +136,,"Purdue Cannon",40,Illinois,86,Purdue,3,3,0,4,0,0,0 +137,"Arch Rivalry",,40,Illinois,64,Missouri,1,1,0,0,0,0,0 +138,"Mid-America Classic",,137,"Illinois State",196,"Eastern Illinois",3,3,1,0,3,0,0 +139,,"Old Brass Spittoon",41,Indiana,60,"Michigan State",2,2,1,4,5,0,0 +140,,"Old Oaken Bucket",41,Indiana,86,Purdue,5,5,1,4,14,0,0 +141,,"Floyd of Rosedale",42,Iowa,62,Minnesota,5,4,1,4,7,0,0 +142,,"Heartland Trophy",129,Wisconsin,42,Iowa,4,4,1,4,10,0,0 +143,,"Cy-Hawk Trophy",42,Iowa,43,"Iowa State",5,5,1,0,2,0,0 +144,Farmageddon,,43,"Iowa State",45,"Kansas State",5,4,0,5,0,0,0 +145,,"Telephone Trophy",43,"Iowa State",64,Missouri,1,1,0,0,0,0,0 +146,"Southern Heritage Classic",,194,"Jackson State",200,"Tennessee State",4,4,1,0,3,0,0 +147,"BoomBox Classic",,194,"Jackson State",187,Southern,3,3,0,19,0,0,0 +148,,,132,"Jacksonville State",175,Samford,3,3,0,0,0,0,0 +149,"Royal Rivalry","The Crown",131,"James Madison",80,"Old Dominion",5,5,1,12,13,0,0 +150,,,131,"James Madison",206,Delaware,4,4,0,0,0,0,0 +151,,,131,"James Madison",214,Richmond,3,3,0,0,0,0,0 +152,,,131,"James Madison",218,"William & Mary",3,3,0,0,0,0,0 +153,"Sunflower Showdown",,44,Kansas,45,"Kansas State",5,5,1,5,14,0,0 +154,"Border War",,44,Kansas,64,Missouri,5,5,1,0,1,0,0 +155,,"Beer Barrel",47,Kentucky,100,Tennessee,3,2,1,7,6,0,0 +156,"Governor's Cup",,47,Kentucky,52,Louisville,5,5,1,0,14,0,0 +157,"The Rivalry",,150,Lafayette,151,Lehigh,5,5,1,15,10,0,0 +158,"Battle of the Border",,248,Lamar,249,McNeese,4,4,1,26,0,0,0 +159,"Battle on the Bayou",,49,Louisiana,50,"Louisiana Monroe",5,5,1,12,13,0,0 +160,,"Sabine Shoe",49,Louisiana,248,Lamar,2,4,0,0,0,0,0 +161,,,49,Louisiana,51,"Louisiana Tech",5,5,1,12,7,0,0 +162,,"Cajun Crown",49,Louisiana,249,McNeese,2,4,0,0,0,0,0 +163,,"Cypress Mug",49,Louisiana,252,"SE Louisiana",1,3,0,0,0,0,0 +164,,,51,"Louisiana Tech",251,"Northwestern State",2,3,0,0,0,0,0 +165,,,50,"Louisiana Monroe",51,"Louisiana Tech",5,5,1,12,8,0,0 +166,,,50,"Louisiana Monroe",251,"Northwestern State",2,4,0,0,0,0,0 +167,,"Schnellenberger Trophy",52,Louisville,57,"Miami (FL)",3,2,0,3,0,0,0 +168,,,52,Louisville,56,Memphis,3,4,0,0,0,0,0 +169,"Battle for the Golden Boot","Golden Boot",7,Arkansas,53,LSU,4,4,1,7,14,0,0 +170,"First Saturday in November",,53,LSU,3,Alabama,4,4,0,7,0,0,0 +171,"Tiger Bowl",,53,LSU,10,Auburn,4,4,0,7,0,0,0 +172,"Magnolia Bowl","Magnolia Bowl Trophy",81,"Ole Miss",53,LSU,3,3,1,7,4,0,0 +173,"Battle for the Rag","Tiger Rag",53,LSU,107,Tulane,2,4,0,0,0,0,0 +175,,,53,LSU,102,"Texas A&M",4,4,1,7,11,0,0 +176,"Battle for Brice-Cowell Musket",,209,Maine,211,"New Hampshire",5,5,1,21,13,0,0 +177,,"Friends of Coal Bowl",54,Marshall,126,"West Virginia",3,1,0,0,0,0,0 +178,"Battle for the Bell",,54,Marshall,76,Ohio,4,4,0,0,0,0,0 +179,,,55,Maryland,84,"Penn State",3,3,0,4,0,0,0 +180,"Crab Bowl Classic","The Crab Bowl",55,Maryland,65,Navy,4,4,0,0,0,0,0 +181,,,55,Maryland,121,Virginia,2,2,0,0,0,0,0 +182,,,55,Maryland,126,"West Virginia",2,2,0,0,0,0,0 +183,,,249,McNeese,251,"Northwestern State",3,3,1,26,4,0,0 +184,"Battle for the Bones",,56,Memphis,109,UAB,4,4,1,8,14,0,0 +185,"Black and Blue Bowl",,56,Memphis,95,"Southern Miss",4,4,1,0,2,0,0 +186,,,57,"Miami (FL)",122,"Virginia Tech",3,4,0,3,0,0,0 +187,"Battle of the Bricks",,58,"Miami (OH)",76,Ohio,5,5,1,10,14,0,0 +188,,"Paul Bunyan Trophy",59,Michigan,60,"Michigan State",5,5,1,4,9,0,0 +189,"The Game",,59,Michigan,77,"Ohio State",5,5,1,4,14,0,0 +190,,"Little Brown Jug",59,Michigan,62,Minnesota,4,4,0,4,0,0,0 +191,,"George Jewett Trophy",59,Michigan,74,Northwestern,1,2,0,4,0,0,0 +192,,,75,"Notre Dame",59,Michigan,5,5,1,0,5,0,0 +193,,"Land Grant Trophy",60,"Michigan State",84,"Penn State",4,3,1,4,14,0,0 +194,,"Megaphone Trophy",60,"Michigan State",75,"Notre Dame",3,2,1,0,2,0,0 +195,"100 Miles of Hate",,61,"Middle Tennessee",127,"Western Kentucky",5,5,1,9,13,0,0 +196,,"Governor's Victory Bell",62,Minnesota,84,"Penn State",1,1,0,4,0,0,0 +197,,"Paul Bunyan's Axe",129,Wisconsin,62,Minnesota,5,5,1,4,14,0,0 +198,"Egg Bowl","Golden Egg",63,"Mississippi State",81,"Ole Miss",5,5,1,7,14,0,0 +199,,"Tiger-Sooner Peace Pipe",64,Missouri,78,Oklahoma,3,3,1,7,12,0,0 +200,"Battle for Columbia","Mayor's Cup",64,Missouri,93,"South Carolina",2,2,0,7,0,0,0 +201,"Brawl of the Wild","The Great Divide Trophy",159,Montana,160,"Montana State",5,5,1,16,13,0,0 +202,"The Battle for Greater Baltimore",,223,"Morgan State",216,Towson,4,4,1,0,11,0,0 +203,,,75,"Notre Dame",65,Navy,4,2,1,0,1,0,0 +204,"Tobacco Road",,66,"NC State",123,"Wake Forest",3,4,0,3,0,0,0 +205,,"Victory Barrel",66,"NC State",27,"East Carolina",2,3,0,0,0,0,0 +206,,"Heroes Trophy",67,Nebraska,42,Iowa,5,5,1,4,14,0,0 +207,,"Victory Bell",67,Nebraska,64,Missouri,3,3,0,0,0,0,0 +208,,,67,Nebraska,44,Kansas,3,3,0,0,0,0,0 +209,,,67,Nebraska,45,"Kansas State",2,2,0,0,0,0,0 +210,,"Bison Head Trophy",24,Colorado,67,Nebraska,4,4,1,0,3,0,0 +211,,,67,Nebraska,78,Oklahoma,5,4,0,0,0,0,0 +212,,"Freedom Trophy",67,Nebraska,129,Wisconsin,3,3,1,4,13,0,0 +213,,"$5 Bits of Broken Chair Trophy",62,Minnesota,67,Nebraska,3,3,1,4,9,0,0 +214,,,67,Nebraska,57,"Miami (FL)",1,1,0,0,0,0,0 +215,,"Fremont Cannon",68,Nevada,114,UNLV,5,5,1,11,14,0,0 +216,"Colonial Clash",,211,"New Hampshire",113,UMass,5,3,0,0,0,0,0 +217,"Rio Grade Rivalry",,69,"New Mexico",70,"New Mexico State",5,5,1,0,14,0,0 +218,"NSU Challenge",,250,Nicholls,251,"Northwestern State",5,5,1,26,8,0,0 +219,"River Bell Classic",,250,Nicholls,252,"SE Louisiana",4,4,0,26,0,0,0 +220,,,212,"North Carolina A&T",225,"North Carolina Central",5,5,1,0,3,0,0 +221,"Tobacco Road",,71,"North Carolina",66,"NC State",4,5,1,3,14,0,0 +222,"South's Oldest Rivalry",,71,"North Carolina",121,Virginia,4,4,0,3,0,0,0 +223,"Tobacco Road",,71,"North Carolina",123,"Wake Forest",3,4,0,3,0,0,0 +224,,,212,"North Carolina A&T",226,"South Carolina State",4,4,1,0,11,0,0 +225,,"Nickel Trophy",142,"North Dakota",143,"North Dakota State",5,5,0,0,0,0,0 +226,,"Sitting Bull Trophy",142,"North Dakota",145,"South Dakota",4,4,1,14,8,0,0 +227,,"Dakota Marker",143,"North Dakota State",144,"South Dakota State",4,4,1,0,1,0,0 +228,"Grand Canyon Rivalry","Hinton Burdick Grand Canyon Trophy",161,"Northern Arizona",260,"Southern Utah",4,4,1,16,12,0,0 +229,,Shillelagh,74,Northwestern,75,"Notre Dame",3,2,0,0,0,0,0 +230,"Battle for Chief Caddo",,251,"Northwestern State",261,"Stephen F. Austin",3,3,1,26,12,0,0 +231,,,251,"Northwestern State",252,"SE Louisiana",5,5,1,26,7,0,0 +232,,"Shillelagh Trophy",75,"Notre Dame",86,Purdue,2,2,0,0,0,0,0 +233,,"Jeweled Shillelagh",75,"Notre Dame",115,USC,5,5,1,0,4,0,0 +234,,,77,"Ohio State",84,"Penn State",3,3,0,4,0,0,0 +235,Bedlam,,78,Oklahoma,79,"Oklahoma State",4,5,0,0,0,0,0 +236,,,79,"Oklahoma State",108,Tulsa,2,3,0,0,0,0,0 +237,,,80,"Old Dominion",224,"Norfolk State",3,5,0,0,0,0,0 +238,"Battle for the Silver Mace","Norfolk Mace",80,"Old Dominion",218,"William & Mary",2,5,0,0,0,0,0 +239,"Mid-South Rivalry",,81,"Ole Miss",56,Memphis,1,2,0,0,0,0,0 +240,,,81,"Ole Miss",107,Tulane,1,1,0,0,0,0,0 +241,"Civil War","Platypus Trophy",82,Oregon,83,"Oregon State",5,3,1,0,14,0,0 +242,"Battle for the P",,170,Pennsylvania,172,Princeton,3,2,1,17,14,0,0 +243,,,84,"Penn State",85,Pittsburgh,3,4,0,0,0,0,0 +244,,,84,"Penn State",97,Syracuse,3,3,0,0,0,0,0 +245,,,84,"Penn State",126,"West Virginia",3,4,0,0,0,0,0 +246,,,85,Pittsburgh,97,Syracuse,4,4,0,3,0,0,0 +247,"City Game",,85,Pittsburgh,228,Duquesne,1,5,0,0,0,0,0 +248,,,85,Pittsburgh,75,"Notre Dame",3,3,0,0,0,0,0 +249,"Labor Day Classic",,185,"Prairie View A&M",192,"Texas Southern",4,4,1,19,1,0,0 +250,,,172,Princeton,173,Yale,3,3,0,17,0,0,0 +251,,,213,"Rhode Island",112,UConn,4,2,0,0,0,0,0 +252,,,87,Rice,101,Texas,3,1,0,0,0,0,0 +253,,"Capital Cup",214,Richmond,218,"William & Mary",4,4,1,15,10,0,0 +254,,,214,Richmond,182,VMI,2,3,1,0,1,0,0 +255,"Causeway Classic","Causeway Trophy",164,"Sacramento State",154,"UC Davis",5,5,1,0,14,0,0 +256,"Battle of the Piney Woods",,133,"Sam Houston State",261,"Stephen F. Austin",5,5,0,0,0,0,0 +257,,,133,"Sam Houston State",103,"Texas State",4,3,0,0,0,0,0 +258,"Boulevard Brawl",,91,SMU,96,Stanford,4,3,1,3,6,0,0 +259,"Boulevard Brawl",,18,California,91,SMU,4,3,1,3,12,0,0 +260,,,91,SMU,12,Baylor,3,2,0,0,0,0,0 +261,,"Gansz Trophy",91,SMU,65,Navy,2,2,0,0,0,0,0 +262,"Safeway Bowl",,91,SMU,72,"North Texas",1,2,0,0,0,0,0 +263,,,91,SMU,87,Rice,2,2,0,0,0,0,0 +264,"Iron Skillet",,91,SMU,98,TCU,5,5,1,0,3,0,0 +265,"Battle for the Belt",,92,"South Alabama",106,Troy,5,5,1,12,13,0,0 +266,,,93,"South Carolina",100,Tennessee,4,4,0,7,0,0,0 +267,"Palmetto Bowl",,93,"South Carolina",22,Clemson,5,5,1,0,14,0,0 +268,"Carolina Clash",,93,"South Carolina",71,"North Carolina",3,3,0,0,0,0,0 +269,"South Dakota Showdown",,145,"South Dakota",144,"South Dakota State",5,5,1,14,11,0,0 +270,"Rivalry in Dixie",,51,"Louisiana Tech",95,"Southern Miss",4,4,1,12,13,0,0 +271,"Battle for the Bell",,95,"Southern Miss",107,Tulane,4,3,1,0,14,0,0 +272,"Beehive Bowl",,260,"Southern Utah",165,"Weber State",5,5,1,16,5,0,0 +273,,,96,Stanford,115,USC,3,3,0,0,0,0,0 +274,,"Legends Trophy",96,Stanford,75,"Notre Dame",5,5,1,0,14,0,0 +275,"Bill Walsh Legacy Game",,96,Stanford,90,"San Jose State",2,3,0,0,0,0,0 +276,,"Ben Schwartzwalder Trophy",97,Syracuse,126,"West Virginia",3,3,0,0,0,0,0 +277,,,97,Syracuse,148,Colgate,1,5,0,0,0,0,0 +278,,,97,Syracuse,112,UConn,3,3,0,0,0,0,0 +279,"The West Texas Championship","The Saddle Trophy",98,TCU,104,"Texas Tech",4,4,0,5,0,0,0 +280,,,98,TCU,101,Texas,4,2,0,0,0,0,0 +281,,,100,Tennessee,120,Vanderbilt,3,5,1,7,14,0,0 +282,,,100,Tennessee,37,"Georgia Tech",3,3,0,0,0,0,0 +283,,"Sgt. York Trophy",200,"Tennessee State",201,"Tennessee Tech",5,5,1,0,8,0,0 +284,,"Sgt. York Trophy",200,"Tennessee State",202,"UT Martin",5,5,1,20,10,0,0 +285,,"Sgt. York Trophy",201,"Tennessee Tech",202,"UT Martin",5,5,1,0,9,0,0 +286,,,101,Texas,104,"Texas Tech",2,3,0,0,0,0,0 +287,"Heart of Texas",,101,Texas,102,"Texas A&M",5,5,1,7,14,0,0 +288,,,102,"Texas A&M",104,"Texas Tech",1,2,0,0,0,0,0 +289,"I-35 Rivalry",,103,"Texas State",117,UTSA,5,5,1,0,14,0,0 +290,"Battle for the Paddle",,103,"Texas State",250,Nicholls,2,3,0,0,0,0,0 +291,"Military Classic of the South",,176,"The Citadel",182,VMI,5,5,1,18,13,0,0 +292,,,174,Furman,176,"The Citadel",3,3,1,18,10,0,0 +293,,"Big Dog Trophy",176,"The Citadel",177,Wofford,3,3,0,18,0,0,0 +294,"Battle for the Ol' School Bell",,106,Troy,132,"Jacksonville State",4,4,1,0,1,0,0 +295,"Battle for the Palladium",,106,Troy,61,"Middle Tennessee",4,4,0,0,0,0,0 +296,,,112,UConn,113,UMass,3,3,0,0,0,0,0 +297,,"Victory Bell",115,USC,111,UCLA,4,5,1,4,13,0,0 +298,"War on I-4",,94,"South Florida",110,UCF,5,5,1,0,14,0,0 +299,"Holy War","Beehive Boot",118,Utah,17,BYU,5,5,1,5,14,0,0 +300,"Battle of the Brothers",,118,Utah,119,"Utah State",3,5,0,0,0,0,0 +301,,,130,Wyoming,119,"Utah State",4,4,1,0,1,0,0 +302,"Battle of I-10",,116,UTEP,70,"New Mexico State",5,5,1,0,3,0,0 +303,"Commonwealth Clash","Commonwealth Cup",121,Virginia,122,"Virginia Tech",5,5,1,3,14,0,0 +304,,,121,Virginia,55,Maryland,4,4,0,0,0,0,0 +305,,,122,"Virginia Tech",182,VMI,1,5,0,0,0,0,0 +306,,,182,VMI,218,"William & Mary",3,2,1,0,3,0,0 +307,"Apple Cup","Apple Cup",124,Washington,125,"Washington State",4,5,1,0,14,0,0 +308,"Border War",,124,Washington,82,Oregon,5,5,1,4,8,0,0 +309,"Battle of the Palouse",,125,"Washington State",157,Idaho,3,5,0,0,0,0,0 +310,,"Left Behind Trophy",125,"Washington State",83,"Oregon State",4,4,1,6,12,0,0 +311,"Backyard Brawl",,126,"West Virginia",85,Pittsburgh,5,5,1,0,14,0,0 +312,,"Black Diamond Trophy",126,"West Virginia",122,"Virginia Tech",3,3,0,0,0,0,0 +313,"Battle for the Red Belt",,127,"Western Kentucky",139,"Murray State",4,4,0,0,0,0,0 +314,,"Michigan MAC Trophy",128,"Western Michigan",28,"Eastern Michigan",5,5,1,10,8,0,0 +315,"Red River Shootout",,101,Texas,78,Oklahoma,5,5,1,7,7,1,0 +316,EASTMAC,,16,Buffalo,113,UMass,5,5,1,10,14,0,0 +317,"Battle for the SAC",,11,"Ball State",164,"Sacramento State",2,5,1,10,13,0,0 +318,,,82,Oregon,115,USC,2,2,0,4,0,0,0 +319,,,52,Louisville,85,Pittsburgh,4,4,1,3,8,0,0 +320,"Battle of the Ax",,260,"Southern Utah",263,"Utah Tech",5,5,1,16,8,0,0 +321,"Yank Townsend Trophy",,173,Yale,151,Lehigh,3,3,1,0,3,0,0 +322,"The Citadel-Charleston Southern",,195,"Charleston Southern",176,"The Citadel",2,2,1,0,1,0,0 +323,"East vs West Classic",,196,"Eastern Illinois",146,"Western Illinois",4,4,1,20,12,0,0 +324,"The Orange Blossom Classic",,190,"Florida A&M",194,"Jackson State",4,4,1,19,1,0,0 +325,"Mississippi Classic",,193,"Mississippi Valley State",194,"Jackson State",4,4,1,19,13,0,0 +326,"Battle of the Pacific",,267,Guam,268,"American Samoa",5,5,1,22,14,0,0 diff --git a/data/dc_positions_migration.csv b/data/dc_positions_migration.csv index 951516a..ccda23e 100644 --- a/data/dc_positions_migration.csv +++ b/data/dc_positions_migration.csv @@ -5,6 +5,7 @@ 206,206,RB,1,,,RB 206,206,RB,2,,,RB 206,206,RB,3,,,RB +206,206,RB,4,,,RB 206,206,FB,1,,,FB 206,206,FB,2,,,FB 206,206,TE,1,,,TE @@ -19,30 +20,39 @@ 206,206,WR,7,,,WR 206,206,LT,1,,,OT 206,206,LT,2,,,OT +206,206,LT,3,,,OT 206,206,LG,1,,,OG 206,206,LG,2,,,OG +206,206,LG,3,,,OG 206,206,C,1,,,C 206,206,C,2,,,C +206,206,C,3,,,C 206,206,RG,1,,,OG 206,206,RG,2,,,OG +206,206,RG,3,,,OG 206,206,RT,1,,,OT 206,206,RT,2,,,OT +206,206,RT,3,,,OT 206,206,LE,1,,,DE 206,206,LE,2,,,DE +206,206,LE,3,,,DE 206,206,DT,1,,,DT 206,206,DT,2,,,DT 206,206,DT,3,,,DT 206,206,DT,4,,,DT 206,206,RE,1,,,DE 206,206,RE,2,,,DE +206,206,RE,3,,,DE 206,206,LOLB,1,,,OLB 206,206,LOLB,2,,,OLB +206,206,LOLB,3,,,OLB 206,206,MLB,1,,,ILB 206,206,MLB,2,,,ILB 206,206,MLB,3,,,ILB 206,206,MLB,4,,,OLB 206,206,ROLB,1,,,OLB 206,206,ROLB,2,,,OLB +206,206,ROLB,3,,,OLB 206,206,CB,1,,,CB 206,206,CB,2,,,CB 206,206,CB,3,,,CB @@ -50,16 +60,20 @@ 206,206,CB,5,,,CB 206,206,FS,1,,,FS 206,206,FS,2,,,FS +206,206,FS,3,,,FS 206,206,SS,1,,,SS 206,206,SS,2,,,SS +206,206,SS,3,,,SS 206,206,P,1,,,P 206,206,P,2,,,P 206,206,PR,1,,,RB 206,206,PR,2,,,CB +206,206,PR,3,,,CB 206,206,K,1,,,K 206,206,K,2,,,P 206,206,KR,1,,,RB 206,206,KR,2,,,CB +206,206,KR,3,,,CB 206,206,FG,1,,,QB 206,206,FG,2,,,QB 206,206,STU,1,,,ILB diff --git a/dbprovider/dbprovider.go b/dbprovider/dbprovider.go index 330ebfc..152de9a 100644 --- a/dbprovider/dbprovider.go +++ b/dbprovider/dbprovider.go @@ -91,6 +91,7 @@ func (p *Provider) InitDatabase() bool { // db.AutoMigrate(&structs.CollegeDepthChartPosition{}) // db.AutoMigrate(&structs.CollegeGameplan{}) // db.AutoMigrate(&structs.CollegeGame{}) + // db.AutoMigrate(&structs.CFBGameRequest{}) // db.AutoMigrate(&structs.CollegeCoach{}) // db.AutoMigrate(&structs.CollegeStandings{}) // db.AutoMigrate(&structs.CollegeWeek{}) @@ -128,6 +129,7 @@ func (p *Provider) InitDatabase() bool { // db.AutoMigrate(&structs.NFLDepthChartPosition{}) // db.AutoMigrate(&structs.NFLExtensionOffer{}) // db.AutoMigrate(&structs.NFLGame{}) + // db.AutoMigrate(&structs.NFLGameRequest{}) // db.AutoMigrate(&structs.NFLGameplan{}) // db.AutoMigrate(&structs.NFLPlayByPlay{}) // db.AutoMigrate(&structs.NFLTradePreferences{}) diff --git a/firebase/notification_service.go b/firebase/notification_service.go index e04afa5..eafddef 100644 --- a/firebase/notification_service.go +++ b/firebase/notification_service.go @@ -154,6 +154,25 @@ func NotifyTeamInjury(ctx context.Context, input TeamInjuryNotificationInput) er }) } +// NotifyScheduleEvent notifies a coach or owner about a game-request lifecycle +// event such as acceptance, rejection, or an admin veto. Idempotent via SourceEventKey. +func NotifyScheduleEvent(ctx context.Context, input ScheduleEventNotificationInput) error { + if len(input.RecipientUIDs) == 0 { + return nil + } + linkTo := BuildTeamRosterRoute(input.League, input.TeamID) + + return writeNotificationsIfNew(ctx, input.RecipientUIDs, ForumNotification{ + Type: NotificationTypeSystem, + Domain: input.Domain, + LinkTo: linkTo, + Message: input.Message, + ActorUsername: "SimSN", + IsRead: false, + SourceEventKey: input.SourceEventKey, + }) +} + // NotifyRecruitSigned creates one notification document per recipient when a // recruit commits to a team. Idempotent via SourceEventKey. func NotifyRecruitSigned(ctx context.Context, input RecruitSignedNotificationInput) error { diff --git a/firebase/types.go b/firebase/types.go index 9ad8fce..1a27f75 100644 --- a/firebase/types.go +++ b/firebase/types.go @@ -202,6 +202,17 @@ type CreateForumThreadInput struct { Metadata map[string]interface{} } +// ScheduleEventNotificationInput carries the context needed to notify a coach or +// owner about a game-request lifecycle event (accepted, rejected, vetoed). +type ScheduleEventNotificationInput struct { + League string + Domain string // e.g. DomainCFB, DomainNFL + TeamID uint + Message string // fully-formed message from the caller + RecipientUIDs []string + SourceEventKey string +} + // PlayerInjuryNotificationInput carries the context needed to build injury notifications. type PlayerInjuryNotificationInput struct { League string diff --git a/main.go b/main.go index eaa162c..7f4aefa 100644 --- a/main.go +++ b/main.go @@ -172,7 +172,7 @@ func handleRequests() http.Handler { // apiRouter.HandleFunc("/fix/player/preferences", controller.FixPlayerPreferences).Methods("GET") // apiRouter.HandleFunc("/admin/fix/affinities", controller.RecalibrateCrootProfiles).Methods("GET") // apiRouter.HandleFunc("/admin/fix/recruit/points", controller.RecalibrateRecruitPoints).Methods("GET") - apiRouter.HandleFunc("/fix/profile/mods", controller.FixRecruitProfileMods).Methods("GET") + // apiRouter.HandleFunc("/fix/profile/mods", controller.FixRecruitProfileMods).Methods("GET") // Free Agency Controls // apiRouter.HandleFunc("/nfl/extensions/sync", controller.SyncExtensions).Methods("GET") @@ -198,6 +198,19 @@ func handleRequests() http.Handler { apiRouter.HandleFunc("/games/result/nfl/{gameID}", controller.GetNFLGameResultsByGameID).Methods("GET") apiRouter.HandleFunc("/games/export/results/{seasonID}/{weekID}/{nflWeekID}/{timeslot}", controller.ExportCFBGameResults).Methods("GET") + // Game Request Controls - CFB + apiRouter.HandleFunc("/cfb/schedule/game/request/create", controller.CreateCFBGameRequest).Methods("POST") + apiRouter.HandleFunc("/cfb/schedule/game/request/accept/{requestID}", controller.AcceptCFBGameRequest).Methods("GET") + apiRouter.HandleFunc("/cfb/schedule/game/request/reject/{requestID}", controller.RejectCFBGameRequest).Methods("GET") + apiRouter.HandleFunc("/cfb/schedule/game/request/process/{requestID}", controller.ProcessCFBGameRequest).Methods("GET") + apiRouter.HandleFunc("/cfb/schedule/game/request/veto/{requestID}", controller.VetoCFBGameRequest).Methods("GET") + // Game Request Controls - NFL + apiRouter.HandleFunc("/nfl/schedule/game/request/create", controller.CreateNFLGameRequest).Methods("POST") + apiRouter.HandleFunc("/nfl/schedule/game/request/accept/{requestID}", controller.AcceptNFLGameRequest).Methods("GET") + apiRouter.HandleFunc("/nfl/schedule/game/request/reject/{requestID}", controller.RejectNFLGameRequest).Methods("GET") + apiRouter.HandleFunc("/nfl/schedule/game/request/process/{requestID}", controller.ProcessNFLGameRequest).Methods("GET") + apiRouter.HandleFunc("/nfl/schedule/game/request/veto/{requestID}", controller.VetoNFLGameRequest).Methods("GET") + // Gameplan Controls apiRouter.HandleFunc("/gameplan/college/team/{teamID}/", controller.GetTeamGameplanByTeamID).Methods("GET") apiRouter.HandleFunc("/gameplan/college/ai/update/", controller.DetermineAIGameplan).Methods("GET") @@ -386,6 +399,7 @@ func handleRequests() http.Handler { apiRouter.HandleFunc("/simnfl/mass/test/{off}/{def}", controller.MassNFLUpdateGameplansTEST).Methods("GET") apiRouter.HandleFunc("/teams/college/test/sim/{gameID}/", controller.GetCFBHomeAndAwayTeamTestData).Methods("GET") apiRouter.HandleFunc("/teams/nfl/test/sim/{gameID}/", controller.GetNFLHomeAndAwayTeamTestData).Methods("GET") + apiRouter.HandleFunc("/test/scheduler/cfb", controller.TestCFBScheduler).Methods("GET") // apiRouter.HandleFunc("/teams/nfl/test/setup/", controller.SetUpNFLTestDataStructs).Methods("GET") // apiRouter.HandleFunc("/simfba/test/cfb/progression/", controller.TestCFBProgressionAlgorithm).Methods("GET") // apiRouter.HandleFunc("/simfba/test/nfl/progression/", controller.TestNFLProgressionAlgorithm).Methods("GET") diff --git a/managers/AdminManager.go b/managers/AdminManager.go index 0bc0603..499fef4 100644 --- a/managers/AdminManager.go +++ b/managers/AdminManager.go @@ -715,6 +715,13 @@ func GenerateOffseasonData() { // Update Profile Affinities UpdateTeamProfileAffinities() + // Generate CFB Conference Schedule + BaseGenerateCFBSchedule(false) + + // Generate NFL Regular Season Schedule + GenerateSimNFLSchedule() + + // Reset Media Post Count ResetSimCFBMediaPostCount() // Generate Next Croot Class diff --git a/managers/BootstrapManager.go b/managers/BootstrapManager.go index 2201990..65d6181 100644 --- a/managers/BootstrapManager.go +++ b/managers/BootstrapManager.go @@ -77,6 +77,9 @@ type BootstrapDataScheduling struct { PollSubmission structs.CollegePollSubmission HistoricCollegePlayers []structs.HistoricCollegePlayer RetiredPlayers []structs.NFLRetiredPlayer + Stadiums []structs.Stadium + CFBGameRequests []structs.CFBGameRequest + NFLGameRequests []structs.NFLGameRequest } type BootstrapDataDraft struct { @@ -442,16 +445,19 @@ func GetFreeAgencyBootstrap(proID string) BootstrapDataFreeAgency { } } -func GetCollegePollsBootstrap(username, collegeID, seasonID string) BootstrapDataScheduling { +func GetSchedulePageBootstrap(username, collegeID, seasonID string) BootstrapDataScheduling { var wg sync.WaitGroup var ( officialPolls []structs.CollegePollOfficial pollSubmission structs.CollegePollSubmission historicCollegePlayers []structs.HistoricCollegePlayer retiredPlayers []structs.NFLRetiredPlayer + stadiums []structs.Stadium + cfbGameRequests []structs.CFBGameRequest + nflGameRequests []structs.NFLGameRequest ) if len(collegeID) > 0 && collegeID != "0" { - wg.Add(3) + wg.Add(4) go func() { defer wg.Done() officialPolls = GetAllOfficialPolls() @@ -464,14 +470,30 @@ func GetCollegePollsBootstrap(username, collegeID, seasonID string) BootstrapDat defer wg.Done() historicCollegePlayers = GetAllHistoricCollegePlayers() }() + go func() { + defer wg.Done() + cfbGameRequests = repository.FindCFBGameRequestRecords(repository.SchedulerQuery{SeasonID: seasonID}) + }() } - wg.Add(1) + wg.Add(4) go func() { defer wg.Done() log.Println("Fetching Retired Players...") retiredPlayers = GetAllRetiredPlayers() log.Println("Fetched Retired Players, count:", len(retiredPlayers)) }() + go func() { + defer wg.Done() + log.Println("Fetching Stadiums...") + stadiums = GetAllStadiums() + log.Println("Fetched Stadiums, count:", len(stadiums)) + }() + go func() { + defer wg.Done() + log.Println("Fetching NFL Game Requests...") + nflGameRequests = repository.FindNFLGameRequestRecords(repository.SchedulerQuery{SeasonID: seasonID}) + log.Println("Fetched NFL Game Requests, count:", len(nflGameRequests)) + }() wg.Wait() return BootstrapDataScheduling{ @@ -479,6 +501,9 @@ func GetCollegePollsBootstrap(username, collegeID, seasonID string) BootstrapDat OfficialPolls: officialPolls, HistoricCollegePlayers: historicCollegePlayers, RetiredPlayers: retiredPlayers, + Stadiums: stadiums, + CFBGameRequests: cfbGameRequests, + NFLGameRequests: nflGameRequests, } } diff --git a/managers/BootstrapManager_easyjson.go b/managers/BootstrapManager_easyjson.go index 2f66ef2..2cf0f27 100644 --- a/managers/BootstrapManager_easyjson.go +++ b/managers/BootstrapManager_easyjson.go @@ -5423,8 +5423,12 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in *jlexer.Lexer, o out.SigningRound = uint(in.Uint()) case "MinimumValue": out.MinimumValue = float64(in.Float64()) + case "OriginalMinimumValue": + out.OriginalMinimumValue = float64(in.Float64()) case "AAV": out.AAV = float64(in.Float64()) + case "OriginalAAV": + out.OriginalAAV = float64(in.Float64()) case "DraftedTeamID": out.DraftedTeamID = uint(in.Uint()) case "DraftedTeam": @@ -5810,11 +5814,21 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out *jwriter.Writer out.RawString(prefix) out.Float64(float64(in.MinimumValue)) } + { + const prefix string = ",\"OriginalMinimumValue\":" + out.RawString(prefix) + out.Float64(float64(in.OriginalMinimumValue)) + } { const prefix string = ",\"AAV\":" out.RawString(prefix) out.Float64(float64(in.AAV)) } + { + const prefix string = ",\"OriginalAAV\":" + out.RawString(prefix) + out.Float64(float64(in.OriginalAAV)) + } { const prefix string = ",\"DraftedTeamID\":" out.RawString(prefix) @@ -17206,8 +17220,12 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs39(in *jlexer.Lexer, o out.SigningRound = uint(in.Uint()) case "MinimumValue": out.MinimumValue = float64(in.Float64()) + case "OriginalMinimumValue": + out.OriginalMinimumValue = float64(in.Float64()) case "AAV": out.AAV = float64(in.Float64()) + case "OriginalAAV": + out.OriginalAAV = float64(in.Float64()) case "DraftedTeamID": out.DraftedTeamID = uint(in.Uint()) case "DraftedTeam": @@ -17593,11 +17611,21 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs39(out *jwriter.Writer out.RawString(prefix) out.Float64(float64(in.MinimumValue)) } + { + const prefix string = ",\"OriginalMinimumValue\":" + out.RawString(prefix) + out.Float64(float64(in.OriginalMinimumValue)) + } { const prefix string = ",\"AAV\":" out.RawString(prefix) out.Float64(float64(in.AAV)) } + { + const prefix string = ",\"OriginalAAV\":" + out.RawString(prefix) + out.Float64(float64(in.OriginalAAV)) + } { const prefix string = ",\"DraftedTeamID\":" out.RawString(prefix) @@ -19655,6 +19683,75 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers6(in *jlexer.Lexer, o } in.Delim(']') } + case "Stadiums": + if in.IsNull() { + in.Skip() + out.Stadiums = nil + } else { + in.Delim('[') + if out.Stadiums == nil { + if !in.IsDelim(']') { + out.Stadiums = make([]structs.Stadium, 0, 0) + } else { + out.Stadiums = []structs.Stadium{} + } + } else { + out.Stadiums = (out.Stadiums)[:0] + } + for !in.IsDelim(']') { + var v167 structs.Stadium + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in, &v167) + out.Stadiums = append(out.Stadiums, v167) + in.WantComma() + } + in.Delim(']') + } + case "CFBGameRequests": + if in.IsNull() { + in.Skip() + out.CFBGameRequests = nil + } else { + in.Delim('[') + if out.CFBGameRequests == nil { + if !in.IsDelim(']') { + out.CFBGameRequests = make([]structs.CFBGameRequest, 0, 0) + } else { + out.CFBGameRequests = []structs.CFBGameRequest{} + } + } else { + out.CFBGameRequests = (out.CFBGameRequests)[:0] + } + for !in.IsDelim(']') { + var v168 structs.CFBGameRequest + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs43(in, &v168) + out.CFBGameRequests = append(out.CFBGameRequests, v168) + in.WantComma() + } + in.Delim(']') + } + case "NFLGameRequests": + if in.IsNull() { + in.Skip() + out.NFLGameRequests = nil + } else { + in.Delim('[') + if out.NFLGameRequests == nil { + if !in.IsDelim(']') { + out.NFLGameRequests = make([]structs.NFLGameRequest, 0, 0) + } else { + out.NFLGameRequests = []structs.NFLGameRequest{} + } + } else { + out.NFLGameRequests = (out.NFLGameRequests)[:0] + } + for !in.IsDelim(']') { + var v169 structs.NFLGameRequest + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs44(in, &v169) + out.NFLGameRequests = append(out.NFLGameRequests, v169) + in.WantComma() + } + in.Delim(']') + } default: in.SkipRecursive() } @@ -19676,11 +19773,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers6(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v167, v168 := range in.OfficialPolls { - if v167 > 0 { + for v170, v171 := range in.OfficialPolls { + if v170 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs40(out, v168) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs40(out, v171) } out.RawByte(']') } @@ -19697,11 +19794,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers6(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v169, v170 := range in.HistoricCollegePlayers { - if v169 > 0 { + for v172, v173 := range in.HistoricCollegePlayers { + if v172 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs38(out, v170) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs38(out, v173) } out.RawByte(']') } @@ -19713,11 +19810,59 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers6(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v171, v172 := range in.RetiredPlayers { - if v171 > 0 { + for v174, v175 := range in.RetiredPlayers { + if v174 > 0 { + out.RawByte(',') + } + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs39(out, v175) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"Stadiums\":" + out.RawString(prefix) + if in.Stadiums == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v176, v177 := range in.Stadiums { + if v176 > 0 { + out.RawByte(',') + } + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out, v177) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"CFBGameRequests\":" + out.RawString(prefix) + if in.CFBGameRequests == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v178, v179 := range in.CFBGameRequests { + if v178 > 0 { + out.RawByte(',') + } + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs43(out, v179) + } + out.RawByte(']') + } + } + { + const prefix string = ",\"NFLGameRequests\":" + out.RawString(prefix) + if in.NFLGameRequests == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v180, v181 := range in.NFLGameRequests { + if v180 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs39(out, v172) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs44(out, v181) } out.RawByte(']') } @@ -19748,7 +19893,7 @@ func (v *BootstrapDataScheduling) UnmarshalJSON(data []byte) error { func (v *BootstrapDataScheduling) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers6(l, v) } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs41(in *jlexer.Lexer, out *structs.CollegePollSubmission) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs44(in *jlexer.Lexer, out *structs.NFLGameRequest) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -19767,114 +19912,34 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs41(in *jlexer.Lexer, o continue } switch key { - case "Username": - out.Username = string(in.String()) + case "IsPreseason": + out.IsPreseason = bool(in.Bool()) + case "HomeTeamID": + out.HomeTeamID = uint(in.Uint()) + case "AwayTeamID": + out.AwayTeamID = uint(in.Uint()) + case "SendingTeamID": + out.SendingTeamID = uint(in.Uint()) + case "RequestingTeamID": + out.RequestingTeamID = uint(in.Uint()) + case "IsAccepted": + out.IsAccepted = bool(in.Bool()) + case "IsApproved": + out.IsApproved = bool(in.Bool()) + case "ArenaID": + out.ArenaID = uint(in.Uint()) + case "Arena": + out.Arena = string(in.String()) + case "IsNeutralSite": + out.IsNeutralSite = bool(in.Bool()) case "SeasonID": out.SeasonID = uint(in.Uint()) case "WeekID": out.WeekID = uint(in.Uint()) case "Week": out.Week = uint(in.Uint()) - case "Rank1": - out.Rank1 = string(in.String()) - case "Rank1ID": - out.Rank1ID = uint(in.Uint()) - case "Rank2": - out.Rank2 = string(in.String()) - case "Rank2ID": - out.Rank2ID = uint(in.Uint()) - case "Rank3": - out.Rank3 = string(in.String()) - case "Rank3ID": - out.Rank3ID = uint(in.Uint()) - case "Rank4": - out.Rank4 = string(in.String()) - case "Rank4ID": - out.Rank4ID = uint(in.Uint()) - case "Rank5": - out.Rank5 = string(in.String()) - case "Rank5ID": - out.Rank5ID = uint(in.Uint()) - case "Rank6": - out.Rank6 = string(in.String()) - case "Rank6ID": - out.Rank6ID = uint(in.Uint()) - case "Rank7": - out.Rank7 = string(in.String()) - case "Rank7ID": - out.Rank7ID = uint(in.Uint()) - case "Rank8": - out.Rank8 = string(in.String()) - case "Rank8ID": - out.Rank8ID = uint(in.Uint()) - case "Rank9": - out.Rank9 = string(in.String()) - case "Rank9ID": - out.Rank9ID = uint(in.Uint()) - case "Rank10": - out.Rank10 = string(in.String()) - case "Rank10ID": - out.Rank10ID = uint(in.Uint()) - case "Rank11": - out.Rank11 = string(in.String()) - case "Rank11ID": - out.Rank11ID = uint(in.Uint()) - case "Rank12": - out.Rank12 = string(in.String()) - case "Rank12ID": - out.Rank12ID = uint(in.Uint()) - case "Rank13": - out.Rank13 = string(in.String()) - case "Rank13ID": - out.Rank13ID = uint(in.Uint()) - case "Rank14": - out.Rank14 = string(in.String()) - case "Rank14ID": - out.Rank14ID = uint(in.Uint()) - case "Rank15": - out.Rank15 = string(in.String()) - case "Rank15ID": - out.Rank15ID = uint(in.Uint()) - case "Rank16": - out.Rank16 = string(in.String()) - case "Rank16ID": - out.Rank16ID = uint(in.Uint()) - case "Rank17": - out.Rank17 = string(in.String()) - case "Rank17ID": - out.Rank17ID = uint(in.Uint()) - case "Rank18": - out.Rank18 = string(in.String()) - case "Rank18ID": - out.Rank18ID = uint(in.Uint()) - case "Rank19": - out.Rank19 = string(in.String()) - case "Rank19ID": - out.Rank19ID = uint(in.Uint()) - case "Rank20": - out.Rank20 = string(in.String()) - case "Rank20ID": - out.Rank20ID = uint(in.Uint()) - case "Rank21": - out.Rank21 = string(in.String()) - case "Rank21ID": - out.Rank21ID = uint(in.Uint()) - case "Rank22": - out.Rank22 = string(in.String()) - case "Rank22ID": - out.Rank22ID = uint(in.Uint()) - case "Rank23": - out.Rank23 = string(in.String()) - case "Rank23ID": - out.Rank23ID = uint(in.Uint()) - case "Rank24": - out.Rank24 = string(in.String()) - case "Rank24ID": - out.Rank24ID = uint(in.Uint()) - case "Rank25": - out.Rank25 = string(in.String()) - case "Rank25ID": - out.Rank25ID = uint(in.Uint()) + case "Timeslot": + out.Timeslot = string(in.String()) case "ID": out.ID = uint(in.Uint()) case "CreatedAt": @@ -19886,8 +19951,16 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs41(in *jlexer.Lexer, o in.AddError((out.UpdatedAt).UnmarshalJSON(data)) } case "DeletedAt": - if data := in.Raw(); in.Ok() { - in.AddError((out.DeletedAt).UnmarshalJSON(data)) + if in.IsNull() { + in.Skip() + out.DeletedAt = nil + } else { + if out.DeletedAt == nil { + out.DeletedAt = new(time.Time) + } + if data := in.Raw(); in.Ok() { + in.AddError((*out.DeletedAt).UnmarshalJSON(data)) + } } default: in.SkipRecursive() @@ -19899,89 +19972,698 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs41(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs41(out *jwriter.Writer, in structs.CollegePollSubmission) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs44(out *jwriter.Writer, in structs.NFLGameRequest) { out.RawByte('{') first := true _ = first { - const prefix string = ",\"Username\":" + const prefix string = ",\"IsPreseason\":" out.RawString(prefix[1:]) - out.String(string(in.Username)) + out.Bool(bool(in.IsPreseason)) } { - const prefix string = ",\"SeasonID\":" + const prefix string = ",\"HomeTeamID\":" out.RawString(prefix) - out.Uint(uint(in.SeasonID)) + out.Uint(uint(in.HomeTeamID)) } { - const prefix string = ",\"WeekID\":" + const prefix string = ",\"AwayTeamID\":" out.RawString(prefix) - out.Uint(uint(in.WeekID)) + out.Uint(uint(in.AwayTeamID)) } { - const prefix string = ",\"Week\":" + const prefix string = ",\"SendingTeamID\":" out.RawString(prefix) - out.Uint(uint(in.Week)) + out.Uint(uint(in.SendingTeamID)) } { - const prefix string = ",\"Rank1\":" + const prefix string = ",\"RequestingTeamID\":" out.RawString(prefix) - out.String(string(in.Rank1)) + out.Uint(uint(in.RequestingTeamID)) } { - const prefix string = ",\"Rank1ID\":" + const prefix string = ",\"IsAccepted\":" out.RawString(prefix) - out.Uint(uint(in.Rank1ID)) + out.Bool(bool(in.IsAccepted)) } { - const prefix string = ",\"Rank2\":" + const prefix string = ",\"IsApproved\":" out.RawString(prefix) - out.String(string(in.Rank2)) + out.Bool(bool(in.IsApproved)) } { - const prefix string = ",\"Rank2ID\":" + const prefix string = ",\"ArenaID\":" out.RawString(prefix) - out.Uint(uint(in.Rank2ID)) + out.Uint(uint(in.ArenaID)) } { - const prefix string = ",\"Rank3\":" + const prefix string = ",\"Arena\":" out.RawString(prefix) - out.String(string(in.Rank3)) + out.String(string(in.Arena)) } { - const prefix string = ",\"Rank3ID\":" + const prefix string = ",\"IsNeutralSite\":" out.RawString(prefix) - out.Uint(uint(in.Rank3ID)) + out.Bool(bool(in.IsNeutralSite)) } { - const prefix string = ",\"Rank4\":" + const prefix string = ",\"SeasonID\":" out.RawString(prefix) - out.String(string(in.Rank4)) + out.Uint(uint(in.SeasonID)) } { - const prefix string = ",\"Rank4ID\":" + const prefix string = ",\"WeekID\":" out.RawString(prefix) - out.Uint(uint(in.Rank4ID)) + out.Uint(uint(in.WeekID)) } { - const prefix string = ",\"Rank5\":" + const prefix string = ",\"Week\":" out.RawString(prefix) - out.String(string(in.Rank5)) + out.Uint(uint(in.Week)) } { - const prefix string = ",\"Rank5ID\":" + const prefix string = ",\"Timeslot\":" out.RawString(prefix) - out.Uint(uint(in.Rank5ID)) + out.String(string(in.Timeslot)) } { - const prefix string = ",\"Rank6\":" + const prefix string = ",\"ID\":" out.RawString(prefix) - out.String(string(in.Rank6)) + out.Uint(uint(in.ID)) } { - const prefix string = ",\"Rank6ID\":" + const prefix string = ",\"CreatedAt\":" out.RawString(prefix) - out.Uint(uint(in.Rank6ID)) + out.Raw((in.CreatedAt).MarshalJSON()) + } + { + const prefix string = ",\"UpdatedAt\":" + out.RawString(prefix) + out.Raw((in.UpdatedAt).MarshalJSON()) + } + { + const prefix string = ",\"DeletedAt\":" + out.RawString(prefix) + if in.DeletedAt == nil { + out.RawString("null") + } else { + out.Raw((*in.DeletedAt).MarshalJSON()) + } + } + out.RawByte('}') +} +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs43(in *jlexer.Lexer, out *structs.CFBGameRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "IsSpringGame": + out.IsSpringGame = bool(in.Bool()) + case "HomeTeamID": + out.HomeTeamID = uint(in.Uint()) + case "AwayTeamID": + out.AwayTeamID = uint(in.Uint()) + case "SendingTeamID": + out.SendingTeamID = uint(in.Uint()) + case "RequestingTeamID": + out.RequestingTeamID = uint(in.Uint()) + case "IsAccepted": + out.IsAccepted = bool(in.Bool()) + case "IsApproved": + out.IsApproved = bool(in.Bool()) + case "ArenaID": + out.ArenaID = uint(in.Uint()) + case "Arena": + out.Arena = string(in.String()) + case "IsNeutralSite": + out.IsNeutralSite = bool(in.Bool()) + case "SeasonID": + out.SeasonID = uint(in.Uint()) + case "WeekID": + out.WeekID = uint(in.Uint()) + case "Week": + out.Week = uint(in.Uint()) + case "Timeslot": + out.Timeslot = string(in.String()) + case "ID": + out.ID = uint(in.Uint()) + case "CreatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + case "UpdatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.UpdatedAt).UnmarshalJSON(data)) + } + case "DeletedAt": + if in.IsNull() { + in.Skip() + out.DeletedAt = nil + } else { + if out.DeletedAt == nil { + out.DeletedAt = new(time.Time) + } + if data := in.Raw(); in.Ok() { + in.AddError((*out.DeletedAt).UnmarshalJSON(data)) + } + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs43(out *jwriter.Writer, in structs.CFBGameRequest) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"IsSpringGame\":" + out.RawString(prefix[1:]) + out.Bool(bool(in.IsSpringGame)) + } + { + const prefix string = ",\"HomeTeamID\":" + out.RawString(prefix) + out.Uint(uint(in.HomeTeamID)) + } + { + const prefix string = ",\"AwayTeamID\":" + out.RawString(prefix) + out.Uint(uint(in.AwayTeamID)) + } + { + const prefix string = ",\"SendingTeamID\":" + out.RawString(prefix) + out.Uint(uint(in.SendingTeamID)) + } + { + const prefix string = ",\"RequestingTeamID\":" + out.RawString(prefix) + out.Uint(uint(in.RequestingTeamID)) + } + { + const prefix string = ",\"IsAccepted\":" + out.RawString(prefix) + out.Bool(bool(in.IsAccepted)) + } + { + const prefix string = ",\"IsApproved\":" + out.RawString(prefix) + out.Bool(bool(in.IsApproved)) + } + { + const prefix string = ",\"ArenaID\":" + out.RawString(prefix) + out.Uint(uint(in.ArenaID)) + } + { + const prefix string = ",\"Arena\":" + out.RawString(prefix) + out.String(string(in.Arena)) + } + { + const prefix string = ",\"IsNeutralSite\":" + out.RawString(prefix) + out.Bool(bool(in.IsNeutralSite)) + } + { + const prefix string = ",\"SeasonID\":" + out.RawString(prefix) + out.Uint(uint(in.SeasonID)) + } + { + const prefix string = ",\"WeekID\":" + out.RawString(prefix) + out.Uint(uint(in.WeekID)) + } + { + const prefix string = ",\"Week\":" + out.RawString(prefix) + out.Uint(uint(in.Week)) + } + { + const prefix string = ",\"Timeslot\":" + out.RawString(prefix) + out.String(string(in.Timeslot)) + } + { + const prefix string = ",\"ID\":" + out.RawString(prefix) + out.Uint(uint(in.ID)) + } + { + const prefix string = ",\"CreatedAt\":" + out.RawString(prefix) + out.Raw((in.CreatedAt).MarshalJSON()) + } + { + const prefix string = ",\"UpdatedAt\":" + out.RawString(prefix) + out.Raw((in.UpdatedAt).MarshalJSON()) + } + { + const prefix string = ",\"DeletedAt\":" + out.RawString(prefix) + if in.DeletedAt == nil { + out.RawString("null") + } else { + out.Raw((*in.DeletedAt).MarshalJSON()) + } + } + out.RawByte('}') +} +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in *jlexer.Lexer, out *structs.Stadium) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "StadiumName": + out.StadiumName = string(in.String()) + case "TeamID": + out.TeamID = uint(in.Uint()) + case "TeamAbbr": + out.TeamAbbr = string(in.String()) + case "City": + out.City = string(in.String()) + case "State": + out.State = string(in.String()) + case "Country": + out.Country = string(in.String()) + case "Region": + out.Region = string(in.String()) + case "WeatherRegion": + out.WeatherRegion = string(in.String()) + case "Capacity": + out.Capacity = uint(in.Uint()) + case "RecordAttendance": + out.RecordAttendance = uint(in.Uint()) + case "FirstSeason": + out.FirstSeason = uint(in.Uint()) + case "LeagueID": + out.LeagueID = uint(in.Uint()) + case "LeagueName": + out.LeagueName = string(in.String()) + case "IsDomed": + out.IsDomed = bool(in.Bool()) + case "ID": + out.ID = uint(in.Uint()) + case "CreatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + case "UpdatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.UpdatedAt).UnmarshalJSON(data)) + } + case "DeletedAt": + if in.IsNull() { + in.Skip() + out.DeletedAt = nil + } else { + if out.DeletedAt == nil { + out.DeletedAt = new(time.Time) + } + if data := in.Raw(); in.Ok() { + in.AddError((*out.DeletedAt).UnmarshalJSON(data)) + } + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out *jwriter.Writer, in structs.Stadium) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"StadiumName\":" + out.RawString(prefix[1:]) + out.String(string(in.StadiumName)) + } + { + const prefix string = ",\"TeamID\":" + out.RawString(prefix) + out.Uint(uint(in.TeamID)) + } + { + const prefix string = ",\"TeamAbbr\":" + out.RawString(prefix) + out.String(string(in.TeamAbbr)) + } + { + const prefix string = ",\"City\":" + out.RawString(prefix) + out.String(string(in.City)) + } + { + const prefix string = ",\"State\":" + out.RawString(prefix) + out.String(string(in.State)) + } + { + const prefix string = ",\"Country\":" + out.RawString(prefix) + out.String(string(in.Country)) + } + { + const prefix string = ",\"Region\":" + out.RawString(prefix) + out.String(string(in.Region)) + } + { + const prefix string = ",\"WeatherRegion\":" + out.RawString(prefix) + out.String(string(in.WeatherRegion)) + } + { + const prefix string = ",\"Capacity\":" + out.RawString(prefix) + out.Uint(uint(in.Capacity)) + } + { + const prefix string = ",\"RecordAttendance\":" + out.RawString(prefix) + out.Uint(uint(in.RecordAttendance)) + } + { + const prefix string = ",\"FirstSeason\":" + out.RawString(prefix) + out.Uint(uint(in.FirstSeason)) + } + { + const prefix string = ",\"LeagueID\":" + out.RawString(prefix) + out.Uint(uint(in.LeagueID)) + } + { + const prefix string = ",\"LeagueName\":" + out.RawString(prefix) + out.String(string(in.LeagueName)) + } + { + const prefix string = ",\"IsDomed\":" + out.RawString(prefix) + out.Bool(bool(in.IsDomed)) + } + { + const prefix string = ",\"ID\":" + out.RawString(prefix) + out.Uint(uint(in.ID)) + } + { + const prefix string = ",\"CreatedAt\":" + out.RawString(prefix) + out.Raw((in.CreatedAt).MarshalJSON()) + } + { + const prefix string = ",\"UpdatedAt\":" + out.RawString(prefix) + out.Raw((in.UpdatedAt).MarshalJSON()) + } + { + const prefix string = ",\"DeletedAt\":" + out.RawString(prefix) + if in.DeletedAt == nil { + out.RawString("null") + } else { + out.Raw((*in.DeletedAt).MarshalJSON()) + } + } + out.RawByte('}') +} +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs41(in *jlexer.Lexer, out *structs.CollegePollSubmission) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "Username": + out.Username = string(in.String()) + case "SeasonID": + out.SeasonID = uint(in.Uint()) + case "WeekID": + out.WeekID = uint(in.Uint()) + case "Week": + out.Week = uint(in.Uint()) + case "Rank1": + out.Rank1 = string(in.String()) + case "Rank1ID": + out.Rank1ID = uint(in.Uint()) + case "Rank2": + out.Rank2 = string(in.String()) + case "Rank2ID": + out.Rank2ID = uint(in.Uint()) + case "Rank3": + out.Rank3 = string(in.String()) + case "Rank3ID": + out.Rank3ID = uint(in.Uint()) + case "Rank4": + out.Rank4 = string(in.String()) + case "Rank4ID": + out.Rank4ID = uint(in.Uint()) + case "Rank5": + out.Rank5 = string(in.String()) + case "Rank5ID": + out.Rank5ID = uint(in.Uint()) + case "Rank6": + out.Rank6 = string(in.String()) + case "Rank6ID": + out.Rank6ID = uint(in.Uint()) + case "Rank7": + out.Rank7 = string(in.String()) + case "Rank7ID": + out.Rank7ID = uint(in.Uint()) + case "Rank8": + out.Rank8 = string(in.String()) + case "Rank8ID": + out.Rank8ID = uint(in.Uint()) + case "Rank9": + out.Rank9 = string(in.String()) + case "Rank9ID": + out.Rank9ID = uint(in.Uint()) + case "Rank10": + out.Rank10 = string(in.String()) + case "Rank10ID": + out.Rank10ID = uint(in.Uint()) + case "Rank11": + out.Rank11 = string(in.String()) + case "Rank11ID": + out.Rank11ID = uint(in.Uint()) + case "Rank12": + out.Rank12 = string(in.String()) + case "Rank12ID": + out.Rank12ID = uint(in.Uint()) + case "Rank13": + out.Rank13 = string(in.String()) + case "Rank13ID": + out.Rank13ID = uint(in.Uint()) + case "Rank14": + out.Rank14 = string(in.String()) + case "Rank14ID": + out.Rank14ID = uint(in.Uint()) + case "Rank15": + out.Rank15 = string(in.String()) + case "Rank15ID": + out.Rank15ID = uint(in.Uint()) + case "Rank16": + out.Rank16 = string(in.String()) + case "Rank16ID": + out.Rank16ID = uint(in.Uint()) + case "Rank17": + out.Rank17 = string(in.String()) + case "Rank17ID": + out.Rank17ID = uint(in.Uint()) + case "Rank18": + out.Rank18 = string(in.String()) + case "Rank18ID": + out.Rank18ID = uint(in.Uint()) + case "Rank19": + out.Rank19 = string(in.String()) + case "Rank19ID": + out.Rank19ID = uint(in.Uint()) + case "Rank20": + out.Rank20 = string(in.String()) + case "Rank20ID": + out.Rank20ID = uint(in.Uint()) + case "Rank21": + out.Rank21 = string(in.String()) + case "Rank21ID": + out.Rank21ID = uint(in.Uint()) + case "Rank22": + out.Rank22 = string(in.String()) + case "Rank22ID": + out.Rank22ID = uint(in.Uint()) + case "Rank23": + out.Rank23 = string(in.String()) + case "Rank23ID": + out.Rank23ID = uint(in.Uint()) + case "Rank24": + out.Rank24 = string(in.String()) + case "Rank24ID": + out.Rank24ID = uint(in.Uint()) + case "Rank25": + out.Rank25 = string(in.String()) + case "Rank25ID": + out.Rank25ID = uint(in.Uint()) + case "ID": + out.ID = uint(in.Uint()) + case "CreatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + case "UpdatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.UpdatedAt).UnmarshalJSON(data)) + } + case "DeletedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.DeletedAt).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs41(out *jwriter.Writer, in structs.CollegePollSubmission) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"Username\":" + out.RawString(prefix[1:]) + out.String(string(in.Username)) + } + { + const prefix string = ",\"SeasonID\":" + out.RawString(prefix) + out.Uint(uint(in.SeasonID)) + } + { + const prefix string = ",\"WeekID\":" + out.RawString(prefix) + out.Uint(uint(in.WeekID)) + } + { + const prefix string = ",\"Week\":" + out.RawString(prefix) + out.Uint(uint(in.Week)) + } + { + const prefix string = ",\"Rank1\":" + out.RawString(prefix) + out.String(string(in.Rank1)) + } + { + const prefix string = ",\"Rank1ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank1ID)) + } + { + const prefix string = ",\"Rank2\":" + out.RawString(prefix) + out.String(string(in.Rank2)) + } + { + const prefix string = ",\"Rank2ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank2ID)) + } + { + const prefix string = ",\"Rank3\":" + out.RawString(prefix) + out.String(string(in.Rank3)) + } + { + const prefix string = ",\"Rank3ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank3ID)) + } + { + const prefix string = ",\"Rank4\":" + out.RawString(prefix) + out.String(string(in.Rank4)) + } + { + const prefix string = ",\"Rank4ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank4ID)) + } + { + const prefix string = ",\"Rank5\":" + out.RawString(prefix) + out.String(string(in.Rank5)) + } + { + const prefix string = ",\"Rank5ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank5ID)) + } + { + const prefix string = ",\"Rank6\":" + out.RawString(prefix) + out.String(string(in.Rank6)) + } + { + const prefix string = ",\"Rank6ID\":" + out.RawString(prefix) + out.Uint(uint(in.Rank6ID)) } { const prefix string = ",\"Rank7\":" @@ -21020,9 +21702,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers7(in *jlexer.Lexer, o out.Recruits = (out.Recruits)[:0] } for !in.IsDelim(']') { - var v173 structs.Croot - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in, &v173) - out.Recruits = append(out.Recruits, v173) + var v182 structs.Croot + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in, &v182) + out.Recruits = append(out.Recruits, v182) in.WantComma() } in.Delim(']') @@ -21043,9 +21725,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers7(in *jlexer.Lexer, o out.RecruitProfiles = (out.RecruitProfiles)[:0] } for !in.IsDelim(']') { - var v174 structs.RecruitPlayerProfile - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs31(in, &v174) - out.RecruitProfiles = append(out.RecruitProfiles, v174) + var v183 structs.RecruitPlayerProfile + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs31(in, &v183) + out.RecruitProfiles = append(out.RecruitProfiles, v183) in.WantComma() } in.Delim(']') @@ -21059,17 +21741,17 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers7(in *jlexer.Lexer, o for !in.IsDelim('}') { key := string(in.String()) in.WantColon() - var v175 *structs.RecruitingTeamProfile + var v184 *structs.RecruitingTeamProfile if in.IsNull() { in.Skip() - v175 = nil + v184 = nil } else { - if v175 == nil { - v175 = new(structs.RecruitingTeamProfile) + if v184 == nil { + v184 = new(structs.RecruitingTeamProfile) } - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs24(in, v175) + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs24(in, v184) } - (out.TeamProfileMap)[key] = v175 + (out.TeamProfileMap)[key] = v184 in.WantComma() } in.Delim('}') @@ -21095,11 +21777,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers7(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v176, v177 := range in.Recruits { - if v176 > 0 { + for v185, v186 := range in.Recruits { + if v185 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out, v177) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs45(out, v186) } out.RawByte(']') } @@ -21111,11 +21793,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers7(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v178, v179 := range in.RecruitProfiles { - if v178 > 0 { + for v187, v188 := range in.RecruitProfiles { + if v187 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs31(out, v179) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs31(out, v188) } out.RawByte(']') } @@ -21127,19 +21809,19 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers7(out *jwriter.Writer out.RawString(`null`) } else { out.RawByte('{') - v180First := true - for v180Name, v180Value := range in.TeamProfileMap { - if v180First { - v180First = false + v189First := true + for v189Name, v189Value := range in.TeamProfileMap { + if v189First { + v189First = false } else { out.RawByte(',') } - out.String(string(v180Name)) + out.String(string(v189Name)) out.RawByte(':') - if v180Value == nil { + if v189Value == nil { out.RawString("null") } else { - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs24(out, *v180Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs24(out, *v189Value) } } out.RawByte('}') @@ -21171,7 +21853,7 @@ func (v *BootstrapDataRecruiting) UnmarshalJSON(data []byte) error { func (v *BootstrapDataRecruiting) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers7(l, v) } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in *jlexer.Lexer, out *structs.Croot) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in *jlexer.Lexer, out *structs.Croot) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -21262,9 +21944,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in *jlexer.Lexer, o out.LeadingTeams = (out.LeadingTeams)[:0] } for !in.IsDelim(']') { - var v181 structs.LeadingTeams - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs43(in, &v181) - out.LeadingTeams = append(out.LeadingTeams, v181) + var v190 structs.LeadingTeams + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in, &v190) + out.LeadingTeams = append(out.LeadingTeams, v190) in.WantComma() } in.Delim(']') @@ -21309,7 +21991,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs42(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out *jwriter.Writer, in structs.Croot) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs45(out *jwriter.Writer, in structs.Croot) { out.RawByte('{') first := true _ = first @@ -21460,11 +22142,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v182, v183 := range in.LeadingTeams { - if v182 > 0 { + for v191, v192 := range in.LeadingTeams { + if v191 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs43(out, v183) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs46(out, v192) } out.RawByte(']') } @@ -21546,7 +22228,7 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs42(out *jwriter.Writer } out.RawByte('}') } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs43(in *jlexer.Lexer, out *structs.LeadingTeams) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in *jlexer.Lexer, out *structs.LeadingTeams) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -21585,7 +22267,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs43(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs43(out *jwriter.Writer, in structs.LeadingTeams) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs46(out *jwriter.Writer, in structs.LeadingTeams) { out.RawByte('{') first := true _ = first @@ -21644,17 +22326,17 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers8(in *jlexer.Lexer, o for !in.IsDelim('}') { key := string(in.String()) in.WantColon() - var v184 *structs.RecruitingTeamProfile + var v193 *structs.RecruitingTeamProfile if in.IsNull() { in.Skip() - v184 = nil + v193 = nil } else { - if v184 == nil { - v184 = new(structs.RecruitingTeamProfile) + if v193 == nil { + v193 = new(structs.RecruitingTeamProfile) } - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs24(in, v184) + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs24(in, v193) } - (out.TeamProfileMap)[key] = v184 + (out.TeamProfileMap)[key] = v193 in.WantComma() } in.Delim('}') @@ -21675,9 +22357,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers8(in *jlexer.Lexer, o out.TransferPortalProfiles = (out.TransferPortalProfiles)[:0] } for !in.IsDelim(']') { - var v185 structs.TransferPortalProfile - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs44(in, &v185) - out.TransferPortalProfiles = append(out.TransferPortalProfiles, v185) + var v194 structs.TransferPortalProfile + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs47(in, &v194) + out.TransferPortalProfiles = append(out.TransferPortalProfiles, v194) in.WantComma() } in.Delim(']') @@ -21698,9 +22380,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers8(in *jlexer.Lexer, o out.CollegePromises = (out.CollegePromises)[:0] } for !in.IsDelim(']') { - var v186 structs.CollegePromise - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs34(in, &v186) - out.CollegePromises = append(out.CollegePromises, v186) + var v195 structs.CollegePromise + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs34(in, &v195) + out.CollegePromises = append(out.CollegePromises, v195) in.WantComma() } in.Delim(']') @@ -21721,9 +22403,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers8(in *jlexer.Lexer, o out.PortalPlayers = (out.PortalPlayers)[:0] } for !in.IsDelim(']') { - var v187 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v187) - out.PortalPlayers = append(out.PortalPlayers, v187) + var v196 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v196) + out.PortalPlayers = append(out.PortalPlayers, v196) in.WantComma() } in.Delim(']') @@ -21749,19 +22431,19 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers8(out *jwriter.Writer out.RawString(`null`) } else { out.RawByte('{') - v188First := true - for v188Name, v188Value := range in.TeamProfileMap { - if v188First { - v188First = false + v197First := true + for v197Name, v197Value := range in.TeamProfileMap { + if v197First { + v197First = false } else { out.RawByte(',') } - out.String(string(v188Name)) + out.String(string(v197Name)) out.RawByte(':') - if v188Value == nil { + if v197Value == nil { out.RawString("null") } else { - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs24(out, *v188Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs24(out, *v197Value) } } out.RawByte('}') @@ -21774,11 +22456,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers8(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v189, v190 := range in.TransferPortalProfiles { - if v189 > 0 { + for v198, v199 := range in.TransferPortalProfiles { + if v198 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs44(out, v190) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs47(out, v199) } out.RawByte(']') } @@ -21790,11 +22472,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers8(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v191, v192 := range in.CollegePromises { - if v191 > 0 { + for v200, v201 := range in.CollegePromises { + if v200 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs34(out, v192) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs34(out, v201) } out.RawByte(']') } @@ -21806,11 +22488,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers8(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v193, v194 := range in.PortalPlayers { - if v193 > 0 { + for v202, v203 := range in.PortalPlayers { + if v202 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v194) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v203) } out.RawByte(']') } @@ -21841,7 +22523,7 @@ func (v *BootstrapDataPortal) UnmarshalJSON(data []byte) error { func (v *BootstrapDataPortal) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers8(l, v) } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs44(in *jlexer.Lexer, out *structs.TransferPortalProfile) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs47(in *jlexer.Lexer, out *structs.TransferPortalProfile) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -21912,7 +22594,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs44(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs44(out *jwriter.Writer, in structs.TransferPortalProfile) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs47(out *jwriter.Writer, in structs.TransferPortalProfile) { out.RawByte('{') first := true _ = first @@ -22092,9 +22774,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers9(in *jlexer.Lexer, o out.CollegeNews = (out.CollegeNews)[:0] } for !in.IsDelim(']') { - var v195 structs.NewsLog - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in, &v195) - out.CollegeNews = append(out.CollegeNews, v195) + var v204 structs.NewsLog + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs48(in, &v204) + out.CollegeNews = append(out.CollegeNews, v204) in.WantComma() } in.Delim(']') @@ -22115,9 +22797,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers9(in *jlexer.Lexer, o out.ProNews = (out.ProNews)[:0] } for !in.IsDelim(']') { - var v196 structs.NewsLog - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in, &v196) - out.ProNews = append(out.ProNews, v196) + var v205 structs.NewsLog + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs48(in, &v205) + out.ProNews = append(out.ProNews, v205) in.WantComma() } in.Delim(']') @@ -22143,11 +22825,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers9(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v197, v198 := range in.CollegeNews { - if v197 > 0 { + for v206, v207 := range in.CollegeNews { + if v206 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs45(out, v198) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs48(out, v207) } out.RawByte(']') } @@ -22159,11 +22841,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers9(out *jwriter.Writer out.RawString("null") } else { out.RawByte('[') - for v199, v200 := range in.ProNews { - if v199 > 0 { + for v208, v209 := range in.ProNews { + if v208 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs45(out, v200) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs48(out, v209) } out.RawByte(']') } @@ -22194,7 +22876,7 @@ func (v *BootstrapDataNews) UnmarshalJSON(data []byte) error { func (v *BootstrapDataNews) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers9(l, v) } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in *jlexer.Lexer, out *structs.NewsLog) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs48(in *jlexer.Lexer, out *structs.NewsLog) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -22259,7 +22941,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs45(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs45(out *jwriter.Writer, in structs.NewsLog) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs48(out *jwriter.Writer, in structs.NewsLog) { out.RawByte('{') first := true _ = first @@ -22354,30 +23036,30 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v201 []structs.CollegePlayer + var v210 []structs.CollegePlayer if in.IsNull() { in.Skip() - v201 = nil + v210 = nil } else { in.Delim('[') - if v201 == nil { + if v210 == nil { if !in.IsDelim(']') { - v201 = make([]structs.CollegePlayer, 0, 0) + v210 = make([]structs.CollegePlayer, 0, 0) } else { - v201 = []structs.CollegePlayer{} + v210 = []structs.CollegePlayer{} } } else { - v201 = (v201)[:0] + v210 = (v210)[:0] } for !in.IsDelim(']') { - var v202 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v202) - v201 = append(v201, v202) + var v211 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v211) + v210 = append(v210, v211) in.WantComma() } in.Delim(']') } - (out.CollegeRosterMap)[key] = v201 + (out.CollegeRosterMap)[key] = v210 in.WantComma() } in.Delim('}') @@ -22398,9 +23080,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.CollegeStandings = (out.CollegeStandings)[:0] } for !in.IsDelim(']') { - var v203 structs.CollegeStandings - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs1(in, &v203) - out.CollegeStandings = append(out.CollegeStandings, v203) + var v212 structs.CollegeStandings + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs1(in, &v212) + out.CollegeStandings = append(out.CollegeStandings, v212) in.WantComma() } in.Delim(']') @@ -22421,9 +23103,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.AllCollegeGames = (out.AllCollegeGames)[:0] } for !in.IsDelim(']') { - var v204 structs.CollegeGame - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs4(in, &v204) - out.AllCollegeGames = append(out.AllCollegeGames, v204) + var v213 structs.CollegeGame + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs4(in, &v213) + out.AllCollegeGames = append(out.AllCollegeGames, v213) in.WantComma() } in.Delim(']') @@ -22444,9 +23126,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.OfficialPolls = (out.OfficialPolls)[:0] } for !in.IsDelim(']') { - var v205 structs.CollegePollOfficial - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs40(in, &v205) - out.OfficialPolls = append(out.OfficialPolls, v205) + var v214 structs.CollegePollOfficial + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs40(in, &v214) + out.OfficialPolls = append(out.OfficialPolls, v214) in.WantComma() } in.Delim(']') @@ -22467,9 +23149,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopCFBPassers = (out.TopCFBPassers)[:0] } for !in.IsDelim(']') { - var v206 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v206) - out.TopCFBPassers = append(out.TopCFBPassers, v206) + var v215 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v215) + out.TopCFBPassers = append(out.TopCFBPassers, v215) in.WantComma() } in.Delim(']') @@ -22490,9 +23172,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopCFBRushers = (out.TopCFBRushers)[:0] } for !in.IsDelim(']') { - var v207 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v207) - out.TopCFBRushers = append(out.TopCFBRushers, v207) + var v216 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v216) + out.TopCFBRushers = append(out.TopCFBRushers, v216) in.WantComma() } in.Delim(']') @@ -22513,9 +23195,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopCFBReceivers = (out.TopCFBReceivers)[:0] } for !in.IsDelim(']') { - var v208 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v208) - out.TopCFBReceivers = append(out.TopCFBReceivers, v208) + var v217 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v217) + out.TopCFBReceivers = append(out.TopCFBReceivers, v217) in.WantComma() } in.Delim(']') @@ -22536,9 +23218,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.CollegeInjuryReport = (out.CollegeInjuryReport)[:0] } for !in.IsDelim(']') { - var v209 structs.CollegePlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v209) - out.CollegeInjuryReport = append(out.CollegeInjuryReport, v209) + var v218 structs.CollegePlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs3(in, &v218) + out.CollegeInjuryReport = append(out.CollegeInjuryReport, v218) in.WantComma() } in.Delim(']') @@ -22559,9 +23241,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.CollegeNotifications = (out.CollegeNotifications)[:0] } for !in.IsDelim(']') { - var v210 structs.Notification - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in, &v210) - out.CollegeNotifications = append(out.CollegeNotifications, v210) + var v219 structs.Notification + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs49(in, &v219) + out.CollegeNotifications = append(out.CollegeNotifications, v219) in.WantComma() } in.Delim(']') @@ -22584,9 +23266,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.ProNotifications = (out.ProNotifications)[:0] } for !in.IsDelim(']') { - var v211 structs.Notification - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in, &v211) - out.ProNotifications = append(out.ProNotifications, v211) + var v220 structs.Notification + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs49(in, &v220) + out.ProNotifications = append(out.ProNotifications, v220) in.WantComma() } in.Delim(']') @@ -22607,9 +23289,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.ProStandings = (out.ProStandings)[:0] } for !in.IsDelim(']') { - var v212 structs.NFLStandings - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs15(in, &v212) - out.ProStandings = append(out.ProStandings, v212) + var v221 structs.NFLStandings + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs15(in, &v221) + out.ProStandings = append(out.ProStandings, v221) in.WantComma() } in.Delim(']') @@ -22630,9 +23312,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.AllProGames = (out.AllProGames)[:0] } for !in.IsDelim(']') { - var v213 structs.NFLGame - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs47(in, &v213) - out.AllProGames = append(out.AllProGames, v213) + var v222 structs.NFLGame + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs50(in, &v222) + out.AllProGames = append(out.AllProGames, v222) in.WantComma() } in.Delim(']') @@ -22655,9 +23337,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopNFLPassers = (out.TopNFLPassers)[:0] } for !in.IsDelim(']') { - var v214 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v214) - out.TopNFLPassers = append(out.TopNFLPassers, v214) + var v223 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v223) + out.TopNFLPassers = append(out.TopNFLPassers, v223) in.WantComma() } in.Delim(']') @@ -22678,9 +23360,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopNFLRushers = (out.TopNFLRushers)[:0] } for !in.IsDelim(']') { - var v215 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v215) - out.TopNFLRushers = append(out.TopNFLRushers, v215) + var v224 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v224) + out.TopNFLRushers = append(out.TopNFLRushers, v224) in.WantComma() } in.Delim(']') @@ -22701,9 +23383,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.TopNFLReceivers = (out.TopNFLReceivers)[:0] } for !in.IsDelim(']') { - var v216 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v216) - out.TopNFLReceivers = append(out.TopNFLReceivers, v216) + var v225 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v225) + out.TopNFLReceivers = append(out.TopNFLReceivers, v225) in.WantComma() } in.Delim(']') @@ -22717,30 +23399,30 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v217 []structs.NFLPlayer + var v226 []structs.NFLPlayer if in.IsNull() { in.Skip() - v217 = nil + v226 = nil } else { in.Delim('[') - if v217 == nil { + if v226 == nil { if !in.IsDelim(']') { - v217 = make([]structs.NFLPlayer, 0, 0) + v226 = make([]structs.NFLPlayer, 0, 0) } else { - v217 = []structs.NFLPlayer{} + v226 = []structs.NFLPlayer{} } } else { - v217 = (v217)[:0] + v226 = (v226)[:0] } for !in.IsDelim(']') { - var v218 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v218) - v217 = append(v217, v218) + var v227 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v227) + v226 = append(v226, v227) in.WantComma() } in.Delim(']') } - (out.ProRosterMap)[key] = v217 + (out.ProRosterMap)[key] = v226 in.WantComma() } in.Delim('}') @@ -22761,9 +23443,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.ProInjuryReport = (out.ProInjuryReport)[:0] } for !in.IsDelim(']') { - var v219 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v219) - out.ProInjuryReport = append(out.ProInjuryReport, v219) + var v228 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v228) + out.ProInjuryReport = append(out.ProInjuryReport, v228) in.WantComma() } in.Delim(']') @@ -22784,9 +23466,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.PracticeSquadPlayers = (out.PracticeSquadPlayers)[:0] } for !in.IsDelim(']') { - var v220 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v220) - out.PracticeSquadPlayers = append(out.PracticeSquadPlayers, v220) + var v229 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v229) + out.PracticeSquadPlayers = append(out.PracticeSquadPlayers, v229) in.WantComma() } in.Delim(']') @@ -22800,9 +23482,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v221 structs.NFLCapsheet - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs8(in, &v221) - (out.CapsheetMap)[key] = v221 + var v230 structs.NFLCapsheet + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs8(in, &v230) + (out.CapsheetMap)[key] = v230 in.WantComma() } in.Delim('}') @@ -22823,9 +23505,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(in *jlexer.Lexer, out.RetiredPlayers = (out.RetiredPlayers)[:0] } for !in.IsDelim(']') { - var v222 structs.NFLRetiredPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs39(in, &v222) - out.RetiredPlayers = append(out.RetiredPlayers, v222) + var v231 structs.NFLRetiredPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs39(in, &v231) + out.RetiredPlayers = append(out.RetiredPlayers, v231) in.WantComma() } in.Delim(']') @@ -22856,24 +23538,24 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v223First := true - for v223Name, v223Value := range in.CollegeRosterMap { - if v223First { - v223First = false + v232First := true + for v232Name, v232Value := range in.CollegeRosterMap { + if v232First { + v232First = false } else { out.RawByte(',') } - out.UintStr(uint(v223Name)) + out.UintStr(uint(v232Name)) out.RawByte(':') - if v223Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + if v232Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { out.RawString("null") } else { out.RawByte('[') - for v224, v225 := range v223Value { - if v224 > 0 { + for v233, v234 := range v232Value { + if v233 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v225) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v234) } out.RawByte(']') } @@ -22888,11 +23570,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v226, v227 := range in.CollegeStandings { - if v226 > 0 { + for v235, v236 := range in.CollegeStandings { + if v235 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs1(out, v227) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs1(out, v236) } out.RawByte(']') } @@ -22904,11 +23586,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v228, v229 := range in.AllCollegeGames { - if v228 > 0 { + for v237, v238 := range in.AllCollegeGames { + if v237 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs4(out, v229) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs4(out, v238) } out.RawByte(']') } @@ -22920,11 +23602,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v230, v231 := range in.OfficialPolls { - if v230 > 0 { + for v239, v240 := range in.OfficialPolls { + if v239 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs40(out, v231) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs40(out, v240) } out.RawByte(']') } @@ -22936,11 +23618,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v232, v233 := range in.TopCFBPassers { - if v232 > 0 { + for v241, v242 := range in.TopCFBPassers { + if v241 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v233) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v242) } out.RawByte(']') } @@ -22952,11 +23634,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v234, v235 := range in.TopCFBRushers { - if v234 > 0 { + for v243, v244 := range in.TopCFBRushers { + if v243 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v235) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v244) } out.RawByte(']') } @@ -22968,11 +23650,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v236, v237 := range in.TopCFBReceivers { - if v236 > 0 { + for v245, v246 := range in.TopCFBReceivers { + if v245 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v237) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v246) } out.RawByte(']') } @@ -22984,11 +23666,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v238, v239 := range in.CollegeInjuryReport { - if v238 > 0 { + for v247, v248 := range in.CollegeInjuryReport { + if v247 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v239) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs3(out, v248) } out.RawByte(']') } @@ -23000,11 +23682,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v240, v241 := range in.CollegeNotifications { - if v240 > 0 { + for v249, v250 := range in.CollegeNotifications { + if v249 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs46(out, v241) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs49(out, v250) } out.RawByte(']') } @@ -23021,11 +23703,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v242, v243 := range in.ProNotifications { - if v242 > 0 { + for v251, v252 := range in.ProNotifications { + if v251 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs46(out, v243) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs49(out, v252) } out.RawByte(']') } @@ -23037,11 +23719,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v244, v245 := range in.ProStandings { - if v244 > 0 { + for v253, v254 := range in.ProStandings { + if v253 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs15(out, v245) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs15(out, v254) } out.RawByte(']') } @@ -23053,11 +23735,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v246, v247 := range in.AllProGames { - if v246 > 0 { + for v255, v256 := range in.AllProGames { + if v255 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs47(out, v247) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs50(out, v256) } out.RawByte(']') } @@ -23074,11 +23756,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v248, v249 := range in.TopNFLPassers { - if v248 > 0 { + for v257, v258 := range in.TopNFLPassers { + if v257 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v249) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v258) } out.RawByte(']') } @@ -23090,11 +23772,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v250, v251 := range in.TopNFLRushers { - if v250 > 0 { + for v259, v260 := range in.TopNFLRushers { + if v259 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v251) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v260) } out.RawByte(']') } @@ -23106,11 +23788,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v252, v253 := range in.TopNFLReceivers { - if v252 > 0 { + for v261, v262 := range in.TopNFLReceivers { + if v261 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v253) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v262) } out.RawByte(']') } @@ -23122,24 +23804,24 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v254First := true - for v254Name, v254Value := range in.ProRosterMap { - if v254First { - v254First = false + v263First := true + for v263Name, v263Value := range in.ProRosterMap { + if v263First { + v263First = false } else { out.RawByte(',') } - out.UintStr(uint(v254Name)) + out.UintStr(uint(v263Name)) out.RawByte(':') - if v254Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + if v263Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { out.RawString("null") } else { out.RawByte('[') - for v255, v256 := range v254Value { - if v255 > 0 { + for v264, v265 := range v263Value { + if v264 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v256) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v265) } out.RawByte(']') } @@ -23154,11 +23836,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v257, v258 := range in.ProInjuryReport { - if v257 > 0 { + for v266, v267 := range in.ProInjuryReport { + if v266 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v258) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v267) } out.RawByte(']') } @@ -23170,11 +23852,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v259, v260 := range in.PracticeSquadPlayers { - if v259 > 0 { + for v268, v269 := range in.PracticeSquadPlayers { + if v268 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v260) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v269) } out.RawByte(']') } @@ -23186,16 +23868,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v261First := true - for v261Name, v261Value := range in.CapsheetMap { - if v261First { - v261First = false + v270First := true + for v270Name, v270Value := range in.CapsheetMap { + if v270First { + v270First = false } else { out.RawByte(',') } - out.UintStr(uint(v261Name)) + out.UintStr(uint(v270Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs8(out, v261Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs8(out, v270Value) } out.RawByte('}') } @@ -23207,11 +23889,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers10(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v262, v263 := range in.RetiredPlayers { - if v262 > 0 { + for v271, v272 := range in.RetiredPlayers { + if v271 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs39(out, v263) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs39(out, v272) } out.RawByte(']') } @@ -23242,7 +23924,7 @@ func (v *BootstrapDataLanding) UnmarshalJSON(data []byte) error { func (v *BootstrapDataLanding) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers10(l, v) } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs47(in *jlexer.Lexer, out *structs.NFLGame) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs50(in *jlexer.Lexer, out *structs.NFLGame) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -23381,7 +24063,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs47(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs47(out *jwriter.Writer, in structs.NFLGame) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs50(out *jwriter.Writer, in structs.NFLGame) { out.RawByte('{') first := true _ = first @@ -23631,7 +24313,7 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs47(out *jwriter.Writer } out.RawByte('}') } -func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in *jlexer.Lexer, out *structs.Notification) { +func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs49(in *jlexer.Lexer, out *structs.Notification) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -23686,7 +24368,7 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs46(in *jlexer.Lexer, o in.Consumed() } } -func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs46(out *jwriter.Writer, in structs.Notification) { +func easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs49(out *jwriter.Writer, in structs.Notification) { out.RawByte('{') first := true _ = first @@ -23770,9 +24452,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers11(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v264 structs.CollegeGameplan - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs28(in, &v264) - (out.CollegeGameplanMap)[key] = v264 + var v273 structs.CollegeGameplan + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs28(in, &v273) + (out.CollegeGameplanMap)[key] = v273 in.WantComma() } in.Delim('}') @@ -23788,9 +24470,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers11(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v265 structs.CollegeTeamDepthChart - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs29(in, &v265) - (out.CollegeDepthChartMap)[key] = v265 + var v274 structs.CollegeTeamDepthChart + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs29(in, &v274) + (out.CollegeDepthChartMap)[key] = v274 in.WantComma() } in.Delim('}') @@ -23804,9 +24486,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers11(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v266 structs.NFLGameplan - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs14(in, &v266) - (out.NFLGameplanMap)[key] = v266 + var v275 structs.NFLGameplan + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs14(in, &v275) + (out.NFLGameplanMap)[key] = v275 in.WantComma() } in.Delim('}') @@ -23822,9 +24504,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers11(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v267 structs.NFLDepthChart - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs13(in, &v267) - (out.NFLDepthChartMap)[key] = v267 + var v276 structs.NFLDepthChart + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs13(in, &v276) + (out.NFLDepthChartMap)[key] = v276 in.WantComma() } in.Delim('}') @@ -23850,16 +24532,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers11(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v268First := true - for v268Name, v268Value := range in.CollegeGameplanMap { - if v268First { - v268First = false + v277First := true + for v277Name, v277Value := range in.CollegeGameplanMap { + if v277First { + v277First = false } else { out.RawByte(',') } - out.UintStr(uint(v268Name)) + out.UintStr(uint(v277Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs28(out, v268Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs28(out, v277Value) } out.RawByte('}') } @@ -23876,16 +24558,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers11(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v269First := true - for v269Name, v269Value := range in.CollegeDepthChartMap { - if v269First { - v269First = false + v278First := true + for v278Name, v278Value := range in.CollegeDepthChartMap { + if v278First { + v278First = false } else { out.RawByte(',') } - out.UintStr(uint(v269Name)) + out.UintStr(uint(v278Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs29(out, v269Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs29(out, v278Value) } out.RawByte('}') } @@ -23897,16 +24579,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers11(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v270First := true - for v270Name, v270Value := range in.NFLGameplanMap { - if v270First { - v270First = false + v279First := true + for v279Name, v279Value := range in.NFLGameplanMap { + if v279First { + v279First = false } else { out.RawByte(',') } - out.UintStr(uint(v270Name)) + out.UintStr(uint(v279Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs14(out, v270Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs14(out, v279Value) } out.RawByte('}') } @@ -23923,16 +24605,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers11(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v271First := true - for v271Name, v271Value := range in.NFLDepthChartMap { - if v271First { - v271First = false + v280First := true + for v280Name, v280Value := range in.NFLDepthChartMap { + if v280First { + v280First = false } else { out.RawByte(',') } - out.UintStr(uint(v271Name)) + out.UintStr(uint(v280Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs13(out, v271Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs13(out, v280Value) } out.RawByte('}') } @@ -23998,9 +24680,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers12(in *jlexer.Lexer, out.FreeAgents = (out.FreeAgents)[:0] } for !in.IsDelim(']') { - var v272 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v272) - out.FreeAgents = append(out.FreeAgents, v272) + var v281 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v281) + out.FreeAgents = append(out.FreeAgents, v281) in.WantComma() } in.Delim(']') @@ -24021,9 +24703,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers12(in *jlexer.Lexer, out.WaiverPlayers = (out.WaiverPlayers)[:0] } for !in.IsDelim(']') { - var v273 structs.NFLPlayer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v273) - out.WaiverPlayers = append(out.WaiverPlayers, v273) + var v282 structs.NFLPlayer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs17(in, &v282) + out.WaiverPlayers = append(out.WaiverPlayers, v282) in.WantComma() } in.Delim(']') @@ -24044,9 +24726,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers12(in *jlexer.Lexer, out.FreeAgentOffers = (out.FreeAgentOffers)[:0] } for !in.IsDelim(']') { - var v274 structs.FreeAgencyOffer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs20(in, &v274) - out.FreeAgentOffers = append(out.FreeAgentOffers, v274) + var v283 structs.FreeAgencyOffer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs20(in, &v283) + out.FreeAgentOffers = append(out.FreeAgentOffers, v283) in.WantComma() } in.Delim(']') @@ -24067,9 +24749,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers12(in *jlexer.Lexer, out.WaiverOffers = (out.WaiverOffers)[:0] } for !in.IsDelim(']') { - var v275 structs.NFLWaiverOffer - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs21(in, &v275) - out.WaiverOffers = append(out.WaiverOffers, v275) + var v284 structs.NFLWaiverOffer + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs21(in, &v284) + out.WaiverOffers = append(out.WaiverOffers, v284) in.WantComma() } in.Delim(']') @@ -24095,11 +24777,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers12(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v276, v277 := range in.FreeAgents { - if v276 > 0 { + for v285, v286 := range in.FreeAgents { + if v285 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v277) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v286) } out.RawByte(']') } @@ -24111,11 +24793,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers12(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v278, v279 := range in.WaiverPlayers { - if v278 > 0 { + for v287, v288 := range in.WaiverPlayers { + if v287 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v279) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs17(out, v288) } out.RawByte(']') } @@ -24127,11 +24809,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers12(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v280, v281 := range in.FreeAgentOffers { - if v280 > 0 { + for v289, v290 := range in.FreeAgentOffers { + if v289 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs20(out, v281) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs20(out, v290) } out.RawByte(']') } @@ -24143,11 +24825,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers12(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v282, v283 := range in.WaiverOffers { - if v282 > 0 { + for v291, v292 := range in.WaiverOffers { + if v291 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs21(out, v283) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs21(out, v292) } out.RawByte(']') } @@ -24213,9 +24895,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers13(in *jlexer.Lexer, out.NFLDraftees = (out.NFLDraftees)[:0] } for !in.IsDelim(']') { - var v284 models.NFLDraftee - easyjson83226b63DecodeGithubComCalebRoseSimFBAModels(in, &v284) - out.NFLDraftees = append(out.NFLDraftees, v284) + var v293 models.NFLDraftee + easyjson83226b63DecodeGithubComCalebRoseSimFBAModels(in, &v293) + out.NFLDraftees = append(out.NFLDraftees, v293) in.WantComma() } in.Delim(']') @@ -24229,9 +24911,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers13(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v285 models.NFLWarRoom - easyjson83226b63DecodeGithubComCalebRoseSimFBAModels1(in, &v285) - (out.NFLWarRoomMap)[key] = v285 + var v294 models.NFLWarRoom + easyjson83226b63DecodeGithubComCalebRoseSimFBAModels1(in, &v294) + (out.NFLWarRoomMap)[key] = v294 in.WantComma() } in.Delim('}') @@ -24245,30 +24927,30 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers13(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v286 []models.ScoutingProfile + var v295 []models.ScoutingProfile if in.IsNull() { in.Skip() - v286 = nil + v295 = nil } else { in.Delim('[') - if v286 == nil { + if v295 == nil { if !in.IsDelim(']') { - v286 = make([]models.ScoutingProfile, 0, 0) + v295 = make([]models.ScoutingProfile, 0, 0) } else { - v286 = []models.ScoutingProfile{} + v295 = []models.ScoutingProfile{} } } else { - v286 = (v286)[:0] + v295 = (v295)[:0] } for !in.IsDelim(']') { - var v287 models.ScoutingProfile - easyjson83226b63DecodeGithubComCalebRoseSimFBAModels2(in, &v287) - v286 = append(v286, v287) + var v296 models.ScoutingProfile + easyjson83226b63DecodeGithubComCalebRoseSimFBAModels2(in, &v296) + v295 = append(v295, v296) in.WantComma() } in.Delim(']') } - (out.DraftScoutingProfileMap)[key] = v286 + (out.DraftScoutingProfileMap)[key] = v295 in.WantComma() } in.Delim('}') @@ -24282,9 +24964,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers13(in *jlexer.Lexer, for !in.IsDelim('}') { key := uint(in.UintStr()) in.WantColon() - var v288 structs.NFLGameplan - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs14(in, &v288) - (out.NFLGameplanMap)[key] = v288 + var v297 structs.NFLGameplan + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs14(in, &v297) + (out.NFLGameplanMap)[key] = v297 in.WantComma() } in.Delim('}') @@ -24305,9 +24987,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAManagers13(in *jlexer.Lexer, out.NFLDraftPicks = (out.NFLDraftPicks)[:0] } for !in.IsDelim(']') { - var v289 structs.NFLDraftPick - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs10(in, &v289) - out.NFLDraftPicks = append(out.NFLDraftPicks, v289) + var v298 structs.NFLDraftPick + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs10(in, &v298) + out.NFLDraftPicks = append(out.NFLDraftPicks, v298) in.WantComma() } in.Delim(']') @@ -24333,11 +25015,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers13(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v290, v291 := range in.NFLDraftees { - if v290 > 0 { + for v299, v300 := range in.NFLDraftees { + if v299 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAModels(out, v291) + easyjson83226b63EncodeGithubComCalebRoseSimFBAModels(out, v300) } out.RawByte(']') } @@ -24349,16 +25031,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers13(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v292First := true - for v292Name, v292Value := range in.NFLWarRoomMap { - if v292First { - v292First = false + v301First := true + for v301Name, v301Value := range in.NFLWarRoomMap { + if v301First { + v301First = false } else { out.RawByte(',') } - out.UintStr(uint(v292Name)) + out.UintStr(uint(v301Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAModels1(out, v292Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAModels1(out, v301Value) } out.RawByte('}') } @@ -24370,24 +25052,24 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers13(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v293First := true - for v293Name, v293Value := range in.DraftScoutingProfileMap { - if v293First { - v293First = false + v302First := true + for v302Name, v302Value := range in.DraftScoutingProfileMap { + if v302First { + v302First = false } else { out.RawByte(',') } - out.UintStr(uint(v293Name)) + out.UintStr(uint(v302Name)) out.RawByte(':') - if v293Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + if v302Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { out.RawString("null") } else { out.RawByte('[') - for v294, v295 := range v293Value { - if v294 > 0 { + for v303, v304 := range v302Value { + if v303 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAModels2(out, v295) + easyjson83226b63EncodeGithubComCalebRoseSimFBAModels2(out, v304) } out.RawByte(']') } @@ -24402,16 +25084,16 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers13(out *jwriter.Write out.RawString(`null`) } else { out.RawByte('{') - v296First := true - for v296Name, v296Value := range in.NFLGameplanMap { - if v296First { - v296First = false + v305First := true + for v305Name, v305Value := range in.NFLGameplanMap { + if v305First { + v305First = false } else { out.RawByte(',') } - out.UintStr(uint(v296Name)) + out.UintStr(uint(v305Name)) out.RawByte(':') - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs14(out, v296Value) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs14(out, v305Value) } out.RawByte('}') } @@ -24423,11 +25105,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAManagers13(out *jwriter.Write out.RawString("null") } else { out.RawByte('[') - for v297, v298 := range in.NFLDraftPicks { - if v297 > 0 { + for v306, v307 := range in.NFLDraftPicks { + if v306 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs10(out, v298) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs10(out, v307) } out.RawByte(']') } @@ -24680,9 +25362,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAModels1(in *jlexer.Lexer, out out.DraftPicks = (out.DraftPicks)[:0] } for !in.IsDelim(']') { - var v299 structs.NFLDraftPick - easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs10(in, &v299) - out.DraftPicks = append(out.DraftPicks, v299) + var v308 structs.NFLDraftPick + easyjson83226b63DecodeGithubComCalebRoseSimFBAStructs10(in, &v308) + out.DraftPicks = append(out.DraftPicks, v308) in.WantComma() } in.Delim(']') @@ -24703,9 +25385,9 @@ func easyjson83226b63DecodeGithubComCalebRoseSimFBAModels1(in *jlexer.Lexer, out out.ScoutProfiles = (out.ScoutProfiles)[:0] } for !in.IsDelim(']') { - var v300 models.ScoutingProfile - easyjson83226b63DecodeGithubComCalebRoseSimFBAModels2(in, &v300) - out.ScoutProfiles = append(out.ScoutProfiles, v300) + var v309 models.ScoutingProfile + easyjson83226b63DecodeGithubComCalebRoseSimFBAModels2(in, &v309) + out.ScoutProfiles = append(out.ScoutProfiles, v309) in.WantComma() } in.Delim(']') @@ -24773,11 +25455,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAModels1(out *jwriter.Writer, out.RawString("null") } else { out.RawByte('[') - for v301, v302 := range in.DraftPicks { - if v301 > 0 { + for v310, v311 := range in.DraftPicks { + if v310 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs10(out, v302) + easyjson83226b63EncodeGithubComCalebRoseSimFBAStructs10(out, v311) } out.RawByte(']') } @@ -24789,11 +25471,11 @@ func easyjson83226b63EncodeGithubComCalebRoseSimFBAModels1(out *jwriter.Writer, out.RawString("null") } else { out.RawByte('[') - for v303, v304 := range in.ScoutProfiles { - if v303 > 0 { + for v312, v313 := range in.ScoutProfiles { + if v312 > 0 { out.RawByte(',') } - easyjson83226b63EncodeGithubComCalebRoseSimFBAModels2(out, v304) + easyjson83226b63EncodeGithubComCalebRoseSimFBAModels2(out, v313) } out.RawByte(']') } diff --git a/managers/CFBScheduleAAC.go b/managers/CFBScheduleAAC.go new file mode 100644 index 0000000..81f7bfa --- /dev/null +++ b/managers/CFBScheduleAAC.go @@ -0,0 +1,187 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// AAC Conference Schedule Generator +// 14 teams | 8 conf games per team +// Annual locks: Army/Navy (Week 14), Memphis/UAB (Week 14) +// OOC busy Week 14: Tulane, USF, UTSA +// Week 14 bye: ECU, FAU, Charlotte, North Texas, Rice, Temple, Tulsa +// ============================================================ +// +// AAC team IDs: +// Army(9), Charlotte(20), ECU(27), FAU(31), Memphis(56), Navy(65), +// North Texas(72), Rice(87), South Florida(94), Temple(99), +// Tulane(107), Tulsa(108), UAB(109), UTSA(117) + +var aacTeamIDs = []uint{9, 20, 27, 31, 56, 65, 72, 87, 94, 99, 107, 108, 109, 117} + +// aacWeek14ConfLocks: conference games locked to Week 14 +var aacWeek14ConfLocks = []SchedulerHistoryKey{ + makeHistoryKey(9, 65), // Army vs Navy + makeHistoryKey(56, 109), // Memphis vs UAB +} + +// aacWeek14OOC: teams busy Week 14 with OOC rivals +var aacWeek14OOC = map[uint]bool{ + 107: true, // Tulane (vs Southern Miss) + 94: true, // South Florida (vs UCF) + 117: true, // UTSA (vs Texas State) +} + +// aacWeek14Bye: teams with a hard bye in Week 14 +var aacWeek14Bye = map[uint]bool{ + 27: true, // ECU + 31: true, // FAU + 20: true, // Charlotte + 72: true, // North Texas + 87: true, // Rice + 99: true, // Temple + 108: true, // Tulsa +} + +// GenerateAACSchedule produces all AAC conference games for the season. +func GenerateAACSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + emit := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][week] { + return + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][week] { + return + } + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Mark Week 14 busy for OOC and bye teams + for teamID := range aacWeek14OOC { + if gamesPlayedByWeekMap[teamID] == nil { + gamesPlayedByWeekMap[teamID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[teamID][14] = true + } + for teamID := range aacWeek14Bye { + if gamesPlayedByWeekMap[teamID] == nil { + gamesPlayedByWeekMap[teamID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[teamID][14] = true + } + + // Phase 1: Week 14 conference locks + for _, key := range aacWeek14ConfLocks { + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + emit(home, away, 14) + } + + // Phase 2: Rotating partial round-robin for remaining 8 conf games per team + aacTeamSet := make(map[uint]bool, len(aacTeamIDs)) + for _, id := range aacTeamIDs { + aacTeamSet[id] = true + } + confGameCount := make(map[uint]int) + // Seed from all already-scheduled AAC games (annual rivalries + Phase 1) + for _, id := range aacTeamIDs { + for oppID := range gamesPlayedAgainstOpponentsMap[id] { + if aacTeamSet[oppID] { + confGameCount[id]++ + } + } + } + + ids := sortedTeamIDs(collegeTeams) + pairs := getRoundRobinPairs(ids) + // Shuffle for variety + for i := len(pairs) - 1; i > 0; i-- { + j := i / 2 + pairs[i], pairs[j] = pairs[j], pairs[i] + } + + for _, pair := range pairs { + a, b := pair[0], pair[1] + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a] >= 8 || confGameCount[b] >= 8 { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 4, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 1, 3, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Final validation: if any team is still short, return an empty slice to + // signal the manager's retry loop to reseed and try again. + for _, teamID := range aacTeamIDs { + if confGameCount[teamID] < 8 { + return []structs.CollegeGame{} + } + } + + return games +} diff --git a/managers/CFBScheduleACC.go b/managers/CFBScheduleACC.go new file mode 100644 index 0000000..47cd3a9 --- /dev/null +++ b/managers/CFBScheduleACC.go @@ -0,0 +1,326 @@ +package managers + +import ( + "math/rand/v2" + "sort" + + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// ACC Conference Schedule Generator +// 17 teams | 9 conf games (8 for the designated team) +// Tobacco Road group plays each other every season +// Week 14 conf locks + OOC locks +// ============================================================ +// +// ACC team IDs: +// Boston College(14), California(18), Clemson(22), Duke(26), +// Florida State(32), Georgia Tech(37), Louisville(52), Miami FL(57), +// NC State(66), North Carolina(71), Pittsburgh(85), SMU(91), +// Stanford(96), Syracuse(97), Virginia(121), Virginia Tech(122), +// Wake Forest(123) + +// accTeamIDs for convenience +var accTeamIDs = []uint{14, 18, 22, 26, 32, 37, 52, 57, 66, 71, 85, 91, 96, 97, 121, 122, 123} + +// accTobaccoRoad: Duke(26), UNC(71), NC State(66), Wake Forest(123) +// All four play each other every season (6 intra-group games). +var accTobaccoRoadTeams = []uint{26, 71, 66, 123} + +// accWeek14ConfLocks: conference games always in Week 14 +var accWeek14ConfLocks = []SchedulerHistoryKey{ + makeHistoryKey(18, 96), // California vs Stanford + makeHistoryKey(71, 66), // North Carolina vs NC State + makeHistoryKey(97, 14), // Syracuse vs Boston College + makeHistoryKey(121, 122), // Virginia vs Virginia Tech +} + +// accWeek14OOCTeams: teams busy Week 14 with OOC rivals (do not schedule conf game) +var accWeek14OOCTeams = map[uint]bool{ + 32: true, // Florida State (vs Florida) + 22: true, // Clemson (vs South Carolina) + 37: true, // Georgia Tech (vs Georgia) + 52: true, // Louisville (vs Kentucky) + 85: true, // Pittsburgh (vs West Virginia) +} + +// accWeek14HardBye: teams with neither conf lock nor OOC in Week 14 +var accWeek14HardBye = map[uint]bool{ + 57: true, // Miami + 66: true, // NC State (already plays UNC in W14 conf lock) + 91: true, // SMU + 123: true, // Wake Forest +} + +// accEightGameTeamHistory: tracks which team has been given 8 instead of 9 games. +// In practice, we pick the team least-recently selected. For simulation, we derive +// from game count — the team with the most conf games in recent history gets +// the "rest" of 8 games. We always use the simple heuristic: rotate annually +// through teams sorted by ID, picking the one whose season%len cycle points to them. +func accEightGameTeamForSeason(season int) uint { + idx := season % len(accTeamIDs) + return accTeamIDs[idx] +} + +// GenerateACCSchedule produces all ACC conference games for the season. +// Returns an empty slice if Phase 4 cannot fill all required games, which signals +// the manager's retry loop to reseed and try again. +func GenerateACCSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + eightGameTeam := accEightGameTeamForSeason(season) + + teamMap := buildTeamMapFromSlice(collegeTeams) + + // Per-team max conference game counts: 9 for all teams, 8 for the designated team. + maxGameMap := make(map[uint]int, len(accTeamIDs)) + for _, id := range accTeamIDs { + maxGameMap[id] = 9 + } + maxGameMap[eightGameTeam] = 8 + + // Build conference team set for membership checks. + accTeamSet := make(map[uint]bool, len(accTeamIDs)) + for _, id := range accTeamIDs { + accTeamSet[id] = true + } + + // Pre-seed confGameCount from any conference games already placed before this + // generator runs (e.g. rivalry games between ACC teammates from the rivalry pass). + confGameCount := make(map[uint]int) + for _, teamID := range accTeamIDs { + for oppID := range gamesPlayedAgainstOpponentsMap[teamID] { + if accTeamSet[oppID] { + confGameCount[teamID]++ + } + } + } + + // Seed homecountMap from rivalry-pass home game counts so ShouldBeHome sees + // correct context from the very first conference game assignment. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + // recordGame commits a game for a week that has already been secured (either by + // assignWeek or by an explicit free-slot check). It updates all tracking maps. + // Callers must NOT call assignWeek and then pass that week to recordGame — + // assignWeek already marks the week, and recordGame marks it again (idempotent). + // For Phase 1 locked games, callers verify the week is free before calling. + recordGame := func(home, away structs.CollegeTeam, week uint) { + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Mark Week 14 unavailable for OOC and hard-bye teams before any phase runs. + // This must happen before Phase 0 so that assignWeek in Phase 0 never claims + // week 14 for any team that has an OOC or hard-bye constraint there. + for teamID := range accWeek14OOCTeams { + if gamesPlayedByWeekMap[teamID] == nil { + gamesPlayedByWeekMap[teamID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[teamID][14] = true + } + for teamID := range accWeek14HardBye { + if gamesPlayedByWeekMap[teamID] == nil { + gamesPlayedByWeekMap[teamID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[teamID][14] = true + } + + // Phase 0: Schedule the 8-game team's full conference slate before any other + // phase runs. This eliminates the cap-check asymmetry that causes ripple failures + // when the 8-game team's pairs are processed late in the shuffled round-robin. + // Once this phase completes, all subsequent phases can skip that team entirely. + // + // Week 14 conf-locked opponents are skipped here — Phase 1 owns those pairs and + // must place them at the correct week. + { + // Build the set of opponents the 8-game team has locked in Week 14 so we + // don't consume that pair in the floating window and cause Phase 1 to miss it. + week14LockedOpponents := make(map[uint]bool) + for _, key := range accWeek14ConfLocks { + if key.A == eightGameTeam { + week14LockedOpponents[key.B] = true + } else if key.B == eightGameTeam { + week14LockedOpponents[key.A] = true + } + } + + opponents := make([]uint, 0, len(accTeamIDs)-1) + for _, id := range accTeamIDs { + if id != eightGameTeam { + opponents = append(opponents, id) + } + } + rand.Shuffle(len(opponents), func(i, j int) { + opponents[i], opponents[j] = opponents[j], opponents[i] + }) + eightObj := teamMap[eightGameTeam] + for _, oppID := range opponents { + if confGameCount[eightGameTeam] >= maxGameMap[eightGameTeam] { + break + } + if week14LockedOpponents[oppID] { + continue // reserved for Phase 1 + } + if alreadyScheduled(eightGameTeam, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + oppObj := teamMap[oppID] + if oppObj.ID == 0 || eightObj.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(eightGameTeam, oppID, season, lastHomeMap, homecountMap) { + home, away = eightObj, oppObj + } else { + home, away = oppObj, eightObj + } + w := assignWeek(home.ID, away.ID, 3, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + } + + // Phase 1: Week 14 conference locks. + // Explicitly verify week 14 is free for both teams before recording. + for _, key := range accWeek14ConfLocks { + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + if alreadyScheduled(a.ID, b.ID, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a.ID] >= maxGameMap[a.ID] || confGameCount[b.ID] >= maxGameMap[b.ID] { + continue + } + if gamesPlayedByWeekMap[a.ID] != nil && gamesPlayedByWeekMap[a.ID][14] { + continue + } + if gamesPlayedByWeekMap[b.ID] != nil && gamesPlayedByWeekMap[b.ID][14] { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, lastHomeMap, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + recordGame(home, away, 14) + } + + // Phase 3: Remaining conference games via shuffled round-robin. + // Tobacco Road pairs (Duke, UNC, NC State, Wake Forest) are included in the + // general pool here rather than in a dedicated phase, so homecountMap has + // proper context when their home/away is decided and Duke's assignments are + // naturally balanced against non-Tobacco-Road games. + // getRoundRobinPairs returns a randomly shuffled list, preventing ID-ordering bias. + ids := sortedTeamIDs(collegeTeams) + pairs := getRoundRobinPairs(ids) + // Sort by historical play count ascending so least-played pairs get priority. + // Stable sort preserves the shuffle order from getRoundRobinPairs within ties. + sort.SliceStable(pairs, func(i, j int) bool { + ki := makeHistoryKey(pairs[i][0], pairs[i][1]) + kj := makeHistoryKey(pairs[j][0], pairs[j][1]) + return playCountMap[ki] < playCountMap[kj] + }) + + for _, pair := range pairs { + a, b := pair[0], pair[1] + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a] >= maxGameMap[a] || confGameCount[b] >= maxGameMap[b] { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 4, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + + // Phase 4: Validation pass — check every team's conference game count and + // attempt to fill any remaining gaps using an expanded week window (1–13). + // This catches cases where Phase 3's pair ordering left some teams short. + for _, teamID := range accTeamIDs { + if confGameCount[teamID] >= maxGameMap[teamID] { + continue + } + for _, oppID := range accTeamIDs { + if oppID == teamID { + continue + } + if confGameCount[teamID] >= maxGameMap[teamID] { + break + } + if confGameCount[oppID] >= maxGameMap[oppID] { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[teamID] + tB := teamMap[oppID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(teamID, oppID, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 1, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + } + + // Final validation: if any team still hasn't reached its target, return an + // empty slice to signal the manager's retry loop to reseed and try again. + for _, teamID := range accTeamIDs { + if confGameCount[teamID] < maxGameMap[teamID] { + return []structs.CollegeGame{} + } + } + + return games +} diff --git a/managers/CFBScheduleBig12.go b/managers/CFBScheduleBig12.go new file mode 100644 index 0000000..dfc7056 --- /dev/null +++ b/managers/CFBScheduleBig12.go @@ -0,0 +1,614 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// Big 12 Conference Schedule Generator +// 16 teams | 4 pods of 4 | 9 conf games per team +// Pod games: Weeks 7, 8, 9 (rivalry=9) +// Non-pod games: Weeks 4-9 (6 games, ≤2 consecutive away) +// ============================================================ + +// Big 12 team IDs (from college_teams_csv.csv) +// Pod Red: Arizona(5), Arizona State(6), BYU(17), Utah(118) +// Pod Yellow: Texas Tech(104), TCU(98), Houston(39), Baylor(12) +// Pod Green: Kansas(44), Kansas State(45), Oklahoma State(79), Colorado(24) +// Pod Orange: West Virginia(126), UCF(110), Cincinnati(21), Iowa State(43) + +const ( + big12PodRed = 0 + big12PodYellow = 1 + big12PodGreen = 2 + big12PodOrange = 3 +) + +var big12Pods = [4][]uint{ + {5, 6, 17, 118}, // Red + {104, 98, 39, 12}, // Yellow + {44, 45, 79, 24}, // Green + {126, 110, 21, 43}, // Orange +} + +// big12PodOf returns which pod index a team belongs to, -1 if not found. +func big12PodOf(teamID uint) int { + for p, pod := range big12Pods { + for _, id := range pod { + if id == teamID { + return p + } + } + } + return -1 +} + +// Big 12 Annual Rivalry Registry (within-pod, always Week 9) +// key = makeHistoryKey(a, b), value = true +var big12RivalryPairs = []SchedulerHistoryKey{ + makeHistoryKey(17, 118), // BYU vs Utah + makeHistoryKey(5, 6), // Arizona vs Arizona State + makeHistoryKey(12, 98), // Baylor vs TCU + makeHistoryKey(44, 45), // Kansas vs Kansas State +} + +func isBig12Rivalry(a, b uint) bool { + key := makeHistoryKey(a, b) + for _, r := range big12RivalryPairs { + if r == key { + return true + } + } + return false +} + +// big12CrossPodRotationTable defines the 6 non-pod opponents each team faces per +// season. The table is indexed by [teamID][cycleYear(1-4)] => []opponentID (6 opponents). +// Home/away: if the team is listed first in the pair for Year 1, they host in Year 1 & 3 +// and visit in Year 2 & 4 (flip on cycle years 2 & 4). +// +// Structure: rotTable[teamID] = [4][]uint (index 0 = Year1, ..., 3 = Year4) +// Each inner slice has 6 opponents. +// Home/away is indicated separately via big12CrossPodHomeYear1. +// If big12CrossPodHomeYear1[makeHistoryKey(team, opp)] == true, team hosts in Year 1. + +var big12CrossPodRotation = map[uint][4][]uint{ + // ---- Red Pod ---- + // Arizona (5): faces Yellow(2) + Green(2) + Orange(2) per year, rotating + 5: { + {104, 98, 44, 45, 126, 110}, // Year 1 + {39, 12, 79, 24, 21, 43}, // Year 2 + {104, 98, 44, 45, 126, 110}, // Year 3 (same opponents, flipped H/A) + {39, 12, 79, 24, 21, 43}, // Year 4 + }, + // Arizona State (6) + 6: { + {39, 12, 79, 24, 21, 43}, // Year 1 + {104, 98, 44, 45, 126, 110}, // Year 2 + {39, 12, 79, 24, 21, 43}, // Year 3 + {104, 98, 44, 45, 126, 110}, // Year 4 + }, + // BYU (17) + 17: { + {104, 98, 44, 45, 21, 43}, // Year 1 + {39, 12, 79, 24, 126, 110}, // Year 2 + {104, 98, 44, 45, 21, 43}, // Year 3 + {39, 12, 79, 24, 126, 110}, // Year 4 + }, + // Utah (118) + 118: { + {39, 12, 79, 24, 126, 110}, // Year 1 + {104, 98, 44, 45, 21, 43}, // Year 2 + {39, 12, 79, 24, 126, 110}, // Year 3 + {104, 98, 44, 45, 21, 43}, // Year 4 + }, + // ---- Yellow Pod ---- + // Baylor (12) + 12: { + {5, 6, 44, 45, 126, 110}, // Year 1 + {17, 118, 79, 24, 21, 43}, // Year 2 + {5, 6, 44, 45, 126, 110}, // Year 3 + {17, 118, 79, 24, 21, 43}, // Year 4 + }, + // TCU (98) + 98: { + {17, 118, 79, 24, 21, 43}, // Year 1 + {5, 6, 44, 45, 126, 110}, // Year 2 + {17, 118, 79, 24, 21, 43}, // Year 3 + {5, 6, 44, 45, 126, 110}, // Year 4 + }, + // Houston (39) + 39: { + {5, 6, 44, 45, 21, 43}, // Year 1 + {17, 118, 79, 24, 126, 110}, // Year 2 + {5, 6, 44, 45, 21, 43}, // Year 3 + {17, 118, 79, 24, 126, 110}, // Year 4 + }, + // Texas Tech (104) + 104: { + {17, 118, 79, 24, 126, 110}, // Year 1 + {5, 6, 44, 45, 21, 43}, // Year 2 + {17, 118, 79, 24, 126, 110}, // Year 3 + {5, 6, 44, 45, 21, 43}, // Year 4 + }, + // ---- Green Pod ---- + // Kansas (44) + 44: { + {5, 6, 104, 98, 126, 110}, // Year 1 + {17, 118, 39, 12, 21, 43}, // Year 2 + {5, 6, 104, 98, 126, 110}, // Year 3 + {17, 118, 39, 12, 21, 43}, // Year 4 + }, + // Kansas State (45) + 45: { + {17, 118, 39, 12, 21, 43}, // Year 1 + {5, 6, 104, 98, 126, 110}, // Year 2 + {17, 118, 39, 12, 21, 43}, // Year 3 + {5, 6, 104, 98, 126, 110}, // Year 4 + }, + // Oklahoma State (79) + 79: { + {5, 6, 104, 98, 21, 43}, // Year 1 + {17, 118, 39, 12, 126, 110}, // Year 2 + {5, 6, 104, 98, 21, 43}, // Year 3 + {17, 118, 39, 12, 126, 110}, // Year 4 + }, + // Colorado (24) + 24: { + {17, 118, 39, 12, 126, 110}, // Year 1 + {5, 6, 104, 98, 21, 43}, // Year 2 + {17, 118, 39, 12, 126, 110}, // Year 3 + {5, 6, 104, 98, 21, 43}, // Year 4 + }, + // ---- Orange Pod ---- + // West Virginia (126) + 126: { + {5, 6, 104, 98, 44, 45}, // Year 1 + {17, 118, 39, 12, 79, 24}, // Year 2 + {5, 6, 104, 98, 44, 45}, // Year 3 + {17, 118, 39, 12, 79, 24}, // Year 4 + }, + // UCF (110) + 110: { + {17, 118, 39, 12, 79, 24}, // Year 1 + {5, 6, 104, 98, 44, 45}, // Year 2 + {17, 118, 39, 12, 79, 24}, // Year 3 + {5, 6, 104, 98, 44, 45}, // Year 4 + }, + // Cincinnati (21) + 21: { + {5, 6, 104, 98, 79, 24}, // Year 1 + {17, 118, 39, 12, 44, 45}, // Year 2 + {5, 6, 104, 98, 79, 24}, // Year 3 + {17, 118, 39, 12, 44, 45}, // Year 4 + }, + // Iowa State (43) + 43: { + {17, 118, 39, 12, 44, 45}, // Year 1 + {5, 6, 104, 98, 79, 24}, // Year 2 + {17, 118, 39, 12, 44, 45}, // Year 3 + {5, 6, 104, 98, 79, 24}, // Year 4 + }, +} + +// big12CrossPodHomeYear1[makeHistoryKey(a,b)] == true means team A hosts in Year 1. +// We define the base home side (Year 1) for each cross-pod pair. +var big12CrossPodHomeYear1 = map[SchedulerHistoryKey]uint{ + // Red vs Yellow + makeHistoryKey(5, 104): 5, + makeHistoryKey(5, 98): 98, + makeHistoryKey(5, 39): 5, + makeHistoryKey(5, 12): 12, + makeHistoryKey(6, 104): 104, + makeHistoryKey(6, 98): 6, + makeHistoryKey(6, 39): 39, + makeHistoryKey(6, 12): 6, + makeHistoryKey(17, 104): 104, + makeHistoryKey(17, 98): 17, + makeHistoryKey(17, 39): 39, + makeHistoryKey(17, 12): 17, + makeHistoryKey(118, 104): 104, + makeHistoryKey(118, 98): 118, + makeHistoryKey(118, 39): 118, + makeHistoryKey(118, 12): 12, + // Red vs Green + makeHistoryKey(5, 44): 5, + makeHistoryKey(5, 45): 45, + makeHistoryKey(5, 79): 79, + makeHistoryKey(5, 24): 5, + makeHistoryKey(6, 44): 44, + makeHistoryKey(6, 45): 6, + makeHistoryKey(6, 79): 6, + makeHistoryKey(6, 24): 24, + makeHistoryKey(17, 44): 17, + makeHistoryKey(17, 45): 45, + makeHistoryKey(17, 79): 17, + makeHistoryKey(17, 24): 24, + makeHistoryKey(118, 44): 44, + makeHistoryKey(118, 45): 118, + makeHistoryKey(118, 79): 118, + makeHistoryKey(118, 24): 24, + // Red vs Orange + makeHistoryKey(5, 126): 5, + makeHistoryKey(5, 110): 110, + makeHistoryKey(5, 21): 5, + makeHistoryKey(5, 43): 43, + makeHistoryKey(6, 126): 126, + makeHistoryKey(6, 110): 6, + makeHistoryKey(6, 21): 21, + makeHistoryKey(6, 43): 6, + makeHistoryKey(17, 126): 126, + makeHistoryKey(17, 110): 17, + makeHistoryKey(17, 21): 21, + makeHistoryKey(17, 43): 17, + makeHistoryKey(118, 126): 118, + makeHistoryKey(118, 110): 110, + makeHistoryKey(118, 21): 118, + makeHistoryKey(118, 43): 43, + // Yellow vs Green + makeHistoryKey(12, 44): 12, + makeHistoryKey(12, 45): 45, + makeHistoryKey(12, 79): 12, + makeHistoryKey(12, 24): 24, + makeHistoryKey(98, 44): 44, + makeHistoryKey(98, 45): 98, + makeHistoryKey(98, 79): 79, + makeHistoryKey(98, 24): 98, + makeHistoryKey(39, 44): 39, + makeHistoryKey(39, 45): 45, + makeHistoryKey(39, 79): 79, + makeHistoryKey(39, 24): 39, + makeHistoryKey(104, 44): 44, + makeHistoryKey(104, 45): 104, + makeHistoryKey(104, 79): 104, + makeHistoryKey(104, 24): 24, + // Yellow vs Orange + makeHistoryKey(12, 126): 126, + makeHistoryKey(12, 110): 12, + makeHistoryKey(12, 21): 12, + makeHistoryKey(12, 43): 43, + makeHistoryKey(98, 126): 98, + makeHistoryKey(98, 110): 110, + makeHistoryKey(98, 21): 21, + makeHistoryKey(98, 43): 98, + makeHistoryKey(39, 126): 126, + makeHistoryKey(39, 110): 39, + makeHistoryKey(39, 21): 39, + makeHistoryKey(39, 43): 43, + makeHistoryKey(104, 126): 104, + makeHistoryKey(104, 110): 110, + makeHistoryKey(104, 21): 104, + makeHistoryKey(104, 43): 43, + // Green vs Orange + makeHistoryKey(44, 126): 44, + makeHistoryKey(44, 110): 110, + makeHistoryKey(44, 21): 44, + makeHistoryKey(44, 43): 43, + makeHistoryKey(45, 126): 45, + makeHistoryKey(45, 110): 45, + makeHistoryKey(45, 21): 21, + makeHistoryKey(45, 43): 43, + makeHistoryKey(79, 126): 126, + makeHistoryKey(79, 110): 79, + makeHistoryKey(79, 21): 79, + makeHistoryKey(79, 43): 43, + makeHistoryKey(24, 126): 126, + makeHistoryKey(24, 110): 24, + makeHistoryKey(24, 21): 21, + makeHistoryKey(24, 43): 24, +} + +// big12HomeForSeason returns whether teamID is the home team against oppID in a +// given season, based on the Year-1 base and cycle year flip. +func big12HomeForSeason(teamID, oppID uint, season int) bool { + key := makeHistoryKey(teamID, oppID) + year1Home, ok := big12CrossPodHomeYear1[key] + if !ok { + // Fallback: lower ID hosts in odd years + cy := cycleYear(season) + return (cy%2 == 1) == (teamID == key.A) + } + cy := cycleYear(season) + baseIsHome := year1Home == teamID + if cy == 1 || cy == 3 { + return baseIsHome + } + return !baseIsHome +} + +// GenerateBigTwelveSchedule produces all Big 12 conference games for the season. +func GenerateBigTwelveSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + cy := cycleYear(season) + + teamMap := buildTeamMapFromSlice(collegeTeams) + confGameCount := make(map[uint]int) + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + // Build Big 12 team set and pre-seed confGameCount from any games already placed. + var allBig12IDs []uint + big12TeamSet := make(map[uint]bool) + for _, pod := range big12Pods { + for _, id := range pod { + allBig12IDs = append(allBig12IDs, id) + big12TeamSet[id] = true + } + } + for _, id := range allBig12IDs { + for oppID := range gamesPlayedAgainstOpponentsMap[id] { + if big12TeamSet[oppID] { + confGameCount[id]++ + } + } + } + + // Helper: emit a game record + emit := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // ---------------------------------------------------------------- + // For each team, build its 9-game slate: + // Weeks 4-9: 6 non-pod games (slots 0-5, ≤2 consecutive away) + // Week 7: pod game 1 (non-rivalry) + // Week 8: pod game 2 (non-rivalry) + // Week 9: rivalry pod game (locked) + // We process pod games first (weeks 7,8,9) to lock those weeks, + // then distribute non-pod games into weeks 4-6 & remaining slots. + // ---------------------------------------------------------------- + + // Phase 1: Rivalry games (Week 9) — process once per pair + for _, rkey := range big12RivalryPairs { + a := teamMap[rkey.A] + b := teamMap[rkey.B] + if a.ID == 0 || b.ID == 0 { + continue + } + if confGameCount[rkey.A] >= 9 || confGameCount[rkey.B] >= 9 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(rkey.A, rkey.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + emit(home, away, 9) + } + + // Phase 2: Non-rivalry pod games (Weeks 7 & 8) + // Each pod: 4 teams, 6 intra-pod pairs; 4 are non-rivalry (rivalry already handled) + for _, pod := range big12Pods { + // Collect non-rivalry pairs in this pod + var nonRivalryPairs [][2]uint + for i := 0; i < len(pod); i++ { + for j := i + 1; j < len(pod); j++ { + if !isBig12Rivalry(pod[i], pod[j]) { + nonRivalryPairs = append(nonRivalryPairs, [2]uint{pod[i], pod[j]}) + } + } + } + // Assign non-rivalry pairs to weeks 7 & 8 (2 games per week for 4-team pod = 2 matchups) + weeks := []uint{7, 8} + for idx, pair := range nonRivalryPairs { + if idx >= 2 { + break + } + if confGameCount[pair[0]] >= 9 || confGameCount[pair[1]] >= 9 { + continue + } + a := teamMap[pair[0]] + b := teamMap[pair[1]] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(pair[0], pair[1], season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + w := weeks[idx] + // Check if already occupied; if so, swap weeks or find next open + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][w] { + other := weeks[1-idx] + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][other] { + // fallback overflow + w = assignWeek(home.ID, away.ID, 4, 6, gamesPlayedByWeekMap) + } else { + w = other + } + } else if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][w] { + other := weeks[1-idx] + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][other] { + w = assignWeek(home.ID, away.ID, 4, 6, gamesPlayedByWeekMap) + } else { + w = other + } + } + if w == 0 { + continue + } + emit(home, away, w) + } + } + + // Phase 3: Non-pod games (Weeks 4-6, overflow to 10 if needed) + // For each team, get their 6 non-pod opponents from the rotation table. + // Track processed pairs to avoid duplicates. + processedCrossPod := make(map[SchedulerHistoryKey]bool) + + for _, pod := range big12Pods { + for _, teamID := range pod { + if confGameCount[teamID] >= 9 { + continue + } + team := teamMap[teamID] + if team.ID == 0 { + continue + } + rotEntry, ok := big12CrossPodRotation[teamID] + if !ok { + continue + } + opponents := rotEntry[cy-1] // 0-indexed + + // Build list of (home, away, week=0) for this team's 6 opponents + // Avoid duplicating pairs already processed + type nonPodEntry struct { + home, away structs.CollegeTeam + } + var pending []nonPodEntry + for _, oppID := range opponents { + key := makeHistoryKey(teamID, oppID) + if processedCrossPod[key] { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[oppID] >= 9 { + processedCrossPod[key] = true + continue + } + opp := teamMap[oppID] + if opp.ID == 0 { + continue + } + var home, away structs.CollegeTeam + // Priority 1: balance home counts; Priority 2: big12HomeForSeason table + if homecountMap[teamID] < homecountMap[oppID] { + home, away = team, opp + } else if homecountMap[oppID] < homecountMap[teamID] { + home, away = opp, team + } else if big12HomeForSeason(teamID, oppID, season) { + home, away = team, opp + } else { + home, away = opp, team + } + pending = append(pending, nonPodEntry{home, away}) + processedCrossPod[key] = true + } + + // Schedule each pending matchup in Weeks 4-6 (overflow to 10-12) + // enforcing ≤2 consecutive away games for 'team' + consecutiveAway := 0 + for _, e := range pending { + // Determine if 'team' is away in this game + teamIsAway := e.away.ID == teamID + // Re-check caps since earlier games in the loop may have incremented counts. + if confGameCount[e.home.ID] >= 9 || confGameCount[e.away.ID] >= 9 { + continue + } + + // If 3 consecutive away, find a week where a home game can be inserted + // For simplicity: try weeks 4-6, then 10-12 as overflow + var w uint + if teamIsAway && consecutiveAway >= 2 { + // Must find home game — swap if possible, else just schedule normally + // Try to find a week; we don't swap but just push this to later + w = assignWeek(e.home.ID, e.away.ID, 4, 6, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(e.home.ID, e.away.ID, 1, 13, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + consecutiveAway = 0 + } else { + w = assignWeek(e.home.ID, e.away.ID, 4, 6, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(e.home.ID, e.away.ID, 1, 13, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + if teamIsAway { + consecutiveAway++ + } else { + consecutiveAway = 0 + } + } + emit(e.home, e.away, w) + } + } + } + + // Phase 4: Validate every Big 12 team has 9 conference games. + // Attempt to fill gaps using an expanded week window (1–13). + // confGameCount is already live from Phases 1–3. + for _, teamID := range allBig12IDs { + if confGameCount[teamID] >= 9 { + continue + } + for _, oppID := range allBig12IDs { + if oppID == teamID { + continue + } + if confGameCount[teamID] >= 9 { + break + } + if confGameCount[oppID] >= 9 { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[teamID] + tB := teamMap[oppID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(teamID, oppID, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 1, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + emit(home, away, w) + } + } + + // If any team is still short, return empty slice to trigger the manager's + // retry loop to reseed and try again. + for _, id := range allBig12IDs { + if confGameCount[id] < 9 { + return []structs.CollegeGame{} + } + } + + return games +} diff --git a/managers/CFBScheduleBigTen.go b/managers/CFBScheduleBigTen.go new file mode 100644 index 0000000..39e343f --- /dev/null +++ b/managers/CFBScheduleBigTen.go @@ -0,0 +1,275 @@ +package managers + +import ( + "sort" + + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// Big Ten Conference Schedule Generator +// 18 teams | no divisions | 9 conf games per team +// Protected annual rivalries (some Week 14, some mid-season) +// 5-year rolling cycle — coverage gap prioritisation +// ============================================================ +// +// Big Ten team IDs: +// Illinois(40), Indiana(41), Iowa(42), Maryland(55), Michigan(59), +// Michigan State(60), Minnesota(62), Nebraska(67), Northwestern(74), +// Ohio State(77), Oregon(82), Penn State(84), Purdue(86), Rutgers(88), +// UCLA(111), USC(115), Washington(124), Wisconsin(129) + +// bigTenWeek14Rivalries: pairs always played in Week 14 +var bigTenWeek14Rivalries = []struct { + key SchedulerHistoryKey + week uint +}{ + {makeHistoryKey(59, 77), 14}, // Michigan vs Ohio State + {makeHistoryKey(42, 67), 14}, // Iowa vs Nebraska + {makeHistoryKey(62, 129), 14}, // Minnesota vs Wisconsin + {makeHistoryKey(41, 86), 14}, // Indiana vs Purdue + {makeHistoryKey(40, 74), 14}, // Illinois vs Northwestern + {makeHistoryKey(55, 88), 14}, // Maryland vs Rutgers + {makeHistoryKey(111, 115), 14}, // UCLA vs USC + {makeHistoryKey(84, 60), 14}, // Penn State vs Michigan State + +} + +// bigTenMidSeasonRivalries: pairs with a traditional fixed week (not Week 14) +var bigTenMidSeasonRivalries = []struct { + key SchedulerHistoryKey + week uint +}{ + {makeHistoryKey(82, 124), 8}, // Oregon vs Washington + {makeHistoryKey(59, 60), 8}, // Michigan vs Michigan State + {makeHistoryKey(42, 129), 10}, // Iowa vs Wisconsin + {makeHistoryKey(42, 62), 8}, // Iowa vs Minnesota + {makeHistoryKey(67, 62), 6}, // Nebraska vs Minnesota + +} + +// bigTenTeamIDs for convenience +var bigTenTeamIDs = []uint{40, 41, 42, 55, 59, 60, 62, 67, 74, 77, 82, 84, 86, 88, 111, 115, 124, 129} + +// bigTenProtectedSet returns a set of all protected-pair keys. +func bigTenProtectedSet() map[SchedulerHistoryKey]uint { + m := make(map[SchedulerHistoryKey]uint) + for _, r := range bigTenWeek14Rivalries { + m[r.key] = r.week + } + for _, r := range bigTenMidSeasonRivalries { + m[r.key] = r.week + } + return m +} + +// GenerateBigTenSchedule produces all Big Ten conference games for the season. +// Returns an empty slice if Phase 4 cannot fill all required games, which signals +// the manager's retry loop to reseed and try again. +func GenerateBigTenSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + protectedSet := bigTenProtectedSet() + + bigTenTeamSet := make(map[uint]bool, len(bigTenTeamIDs)) + for _, id := range bigTenTeamIDs { + bigTenTeamSet[id] = true + } + + // Pre-seed confGameCount from any conference games already placed before this + // generator runs (e.g. annual rivalry games between Big Ten teammates from the + // rivalry pass that are already in gamesPlayedAgainstOpponentsMap). + confGameCount := make(map[uint]int) + for _, id := range bigTenTeamIDs { + for oppID := range gamesPlayedAgainstOpponentsMap[id] { + if bigTenTeamSet[oppID] { + confGameCount[id]++ + } + } + } + + // Seed homecountMap from rivalry-pass home game counts so ShouldBeHome sees + // correct context from the very first conference game assignment. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + // recordGame commits a game and updates all tracking maps. + recordGame := func(home, away structs.CollegeTeam, week uint) { + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Phase 1: Lock all protected rivalries at their designated weeks. + // Explicitly verify the week is free before recording to handle cases where + // a pre-existing rivalry-pass game has already claimed that slot. + for _, r := range bigTenWeek14Rivalries { + a := teamMap[r.key.A] + b := teamMap[r.key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + if alreadyScheduled(a.ID, b.ID, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a.ID] >= 9 || confGameCount[b.ID] >= 9 { + continue + } + if gamesPlayedByWeekMap[a.ID] != nil && gamesPlayedByWeekMap[a.ID][r.week] { + continue + } + if gamesPlayedByWeekMap[b.ID] != nil && gamesPlayedByWeekMap[b.ID][r.week] { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(r.key.A, r.key.B, season, lastHomeMap, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + recordGame(home, away, r.week) + } + for _, r := range bigTenMidSeasonRivalries { + a := teamMap[r.key.A] + b := teamMap[r.key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + if alreadyScheduled(a.ID, b.ID, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a.ID] >= 9 || confGameCount[b.ID] >= 9 { + continue + } + if gamesPlayedByWeekMap[a.ID] != nil && gamesPlayedByWeekMap[a.ID][r.week] { + continue + } + if gamesPlayedByWeekMap[b.ID] != nil && gamesPlayedByWeekMap[b.ID][r.week] { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(r.key.A, r.key.B, season, lastHomeMap, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + recordGame(home, away, r.week) + } + + // Phase 3: Fill rotating conference games via shuffled round-robin. + // getRoundRobinPairs returns a randomly shuffled list, preventing ID-ordering bias. + ids := sortedTeamIDs(collegeTeams) + pairs := getRoundRobinPairs(ids) + // Sort by historical play count ascending so least-played pairs get priority. + // Stable sort preserves the shuffle order from getRoundRobinPairs within ties. + sort.SliceStable(pairs, func(i, j int) bool { + ki := makeHistoryKey(pairs[i][0], pairs[i][1]) + kj := makeHistoryKey(pairs[j][0], pairs[j][1]) + return playCountMap[ki] < playCountMap[kj] + }) + + for _, pair := range pairs { + a, b := pair[0], pair[1] + pkey := makeHistoryKey(a, b) + if _, isProtected := protectedSet[pkey]; isProtected { + continue // already handled in Phase 1 + } + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a] >= 9 || confGameCount[b] >= 9 { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 4, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + + // Phase 4: Validation pass — check every team's conference game count and + // attempt to fill any remaining gaps with an expanded week window (1–14). + // Oregon and Washington are free in Week 14 so the full 1–14 range is valid. + // Protected pairs are skipped — they have designated weeks and should have + // been placed in Phase 1; reschedule attempts here could violate week locks. + for _, teamID := range bigTenTeamIDs { + if confGameCount[teamID] >= 9 { + continue + } + for _, oppID := range bigTenTeamIDs { + if oppID == teamID { + continue + } + if confGameCount[teamID] >= 9 { + break + } + if confGameCount[oppID] >= 9 { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + pkey := makeHistoryKey(teamID, oppID) + if _, isProtected := protectedSet[pkey]; isProtected { + continue + } + tA := teamMap[teamID] + tB := teamMap[oppID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(teamID, oppID, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 1, 14, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + } + + // Final validation: if any team is still short, return an empty slice to + // signal the manager's retry loop to reseed and try again. + for _, teamID := range bigTenTeamIDs { + if confGameCount[teamID] < 9 { + return []structs.CollegeGame{} + } + } + + return games +} diff --git a/managers/CFBScheduleCUSA.go b/managers/CFBScheduleCUSA.go new file mode 100644 index 0000000..e8dd584 --- /dev/null +++ b/managers/CFBScheduleCUSA.go @@ -0,0 +1,61 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// C-USA Conference Schedule Generator +// 10 teams | 8 conf games | generic partial round-robin +// Locked: Middle Tennessee/Western Kentucky — Week 13 +// ============================================================ +// +// C-USA team IDs: +// FIU(29), Liberty(48), Middle Tennessee(61), New Mexico State(70), +// Western Kentucky(127), Jacksonville State(132), Sam Houston State(133), +// Kennesaw State(134), Missouri State(138), Delaware(206) + +var cusaLockedMatchups = []struct { + key SchedulerHistoryKey + week uint +}{ + {makeHistoryKey(61, 127), 13}, // Middle Tennessee vs Western Kentucky +} + +// GenerateCUSASchedule produces all C-USA conference games for the season. +func GenerateCUSASchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + lockedSet := make(map[SchedulerHistoryKey]uint) + for _, l := range cusaLockedMatchups { + lockedSet[l.key] = l.week + } + + return generateGenericRoundRobinSchedule( + collegeTeams, + stadiumMap, + stadiumMapByID, + rivalryMap, + gamesPlayedAgainstOpponentsMap, + gamesPlayedByWeekMap, + playCountMap, + lastHomeMap, + homeCountSeedMap, + ts, + lockedSet, + 8, // games per team + 4, // min week + 13, // max week + 1, 13, // overflow + 0, // retrySeed + ) +} diff --git a/managers/CFBScheduleExport.go b/managers/CFBScheduleExport.go new file mode 100644 index 0000000..4d01a21 --- /dev/null +++ b/managers/CFBScheduleExport.go @@ -0,0 +1,61 @@ +package managers + +import ( + "encoding/csv" + "fmt" + "os" + "strconv" + + "github.com/CalebRose/SimFBA/structs" +) + +// ExportScheduleToCSV writes collegeGamesUpload data to a CSV file at filePath +// so the schedule can be reviewed before committing to the database. +func ExportScheduleToCSV(games []structs.CollegeGame, filePath string) error { + f, err := os.Create(filePath) + if err != nil { + return fmt.Errorf("create file: %w", err) + } + defer f.Close() + + w := csv.NewWriter(f) + defer w.Flush() + + header := []string{ + "SeasonID", "WeekID", "Week", + "HomeTeamID", "HomeTeam", + "AwayTeamID", "AwayTeam", + "IsConference", "IsDivisional", "IsRivalry", "IsNeutral", + "StadiumID", "Stadium", "City", "State", + "TimeSlot", + } + if err := w.Write(header); err != nil { + return fmt.Errorf("write header: %w", err) + } + + for _, g := range games { + row := []string{ + strconv.Itoa(g.SeasonID), + strconv.Itoa(g.WeekID), + strconv.Itoa(g.Week), + strconv.Itoa(g.HomeTeamID), + g.HomeTeam, + strconv.Itoa(g.AwayTeamID), + g.AwayTeam, + strconv.FormatBool(g.IsConference), + strconv.FormatBool(g.IsDivisional), + strconv.FormatBool(g.IsRivalryGame), + strconv.FormatBool(g.IsNeutral), + strconv.Itoa(int(g.StadiumID)), + g.Stadium, + g.City, + g.State, + g.TimeSlot, + } + if err := w.Write(row); err != nil { + return fmt.Errorf("write row: %w", err) + } + } + + return w.Error() +} diff --git a/managers/CFBScheduleHelper.go b/managers/CFBScheduleHelper.go new file mode 100644 index 0000000..f84ecd7 --- /dev/null +++ b/managers/CFBScheduleHelper.go @@ -0,0 +1,705 @@ +package managers + +import ( + "math/rand/v2" + "sort" + + "github.com/CalebRose/SimFBA/structs" +) + +// SchedulerHistoryKey uniquely identifies a (teamA, teamB) pair in a canonical +// order (lower ID first) so we can look up play counts and home/away history. +type SchedulerHistoryKey struct { + A, B uint +} + +func makeHistoryKey(a, b uint) SchedulerHistoryKey { + if a < b { + return SchedulerHistoryKey{a, b} + } + return SchedulerHistoryKey{b, a} +} + +// HistoryRecord stores how many times A (lower ID) hosted and B (higher ID) +// hosted this pair within the tracking window. +type HistoryRecord struct { + AHosted uint // games where team with lower ID was home + BHosted uint // games where team with higher ID was home +} + +// BuildScheduleHistoryMaps builds two maps from a slice of historic regular-season +// games (non-spring, non-postseason): +// - playCountMap: (teamA, teamB) -> total games played +// - homeAwayMap: (teamA, teamB) -> HistoryRecord +// - lastHomeMap: teamID -> map[opponentID]bool (true = teamID was home last time) +func BuildScheduleHistoryMaps(historicGames []structs.CollegeGame) ( + playCountMap map[SchedulerHistoryKey]int, + homeAwayMap map[SchedulerHistoryKey]HistoryRecord, + lastHomeMap map[uint]map[uint]bool, +) { + playCountMap = make(map[SchedulerHistoryKey]int) + homeAwayMap = make(map[SchedulerHistoryKey]HistoryRecord) + lastHomeMap = make(map[uint]map[uint]bool) + + // Sort oldest to newest so "last" home tracking is correct. + sorted := make([]structs.CollegeGame, len(historicGames)) + copy(sorted, historicGames) + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].SeasonID < sorted[j].SeasonID || + (sorted[i].SeasonID == sorted[j].SeasonID && sorted[i].Week < sorted[j].Week) + }) + + for _, g := range sorted { + if g.IsBowlGame || g.IsPlayoffGame || g.IsNationalChampionship || g.IsConferenceChampionship || g.IsSpringGame { + continue + } + home := uint(g.HomeTeamID) + away := uint(g.AwayTeamID) + if home == 0 || away == 0 { + continue + } + key := makeHistoryKey(home, away) + playCountMap[key]++ + rec := homeAwayMap[key] + if key.A == home { + rec.AHosted++ + } else { + rec.BHosted++ + } + homeAwayMap[key] = rec + + // update lastHomeMap + if lastHomeMap[home] == nil { + lastHomeMap[home] = make(map[uint]bool) + } + if lastHomeMap[away] == nil { + lastHomeMap[away] = make(map[uint]bool) + } + lastHomeMap[home][away] = true + lastHomeMap[away][home] = false + } + return +} + +// ShouldBeHome returns true if teamID should be the home team against oppID. +// Priority order: +// 1. homeCountMap: if one team has strictly fewer home games this session, they host. +// 2. lastHomeMap: if we have history, flip from last time. +// 3. Coin flip: (teamID + oppID + season) % 2 — deterministic per-pair per-season, +// giving ~50% home/away balance for teams with no shared play history. +// +// Pass nil for homeCountMap or lastHomeMap when those signals are unavailable. +func ShouldBeHome(teamID, oppID uint, season int, lastHomeMap map[uint]map[uint]bool, homeCountMap map[uint]int) bool { + // Priority 1: balance by home game count within the current scheduling session. + if homeCountMap != nil { + aHomes := homeCountMap[teamID] + bHomes := homeCountMap[oppID] + if aHomes < bHomes { + return true + } + if bHomes < aHomes { + return false + } + // Equal — fall through to history/parity + } + // Priority 2: flip from last known result. + if lastHomeMap[teamID] != nil { + if wasHome, ok := lastHomeMap[teamID][oppID]; ok { + return !wasHome + } + } + // Priority 3: coin flip — deterministic but varies by pair and season. + // Shift right by one bit before testing parity: the plain sum of two odd IDs + // is always even, which would produce a constant result for same-parity + // conferences (e.g. Pac-12 where every team ID is odd). The >>1 uses the + // second-to-last bit of the sum, which differs meaningfully even when all + // IDs share the same parity, giving a roughly 50/50 split across pairs. + return ((teamID+oppID+uint(season))>>1)%2 == 0 +} + +// assignWeek tries to place a floating matchup into an open week between minWeek +// and maxWeek, updating gamesPlayedByWeekMap. Returns 0 if no slot was found. +func assignWeek(homeID, awayID uint, minWeek, maxWeek uint, gamesPlayedByWeekMap map[uint]map[uint]bool) uint { + for w := maxWeek; w >= minWeek; w-- { + homeOccupied := gamesPlayedByWeekMap[homeID] != nil && gamesPlayedByWeekMap[homeID][w] + awayOccupied := gamesPlayedByWeekMap[awayID] != nil && gamesPlayedByWeekMap[awayID][w] + if !homeOccupied && !awayOccupied { + if gamesPlayedByWeekMap[homeID] == nil { + gamesPlayedByWeekMap[homeID] = make(map[uint]bool) + } + if gamesPlayedByWeekMap[awayID] == nil { + gamesPlayedByWeekMap[awayID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[homeID][w] = true + gamesPlayedByWeekMap[awayID][w] = true + return w + } + } + // If pairing still isn't made, try to find any open week for both teams up to maxWeek to avoid leaving a game unassigned. + // Check backwards from maxWeek to preserve the ideal conference window as much as possible, only using this as a last resort. + // This is a fallback to prevent deadlock in edge cases where the ideal conference window is too tight to fit all games. + if gamesPlayedByWeekMap[homeID] == nil && gamesPlayedByWeekMap[awayID] == nil { + for w := uint(13); w >= 1; w-- { + homeOccupied := gamesPlayedByWeekMap[homeID] != nil && gamesPlayedByWeekMap[homeID][w] + awayOccupied := gamesPlayedByWeekMap[awayID] != nil && gamesPlayedByWeekMap[awayID][w] + if !homeOccupied && !awayOccupied { + if gamesPlayedByWeekMap[homeID] == nil { + gamesPlayedByWeekMap[homeID] = make(map[uint]bool) + } + if gamesPlayedByWeekMap[awayID] == nil { + gamesPlayedByWeekMap[awayID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[homeID][w] = true + gamesPlayedByWeekMap[awayID][w] = true + return w + } + } + } + return 0 +} + +// markWeek marks both teams as playing in a given week (for pre-assigned locked games). +func markWeek(homeID, awayID, week uint, gamesPlayedByWeekMap map[uint]map[uint]bool) { + if gamesPlayedByWeekMap[homeID] == nil { + gamesPlayedByWeekMap[homeID] = make(map[uint]bool) + } + if gamesPlayedByWeekMap[awayID] == nil { + gamesPlayedByWeekMap[awayID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[homeID][week] = true + gamesPlayedByWeekMap[awayID][week] = true +} + +// markOpponents records that two teams have been matched against one another. +func markOpponents(homeID, awayID uint, gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool) { + if gamesPlayedAgainstOpponentsMap[homeID] == nil { + gamesPlayedAgainstOpponentsMap[homeID] = make(map[uint]bool) + } + if gamesPlayedAgainstOpponentsMap[awayID] == nil { + gamesPlayedAgainstOpponentsMap[awayID] = make(map[uint]bool) + } + gamesPlayedAgainstOpponentsMap[homeID][awayID] = true + gamesPlayedAgainstOpponentsMap[awayID][homeID] = true +} + +// alreadyScheduled returns true if the two teams have already been matched in +// the current season's opponent map. +func alreadyScheduled(a, b uint, gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool) bool { + if gamesPlayedAgainstOpponentsMap[a] == nil { + return false + } + return gamesPlayedAgainstOpponentsMap[a][b] +} + +// sortedTeamIDs returns the IDs of a team slice in ascending order. +func sortedTeamIDs(teams []structs.CollegeTeam) []uint { + ids := make([]uint, len(teams)) + for i, t := range teams { + ids[i] = t.ID + } + sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) + return ids +} + +// buildTeamMapFromSlice builds a map of ID -> CollegeTeam. +func buildTeamMapFromSlice(teams []structs.CollegeTeam) map[uint]structs.CollegeTeam { + m := make(map[uint]structs.CollegeTeam, len(teams)) + for _, t := range teams { + m[t.ID] = t + } + return m +} + +// getRoundRobinPairs returns all unique (i, j) pairs from a list of IDs, i < j. +func getRoundRobinPairs(ids []uint) [][2]uint { + var pairs [][2]uint + for i := 0; i < len(ids); i++ { + for j := i + 1; j < len(ids); j++ { + pairs = append(pairs, [2]uint{ids[i], ids[j]}) + } + } + // Proposing a shuffle. + rand.Shuffle(len(pairs), func(i, j int) { + pairs[i], pairs[j] = pairs[j], pairs[i] + }) + return pairs +} + +// cycleYear maps a global season number to a 1-4 cycle year. +func cycleYear(season int) int { + y := ((season - 1) % 4) + 1 + if y <= 0 { + y += 4 + } + return y +} + +// selectGroupForCycleYear returns true if the team should play Group A this season. +func groupAThisSeason(season int) bool { + cy := cycleYear(season) + return cy == 1 || cy == 3 +} + +// homeForThisSeason returns whether teamID should be home against oppID given +// the cycle year and a given "base" home assignment (true = teamID hosts in Year 1). +// Years 1 & 3 keep base, Years 2 & 4 flip. +func homeForCycleYear(season int, baseIsHome bool) bool { + cy := cycleYear(season) + if cy == 1 || cy == 3 { + return baseIsHome + } + return !baseIsHome +} + +// deepCopyBoolMap creates a full deep copy of a map[uint]map[uint]bool. +// Used to snapshot shared scheduling maps before retry attempts so each seed +// can be tried in isolation and the winning attempt committed cleanly. +func deepCopyBoolMap(src map[uint]map[uint]bool) map[uint]map[uint]bool { + dst := make(map[uint]map[uint]bool, len(src)) + for k, inner := range src { + innerCopy := make(map[uint]bool, len(inner)) + for ik, iv := range inner { + innerCopy[ik] = iv + } + dst[k] = innerCopy + } + return dst +} + +// generateGenericRoundRobinSchedule creates a conference schedule for any conference +// using a round-robin model with a specified game count, conference window, and +// optional locked-week rivalries (intraConf only). It obeys the global +// gamesPlayedAgainstOpponentsMap and gamesPlayedByWeekMap. +// +// lockedPairs: map of (lowID, highID) -> preferred week (0 = no lock). +// conferenceGamesPerTeam: how many conf games each team plays (< n-1 means partial round-robin). +// confWindow: [minWeek, maxWeek] for floating games. +// overflowWindow: [minWeek, maxWeek] used only if confWindow exhausted. +func generateGenericRoundRobinSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, + lockedPairs map[SchedulerHistoryKey]uint, // key -> preferred week (0 = floating) + conferenceGamesPerTeam int, + minWeek, maxWeek uint, + overflowMinWeek, overflowMaxWeek uint, + retrySeed uint, // 0 = default pair order; >0 = shuffled for retry +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + ids := sortedTeamIDs(collegeTeams) + + // Track how many conference games each team has been assigned this season. + confGameCount := make(map[uint]int) + // Seed homeCountMap from rivalry-pass home game counts so ShouldBeHome sees + // correct context from the very first conference game assignment. + homeCountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homeCountMap[id] = count + } + + // Pre-seed confGameCount from conference games already placed before this + // function runs (e.g. annual rivalry games between conference teammates that + // were scheduled in the rivalry pass and are already in gamesPlayedAgainstOpponentsMap). + for _, t := range collegeTeams { + for oppID := range gamesPlayedAgainstOpponentsMap[t.ID] { + if opp, ok := teamMap[oppID]; ok && opp.ConferenceID != 0 && opp.ConferenceID == t.ConferenceID { + confGameCount[t.ID]++ + } + } + } + + // Step 1: place locked pairs first + type lockedGame struct { + homeID, awayID uint + week uint + } + var locked []lockedGame + for key, week := range lockedPairs { + if week == 0 { + continue + } + if alreadyScheduled(key.A, key.B, gamesPlayedAgainstOpponentsMap) { + continue + } + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, lastHomeMap, homeCountMap) { + home, away = a, b + } else { + home, away = b, a + } + // Skip if either team is already playing this week (pre-existing OOC or conf game). + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][week] { + continue + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][week] { + continue + } + locked = append(locked, lockedGame{homeID: home.ID, awayID: away.ID, week: week}) + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + isConference := home.ConferenceID != 0 && home.ConferenceID == away.ConferenceID + if isConference { + confGameCount[home.ID]++ + confGameCount[away.ID]++ + } + homeCountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Step 2: floating locked pairs (week == 0 in lockedPairs but pair still required) + for key, week := range lockedPairs { + if week != 0 { + continue // already handled above + } + if alreadyScheduled(key.A, key.B, gamesPlayedAgainstOpponentsMap) { + continue + } + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + // Respect the conference game cap for floating locked pairs, same as Step 3. + if a.ConferenceID != 0 && a.ConferenceID == b.ConferenceID && + (confGameCount[key.A] >= conferenceGamesPerTeam || confGameCount[key.B] >= conferenceGamesPerTeam) { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, lastHomeMap, homeCountMap) { + home, away = a, b + } else { + home, away = b, a + } + w := assignWeek(home.ID, away.ID, minWeek, maxWeek, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, overflowMinWeek, overflowMaxWeek, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + isConference := home.ConferenceID != 0 && home.ConferenceID == away.ConferenceID + if isConference { + confGameCount[home.ID]++ + confGameCount[away.ID]++ + } + homeCountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Step 3: Fill remaining conference games + // Build a priority list of pairs, favouring least-recently-played opponents. + pairs := getRoundRobinPairs(ids) + // Sort pairs by combined play count ascending + sort.SliceStable(pairs, func(i, j int) bool { + ki := makeHistoryKey(pairs[i][0], pairs[i][1]) + kj := makeHistoryKey(pairs[j][0], pairs[j][1]) + return playCountMap[ki] < playCountMap[kj] + }) + // Always shuffle pairs to reduce ID-ordering bias. When retrySeed is 0 (first pass), + // use the season number so the order is deterministic per season but not tied to + // team IDs. Retry attempts use different seeds to vary ordering further. + { + seed := retrySeed + if seed == 0 { + seed = uint(season) + } + r := uint64(seed) * 2654435761 + for i := len(pairs) - 1; i > 0; i-- { + r = r*6364136223846793005 + 1442695040888963407 + j := int(r>>33) % (i + 1) + pairs[i], pairs[j] = pairs[j], pairs[i] + } + } + + for _, pair := range pairs { + a, b := pair[0], pair[1] + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a] >= conferenceGamesPerTeam || confGameCount[b] >= conferenceGamesPerTeam { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, lastHomeMap, homeCountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, minWeek, maxWeek, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, overflowMinWeek, overflowMaxWeek, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + isConference := home.ConferenceID != 0 && home.ConferenceID == away.ConferenceID + if isConference { + confGameCount[home.ID]++ + confGameCount[away.ID]++ + } + homeCountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Retry signal: if any team is below target, return empty slice. + // Exception: with an odd number of teams and an odd per-team target, the sum + // (n × target) is odd and cannot be divided into whole game-pairs, so exactly + // one team will always be one game short. Accept that result rather than + // burning all retry slots on an unsolvable parity problem. + // oddTeamsParity := len(ids)%2 == 1 && conferenceGamesPerTeam%2 == 1 + for _, teamID := range ids { + if confGameCount[teamID] < conferenceGamesPerTeam { + // if oddTeamsParity { + // return games // one short is the mathematical floor; accept it + // } + return []structs.CollegeGame{} + } + } + + return games +} + +// MissingGame records a conference matchup that ValidateAndRescueConference +// could not fit into any available week. +type MissingGame struct { + ConferenceID int + TeamAID uint + TeamBID uint + Reason string +} + +// ConferenceExpectedGames maps conference ID to the minimum number of conference +// games every team in that conference should play. Used by the validation pass. +var ConferenceExpectedGames = map[int]int{ + 3: 8, // ACC (one designated team plays 8, rest play 9; floor is 8) + 4: 9, // Big Ten + 5: 9, // Big 12 + 6: 7, // Pac-12 + 7: 9, // SEC + 8: 8, // AAC + 9: 8, // C-USA + 10: 8, // MAC (3 intra-pod + 6 cross-pod = 9 per MAC code design) + 11: 8, // MWC + 12: 8, // Sun Belt + 14: 8, // MVFC + 15: 7, // Patriot + 16: 8, // Big Sky + 17: 7, // Ivy League + 18: 9, // SoCon + 19: 8, // SWAC + 20: 7, // Big South-OVC + 21: 8, // CAA + 23: 5, // MEAC + 24: 8, // NEC + 25: 8, // Pioneer (11 teams × 9 target = 99 slots / 2 = non-integer; one team always gets 8) + 26: 8, // Southland + 27: 7, // UAC +} + +// rebalanceConferenceHomeAway performs a multi-pass greedy swap of home/away +// roles for conference games where the current home team is home-heavy and the +// current away team is away-heavy. The goal is to bring every team's +// |home − away| conference game count to ≤ 2. +// +// Neutral-site and rivalry games are never swapped. The game record (stadium, +// city, timeslot, etc.) is fully rebuilt from the new home team's data for +// every swapped pair. +func rebalanceConferenceHomeAway( + games []structs.CollegeGame, + teamMap map[uint]structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, +) []structs.CollegeGame { + const maxPasses = 20 + for pass := 0; pass < maxPasses; pass++ { + // Recount home/away at the start of each pass. + homeCount := make(map[uint]int) + awayCount := make(map[uint]int) + for _, g := range games { + if !g.IsConference || g.IsNeutral { + continue + } + homeCount[uint(g.HomeTeamID)]++ + awayCount[uint(g.AwayTeamID)]++ + } + + swapMade := false + for i, g := range games { + if !g.IsConference || g.IsNeutral { + continue + } + rivalries := rivalryMap[uint(g.HomeTeamID)] + isAnnualRivalry := false + for _, r := range rivalries { + if (r.TeamOneID == uint(g.AwayTeamID) || r.TeamTwoID == uint(g.AwayTeamID)) && r.IsAnnualRivalry { + isAnnualRivalry = true + break + } + } + if isAnnualRivalry { + continue + } + homeID := uint(g.HomeTeamID) + awayID := uint(g.AwayTeamID) + + // homeDiff > 0: current home team has more home than away conf games. + homeDiff := homeCount[homeID] - awayCount[homeID] + + // Only bother swapping when the home team is noticeably home-heavy. + if homeDiff <= 0 { + continue + } + + // Compute what the away team's imbalance would look like after + // the swap: they gain 1 home game and lose 1 away game. + // postSwapAwayDiff = (homeCount[away]+1) − (awayCount[away]−1) + // = homeCount[away] − awayCount[away] + 2 + // We allow the swap as long as the away team doesn't end up with + // a home-heavy diff > 2 (i.e. worse than acceptable). + postSwapAwayDiff := (homeCount[awayID] + 1) - (awayCount[awayID] - 1) + if postSwapAwayDiff > 3 { + continue + } + + newHome := teamMap[awayID] + newAway := teamMap[homeID] + if newHome.ID == 0 || newAway.ID == 0 { + continue + } + games[i] = MakeCollegeGameRecord(newHome, newAway, uint(g.Week), uint(g.SeasonID), stadiumMap, stadiumMapByID, rivalryMap) + // Update running counts immediately so later games in this pass + // see the corrected state rather than the pre-swap state. + homeCount[homeID]-- + awayCount[homeID]++ + homeCount[awayID]++ + awayCount[awayID]-- + swapMade = true + } + if !swapMade { + break + } + } + return games +} + +// ValidateAndRescueConference verifies every team in the conference has at least +// expectedGames conference games scheduled. For any team that is short, it tries +// to add games vs unplayed conference opponents using the full week 1–14 window. +// Returns newly created rescue games and any pairs that still cannot be scheduled. +func ValidateAndRescueConference( + conferenceID int, + expectedGames int, + teams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + seasonID uint, + season int, +) ([]structs.CollegeGame, []MissingGame) { + rescueGames := []structs.CollegeGame{} + var missing []MissingGame + + if len(teams) == 0 { + return rescueGames, missing + } + + // Build a set of conference team IDs for fast membership checks. + confTeamSet := make(map[uint]bool, len(teams)) + for _, t := range teams { + confTeamSet[t.ID] = true + } + teamMap := buildTeamMapFromSlice(teams) + + // Count conference games already scheduled for each team. + confGameCount := make(map[uint]int, len(teams)) + for _, t := range teams { + for oppID := range gamesPlayedAgainstOpponentsMap[t.ID] { + if confTeamSet[oppID] { + confGameCount[t.ID]++ + } + } + } + + // Track which pairs we've already attempted to avoid double-scheduling. + rescuedPairs := make(map[SchedulerHistoryKey]bool) + + for _, t := range teams { + if confGameCount[t.ID] >= expectedGames { + continue + } + for _, opp := range teams { + if opp.ID == t.ID { + continue + } + if confGameCount[t.ID] >= expectedGames { + break + } + if alreadyScheduled(t.ID, opp.ID, gamesPlayedAgainstOpponentsMap) { + continue + } + key := makeHistoryKey(t.ID, opp.ID) + if rescuedPairs[key] { + continue + } + rescuedPairs[key] = true + if confGameCount[opp.ID] >= expectedGames { + continue + } + + var home, away structs.CollegeTeam + if ShouldBeHome(t.ID, opp.ID, season, nil, nil) { + home, away = teamMap[t.ID], teamMap[opp.ID] + } else { + home, away = teamMap[opp.ID], teamMap[t.ID] + } + + w := assignWeek(home.ID, away.ID, 1, 14, gamesPlayedByWeekMap) + if w == 0 { + missing = append(missing, MissingGame{ + ConferenceID: conferenceID, + TeamAID: t.ID, + TeamBID: opp.ID, + Reason: "no open week available in 1-14 for both teams", + }) + continue + } + + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + rescueGames = append(rescueGames, g) + } + } + + return rescueGames, missing +} diff --git a/managers/CFBScheduleMAC.go b/managers/CFBScheduleMAC.go new file mode 100644 index 0000000..3ac7286 --- /dev/null +++ b/managers/CFBScheduleMAC.go @@ -0,0 +1,226 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// MAC Conference Schedule Generator +// 13 teams | 4 pods | each team plays all pod-mates every year +// Cross-pod rotation ensures every team meets at least once in 4 years +// Locked Week 14: Akron/Kent, BG/Toledo, CMU/WMU, Buffalo/UMass, Miami OH/Ohio +// Locked Week 13: BG/Sacramento State +// ============================================================ +// +// MAC team IDs: +// Pod 1 (East-A): Akron(2), Buffalo(16), Kent State(46), UMass(113) +// Pod 2 (East-B): Ball State(11), Miami OH(58), Ohio(76) +// Pod 3 (West-A): Bowling Green(15), Sacramento State(164), Toledo(105) +// Pod 4 (West-B): CMU(19), EMU(28), WMU(128) + +var macPods = [4][]uint{ + {2, 16, 46, 113}, // Pod 1 + {11, 58, 76}, // Pod 2 + {15, 164, 105}, // Pod 3 + {19, 28, 128}, // Pod 4 +} + +func macPodOf(teamID uint) int { + for p, pod := range macPods { + for _, id := range pod { + if id == teamID { + return p + } + } + } + return -1 +} + +// macWeek14Locks: conf game locks in Week 14 +var macWeek14Locks = []SchedulerHistoryKey{ + makeHistoryKey(2, 46), // Akron vs Kent State + makeHistoryKey(15, 105), // Bowling Green vs Toledo + makeHistoryKey(19, 128), // CMU vs WMU + makeHistoryKey(16, 113), // Buffalo vs UMass + makeHistoryKey(58, 76), // Miami OH vs Ohio +} + +// macWeek13Locks: conf game locks in Week 13 +var macWeek13Locks = []SchedulerHistoryKey{ + makeHistoryKey(15, 164), // BG vs Sacramento State +} + +// macCrossRotation defines which 2 additional pods each pod faces per cycle year. +// Index: [podIndex][cycleYear-1] => other pod indices to play cross games against +var macCrossRotation = [4][4][]int{ + {{1, 2}, {1, 3}, {2, 3}, {1, 2}}, // Pod 0 plays pods... + {{0, 2}, {0, 3}, {0, 2}, {0, 3}}, // Pod 1 + {{0, 3}, {1, 3}, {0, 1}, {0, 3}}, // Pod 2 + {{1, 2}, {0, 2}, {0, 1}, {1, 2}}, // Pod 3 +} + +// GenerateMACSchedule produces all MAC conference games for the season. +func GenerateMACSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + cy := cycleYear(season) + + teamMap := buildTeamMapFromSlice(collegeTeams) + + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + emit := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][week] { + return + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][week] { + return + } + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Phase 1: Locked games + allLocked := make(map[SchedulerHistoryKey]bool) + for _, key := range macWeek14Locks { + allLocked[key] = true + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + emit(home, away, 14) + } + for _, key := range macWeek13Locks { + allLocked[key] = true + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + emit(home, away, 13) + } + + // Phase 2: Intra-pod games (all pod-mates every season, non-locked) + for _, pod := range macPods { + for i := 0; i < len(pod); i++ { + for j := i + 1; j < len(pod); j++ { + a := pod[i] + b := pod[j] + key := makeHistoryKey(a, b) + if allLocked[key] { + continue // week already set + } + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 5, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 1, 4, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + } + } + + // Phase 3: Cross-pod games based on rotation + crossProcessed := make(map[SchedulerHistoryKey]bool) + for podIdx, pod := range macPods { + otherPodIndices := macCrossRotation[podIdx][cy-1] + for _, oppPodIdx := range otherPodIndices { + oppPod := macPods[oppPodIdx] + for _, teamID := range pod { + for _, oppID := range oppPod { + key := makeHistoryKey(teamID, oppID) + if crossProcessed[key] { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + crossProcessed[key] = true + continue + } + tA := teamMap[teamID] + tB := teamMap[oppID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(teamID, oppID, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 5, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 1, 13, gamesPlayedByWeekMap) + } + if w == 0 { + crossProcessed[key] = true + continue + } + crossProcessed[key] = true + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + } + } + } + + return games +} diff --git a/managers/CFBScheduleMWC.go b/managers/CFBScheduleMWC.go new file mode 100644 index 0000000..a7d8bfa --- /dev/null +++ b/managers/CFBScheduleMWC.go @@ -0,0 +1,66 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// MWC Conference Schedule Generator +// 10 teams | 8 conf games per season (not full round-robin) +// Locked: UNLV/Nevada Week 14, Wyoming/Hawaii Week 13, +// Hawaii/San Jose State Week 4 +// ============================================================ +// +// MWC team IDs: +// Air Force(1), Hawaii(38), Nevada(68), New Mexico(69), +// Northern Illinois(73), San Jose State(90), UNLV(114), +// UTEP(116), Wyoming(130), North Dakota State(143) + +var mwcTeamIDs = []uint{1, 38, 68, 69, 73, 90, 114, 116, 130, 143} + +// mwcLockedMatchups: pairs with a specific week assignment +var mwcLockedMatchups = []struct { + key SchedulerHistoryKey + week uint +}{ + {makeHistoryKey(114, 68), 14}, // UNLV vs Nevada + {makeHistoryKey(130, 38), 13}, // Wyoming vs Hawaii + {makeHistoryKey(38, 90), 4}, // Hawaii vs San Jose State +} + +func GenerateMWCSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + lockedSet := make(map[SchedulerHistoryKey]uint) + for _, l := range mwcLockedMatchups { + lockedSet[l.key] = l.week + } + + return generateGenericRoundRobinSchedule( + collegeTeams, + stadiumMap, + stadiumMapByID, + rivalryMap, + gamesPlayedAgainstOpponentsMap, + gamesPlayedByWeekMap, + playCountMap, + lastHomeMap, + homeCountSeedMap, + ts, + lockedSet, + 8, // games per team + 4, // min week + 13, // max week + 1, 14, // overflow + 0, // retrySeed + ) +} diff --git a/managers/CFBScheduleManager.go b/managers/CFBScheduleManager.go new file mode 100644 index 0000000..ba0c8af --- /dev/null +++ b/managers/CFBScheduleManager.go @@ -0,0 +1,387 @@ +package managers + +import ( + "fmt" + "sort" + + "github.com/CalebRose/SimFBA/dbprovider" + "github.com/CalebRose/SimFBA/repository" + "github.com/CalebRose/SimFBA/structs" + "github.com/CalebRose/SimFBA/util" +) + +func BaseGenerateCFBSchedule(testTheData bool) { + db := dbprovider.GetInstance().GetDB() + ts := GetTimestamp() + + collegeTeams := GetAllCollegeTeams() + collegeTeamMap := MakeCollegeTeamMap(collegeTeams) + collegeTeamsByConference := MakeCollegeTeamsByConference(collegeTeams) + allHistoricGames := GetAllCollegeGames() + playCountMap, _, lastHomeMap := BuildScheduleHistoryMaps(allHistoricGames) + + stadium := GetAllStadiums() + stadiumMap := MakeStadiumMapByTeamID(stadium, true) + stadiumMapByID := MakeStadiumMapByID(stadium) + + rivalries := GetAllRivalries() + rivalryMap := MakeHistoricRivalriesMapByTeamID(rivalries) + + gamesPlayedAgainstOpponentsMap := make(map[uint]map[uint]bool) // teamID -> opponentID -> bool + gamesPlayedByWeekMap := make(map[uint]map[uint]bool) // teamID -> week -> bool + // homeCountSeedMap tracks how many times each team was the home team in the + // OOC rivalry pass. This is forwarded to conference generators so they can + // seed their homecountMap with pre-existing home game counts and avoid + // accidentally over-scheduling home games for teams that are already "home-heavy". + homeCountSeedMap := make(map[uint]int) + + collegeGamesUpload := []structs.CollegeGame{} + + // Iterate through rivalry games first to ensure that annual games will be generated + for _, rivalry := range rivalries { + if !rivalry.IsAnnualRivalry { + continue + } + // Skip annual rivalries that have no preferred week — the conference + // scheduler will handle them as floating locked pairs. + if rivalry.PreferredWeek == 0 { + continue + } + homeTeam := collegeTeamMap[rivalry.TeamOneID] + awayTeam := collegeTeamMap[rivalry.TeamTwoID] + if homeTeam.ID == 0 || awayTeam.ID == 0 { + continue + } + if ts.Season%2 == 0 { + homeTeam, awayTeam = awayTeam, homeTeam + } + preferredWeek := rivalry.PreferredWeek + // Notre Dame vs USC + if rivalry.ID == 233 { + // If it's an odd year, USC and Notre Dame play in week 14 at USC + if ts.Season%2 != 0 { + preferredWeek = 14 + } + } + // Stanford vs USC + if rivalry.ID == 274 { + // If it's an odd year, Stanford and Notre Dame play in week 4 at Notre Dame + if ts.Season%2 != 0 { + preferredWeek = 4 + } + } + rivalryGame := MakeCollegeGameRecord(homeTeam, awayTeam, uint(preferredWeek), uint(ts.CollegeSeasonID), stadiumMap, stadiumMapByID, rivalryMap) + + collegeGamesUpload = append(collegeGamesUpload, rivalryGame) + // Update nested map data structures + if gamesPlayedAgainstOpponentsMap[homeTeam.ID] == nil { + gamesPlayedAgainstOpponentsMap[homeTeam.ID] = make(map[uint]bool) + } + if gamesPlayedAgainstOpponentsMap[awayTeam.ID] == nil { + gamesPlayedAgainstOpponentsMap[awayTeam.ID] = make(map[uint]bool) + } + gamesPlayedAgainstOpponentsMap[homeTeam.ID][awayTeam.ID] = true + gamesPlayedAgainstOpponentsMap[awayTeam.ID][homeTeam.ID] = true + if gamesPlayedByWeekMap[homeTeam.ID] == nil { + gamesPlayedByWeekMap[homeTeam.ID] = make(map[uint]bool) + } + if gamesPlayedByWeekMap[awayTeam.ID] == nil { + gamesPlayedByWeekMap[awayTeam.ID] = make(map[uint]bool) + } + // Use the week NUMBER (not WeekID) so conference schedulers can see these slots as occupied. + gamesPlayedByWeekMap[homeTeam.ID][uint(rivalryGame.Week)] = true + gamesPlayedByWeekMap[awayTeam.ID][uint(rivalryGame.Week)] = true + // Track home team for seeding conference generators' homecountMap. + homeCountSeedMap[homeTeam.ID]++ + } + + // Generate Conference Schedules + + conferenceGames := BaseGenerateCFBConferenceSchedule(collegeTeamMap, collegeTeamsByConference, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + collegeGamesUpload = append(collegeGamesUpload, conferenceGames...) + + // Sort by week ID for easier reading in CSV output + sort.Slice(collegeGamesUpload, func(i, j int) bool { + // Sort by week ID and then timeslot and then home team ID for consistent ordering + if collegeGamesUpload[i].WeekID != collegeGamesUpload[j].WeekID { + return collegeGamesUpload[i].WeekID < collegeGamesUpload[j].WeekID + } + if collegeGamesUpload[i].TimeSlot != collegeGamesUpload[j].TimeSlot { + return collegeGamesUpload[i].TimeSlot < collegeGamesUpload[j].TimeSlot + } + return collegeGamesUpload[i].HomeTeamID < collegeGamesUpload[j].HomeTeamID + }) + + // Conduct Upload + if testTheData { + exportPath := fmt.Sprintf("schedule_preview_season_%d.csv", ts.Season) + if err := ExportScheduleToCSV(collegeGamesUpload, exportPath); err != nil { + fmt.Printf("CSV export failed: %v\n", err) + } else { + fmt.Printf("Schedule preview exported to %s (%d total games)\n", exportPath, len(collegeGamesUpload)) + } + } else { + repository.CreateCFBGameRecordsBatch(db, collegeGamesUpload, 200) + } +} + +// BaseGenerateCFBConferenceSchedule generates conference games for every conference, +// processing one conference at a time (partition approach). After each conference's +// primary generation, a validation pass checks that every team has the expected +// number of conference games and attempts to schedule any missing matchups. +func BaseGenerateCFBConferenceSchedule(collegeTeamMap map[uint]structs.CollegeTeam, collegeTeamsByConference map[int][]structs.CollegeTeam, stadiumMap map[uint]structs.Stadium, stadiumMapByID map[uint]structs.Stadium, rivalryMap map[uint][]structs.CollegeRival, gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, gamesPlayedByWeekMap map[uint]map[uint]bool, playCountMap map[SchedulerHistoryKey]int, lastHomeMap map[uint]map[uint]bool, homeCountSeedMap map[uint]int, ts structs.Timestamp) []structs.CollegeGame { + allConferenceGames := []structs.CollegeGame{} + // IDs 22 and 13 are excluded because these are independent conferences + // 3=ACC, 4=Big Ten, 5=Big 12, 6=Pac-12, 7=SEC, 8=AAC, 9=C-USA, 10=MAC, + // 11=MWC, 12=Sun Belt, 14=MVFC, 15=Patriot, 16=Big Sky, 17=Ivy, + // 18=SoCon, 19=SWAC, 20=Big South-OVC, 21=CAA, 23=MEAC, 24=NEC, + // 25=Pioneer, 26=Southland, 27=UAC + conferenceIDs := []int{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27} + + var allMissing []MissingGame + + // smallConferenceIDs is the set of FCS/small-conference IDs that use the + // generic round-robin generator and are eligible for multi-seed retry. + smallConferenceIDs := map[int]bool{ + 3: true, // ACC — generator returns empty slice on failure to trigger reseed + 4: true, // Big Ten — generator returns empty slice on failure to trigger reseed + 5: false, // Big 12 — generator returns empty slice on failure to trigger reseed + 7: true, // SEC — generator returns empty slice on failure to trigger reseed + 8: true, // AAC — generator returns empty slice on failure to trigger reseed + 9: true, // CUSA — generator returns empty slice on failure to trigger reseed + 10: true, + 11: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, + 20: true, 21: true, 23: true, 24: true, 25: true, 26: true, 27: true, + } + const maxSmallConfRetries = 10000 + + for _, conferenceID := range conferenceIDs { + teams := collegeTeamsByConference[conferenceID] + if len(teams) == 0 { + continue + } + + expected, ok := ConferenceExpectedGames[conferenceID] + if !ok { + expected = 8 + } + + if smallConferenceIDs[conferenceID] { + // --- Small conference: try up to maxSmallConfRetries seeds --- + // Each seed shuffles the pair-processing order differently, changing + // which weeks are claimed first and potentially resolving edge cases + // where certain team pairs cannot find a shared free week. + var bestGames []structs.CollegeGame + var bestMissing []MissingGame + var bestOppMap map[uint]map[uint]bool + var bestWeekMap map[uint]map[uint]bool + bestMissingCount := 999999 + + for seed := uint(0); seed < maxSmallConfRetries; seed++ { + oppClone := deepCopyBoolMap(gamesPlayedAgainstOpponentsMap) + weekClone := deepCopyBoolMap(gamesPlayedByWeekMap) + + cGames := dispatchConferenceGenerator(conferenceID, seed, teams, stadiumMap, stadiumMapByID, rivalryMap, oppClone, weekClone, playCountMap, lastHomeMap, homeCountSeedMap, ts) + if len(cGames) == 0 { + // Generator returned empty slice — signals a failed attempt (e.g. ACC 8-game + // asymmetry unresolvable, or Big Ten week-exhaustion). Decrement seed so the + // outer loop increment lands on the same seed value, effectively retrying + // with a fresh rand.Shuffle ordering without burning a retry slot. + seed-- + continue + } + rGames, missing := ValidateAndRescueConference( + conferenceID, expected, teams, + stadiumMap, stadiumMapByID, rivalryMap, + oppClone, weekClone, + uint(ts.CollegeSeasonID), ts.Season, + ) + total := append(cGames, rGames...) + if len(missing) < bestMissingCount { + bestMissingCount = len(missing) + bestGames = total + bestMissing = missing + bestOppMap = oppClone + bestWeekMap = weekClone + } + if bestMissingCount == 0 { + break + } + } + + // Commit the winning attempt's maps back into the shared maps. + for k := range gamesPlayedAgainstOpponentsMap { + delete(gamesPlayedAgainstOpponentsMap, k) + } + for k, v := range bestOppMap { + gamesPlayedAgainstOpponentsMap[k] = v + } + for k := range gamesPlayedByWeekMap { + delete(gamesPlayedByWeekMap, k) + } + for k, v := range bestWeekMap { + gamesPlayedByWeekMap[k] = v + } + + allConferenceGames = append(allConferenceGames, bestGames...) + logConferenceGameCountIssues(conferenceID, expected, teams, gamesPlayedAgainstOpponentsMap) + if len(bestMissing) > 0 { + fmt.Printf("SCHEDULE RESCUE: conf %d — %d unresolvable game(s) after %d attempts\n", conferenceID, len(bestMissing), maxSmallConfRetries) + allMissing = append(allMissing, bestMissing...) + } + } else { + // --- Large conference: single pass --- + confGames := dispatchConferenceGenerator(conferenceID, 0, teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + allConferenceGames = append(allConferenceGames, confGames...) + + rescueGames, missing := ValidateAndRescueConference( + conferenceID, expected, teams, + stadiumMap, stadiumMapByID, rivalryMap, + gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, + uint(ts.CollegeSeasonID), ts.Season, + ) + if len(rescueGames) > 0 { + fmt.Printf("SCHEDULE RESCUE: conf %d — added %d game(s) in rescue pass\n", conferenceID, len(rescueGames)) + allConferenceGames = append(allConferenceGames, rescueGames...) + } + allMissing = append(allMissing, missing...) + logConferenceGameCountIssues(conferenceID, expected, teams, gamesPlayedAgainstOpponentsMap) + } + } + + if len(allMissing) > 0 { + fmt.Printf("SCHEDULE VALIDATION: %d unresolvable matchup(s) after rescue:\n", len(allMissing)) + for _, m := range allMissing { + fmt.Printf(" Conf %d: team %d vs team %d — %s\n", m.ConferenceID, m.TeamAID, m.TeamBID, m.Reason) + } + } + + // Rebalance home/away within all conference games so that every team ends + // up with |home − away| ≤ 2. Neutral-site and rivalry games are left + // untouched. Swapped pairs are rebuilt with the new home team's stadium + // and timeslot. + // Rerun a few more times to achieve better balance, as each pass may only fix some of the imbalances. + // Commenting out for now as it can cause issues with certain conferences (e.g. Big Ten) where the conference generator is already struggling to find any valid schedule, and the rebalance pass can break some of the delicate balance achieved by the conference generator's retry loop. + // for i := 0; i < 25; i++ { + // allConferenceGames = rebalanceConferenceHomeAway(allConferenceGames, collegeTeamMap, stadiumMap, stadiumMapByID, rivalryMap) + // } + + return allConferenceGames +} + +// dispatchConferenceGenerator routes a conference ID to its dedicated scheduler. +// retrySeed is forwarded to small-conference generators to vary pair ordering on retry. +func dispatchConferenceGenerator(conferenceID int, retrySeed uint, teams []structs.CollegeTeam, stadiumMap map[uint]structs.Stadium, stadiumMapByID map[uint]structs.Stadium, rivalryMap map[uint][]structs.CollegeRival, gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, gamesPlayedByWeekMap map[uint]map[uint]bool, playCountMap map[SchedulerHistoryKey]int, lastHomeMap map[uint]map[uint]bool, homeCountSeedMap map[uint]int, ts structs.Timestamp) []structs.CollegeGame { + switch conferenceID { + case 3: + return GenerateACCSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 4: + return GenerateBigTenSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 5: + return GenerateBigTwelveSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 6: + return GeneratePacTwelveSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 7: + return GenerateSECSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 8: + return GenerateAACSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 9: + return GenerateCUSASchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + // case 10: + // return GenerateMACSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 11: + return GenerateMWCSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + case 12: + return GenerateSunBeltSchedule(teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + default: + return GenerateSmallConferenceSchedule(conferenceID, retrySeed, teams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + } +} + +// logConferenceGameCountIssues prints a per-team warning for any team in the +// conference that ends up SHORT or OVER the expected conference game count. +// Call this after the primary generator and rescue pass have both been committed. +func logConferenceGameCountIssues(conferenceID int, expected int, teams []structs.CollegeTeam, gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool) { + confSet := make(map[uint]bool, len(teams)) + for _, t := range teams { + confSet[t.ID] = true + } + hasIssue := false + for _, t := range teams { + count := 0 + for oppID := range gamesPlayedAgainstOpponentsMap[t.ID] { + if confSet[oppID] { + count++ + } + } + if count < expected { + fmt.Printf(" CONF %d SHORT: %s (id=%d) %d/%d conf games\n", conferenceID, t.TeamName, t.ID, count, expected) + hasIssue = true + } else if count > expected { + fmt.Printf(" CONF %d OVER: %s (id=%d) %d/%d conf games\n", conferenceID, t.TeamName, t.ID, count, expected) + hasIssue = true + } + } + if hasIssue { + fmt.Printf(" CONF %d: expected %d conf games per team\n", conferenceID, expected) + } +} + +// Helper functions +func MakeCollegeGameRecord(homeTeam structs.CollegeTeam, awayTeam structs.CollegeTeam, week uint, seasonID uint, stadiumMap map[uint]structs.Stadium, stadiumMapByID map[uint]structs.Stadium, rivalryMap map[uint][]structs.CollegeRival) structs.CollegeGame { + homeStadium := stadiumMap[homeTeam.ID] + rivalry := rivalryMap[homeTeam.ID] + weekPlayed := week + isRivalry := false + isNeutral := false + stadiumID := homeStadium.ID + timeSlot := "" + for _, r := range rivalry { + if (r.TeamOneID == homeTeam.ID && r.TeamTwoID == awayTeam.ID) || (r.TeamOneID == awayTeam.ID && r.TeamTwoID == homeTeam.ID) { + isRivalry = true + if r.PreferredWeek > 0 { + weekPlayed = uint(r.PreferredWeek) + } + if len(r.Timeslot) > 0 { + timeSlot = r.Timeslot + } + if r.IsNeutralSite { + isNeutral = true + stadiumID = r.StadiumID + homeStadium = stadiumMapByID[r.StadiumID] + } + break + } + } + + if timeSlot == "" { + timeSlot = util.GetTimeslot(homeTeam.State, uint(homeTeam.ConferenceID)) + } + + isDivision := false + if homeTeam.DivisionID > 0 && homeTeam.DivisionID == awayTeam.DivisionID { + isDivision = true + } + + weekID := util.GetWeekID(seasonID, weekPlayed) + + return structs.CollegeGame{ + HomeTeamID: int(homeTeam.ID), + HomeTeam: homeTeam.TeamName, + AwayTeamID: int(awayTeam.ID), + AwayTeam: awayTeam.TeamName, + Week: int(weekPlayed), + SeasonID: int(seasonID), + WeekID: int(weekID), + StadiumID: stadiumID, + Stadium: homeStadium.StadiumName, + City: homeStadium.City, + State: homeStadium.State, + IsRivalryGame: isRivalry, + IsConference: homeTeam.ConferenceID == awayTeam.ConferenceID, + IsDivisional: isDivision, + TimeSlot: timeSlot, + Region: homeStadium.Region, + IsNeutral: isNeutral, + } +} diff --git a/managers/CFBSchedulePac12.go b/managers/CFBSchedulePac12.go new file mode 100644 index 0000000..d24789b --- /dev/null +++ b/managers/CFBSchedulePac12.go @@ -0,0 +1,136 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// Pac-12 Conference Schedule Generator +// 8 teams | full round-robin (7 conf games each) | 5 OOC +// Locked games: +// Boise State/Fresno State — Week 14 +// SDSU/Fresno State — Week 4 +// Oregon State/Wazzu — Week 13 +// ============================================================ +// +// Pac-12 team IDs: +// Boise State(13), Colorado State(25), Fresno State(33), +// Oregon State(83), San Diego State(89), Texas State(103), +// Utah State(119), Washington State(125) + +var pacTwelveTeamIDs = []uint{13, 25, 33, 83, 89, 103, 119, 125} + +// pac12LockedMatchups: pairs with a specific week assignment +var pac12LockedMatchups = []struct { + key SchedulerHistoryKey + week uint +}{ + {makeHistoryKey(13, 33), 14}, // Boise State vs Fresno State + {makeHistoryKey(33, 89), 4}, // SDSU vs Fresno State + {makeHistoryKey(83, 125), 13}, // Oregon State vs Washington State +} + +// GeneratePacTwelveSchedule produces all Pac-12 conference games for the season. +func GeneratePacTwelveSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + lockedSet := make(map[SchedulerHistoryKey]uint) + for _, l := range pac12LockedMatchups { + lockedSet[l.key] = l.week + } + + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + emit := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][week] { + return + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][week] { + return + } + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Phase 1: Locked games + for _, l := range pac12LockedMatchups { + a := teamMap[l.key.A] + b := teamMap[l.key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(l.key.A, l.key.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + emit(home, away, l.week) + } + + // Phase 2: Full round-robin for remaining pairs + for i := 0; i < len(pacTwelveTeamIDs); i++ { + for j := i + 1; j < len(pacTwelveTeamIDs); j++ { + a := pacTwelveTeamIDs[i] + b := pacTwelveTeamIDs[j] + key := makeHistoryKey(a, b) + if _, locked := lockedSet[key]; locked { + continue + } + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 5, 12, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 3, 4, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + } + + return games +} diff --git a/managers/CFBScheduleSEC.go b/managers/CFBScheduleSEC.go new file mode 100644 index 0000000..809b17c --- /dev/null +++ b/managers/CFBScheduleSEC.go @@ -0,0 +1,362 @@ +package managers + +import ( + "math/rand/v2" + "sort" + + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// SEC Conference Schedule Generator +// 16 teams | 9 conf games | 12 total games | 3 bye weeks +// 3 guaranteed annual opponents per team +// 6 flexible opponents on 4-year Group A/B rotation +// Week 14: 6 conf rivalry locks + 4 OOC locks + 6 bye teams +// ============================================================ + +// SEC team IDs +// Alabama(3), Arkansas(7), Auburn(10), Florida(30), Georgia(34), +// Kentucky(47), LSU(53), Mississippi State(63), Missouri(64), +// Oklahoma(78), Ole Miss(81), South Carolina(93), Tennessee(100), +// Texas(101), Texas A&M(102), Vanderbilt(120) + +// secGuaranteedPairs lists all 24 guaranteed annual conference matchups. +// Every pair will be scheduled every season (home/away flips on 2-year cycle). +var secGuaranteedPairs = []SchedulerHistoryKey{ + makeHistoryKey(3, 10), // Alabama vs Auburn (Week 14 lock) + makeHistoryKey(3, 100), // Alabama vs Tennessee + makeHistoryKey(3, 63), // Alabama vs Mississippi State + makeHistoryKey(7, 53), // Arkansas vs LSU (Week 14 lock) + makeHistoryKey(7, 64), // Arkansas vs Missouri + makeHistoryKey(7, 101), // Arkansas vs Texas + makeHistoryKey(10, 34), // Auburn vs Georgia + makeHistoryKey(10, 120), // Auburn vs Vanderbilt + makeHistoryKey(30, 34), // Florida vs Georgia + makeHistoryKey(30, 93), // Florida vs South Carolina + makeHistoryKey(30, 47), // Florida vs Kentucky + makeHistoryKey(34, 93), // Georgia vs South Carolina + makeHistoryKey(47, 100), // Kentucky vs Tennessee + makeHistoryKey(47, 93), // Kentucky vs South Carolina + makeHistoryKey(53, 81), // LSU vs Ole Miss + makeHistoryKey(53, 102), // LSU vs Texas A&M + makeHistoryKey(63, 120), // Mississippi State vs Vanderbilt + makeHistoryKey(63, 81), // Mississippi State vs Ole Miss (Week 14 lock) + makeHistoryKey(64, 78), // Missouri vs Oklahoma (Week 14 lock) + makeHistoryKey(64, 102), // Missouri vs Texas A&M + makeHistoryKey(78, 101), // Oklahoma vs Texas + makeHistoryKey(78, 81), // Oklahoma vs Ole Miss + makeHistoryKey(100, 120), // Tennessee vs Vanderbilt (Week 14 lock) + makeHistoryKey(101, 102), // Texas vs Texas A&M (Week 14 lock) +} + +// secWeek14ConfLocks: pairs locked to Week 14 as conference games. +var secWeek14ConfLocks = map[SchedulerHistoryKey]bool{ + makeHistoryKey(3, 10): true, // Alabama vs Auburn + makeHistoryKey(7, 53): true, // Arkansas vs LSU + makeHistoryKey(63, 81): true, // Ole Miss vs Mississippi State + makeHistoryKey(64, 78): true, // Missouri vs Oklahoma + makeHistoryKey(100, 120): true, // Tennessee vs Vanderbilt + makeHistoryKey(101, 102): true, // Texas vs Texas A&M +} + +// secWeek14OOC: teams with OOC rivals in Week 14 (handled by annual rivalry pass). +// These teams take a bye from conf scheduling in Week 14. +var secWeek14OOC = map[uint]bool{ + 30: true, // Florida (vs Florida State) + 34: true, // Georgia (vs Georgia Tech) + 47: true, // Kentucky (vs Louisville) + 93: true, // South Carolina (vs Clemson) +} + +// secTeamIDs for convenience +var secTeamIDs = []uint{3, 7, 10, 30, 34, 47, 53, 63, 64, 78, 81, 93, 100, 101, 102, 120} + +// secFlexibleGroupA maps each team to their 6 Group A (Years 1 & 3) flexible opponents. +// Group B is derived as the remaining 12 non-guaranteed opponents minus Group A. +var secFlexibleGroupA = map[uint][]uint{ + 3: {7, 30, 64, 78, 81, 101}, // Alabama + 7: {3, 10, 47, 81, 93, 120}, // Arkansas + 10: {7, 47, 53, 81, 101, 102}, // Auburn + 30: {3, 7, 10, 53, 64, 101}, // Florida + 34: {7, 53, 64, 78, 101, 102}, // Georgia (was {7,10,53,64,101,102}; removed Auburn=10 guaranteed, added Oklahoma=78) + 47: {3, 7, 10, 34, 63, 101}, // Kentucky + 53: {3, 10, 30, 64, 78, 120}, // LSU + 63: {30, 34, 47, 78, 93, 101}, // Miss State (was {3,30,34,47,93,101}; removed Alabama=3 guaranteed, added Oklahoma=78) + 64: {3, 7, 10, 30, 47, 81}, // Missouri + 78: {3, 7, 30, 53, 63, 102}, // Oklahoma + 81: {3, 7, 10, 30, 47, 102}, // Ole Miss + 93: {3, 7, 10, 53, 64, 78}, // South Carolina + 100: {7, 30, 53, 63, 64, 78}, // Tennessee (was {3,7,30,53,63,64}; removed Alabama=3 guaranteed, added Oklahoma=78) + 101: {3, 47, 53, 81, 93, 120}, // Texas (was {3,7,47,53,78,120}; removed Arkansas=7+Oklahoma=78 guaranteed, added OleMiss=81+SC=93) + 102: {3, 7, 30, 34, 47, 81}, // Texas A&M + 120: {3, 30, 34, 47, 53, 78}, // Vanderbilt (was {3,10,30,34,47,53}; removed Auburn=10 guaranteed, added Oklahoma=78) +} + +// secFlexGroupB derives Group B for a team as all non-guaranteed non-GroupA opponents. +func secFlexGroupB(teamID uint) []uint { + guaranteed := make(map[uint]bool) + for _, key := range secGuaranteedPairs { + if key.A == teamID { + guaranteed[key.B] = true + } else if key.B == teamID { + guaranteed[key.A] = true + } + } + groupA := make(map[uint]bool) + for _, id := range secFlexibleGroupA[teamID] { + groupA[id] = true + } + var groupB []uint + for _, id := range secTeamIDs { + if id == teamID { + continue + } + if !guaranteed[id] && !groupA[id] { + groupB = append(groupB, id) + } + } + return groupB +} + +// GenerateSECSchedule produces all SEC conference games for the season. +func GenerateSECSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + useGroupA := groupAThisSeason(season) + + teamMap := buildTeamMapFromSlice(collegeTeams) + + // Seed homecountMap from rivalry-pass home game counts so ShouldBeHome sees + // correct context from the very first conference game assignment. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + // Pre-seed confGameCount from any conference games already placed before this + // generator runs (e.g. annual rivalry games from the rivalry pass). + const secConferenceGamesPerTeam = 9 + secTeamSet := make(map[uint]bool, len(secTeamIDs)) + for _, id := range secTeamIDs { + secTeamSet[id] = true + } + confGameCount := make(map[uint]int, len(secTeamIDs)) + for _, id := range secTeamIDs { + for oppID := range gamesPlayedAgainstOpponentsMap[id] { + if secTeamSet[oppID] { + confGameCount[id]++ + } + } + } + + // recordGame commits a game and updates all tracking maps including live confGameCount. + recordGame := func(home, away structs.CollegeTeam, week uint) { + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + confGameCount[home.ID]++ + confGameCount[away.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // emit is a safe wrapper for week-locked games: skips duplicates and busy weeks, + // then delegates to recordGame. + emit := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][week] { + return + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][week] { + return + } + recordGame(home, away, week) + } + + processed := make(map[SchedulerHistoryKey]bool) + + // Phase 1: Guaranteed pairs — Week 14 locks first + for _, key := range secGuaranteedPairs { + if processed[key] { + continue + } + a := teamMap[key.A] + b := teamMap[key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + // If the annual rivalry loop already created this game, honour it and + // skip — no duplicate should be emitted. + if alreadyScheduled(key.A, key.B, gamesPlayedAgainstOpponentsMap) { + processed[key] = true + continue + } + if confGameCount[key.A] >= secConferenceGamesPerTeam || confGameCount[key.B] >= secConferenceGamesPerTeam { + processed[key] = true + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(key.A, key.B, season, lastHomeMap, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + var week uint + if secWeek14ConfLocks[key] { + emit(home, away, 14) + } else { + week = assignWeek(home.ID, away.ID, 4, 13, gamesPlayedByWeekMap) + if week == 0 { + week = assignWeek(home.ID, away.ID, 1, 3, gamesPlayedByWeekMap) + } + if week == 0 { + continue + } + recordGame(home, away, week) + } + _ = week + processed[key] = true + } + + // Phase 2: Mark Week 14 for OOC teams (those not already marked) + for teamID := range secWeek14OOC { + if gamesPlayedByWeekMap[teamID] == nil { + gamesPlayedByWeekMap[teamID] = make(map[uint]bool) + } + gamesPlayedByWeekMap[teamID][14] = true + } + + // Phase 3: Flexible games — global shuffled pair approach. + // The SEC flex-rotation lists are asymmetric: Tennessee and Vanderbilt only + // appear in their OWN lists, never in their desired opponents' lists. A + // per-team loop therefore fills every opponent to cap before Tennessee/ + // Vanderbilt are reached, leaving them permanently short. Collecting ALL + // pairs from the union of every team's flex list and shuffling them gives + // every pair (including Tennessee's) an equal chance of being scheduled + // early; the retry loop in the manager tries different shuffle seeds. + // confGameCount is already live from Phase 1. + + // Build global flex pair set — include a pair if EITHER side lists the other. + allFlexPairs := make(map[SchedulerHistoryKey]bool) + for _, teamID := range secTeamIDs { + var opponents []uint + if useGroupA { + opponents = secFlexibleGroupA[teamID] + } else { + opponents = secFlexGroupB(teamID) + } + for _, oppID := range opponents { + key := makeHistoryKey(teamID, oppID) + if !processed[key] { + allFlexPairs[key] = true + } + } + } + + flexPairSlice := make([]SchedulerHistoryKey, 0, len(allFlexPairs)) + for k := range allFlexPairs { + flexPairSlice = append(flexPairSlice, k) + } + rand.Shuffle(len(flexPairSlice), func(i, j int) { + flexPairSlice[i], flexPairSlice[j] = flexPairSlice[j], flexPairSlice[i] + }) + // Sort by historical play count ascending so least-played flex pairs get priority. + // Stable sort preserves the shuffle order within ties. + sort.SliceStable(flexPairSlice, func(i, j int) bool { + return playCountMap[flexPairSlice[i]] < playCountMap[flexPairSlice[j]] + }) + + for _, key := range flexPairSlice { + aID, bID := key.A, key.B + if alreadyScheduled(aID, bID, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[aID] >= secConferenceGamesPerTeam || confGameCount[bID] >= secConferenceGamesPerTeam { + continue + } + tA := teamMap[aID] + tB := teamMap[bID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(aID, bID, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 4, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 1, 3, gamesPlayedByWeekMap) + } + if w == 0 { + continue + } + recordGame(home, away, w) + } + + // Phase 4: Rescue any SEC team still below 9 conference games. + for _, teamID := range secTeamIDs { + if confGameCount[teamID] >= secConferenceGamesPerTeam { + continue + } + for _, oppID := range secTeamIDs { + if oppID == teamID { + continue + } + if confGameCount[teamID] >= secConferenceGamesPerTeam { + break + } + if confGameCount[oppID] >= secConferenceGamesPerTeam { + continue + } + if alreadyScheduled(teamID, oppID, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[teamID] + tB := teamMap[oppID] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(teamID, oppID, season, lastHomeMap, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 1, 13, gamesPlayedByWeekMap) + if w == 0 { + continue + } + recordGame(home, away, w) + } + } + + // Retry signal: return empty slice if any team is still short so the + // manager's retry loop can try a different shuffle ordering. + for _, id := range secTeamIDs { + if confGameCount[id] < secConferenceGamesPerTeam { + return []structs.CollegeGame{} + } + } + + return games +} diff --git a/managers/CFBScheduleSmall.go b/managers/CFBScheduleSmall.go new file mode 100644 index 0000000..ae8ecdd --- /dev/null +++ b/managers/CFBScheduleSmall.go @@ -0,0 +1,349 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// Small / FCS Conference Schedule Generators +// Handles conference IDs: 14 (MVFC), 15 (Patriot), 16 (Big Sky), +// 17 (Ivy), 18 (SoCon), 19 (SWAC), 20 (Big South-OVC), 21 (CAA), +// 23 (MEAC), 24 (NEC), 25 (Pioneer), 26 (Southland), 27 (UAC) +// ============================================================ + +// Per-conference game counts +var smallConfGameCount = map[int]int{ + 14: 8, // MVFC + 15: 7, // Patriot + 16: 8, // Big Sky + 17: 7, // Ivy + 18: 9, // SoCon + 19: 8, // SWAC + 20: 7, // Big South-OVC + 21: 8, // CAA + 23: 5, // MEAC + 24: 8, // NEC + 25: 8, // Pioneer + 26: 8, // Southland + 27: 7, // UAC +} + +// smallConfLockedMatchups defines intra-conference rivalry weeks per conference. +// key = conferenceID, value = list of locked matchups with their weeks. +var smallConfLockedMatchups = map[int][]struct { + key SchedulerHistoryKey + week uint +}{ + // Mac (13) + 10: { + {makeHistoryKey(2, 46), 14}, // Akron vs Kent State + {makeHistoryKey(15, 105), 14}, // Bowling Green vs Toledo + {makeHistoryKey(19, 128), 14}, // CMU vs WMU + {makeHistoryKey(16, 113), 14}, // Buffalo vs UMass + {makeHistoryKey(58, 76), 14}, // Miami OH vs Ohio + {makeHistoryKey(11, 164), 13}, // BG vs Sacramento State + {makeHistoryKey(19, 28), 4}, // CMU vs EMU + {makeHistoryKey(16, 2), 4}, // Buffalo vs Akron + {makeHistoryKey(11, 58), 4}, // Ball State vs Miami (OH) + {makeHistoryKey(113, 46), 4}, // UMass vs Kent State + {makeHistoryKey(15, 76), 4}, // Bowling Green vs Ohio + {makeHistoryKey(128, 28), 8}, // WMU vs EMU + {makeHistoryKey(11, 76), 8}, // Ball State vs Ohio + }, + // Big Sky (16) + 16: { + // UC Davis(154) vs Cal Poly(155) — Week 12 + // Eastern Washington(156) vs Montana(159) — Week 12 + // Eastern Washington(156) vs Portland State(163) — Week 13 + // Idaho(157) vs Idaho State(158) — Week 13 + // Idaho(157) vs Montana(159) — Week 8 + // Montana(159) vs Montana State(160) — Week 13 + // Northern Arizona(161) vs Southern Utah(260) — Week 12 + // Weber State(165) vs Southern Utah(260) — Week 5 + // Southern Utah(260) vs Utah Tech(263) — Week 8 + {makeHistoryKey(154, 155), 12}, + {makeHistoryKey(156, 159), 12}, + {makeHistoryKey(156, 163), 13}, + {makeHistoryKey(157, 158), 13}, + {makeHistoryKey(157, 159), 8}, + {makeHistoryKey(159, 160), 13}, + {makeHistoryKey(161, 260), 12}, + {makeHistoryKey(165, 260), 5}, + {makeHistoryKey(260, 263), 8}, + }, + // MVFC (14) + 14: { + // South Dakota State(144) vs South Dakota(145) — Week 11 + // North Dakota(142) vs South Dakota(145) — Week 8 + {makeHistoryKey(144, 145), 11}, + {makeHistoryKey(142, 145), 8}, + }, + // CAA (21) + 21: { + // Albany(135) vs Stony Brook(197) — Week 12 + // Maine(158) vs New Hampshire(184) — Week 13 + {makeHistoryKey(135, 197), 12}, + {makeHistoryKey(158, 184), 13}, + }, + // SoCon (18) + 18: { + // VMI(202) vs The Citadel(198) — Week 13 + // The Citadel(198) vs Furman(153) — Week 10 + {makeHistoryKey(202, 198), 13}, + {makeHistoryKey(198, 153), 10}, + }, + // Big South-OVC (20) + 20: { + // Tennessee State(199) vs UT Martin(201) — Week 10 + // Western Illinois(203) vs Eastern Illinois(151) — Week 12 + {makeHistoryKey(199, 201), 10}, + {makeHistoryKey(203, 151), 12}, + }, + // Ivy League (17) + 17: { + // Harvard(154) vs Yale(205) — Week 14 + // Penn(183) vs Princeton(186) — Week 14 + {makeHistoryKey(154, 205), 14}, + {makeHistoryKey(183, 186), 14}, + }, + // Southland (26) + 26: { + // Stephen F. Austin(174) vs Northwestern State(163) — Week 12 + // Lamar(157) vs McNeese(172) — Week 12 + // Northwestern State(163) vs McNeese(172) — Week 4 + // Northwestern State(163) vs Nicholls(185) — Week 8 + // Northwestern State(163) vs Southeastern Louisiana(192) — Week 8 + {makeHistoryKey(174, 163), 12}, + {makeHistoryKey(157, 172), 12}, + {makeHistoryKey(163, 172), 4}, + {makeHistoryKey(163, 185), 8}, + {makeHistoryKey(163, 192), 8}, + }, +} + +// swacEast and swacWest divisions +// SWAC East: Bethune-Cookman(184), Alabama A&M(188), Florida A&M(190), +// +// Alabama State(191), Mississippi Valley State(193), Jackson State(194) +// +// SWAC West: Grambling State(183), Prairie View A&M(185), Alcorn State(186), +// +// Southern(187), Arkansas-Pine Bluff(189), Texas Southern(192) +var swacEast = []uint{184, 188, 190, 191, 193, 194} // BCookman, AlaA&M, FAMU, AlaSt, MVST, JSU +var swacWest = []uint{183, 185, 186, 187, 189, 192} // Grambling, PVA&M, Alcorn, Southern, UAPB, TxSo + +// GenerateSWACSchedule handles the SWAC 12-team divisional schedule (8 conf games). +func GenerateSWACSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + swacLocked := []struct { + key SchedulerHistoryKey + week uint + }{ + {makeHistoryKey(190, 194), 1}, // FAMU(190) vs Jackson State(194) — Week 1 + {makeHistoryKey(185, 192), 1}, // Prairie View(185) vs Texas Southern(192) — Week 1 + {makeHistoryKey(183, 185), 4}, // Grambling(183) vs Prairie View(185) — Week 4 + {makeHistoryKey(188, 191), 10}, // Alabama A&M(188) vs Alabama State(191) — Week 10 + {makeHistoryKey(184, 190), 13}, // Bethune-Cookman(184) vs FAMU(190) — Week 13 + {makeHistoryKey(183, 187), 13}, // Grambling(183) vs Southern(187) — Week 13 + {makeHistoryKey(193, 194), 13}, // MVST(193) vs Jackson State(194) — Week 13 + } + lockedSet := make(map[SchedulerHistoryKey]uint) + for _, l := range swacLocked { + lockedSet[l.key] = l.week + a := teamMap[l.key.A] + b := teamMap[l.key.B] + if a.ID == 0 || b.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(l.key.A, l.key.B, season, nil, homecountMap) { + home, away = a, b + } else { + home, away = b, a + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + continue + } + // Skip if either team already has a game this week (OOC conflict) + if gamesPlayedByWeekMap[home.ID] != nil && gamesPlayedByWeekMap[home.ID][l.week] { + continue + } + if gamesPlayedByWeekMap[away.ID] != nil && gamesPlayedByWeekMap[away.ID][l.week] { + continue + } + markWeek(home.ID, away.ID, l.week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, l.week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + emitGame := func(home, away structs.CollegeTeam, week uint) { + if home.ID == 0 || away.ID == 0 { + return + } + if alreadyScheduled(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) { + return + } + markWeek(home.ID, away.ID, week, gamesPlayedByWeekMap) + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, week, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + + // Schedule 5 intra-divisional games per team + confGameCount := make(map[uint]int) + scheduleDivGames := func(div []uint, maxGames int) { + for i := 0; i < len(div); i++ { + for j := i + 1; j < len(div); j++ { + a := div[i] + b := div[j] + key := makeHistoryKey(a, b) + if _, locked := lockedSet[key]; locked { + continue + } + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + if confGameCount[a] >= maxGames || confGameCount[b] >= maxGames { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 4, 12, gamesPlayedByWeekMap) + if w == 0 { + continue + } + emitGame(home, away, w) + confGameCount[home.ID]++ + confGameCount[away.ID]++ + } + } + } + scheduleDivGames(swacEast, 5) + scheduleDivGames(swacWest, 5) + + // 3 cross-divisional games per team, rotating + cy := cycleYear(season) + crossProcessed := make(map[SchedulerHistoryKey]bool) + for eIdx, eTeam := range swacEast { + for k := 0; k < 3; k++ { + wIdx := (eIdx + (cy-1)*3 + k) % len(swacWest) + wTeam := swacWest[wIdx] + key := makeHistoryKey(eTeam, wTeam) + if crossProcessed[key] || alreadyScheduled(eTeam, wTeam, gamesPlayedAgainstOpponentsMap) { + crossProcessed[key] = true + continue + } + if confGameCount[eTeam] >= 8 || confGameCount[wTeam] >= 8 { + crossProcessed[key] = true + continue + } + tE := teamMap[eTeam] + tW := teamMap[wTeam] + if tE.ID == 0 || tW.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(eTeam, wTeam, season, nil, homecountMap) { + home, away = tE, tW + } else { + home, away = tW, tE + } + w := assignWeek(home.ID, away.ID, 4, 12, gamesPlayedByWeekMap) + if w == 0 { + crossProcessed[key] = true + continue + } + crossProcessed[key] = true + emitGame(home, away, w) + confGameCount[home.ID]++ + confGameCount[away.ID]++ + } + } + + return games +} + +// GenerateSmallConferenceSchedule dispatches to the correct generator for FCS +// conferences. Falls back to the generic round-robin helper for most conferences. +func GenerateSmallConferenceSchedule( + conferenceID int, + retrySeed uint, + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + if conferenceID == 19 { + return GenerateSWACSchedule(collegeTeams, stadiumMap, stadiumMapByID, rivalryMap, gamesPlayedAgainstOpponentsMap, gamesPlayedByWeekMap, playCountMap, lastHomeMap, homeCountSeedMap, ts) + } + + gamesPerTeam, ok := smallConfGameCount[conferenceID] + if !ok { + gamesPerTeam = 8 + } + + // Build locked set from table + lockedSet := make(map[SchedulerHistoryKey]uint) + if locks, found := smallConfLockedMatchups[conferenceID]; found { + for _, l := range locks { + lockedSet[l.key] = l.week + } + } + + return generateGenericRoundRobinSchedule( + collegeTeams, + stadiumMap, + stadiumMapByID, + rivalryMap, + gamesPlayedAgainstOpponentsMap, + gamesPlayedByWeekMap, + playCountMap, + lastHomeMap, + homeCountSeedMap, + ts, + lockedSet, + gamesPerTeam, + 4, + 14, + 1, 14, // overflow: weeks 1–3 and week 14 + retrySeed, + ) +} diff --git a/managers/CFBScheduleSunBelt.go b/managers/CFBScheduleSunBelt.go new file mode 100644 index 0000000..9b5d6b2 --- /dev/null +++ b/managers/CFBScheduleSunBelt.go @@ -0,0 +1,127 @@ +package managers + +import ( + "github.com/CalebRose/SimFBA/structs" +) + +// ============================================================ +// Sun Belt Conference Schedule Generator +// 14 teams | 2 divisions of 7 | 6 intra-div + 2 cross-div = 8 conf games +// East: App State(4), Coastal Carolina(23), Georgia Southern(35), +// Georgia State(36), James Madison(131), Marshall(54), Old Dominion(80) +// West: Arkansas State(8), Louisiana(49), Louisiana Monroe(50), +// Louisiana Tech(51), South Alabama(92), Southern Miss(95), Troy(106) +// ============================================================ + +var sunBeltEast = []uint{4, 23, 35, 36, 131, 54, 80} +var sunBeltWest = []uint{8, 49, 50, 51, 92, 95, 106} + +// GenerateSunBeltSchedule produces all Sun Belt conference games for the season. +func GenerateSunBeltSchedule( + collegeTeams []structs.CollegeTeam, + stadiumMap map[uint]structs.Stadium, + stadiumMapByID map[uint]structs.Stadium, + rivalryMap map[uint][]structs.CollegeRival, + gamesPlayedAgainstOpponentsMap map[uint]map[uint]bool, + gamesPlayedByWeekMap map[uint]map[uint]bool, + playCountMap map[SchedulerHistoryKey]int, + lastHomeMap map[uint]map[uint]bool, + homeCountSeedMap map[uint]int, + ts structs.Timestamp, +) []structs.CollegeGame { + games := []structs.CollegeGame{} + season := ts.Season + seasonID := uint(ts.CollegeSeasonID) + + teamMap := buildTeamMapFromSlice(collegeTeams) + + // Seed homecountMap from rivalry-pass home game counts. + homecountMap := make(map[uint]int, len(homeCountSeedMap)) + for id, count := range homeCountSeedMap { + homecountMap[id] = count + } + + scheduleDiv := func(div []uint) { + for i := 0; i < len(div); i++ { + for j := i + 1; j < len(div); j++ { + a := div[i] + b := div[j] + if alreadyScheduled(a, b, gamesPlayedAgainstOpponentsMap) { + continue + } + tA := teamMap[a] + tB := teamMap[b] + if tA.ID == 0 || tB.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(a, b, season, nil, homecountMap) { + home, away = tA, tB + } else { + home, away = tB, tA + } + w := assignWeek(home.ID, away.ID, 5, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 4, 4, gamesPlayedByWeekMap) + } + if w == 0 { + return + } + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + } + } + + // Phase 1: Intra-divisional games (all 6 opponents in division) + scheduleDiv(sunBeltEast) + scheduleDiv(sunBeltWest) + + // Phase 2: Cross-divisional games (2 per team, rotating) + // Each East team plays 2 West teams per season; cycle over 4 years to meet all 7. + // Pair each East team with 2 West opponents using (teamIndex + cycleOffset) mod 7. + cy := cycleYear(season) + crossProcessed := make(map[SchedulerHistoryKey]bool) + for eIdx, eTeam := range sunBeltEast { + for k := 0; k < 2; k++ { + wIdx := (eIdx + (cy-1)*2 + k) % len(sunBeltWest) + wTeam := sunBeltWest[wIdx] + key := makeHistoryKey(eTeam, wTeam) + if crossProcessed[key] { + continue + } + if alreadyScheduled(eTeam, wTeam, gamesPlayedAgainstOpponentsMap) { + crossProcessed[key] = true + continue + } + tE := teamMap[eTeam] + tW := teamMap[wTeam] + if tE.ID == 0 || tW.ID == 0 { + continue + } + var home, away structs.CollegeTeam + if ShouldBeHome(eTeam, wTeam, season, nil, homecountMap) { + home, away = tE, tW + } else { + home, away = tW, tE + } + w := assignWeek(home.ID, away.ID, 5, 13, gamesPlayedByWeekMap) + if w == 0 { + w = assignWeek(home.ID, away.ID, 4, 4, gamesPlayedByWeekMap) + } + if w == 0 { + crossProcessed[key] = true + continue + } + crossProcessed[key] = true + markOpponents(home.ID, away.ID, gamesPlayedAgainstOpponentsMap) + homecountMap[home.ID]++ + g := MakeCollegeGameRecord(home, away, w, seasonID, stadiumMap, stadiumMapByID, rivalryMap) + games = append(games, g) + } + } + + return games +} diff --git a/managers/GameManager.go b/managers/GameManager.go index fae9a35..4da606b 100644 --- a/managers/GameManager.go +++ b/managers/GameManager.go @@ -11,6 +11,54 @@ import ( "github.com/CalebRose/SimFBA/util" ) +func SwapCFBGameHomeAndAwayTeams(gameID string) { + db := dbprovider.GetInstance().GetDB() + ts := GetTimestamp() + + game := GetCollegeGameByGameID(gameID) + if game.IsNeutral || game.WeekID < ts.CollegeWeekID { + return + } + + homeTeamID := game.HomeTeamID + homeTeam := game.HomeTeam + homeTeamCoach := game.HomeTeamCoach + awayTeamID := game.AwayTeamID + awayTeam := game.AwayTeam + awayTeamCoach := game.AwayTeamCoach + + // Strings for Home Team & Away Team + awayTeamIDStr := strconv.Itoa(int(awayTeamID)) + + // Get Away Team Arena by Away Team ID + awayTeamData := GetTeamByTeamID(awayTeamIDStr) + stadiumID := awayTeamData.StadiumID + stadium := awayTeamData.Stadium + city := awayTeamData.City + state := awayTeamData.State + + stadiumData := GetStadiumByStadiumID(strconv.Itoa(int(stadiumID))) + isDomed := stadiumData.IsDomed + + // Update Game with new Home and Away Teams + game.HomeTeamID = awayTeamID + game.HomeTeam = awayTeam + game.HomeTeamCoach = awayTeamCoach + game.AwayTeamID = homeTeamID + game.AwayTeam = homeTeam + game.AwayTeamCoach = homeTeamCoach + game.StadiumID = stadiumID + game.Stadium = stadium + game.City = city + game.State = state + game.IsDomed = isDomed + + repository.SaveCFBGameRecord(game, db) + + // Generate Weather + GenerateWeatherForGames() +} + func GetCollegeGamesByWeekIdAndSeasonID(WeekID string, SeasonID string) []structs.CollegeGame { db := dbprovider.GetInstance().GetDB() diff --git a/managers/ImportManager.go b/managers/ImportManager.go index 0882574..4a95ef2 100644 --- a/managers/ImportManager.go +++ b/managers/ImportManager.go @@ -728,13 +728,13 @@ func ImportNFLGames() { func ImportCFBTeams() { db := dbprovider.GetInstance().GetDB() - teamPath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2024\\teams.csv" - stadiumPath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2024\\stadia.csv" - profilePath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2024\\profiles.csv" + teamPath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2027\\teams.csv" + stadiumPath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2027\\stadia.csv" + // profilePath := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2027\\profiles.csv" teamCSV := util.ReadCSV(teamPath) stadiumCSV := util.ReadCSV(stadiumPath) - profileCSV := util.ReadCSV(profilePath) + // profileCSV := util.ReadCSV(profilePath) for idx, row := range teamCSV { if idx == 0 { @@ -742,7 +742,7 @@ func ImportCFBTeams() { } stadiumRecord := stadiumCSV[idx] - profileRecord := profileCSV[idx] + // profileRecord := profileCSV[idx] teamID := util.ConvertStringToInt(row[0]) stadiumID := util.ConvertStringToInt(stadiumRecord[0]) @@ -801,45 +801,45 @@ func ImportCFBTeams() { IsActive: isActive, } - aiBehavior := profileRecord[10] - aiQuality := profileRecord[11] - min := util.ConvertStringToInt(profileRecord[12]) - max := util.ConvertStringToInt(profileRecord[13]) - off := profileRecord[17] - def := profileRecord[18] - - teamProfile := structs.RecruitingTeamProfile{ - Model: gorm.Model{ - ID: uint(teamID), - }, - TeamID: teamID, - Team: teamName, - TeamAbbreviation: abbr, - State: state, - ScholarshipsAvailable: 40, - WeeklyPoints: 100, - SpentPoints: 0, - TotalCommitments: 0, - RecruitClassSize: 20, - PortalReputation: 100, - BaseEfficiencyScore: 0.6, - RecruitingEfficiencyScore: 0.8, - IsFBS: false, - IsUserTeam: false, - IsAI: true, - AIBehavior: aiBehavior, - AIQuality: aiQuality, - AIMinThreshold: min, - AIMaxThreshold: max, - AIStarMin: 1, - AIStarMax: 2, - OffensiveScheme: off, - DefensiveScheme: def, - } + // aiBehavior := profileRecord[10] + // aiQuality := profileRecord[11] + // min := util.ConvertStringToInt(profileRecord[12]) + // max := util.ConvertStringToInt(profileRecord[13]) + // off := profileRecord[17] + // def := profileRecord[18] + + // teamProfile := structs.RecruitingTeamProfile{ + // Model: gorm.Model{ + // ID: uint(teamID), + // }, + // TeamID: teamID, + // Team: teamName, + // TeamAbbreviation: abbr, + // State: state, + // ScholarshipsAvailable: 40, + // WeeklyPoints: 100, + // SpentPoints: 0, + // TotalCommitments: 0, + // RecruitClassSize: 20, + // PortalReputation: 100, + // BaseEfficiencyScore: 0.6, + // RecruitingEfficiencyScore: 0.8, + // IsFBS: false, + // IsUserTeam: false, + // IsAI: true, + // AIBehavior: aiBehavior, + // AIQuality: aiQuality, + // AIMinThreshold: min, + // AIMaxThreshold: max, + // AIStarMin: 1, + // AIStarMax: 2, + // OffensiveScheme: off, + // DefensiveScheme: def, + // } db.Create(&team) db.Create(&stadium) - db.Create(&teamProfile) + // db.Create(&teamProfile) } } @@ -1034,7 +1034,7 @@ func FixCollegeDTs() { func ImportCFBRivals() { db := dbprovider.GetInstance().GetDB() - path := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2025\\rivalries.csv" + path := "C:\\Users\\ctros\\go\\src\\github.com\\CalebRose\\SimFBA\\data\\2027\\rivalries.csv" rivalsCSV := util.ReadCSV(path) @@ -1047,20 +1047,20 @@ func ImportCFBRivals() { } for idx, row := range rivalsCSV { - if idx < 314 { + if idx == 0 { continue } id := util.ConvertStringToInt(row[0]) - rival1 := row[2] - rival2 := row[4] + rival1 := row[4] + rival2 := row[6] if len(rival1) == 0 && len(rival2) == 0 { break } - rivalryName := row[5] - trophyName := row[6] - priority1 := util.ConvertStringToInt(row[7]) - priority2 := util.ConvertStringToInt(row[8]) + rivalryName := row[1] + trophyName := row[2] + priority1 := util.ConvertStringToInt(row[8]) + priority2 := util.ConvertStringToInt(row[9]) team1, ok := teamMap[rival1] if !ok { @@ -1072,6 +1072,17 @@ func ImportCFBRivals() { fmt.Println("FIX!!!") } + isAnnualRivalry := util.ConvertStringToBool(row[10]) + conferenceID := 0 + if team1.ConferenceID > 0 && team1.ConferenceID == team2.ConferenceID { + conferenceID = int(team1.ConferenceID) + } + + preferredWeek := util.ConvertStringToInt(row[12]) + preferredTimeSlot := row[13] + isNeutral := util.ConvertStringToBool(row[14]) + stadiumID := util.ConvertStringToInt(row[15]) + rivalry := structs.CollegeRival{ Model: gorm.Model{ ID: uint(id), @@ -1083,6 +1094,12 @@ func ImportCFBRivals() { HasTrophy: len(trophyName) > 0, TeamOnePriority: uint(priority1), TeamTwoPriority: uint(priority2), + IsAnnualRivalry: isAnnualRivalry, + ConferenceID: uint(conferenceID), + PreferredWeek: uint8(preferredWeek), + Timeslot: preferredTimeSlot, + IsNeutralSite: isNeutral, + StadiumID: uint(stadiumID), } db.Create(&rivalry) diff --git a/managers/MapHelper.go b/managers/MapHelper.go index 97aa26b..080ff6a 100644 --- a/managers/MapHelper.go +++ b/managers/MapHelper.go @@ -434,6 +434,20 @@ func MakeCollegeTeamMap(teams []structs.CollegeTeam) map[uint]structs.CollegeTea return profileMap } +func MakeCollegeTeamsByConference(teams []structs.CollegeTeam) map[int][]structs.CollegeTeam { + conferenceMap := make(map[int][]structs.CollegeTeam) + + for _, team := range teams { + if len(conferenceMap[team.ConferenceID]) > 0 { + conferenceMap[team.ConferenceID] = append(conferenceMap[team.ConferenceID], team) + } else { + conferenceMap[team.ConferenceID] = []structs.CollegeTeam{team} + } + } + + return conferenceMap +} + func MakeCollegeTeamSeasonStatsMap(stats []structs.CollegeTeamSeasonStats) map[uint]structs.CollegeTeamSeasonStats { statsMap := make(map[uint]structs.CollegeTeamSeasonStats) for _, s := range stats { @@ -495,3 +509,27 @@ func MakeCollegeRecruitMapByID(recruits []structs.Recruit) map[uint]structs.Recr } return recruitMap } + +func MakeStadiumMapByTeamID(stadia []structs.Stadium, isCollege bool) map[uint]structs.Stadium { + stadiumMap := make(map[uint]structs.Stadium) + + for _, s := range stadia { + if isCollege && s.LeagueID == 3 { + continue + } + if !isCollege && s.LeagueID != 3 { + continue + } + stadiumMap[s.TeamID] = s + } + return stadiumMap +} + +func MakeStadiumMapByID(stadia []structs.Stadium) map[uint]structs.Stadium { + stadiumMap := make(map[uint]structs.Stadium) + + for _, s := range stadia { + stadiumMap[s.ID] = s + } + return stadiumMap +} diff --git a/managers/SchedulerManager.go b/managers/SchedulerManager.go new file mode 100644 index 0000000..ce142b0 --- /dev/null +++ b/managers/SchedulerManager.go @@ -0,0 +1,318 @@ +package managers + +import ( + "context" + "fmt" + "strconv" + + "github.com/CalebRose/SimFBA/dbprovider" + "github.com/CalebRose/SimFBA/firebase" + "github.com/CalebRose/SimFBA/repository" + "github.com/CalebRose/SimFBA/structs" +) + +// ───────────────────────────────────────────── +// CFB Game Request +// ───────────────────────────────────────────── + +// CreateCFBGameRequest saves a new CFBGameRequest record to the database. +func CreateCFBGameRequest(request structs.CFBGameRequest) { + db := dbprovider.GetInstance().GetDB() + repository.CreateCFBGameRequest(request, db) +} + +// AcceptCFBGameRequest marks the request as accepted and notifies the sending +// team's coach if they are a user-managed team. +func AcceptCFBGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindCFBGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + request.Accepted() + repository.SaveCFBGameRequest(request, db) + + sendingTeam := GetTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + if isCFBUserTeam(sendingTeam) { + receivingTeam := GetTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + ctx := context.Background() + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.Coach}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "cfb", + Domain: firebase.DomainCFB, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: fmt.Sprintf("%s has accepted your game request for Week %d.", receivingTeam.TeamName, request.Week), + SourceEventKey: firebase.BuildSourceEventKey("gamerequest", "cfb", "accept", requestID), + }) + } +} + +// RejectCFBGameRequest deletes the request and notifies the sending team's coach +// if they are a user-managed team. +func RejectCFBGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindCFBGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + sendingTeam := GetTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + + repository.DeleteCFBGameRequest(request, db) + + if isCFBUserTeam(sendingTeam) { + receivingTeam := GetTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + ctx := context.Background() + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.Coach}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "cfb", + Domain: firebase.DomainCFB, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: fmt.Sprintf("%s has rejected your game request for Week %d.", receivingTeam.TeamName, request.Week), + SourceEventKey: firebase.BuildSourceEventKey("gamerequest", "cfb", "reject", requestID), + }) + } +} + +// ProcessCFBGameRequest creates a CollegeGame record from the existing game +// request and marks the request as approved. +func ProcessCFBGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindCFBGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + homeTeam := GetTeamByTeamID(strconv.Itoa(int(request.HomeTeamID))) + awayTeam := GetTeamByTeamID(strconv.Itoa(int(request.AwayTeamID))) + + stadiums := GetAllStadiums() + stadiumByID := make(map[uint]structs.Stadium, len(stadiums)) + for _, s := range stadiums { + stadiumByID[s.ID] = s + } + stadium := stadiumByID[request.ArenaID] + + isDivisional := homeTeam.DivisionID > 0 && homeTeam.DivisionID == awayTeam.DivisionID + + game := structs.CollegeGame{ + HomeTeamID: int(request.HomeTeamID), + HomeTeam: homeTeam.TeamName, + AwayTeamID: int(request.AwayTeamID), + AwayTeam: awayTeam.TeamName, + Week: int(request.Week), + WeekID: int(request.WeekID), + SeasonID: int(request.SeasonID), + StadiumID: request.ArenaID, + Stadium: stadium.StadiumName, + City: stadium.City, + State: stadium.State, + Region: stadium.Region, + TimeSlot: request.Timeslot, + IsNeutral: request.IsNeutralSite, + IsConference: homeTeam.ConferenceID == awayTeam.ConferenceID, + IsDivisional: isDivisional, + IsSpringGame: request.IsSpringGame, + } + + repository.CreateCFBGameRecordsBatch(db, []structs.CollegeGame{game}, 1) + + request.Approved() + repository.SaveCFBGameRequest(request, db) +} + +// VetoCFBGameRequest deletes the request and notifies both the sending and +// receiving teams' coaches if either is a user-managed team. +func VetoCFBGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindCFBGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + sendingTeam := GetTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + receivingTeam := GetTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + + repository.DeleteCFBGameRequest(request, db) + + ctx := context.Background() + msg := fmt.Sprintf("The game request between %s and %s for Week %d has been vetoed.", sendingTeam.TeamName, receivingTeam.TeamName, request.Week) + vetoKey := firebase.BuildSourceEventKey("gamerequest", "cfb", "veto", requestID) + + if isCFBUserTeam(sendingTeam) { + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.Coach}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "cfb", + Domain: firebase.DomainCFB, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: msg, + SourceEventKey: vetoKey + ":sending", + }) + } + if isCFBUserTeam(receivingTeam) { + uids := firebase.ResolveUIDsByUsernames(ctx, []string{receivingTeam.Coach}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "cfb", + Domain: firebase.DomainCFB, + TeamID: receivingTeam.ID, + RecipientUIDs: uids, + Message: msg, + SourceEventKey: vetoKey + ":receiving", + }) + } +} + +// ───────────────────────────────────────────── +// NFL Game Request +// ───────────────────────────────────────────── + +// CreateNFLGameRequest saves a new NFLGameRequest record to the database. +func CreateNFLGameRequest(request structs.NFLGameRequest) { + db := dbprovider.GetInstance().GetDB() + repository.CreateNFLGameRequest(request, db) +} + +// AcceptNFLGameRequest marks the request as accepted and notifies the sending +// team's owner if they are a user-managed team. +func AcceptNFLGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindNFLGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + request.Accepted() + repository.SaveNFLGameRequest(request, db) + + sendingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + if isNFLUserTeam(sendingTeam) { + receivingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + ctx := context.Background() + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.NFLOwnerName}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "nfl", + Domain: firebase.DomainNFL, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: fmt.Sprintf("%s has accepted your game request for Week %d.", receivingTeam.TeamName, request.Week), + SourceEventKey: firebase.BuildSourceEventKey("gamerequest", "nfl", "accept", requestID), + }) + } +} + +// RejectNFLGameRequest deletes the request and notifies the sending team's owner +// if they are a user-managed team. +func RejectNFLGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindNFLGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + sendingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + + repository.DeleteNFLGameRequest(request, db) + + if isNFLUserTeam(sendingTeam) { + receivingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + ctx := context.Background() + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.NFLOwnerName}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "nfl", + Domain: firebase.DomainNFL, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: fmt.Sprintf("%s has rejected your game request for Week %d.", receivingTeam.TeamName, request.Week), + SourceEventKey: firebase.BuildSourceEventKey("gamerequest", "nfl", "reject", requestID), + }) + } +} + +// ProcessNFLGameRequest creates an NFLGame record from the existing game +// request and marks the request as approved. +func ProcessNFLGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindNFLGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + homeTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.HomeTeamID))) + awayTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.AwayTeamID))) + + stadiums := GetAllStadiums() + stadiumByID := make(map[uint]structs.Stadium, len(stadiums)) + for _, s := range stadiums { + stadiumByID[s.ID] = s + } + stadium := stadiumByID[request.ArenaID] + + isDivisional := homeTeam.DivisionID > 0 && homeTeam.DivisionID == awayTeam.DivisionID + + game := structs.NFLGame{ + HomeTeamID: int(request.HomeTeamID), + HomeTeam: homeTeam.TeamName, + AwayTeamID: int(request.AwayTeamID), + AwayTeam: awayTeam.TeamName, + Week: int(request.Week), + WeekID: int(request.WeekID), + SeasonID: int(request.SeasonID), + StadiumID: request.ArenaID, + Stadium: stadium.StadiumName, + City: stadium.City, + State: stadium.State, + Region: stadium.Region, + TimeSlot: request.Timeslot, + IsNeutral: request.IsNeutralSite, + IsConference: homeTeam.ConferenceID == awayTeam.ConferenceID, + IsDivisional: isDivisional, + IsPreseasonGame: request.IsPreseason, + } + + repository.CreateNFLGameRecordsBatch(db, []structs.NFLGame{game}, 1) + + request.Approved() + repository.SaveNFLGameRequest(request, db) +} + +// VetoNFLGameRequest deletes the request and notifies both the sending and +// receiving teams' owners if either is a user-managed team. +func VetoNFLGameRequest(requestID string) { + db := dbprovider.GetInstance().GetDB() + + request := repository.FindNFLGameRequestRecord(repository.SchedulerQuery{ID: requestID}) + + sendingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.SendingTeamID))) + receivingTeam := GetNFLTeamByTeamID(strconv.Itoa(int(request.RequestingTeamID))) + + repository.DeleteNFLGameRequest(request, db) + + ctx := context.Background() + msg := fmt.Sprintf("The game request between %s and %s for Week %d has been vetoed.", sendingTeam.TeamName, receivingTeam.TeamName, request.Week) + vetoKey := firebase.BuildSourceEventKey("gamerequest", "nfl", "veto", requestID) + + if isNFLUserTeam(sendingTeam) { + uids := firebase.ResolveUIDsByUsernames(ctx, []string{sendingTeam.NFLOwnerName}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "nfl", + Domain: firebase.DomainNFL, + TeamID: sendingTeam.ID, + RecipientUIDs: uids, + Message: msg, + SourceEventKey: vetoKey + ":sending", + }) + } + if isNFLUserTeam(receivingTeam) { + uids := firebase.ResolveUIDsByUsernames(ctx, []string{receivingTeam.NFLOwnerName}) + firebase.NotifyScheduleEvent(ctx, firebase.ScheduleEventNotificationInput{ + League: "nfl", + Domain: firebase.DomainNFL, + TeamID: receivingTeam.ID, + RecipientUIDs: uids, + Message: msg, + SourceEventKey: vetoKey + ":receiving", + }) + } +} + +// ───────────────────────────────────────────── +// Helpers +// ───────────────────────────────────────────── + +func isCFBUserTeam(team structs.CollegeTeam) bool { + return team.Coach != "" && team.Coach != "AI" +} + +func isNFLUserTeam(team structs.NFLTeam) bool { + return team.NFLOwnerName != "" && team.NFLOwnerName != "AI" +} diff --git a/managers/StandingsManager.go b/managers/StandingsManager.go index 732be6b..631a787 100644 --- a/managers/StandingsManager.go +++ b/managers/StandingsManager.go @@ -244,10 +244,14 @@ func GetAllNFLStandingsBySeasonID(seasonID string) []structs.NFLStandings { } func GetCollegeStandingsRecordByTeamID(id string, seasonID string) structs.CollegeStandings { - return repository.FindAllCollegeStandingsRecords(repository.StandingsQuery{ + standings := repository.FindAllCollegeStandingsRecords(repository.StandingsQuery{ TeamID: id, SeasonID: seasonID, - })[0] + }) + if len(standings) > 0 { + return standings[0] + } + return structs.CollegeStandings{} } func ResetCollegeStandingsRanks() { diff --git a/managers/TestManager.go b/managers/TestManager.go index 0894587..9313c78 100644 --- a/managers/TestManager.go +++ b/managers/TestManager.go @@ -926,7 +926,7 @@ func MigrateCFBGameplansAndDepthChartsForRemainingFCSTeams() { var testDCList []structs.CollegeTeamDepthChartTEST var dcPList []structs.CollegeDepthChartPosition var testDCPList []structs.CollegeDepthChartPositionTEST - for i := 195; i < 265; i++ { + for i := 266; i < 271; i++ { gp := structs.CollegeGameplan{ TeamID: i, Model: gorm.Model{ diff --git a/managers/TransferPortalManager.go b/managers/TransferPortalManager.go index 67286ef..55e0b89 100644 --- a/managers/TransferPortalManager.go +++ b/managers/TransferPortalManager.go @@ -1057,6 +1057,10 @@ func AICoachAllocateAndPromisePhase() { } } teamProfile.AIAllocateSpentPoints(points) + if teamProfile.ID > 500 { + // We shouldn't be making dummy records for this + continue + } repository.SaveRecruitingTeamProfile(teamProfile, db) } } @@ -1085,9 +1089,6 @@ func SyncTransferPortal() { if portalPlayer.TransferStatus != 2 || portalPlayer.TeamID > 0 { continue } - if portalPlayer.ID < 82716 { - continue - } portalProfiles := transferPortalProfileMap[portalPlayer.ID] if len(portalProfiles) == 0 && ts.TransferPortalRound < constants.FinalPortalRound { diff --git a/managers/WeatherManager.go b/managers/WeatherManager.go index 24fecaf..9500251 100644 --- a/managers/WeatherManager.go +++ b/managers/WeatherManager.go @@ -2,7 +2,6 @@ package managers import ( "encoding/csv" - "io/ioutil" "log" "math/rand" "os" @@ -741,9 +740,9 @@ func GetFutureWeather() []structs.GameResponse { } func getRegionalWeather() map[string]structs.WeatherRegion { - path := util.ReadLocalPath("data\\WeatherData") + path := filepath.Join(os.Getenv("ROOT"), "data", "WeatherData") - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { log.Fatal(err) } @@ -751,7 +750,7 @@ func getRegionalWeather() map[string]structs.WeatherRegion { regions := make(map[string]structs.WeatherRegion) for _, file := range files { - filePath := path + "\\" + file.Name() + filePath := filepath.Join(path, file.Name()) f, err := os.Open(filePath) if err != nil { log.Fatal("Unable to read input file "+filePath, err) @@ -809,15 +808,14 @@ func getRegionalWeather() map[string]structs.WeatherRegion { } func getRainChart() map[float64]map[int]string { - // path := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - Rain Chart.csv") - path := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "CalebRose", "SimFBA", "data", "WeatherSetup", "Weather Data - Rain Chart.csv") + path := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - Rain Chart.csv") rainChartCSV := util.ReadCSV(path) return getChartMap(rainChartCSV) } func getMixChart() map[float64]map[int]string { - path := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - Mix Chart.csv") + path := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - Mix Chart.csv") mixChartCSV := util.ReadCSV(path) @@ -825,7 +823,7 @@ func getMixChart() map[float64]map[int]string { } func getSnowChart() map[float64]map[int]string { - path := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - Snow Chart.csv") + path := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - Snow Chart.csv") snowChartCSV := util.ReadCSV(path) @@ -858,9 +856,9 @@ func getChartMap(csvRecords [][]string) map[float64]map[int]string { } func getRegionsForSchools() map[string]string { - FBSPath := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - FBS Assigns.csv") - FCSPath := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - FCS Assigns.csv") - NFLPath := util.ReadLocalPath("data\\WeatherSetup\\Weather Data - NFL Assigns.csv") + FBSPath := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - FBS Assigns.csv") + FCSPath := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - FCS Assigns.csv") + NFLPath := filepath.Join(os.Getenv("ROOT"), "data", "WeatherSetup", "Weather Data - NFL Assigns.csv") teamMap := make(map[string]string) diff --git a/repository/SchedulerRepository.go b/repository/SchedulerRepository.go new file mode 100644 index 0000000..a0617cd --- /dev/null +++ b/repository/SchedulerRepository.go @@ -0,0 +1,167 @@ +package repository + +import ( + "log" + + "github.com/CalebRose/SimFBA/dbprovider" + "github.com/CalebRose/SimFBA/structs" + "gorm.io/gorm" +) + +type SchedulerQuery struct { + ID string + TeamID string + IsSpringGames bool + IsNFLPreseason bool + IsAccepted bool + SeasonID string + WeekID string +} + +func FindCFBGameRequestRecord(scheduleParams SchedulerQuery) structs.CFBGameRequest { + db := dbprovider.GetInstance().GetDB() + var request structs.CFBGameRequest + + query := db.Model(&request) + + if len(scheduleParams.ID) > 0 { + query = query.Where("id = ?", scheduleParams.ID) + } + + if len(scheduleParams.TeamID) > 0 { + query = query.Where("home_team_id = ? OR away_team_id = ?", scheduleParams.TeamID, scheduleParams.TeamID) + } + if scheduleParams.IsSpringGames { + query = query.Where("is_spring_game = ?", true) + } + if err := query.Find(&request).Error; err != nil { + return structs.CFBGameRequest{} + } + return request +} + +func FindCFBGameRequestRecords(scheduleParams SchedulerQuery) []structs.CFBGameRequest { + db := dbprovider.GetInstance().GetDB() + var requests []structs.CFBGameRequest + + query := db.Model(&requests) + + if len(scheduleParams.TeamID) > 0 { + query = query.Where("home_team_id = ? OR away_team_id = ?", scheduleParams.TeamID, scheduleParams.TeamID) + } + if scheduleParams.IsAccepted { + query = query.Where("is_accepted = ?", true) + } + if len(scheduleParams.SeasonID) > 0 { + query = query.Where("season_id = ?", scheduleParams.SeasonID) + } + if len(scheduleParams.WeekID) > 0 { + query = query.Where("week_id = ?", scheduleParams.WeekID) + } + if scheduleParams.IsSpringGames { + query = query.Where("is_spring_game = ?", true) + } + + if err := query.Find(&requests).Error; err != nil { + return []structs.CFBGameRequest{} + } + return requests +} + +func FindNFLGameRequestRecord(scheduleParams SchedulerQuery) structs.NFLGameRequest { + db := dbprovider.GetInstance().GetDB() + var request structs.NFLGameRequest + + query := db.Model(&request) + + if len(scheduleParams.ID) > 0 { + query = query.Where("id = ?", scheduleParams.ID) + } + + if len(scheduleParams.TeamID) > 0 { + query = query.Where("home_team_id = ? OR away_team_id = ?", scheduleParams.TeamID, scheduleParams.TeamID) + } + if scheduleParams.IsNFLPreseason { + query = query.Where("is_nfl_preseason = ?", true) + } + if err := query.Find(&request).Error; err != nil { + return structs.NFLGameRequest{} + } + return request +} + +func FindNFLGameRequestRecords(scheduleParams SchedulerQuery) []structs.NFLGameRequest { + db := dbprovider.GetInstance().GetDB() + var requests []structs.NFLGameRequest + + query := db.Model(&requests) + + if len(scheduleParams.TeamID) > 0 { + query = query.Where("home_team_id = ? OR away_team_id = ?", scheduleParams.TeamID, scheduleParams.TeamID) + } + + // Return accepted but not yet approved requests for processing + if scheduleParams.IsAccepted { + query = query.Where("is_accepted = ? AND is_approved = ?", true, false) + } + if len(scheduleParams.SeasonID) > 0 { + query = query.Where("season_id = ?", scheduleParams.SeasonID) + } + if len(scheduleParams.WeekID) > 0 { + query = query.Where("week_id = ?", scheduleParams.WeekID) + } + if scheduleParams.IsNFLPreseason { + query = query.Where("is_nfl_preseason = ?", true) + } + + if err := query.Find(&requests).Error; err != nil { + return []structs.NFLGameRequest{} + } + return requests +} + +func CreateCFBGameRequest(request structs.CFBGameRequest, db *gorm.DB) { + err := db.Create(&request).Error + if err != nil { + log.Panicln("Could not create CFB game request record!") + } +} + +func SaveCFBGameRequest(request structs.CFBGameRequest, db *gorm.DB) error { + err := db.Save(&request).Error + if err != nil { + return err + } + return nil +} + +func CreateNFLGameRequest(request structs.NFLGameRequest, db *gorm.DB) { + err := db.Create(&request).Error + if err != nil { + log.Panicln("Could not create NFL game request record!") + } +} + +func SaveNFLGameRequest(request structs.NFLGameRequest, db *gorm.DB) error { + err := db.Save(&request).Error + if err != nil { + return err + } + return nil +} + +func DeleteCFBGameRequest(request structs.CFBGameRequest, db *gorm.DB) error { + err := db.Delete(&request).Error + if err != nil { + return err + } + return nil +} + +func DeleteNFLGameRequest(request structs.NFLGameRequest, db *gorm.DB) error { + err := db.Delete(&request).Error + if err != nil { + return err + } + return nil +} diff --git a/schedule_preview_season_2027.csv b/schedule_preview_season_2027.csv new file mode 100644 index 0000000..5c71a72 --- /dev/null +++ b/schedule_preview_season_2027.csv @@ -0,0 +1,1115 @@ +SeasonID,WeekID,Week,HomeTeamID,HomeTeam,AwayTeamID,AwayTeam,IsConference,IsDivisional,IsRivalry,IsNeutral,StadiumID,Stadium,City,State,TimeSlot +7,2701,1,130,Wyoming,119,Utah State,false,false,true,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Friday Night +7,2701,1,143,North Dakota State,144,South Dakota State,false,false,true,false,143,Fargodome,Fargo,ND,Friday Night +7,2701,1,185,Prairie View A&M,192,Texas Southern,true,true,true,false,185,Blackshear Field,Prairie View,TX,Friday Night +7,2701,1,44,Kansas,64,Missouri,false,false,true,false,44,David Booth Kansas Memorial Stadium,Lawrence,Kansas,Saturday Afternoon +7,2701,1,25,Colorado State,24,Colorado,false,false,true,false,25,Sonny Lubick Field at Canvas Stadium,Fort Collins,Colorado,Saturday Evening +7,2701,1,85,Pittsburgh,14,Boston College,true,false,true,false,85,Heinz Field,Pittsburgh,Pennsylvania,Saturday Morning +7,2701,1,190,Florida A&M,194,Jackson State,true,true,true,false,190,Bragg Memorial Stadium,Tallahassee,FL,Saturday Morning +7,2701,1,43,Iowa State,110,UCF,true,false,false,false,43,Jack Trice Stadium,Ames,Iowa,Saturday Night +7,2701,1,75,Notre Dame,65,Navy,false,false,true,false,75,Notre Dame Stadium,South Bend,Indiana,Thursday Night +7,2701,1,106,Troy,132,Jacksonville State,false,false,true,false,106,Veterans Memorial Stadium at Larry Blakeney Field,Troy,Alabama,Thursday Night +7,2701,1,195,Charleston Southern,176,The Citadel,false,false,true,false,220,Buccaneer Field,Bules Creek,NC,Thursday Night +7,2701,1,206,Delaware,221,Delaware State,false,false,true,false,231,Delaware Stadium,Newark,DE,Thursday Night +7,2701,1,214,Richmond,182,VMI,false,false,true,false,239,E. Claiborne Robins Stadium,Richmond,VA,Thursday Night +7,2702,2,33,Fresno State,90,San Jose State,false,false,true,false,33,Bulldog Stadium at Jim Sweeney Field,Fresno,California,Friday Night +7,2702,2,21,Cincinnati,110,UCF,true,false,true,false,21,Nippert Stadium,Cincinnati,Ohio,Saturday Afternoon +7,2702,2,201,Tennessee Tech,182,VMI,true,false,false,false,226,Tucker Stadium,Cookeville,TN,Saturday Afternoon +7,2702,2,24,Colorado,12,Baylor,true,false,false,false,24,Folsom Field,Boulder,Colorado,Saturday Evening +7,2702,2,60,Michigan State,75,Notre Dame,false,false,true,false,60,Spartan Stadium,East Lansing,Michigan,Saturday Evening +7,2702,2,14,Boston College,37,Georgia Tech,true,false,false,false,14,Alumni Stadium,Chestnut Hill,Massachusetts,Saturday Morning +7,2702,2,42,Iowa,43,Iowa State,false,false,true,false,42,Kinnick Stadium,Iowa City,Iowa,Saturday Night +7,2702,2,56,Memphis,95,Southern Miss,false,false,true,false,56,Liberty Bowl Memorial Stadium,Memphis,Tennessee,Thursday Night +7,2703,3,45,Kansas State,126,West Virginia,true,false,false,false,45,Bill Snyder Family Football Stadium,Manhattan,Kansas,Friday Night +7,2703,3,257,Central Arkansas,249,McNeese,false,false,true,false,282,Estes Stadium,Conway,AR,Friday Night +7,2703,3,78,Oklahoma,34,Georgia,true,false,false,false,78,Gaylord Family - Oklahoma Memorial Stadium at Owen Field,Norman,Oklahoma,Saturday Afternoon +7,2703,3,91,SMU,98,TCU,false,false,true,false,91,Gerald J. Ford Stadium,University Park,Texas,Saturday Afternoon +7,2703,3,116,UTEP,70,New Mexico State,false,false,true,false,116,Sun Bowl Stadium,El Paso,Texas,Saturday Afternoon +7,2703,3,166,Brown,213,Rhode Island,false,false,true,false,166,Brown Stadium,Providence,RI,Saturday Afternoon +7,2703,3,176,The Citadel,181,Mercer,true,false,false,false,176,Johnson Hagood Stadium,Charleston,SC,Saturday Afternoon +7,2703,3,194,Jackson State,200,Tennessee State,false,false,true,false,194,Mississippi Veterans Memorial Stadium,Jackson,MS,Saturday Afternoon +7,2703,3,25,Colorado State,130,Wyoming,false,false,true,false,25,Sonny Lubick Field at Canvas Stadium,Fort Collins,Colorado,Saturday Evening +7,2703,3,30,Florida,7,Arkansas,true,false,false,false,30,Steve Spurrier-Florida Field at Ben Hill Griffin Stadium,Gainesville,Florida,Saturday Evening +7,2703,3,110,UCF,39,Houston,true,false,false,false,110,Bounce House,Orlando,Florida,Saturday Evening +7,2703,3,137,Illinois State,196,Eastern Illinois,false,false,true,false,137,Hancock Stadium,Normal,IL,Saturday Evening +7,2703,3,14,Boston College,75,Notre Dame,false,false,true,false,14,Alumni Stadium,Chestnut Hill,Massachusetts,Saturday Morning +7,2703,3,148,Colgate,168,Cornell,false,false,true,false,148,Andy Kerr Stadium,Hamilton,NY,Saturday Morning +7,2703,3,24,Colorado,67,Nebraska,false,false,true,false,24,Folsom Field,Boulder,Colorado,Saturday Night +7,2703,3,238,Drake,140,Northern Iowa,false,false,true,false,263,Drake Stadium,Des Moines,IA,Saturday Night +7,2703,3,9,Army,1,Air Force,false,false,true,false,9,Blaik Field at Michie Stadium,West Point,New York,Thursday Night +7,2703,3,173,Yale,151,Lehigh,false,false,true,false,173,Yale Bowl,New Haven,CT,Thursday Night +7,2703,3,182,VMI,218,William & Mary,false,false,true,false,182,Foster Stadium,Lexington,VA,Thursday Night +7,2703,3,203,Albany,216,Towson,true,false,false,false,228,Tom & Mary Casey Stadium,Albany,NY,Thursday Night +7,2703,3,208,Hampton,222,Howard,false,false,true,false,233,Armstrong Stadium,Hampton,VA,Thursday Night +7,2703,3,212,North Carolina A&T,225,North Carolina Central,false,false,true,false,237,Truist Stadium,Greensboro,NC,Thursday Night +7,2704,4,5,Arizona,44,Kansas,true,false,false,false,5,Arizona Stadium,Tucson,Arizona,Friday Night +7,2704,4,8,Arkansas State,50,Louisiana Monroe,true,true,true,false,8,Centennial Bank Stadium,Jonesboro,Arkansas,Friday Night +7,2704,4,45,Kansas State,17,BYU,true,false,false,false,45,Bill Snyder Family Football Stadium,Manhattan,Kansas,Friday Night +7,2704,4,87,Rice,56,Memphis,true,false,false,false,87,Rice Stadium,Houston,Texas,Friday Night +7,2704,4,98,TCU,21,Cincinnati,true,false,false,false,98,Amon G. Carter Stadium,Fort Worth,Texas,Friday Night +7,2704,4,159,Montana,263,Utah Tech,true,false,false,false,159,Washington-Grizzly Stadium,Missoula,MT,Friday Night +7,2704,4,249,McNeese,251,Northwestern State,true,false,true,false,274,Cowboy Stadium,Lake Charles,LA,Friday Night +7,2704,4,12,Baylor,110,UCF,true,false,false,false,12,McLane Stadium,Waco,Texas,Saturday Afternoon +7,2704,4,36,Georgia State,49,Louisiana,true,false,false,false,36,Georgia State Stadium,Atlanta,Georgia,Saturday Afternoon +7,2704,4,75,Notre Dame,115,USC,false,false,true,false,75,Notre Dame Stadium,South Bend,Indiana,Saturday Afternoon +7,2704,4,85,Pittsburgh,122,Virginia Tech,true,false,false,false,85,Heinz Field,Pittsburgh,Pennsylvania,Saturday Afternoon +7,2704,4,92,South Alabama,80,Old Dominion,true,false,false,false,92,Ladd-Peebles Stadium,Mobile,Alabama,Saturday Afternoon +7,2704,4,102,Texas A&M,100,Tennessee,true,false,false,false,102,Kyle Field,College Station,Texas,Saturday Afternoon +7,2704,4,104,Texas Tech,24,Colorado,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Afternoon +7,2704,4,6,Arizona State,79,Oklahoma State,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Evening +7,2704,4,30,Florida,34,Georgia,true,false,true,true,203,TIAA Bank Field,Jacksonville,FL,Saturday Evening +7,2704,4,41,Indiana,42,Iowa,true,false,false,false,41,Memorial Stadium,Bloomington,Indiana,Saturday Evening +7,2704,4,43,Iowa State,39,Houston,true,false,false,false,43,Jack Trice Stadium,Ames,Iowa,Saturday Evening +7,2704,4,71,North Carolina,123,Wake Forest,true,false,true,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Evening +7,2704,4,183,Grambling,185,Prairie View A&M,true,true,true,false,183,Eddie G. Robinson Memorial Stadium,Grambling,LA,Saturday Evening +7,2704,4,46,Kent State,113,UMass,true,false,false,false,46,Dix Stadium,Kent,Ohio,Saturday Morning +7,2704,4,58,Miami (OH),11,Ball State,true,false,false,false,58,Fred C. Yager Stadium,Oxford,Ohio,Saturday Morning +7,2704,4,66,NC State,57,Miami (FL),true,false,false,false,66,Wayne Day Family Field at Carter-Finley Stadium,Raleigh,North Carolina,Saturday Morning +7,2704,4,76,Ohio,15,Bowling Green,true,false,false,false,76,Peden Stadium,Athens,Ohio,Saturday Morning +7,2704,4,126,West Virginia,118,Utah,true,false,false,false,126,Mountaineer Field at Milan Puskar Stadium,Morgantown,West Virginia,Saturday Morning +7,2704,4,180,Western Carolina,181,Mercer,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Saturday Morning +7,2704,4,191,Alabama State,187,Southern,true,false,false,false,191,New ASU Stadium,Montgomery,AL,Saturday Morning +7,2704,4,245,Valparaiso,240,Morehead State,true,false,false,false,270,Brown Field,Valparaiso,IN,Saturday Morning +7,2704,4,33,Fresno State,89,San Diego State,true,false,true,false,33,Bulldog Stadium at Jim Sweeney Field,Fresno,California,Saturday Night +7,2704,4,38,Hawaii,90,San Jose State,true,false,true,false,38,Aloha Stadium,Honolulu,Hawai'i,Saturday Night +7,2704,4,62,Minnesota,60,Michigan State,true,false,false,false,62,TCF Bank Stadium,Minneapolis,Minnesota,Saturday Night +7,2704,4,101,Texas,47,Kentucky,true,false,false,false,101,Darrell K Royal-Texas Memorial Stadium,Austin,Texas,Saturday Night +7,2704,4,16,Buffalo,2,Akron,true,false,false,false,16,UB Stadium,Buffalo,New York,Thursday Night +7,2704,4,22,Clemson,26,Duke,true,false,false,false,22,Frank Howard Field at Clemson Memorial Stadium,Clemson,South Carolina,Thursday Night +7,2704,4,27,East Carolina,108,Tulsa,true,false,false,false,27,Bagwell Field at Dowdy-Ficklen Stadium,Greenville,North Carolina,Thursday Night +7,2704,4,37,Georgia Tech,52,Louisville,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Thursday Night +7,2704,4,55,Maryland,67,Nebraska,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Thursday Night +7,2704,4,59,Michigan,124,Washington,true,false,false,false,59,Michigan Stadium,Ann Arbor,Michigan,Thursday Night +7,2704,4,81,Ole Miss,53,LSU,true,false,true,false,81,Vaught-Hemingway Stadium at Hollingsworth Field,Oxford,Mississippi,Thursday Night +7,2704,4,93,South Carolina,64,Missouri,true,false,true,false,93,Williams-Brice Stadium,Columbia,South Carolina,Thursday Night +7,2704,4,135,Youngstown State,139,Murray State,true,false,false,false,135,Stambaugh Stadium,Youngstown,OH,Thursday Night +7,2704,4,201,Tennessee Tech,178,Chattanooga,true,false,false,false,226,Tucker Stadium,Cookeville,TN,Thursday Night +7,2704,4,216,Towson,215,Stony Brook,true,false,false,false,241,Johnny Unitas Stadiumn,Towson,MD,Thursday Night +7,2704,4,222,Howard,223,Morgan State,true,false,true,false,247,William H. Greene Stadium,Washington,DC,Thursday Night +7,2705,5,8,Arkansas State,36,Georgia State,true,false,false,false,8,Centennial Bank Stadium,Jonesboro,Arkansas,Friday Night +7,2705,5,43,Iowa State,45,Kansas State,true,false,true,false,43,Jack Trice Stadium,Ames,Iowa,Friday Night +7,2705,5,70,New Mexico State,29,FIU,true,false,false,false,70,Aggie Memorial Stadium,Las Cruces,New Mexico,Friday Night +7,2705,5,79,Oklahoma State,21,Cincinnati,true,false,false,false,79,Boone Pickens Stadium,Stillwater,Oklahoma,Friday Night +7,2705,5,98,TCU,5,Arizona,true,false,false,false,98,Amon G. Carter Stadium,Fort Worth,Texas,Friday Night +7,2705,5,103,Texas State,119,Utah State,true,false,false,false,103,Jim Wacker Field at Bobcat Stadium,San Marcos,Texas,Friday Night +7,2705,5,187,Southern,188,Alabama A&M,true,false,false,false,187,A.W. Mumford Stadium,Baton Rouge,LA,Friday Night +7,2705,5,238,Drake,240,Morehead State,true,false,false,false,263,Drake Stadium,Des Moines,IA,Friday Night +7,2705,5,243,St. Thomas,242,San Diego,true,false,false,false,268,O'Shaughnessy Stadium,Saint Paul,MN,Friday Night +7,2705,5,260,Southern Utah,165,Weber State,true,false,true,false,285,Eccles Coliseum,Cedar City,UT,Friday Night +7,2705,5,261,Stephen F. Austin,248,Lamar,true,false,false,false,286,Homer Bryce Stadium,Nacogdoches,TX,Friday Night +7,2705,5,30,Florida,47,Kentucky,true,false,true,false,30,Steve Spurrier-Florida Field at Ben Hill Griffin Stadium,Gainesville,Florida,Saturday Afternoon +7,2705,5,61,Middle Tennessee,206,Delaware,true,false,false,false,61,Johnny Red Floyd Stadium,Murfreesboro,Tennessee,Saturday Afternoon +7,2705,5,117,UTSA,108,Tulsa,true,false,false,false,117,Alamodome,San Antonio,Texas,Saturday Afternoon +7,2705,5,120,Vanderbilt,81,Ole Miss,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Saturday Afternoon +7,2705,5,129,Wisconsin,82,Oregon,true,false,false,false,129,Camp Randall Stadium,Madison,Wisconsin,Saturday Afternoon +7,2705,5,152,Fordham,149,Holy Cross,true,false,true,false,152,Jack Coffey Field,Bronx,NY,Saturday Afternoon +7,2705,5,183,Grambling,194,Jackson State,true,false,false,false,183,Eddie G. Robinson Memorial Stadium,Grambling,LA,Saturday Afternoon +7,2705,5,250,Nicholls,252,SE Louisiana,true,false,true,false,275,Manning Field at John L. Guidry Stadium,Thibodaux,LA,Saturday Afternoon +7,2705,5,37,Georgia Tech,121,Virginia,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Saturday Evening +7,2705,5,52,Louisville,18,California,true,false,false,false,52,Cardinal Stadium,Louisville,Kentucky,Saturday Evening +7,2705,5,68,Nevada,90,San Jose State,true,false,false,false,68,Mackay Stadium,Reno,Nevada,Saturday Evening +7,2705,5,77,Ohio State,74,Northwestern,true,false,false,false,77,Ohio Stadium,Columbus,Ohio,Saturday Evening +7,2705,5,84,Penn State,115,USC,true,false,false,false,84,Beaver Stadium,University Park,Pennsylvania,Saturday Evening +7,2705,5,100,Tennessee,64,Missouri,true,false,false,false,100,Neyland Stadium,Knoxville,Tennessee,Saturday Evening +7,2705,5,125,Washington State,89,San Diego State,true,false,false,false,125,Martin Stadium,Pullman,Washington,Saturday Evening +7,2705,5,10,Auburn,34,Georgia,true,false,true,false,10,Pat Dye Field at Jordan-Hare Stadium,Auburn,Alabama,Saturday Morning +7,2705,5,54,Marshall,80,Old Dominion,true,true,false,false,54,Joan C. Edwards Stadium,Huntington,West Virginia,Saturday Morning +7,2705,5,191,Alabama State,189,Arkansas-Pine Bluff,true,false,false,false,191,New ASU Stadium,Montgomery,AL,Saturday Morning +7,2705,5,201,Tennessee Tech,176,The Citadel,true,false,false,false,226,Tucker Stadium,Cookeville,TN,Saturday Morning +7,2705,5,208,Hampton,211,New Hampshire,true,false,false,false,233,Armstrong Stadium,Hampton,VA,Saturday Morning +7,2705,5,213,Rhode Island,216,Towson,true,false,false,false,238,Meade Stadium,Kingston,RI,Saturday Morning +7,2705,5,229,LIU,265,Chicago State,true,false,false,false,254,Bethpage Federal Credit Union Stadium,Brooklyn,NY,Saturday Morning +7,2705,5,6,Arizona State,12,Baylor,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Night +7,2705,5,39,Houston,118,Utah,true,false,false,false,39,John O'Quinn Field at TDECU Stadium,Houston,Texas,Saturday Night +7,2705,5,69,New Mexico,130,Wyoming,true,false,false,false,69,Dreamstyle Stadium,Albuquerque,New Mexico,Saturday Night +7,2705,5,87,Rice,99,Temple,true,false,false,false,87,Rice Stadium,Houston,Texas,Saturday Night +7,2705,5,104,Texas Tech,17,BYU,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Night +7,2705,5,111,UCLA,67,Nebraska,true,false,false,false,111,Rose Bowl Stadium,Los Angeles,California,Saturday Night +7,2705,5,137,Illinois State,135,Youngstown State,true,false,false,false,137,Hancock Stadium,Normal,IL,Saturday Night +7,2705,5,159,Montana,162,Northern Colorado,true,false,false,false,159,Washington-Grizzly Stadium,Missoula,MT,Saturday Night +7,2705,5,160,Montana State,158,Idaho State,true,false,false,false,160,Bobcat Stadium,Bozeman,MT,Saturday Night +7,2705,5,23,Coastal Carolina,95,Southern Miss,true,false,false,false,23,Brooks Stadium,Conway,South Carolina,Thursday Night +7,2705,5,28,Eastern Michigan,113,UMass,true,false,false,false,28,Rynearson Stadium,Ypsilanti,Michigan,Thursday Night +7,2705,5,35,Georgia Southern,106,Troy,true,false,false,false,35,Allen E. Paulson Stadium,Statesboro,Georgia,Thursday Night +7,2705,5,41,Indiana,60,Michigan State,true,false,true,false,41,Memorial Stadium,Bloomington,Indiana,Thursday Night +7,2705,5,57,Miami (FL),91,SMU,true,false,false,false,57,Hard Rock Stadium,Coral Gables,Florida,Thursday Night +7,2705,5,75,Notre Dame,59,Michigan,false,false,true,false,75,Notre Dame Stadium,South Bend,Indiana,Thursday Night +7,2705,5,85,Pittsburgh,22,Clemson,true,false,false,false,85,Heinz Field,Pittsburgh,Pennsylvania,Thursday Night +7,2705,5,94,South Florida,65,Navy,true,false,false,false,94,Raymond James Stadium,Tampa,Florida,Thursday Night +7,2705,5,97,Syracuse,123,Wake Forest,true,false,false,false,97,Carrier Dome,Syracuse,New York,Thursday Night +7,2705,5,132,Jacksonville State,48,Liberty,true,false,false,false,132,Burgess-Snow Field at JSU Stadium,Jacksonville,Alabama,Thursday Night +7,2705,5,181,Mercer,177,Wofford,true,false,false,false,181,Five Star Stadium,Macon,GA,Thursday Night +7,2705,5,190,Florida A&M,186,Alcorn State,true,false,false,false,190,Bragg Memorial Stadium,Tallahassee,FL,Thursday Night +7,2705,5,193,Mississippi Valley State,192,Texas Southern,true,false,false,false,193,Rice-Totten Stadium,Itta Bena,MS,Thursday Night +7,2705,5,212,North Carolina A&T,207,Elon,true,false,false,false,237,Truist Stadium,Greensboro,NC,Thursday Night +7,2706,6,51,Louisiana Tech,54,Marshall,true,false,false,false,51,JPS Field at Malone Stadium,Ruston,Louisiana,Friday Night +7,2706,6,62,Minnesota,124,Washington,true,false,false,false,62,TCF Bank Stadium,Minneapolis,Minnesota,Friday Night +7,2706,6,91,SMU,96,Stanford,true,false,true,false,91,Gerald J. Ford Stadium,University Park,Texas,Friday Night +7,2706,6,108,Tulsa,107,Tulane,true,false,false,false,108,Skelly Field at H. A. Chapman Stadium,Tulsa,Oklahoma,Friday Night +7,2706,6,138,Missouri State,48,Liberty,true,false,false,false,138,Robert W. Plaster Stadium,Springfield,MO,Friday Night +7,2706,6,140,Northern Iowa,139,Murray State,true,false,false,false,140,UNI-Dome,Cedar Falls,IA,Friday Night +7,2706,6,143,North Dakota State,116,UTEP,true,false,false,false,143,Fargodome,Fargo,ND,Friday Night +7,2706,6,163,Portland State,165,Weber State,true,false,false,false,163,Hillsboro Stadium,Portland,OR,Friday Night +7,2706,6,18,California,85,Pittsburgh,true,false,false,false,18,California Memorial Stadium,Berkeley,California,Saturday Afternoon +7,2706,6,28,Eastern Michigan,11,Ball State,true,false,false,false,28,Rynearson Stadium,Ypsilanti,Michigan,Saturday Afternoon +7,2706,6,30,Florida,63,Mississippi State,true,false,false,false,30,Steve Spurrier-Florida Field at Ben Hill Griffin Stadium,Gainesville,Florida,Saturday Afternoon +7,2706,6,34,Georgia,93,South Carolina,true,false,true,false,34,Sanford Stadium,Athens,Georgia,Saturday Afternoon +7,2706,6,40,Illinois,41,Indiana,true,false,true,false,40,Memorial Stadium,Urbana Champaign,Illinois,Saturday Afternoon +7,2706,6,47,Kentucky,100,Tennessee,true,false,true,false,47,Kroger Field at C.M. Newton Grounds,Lexington,Kentucky,Saturday Afternoon +7,2706,6,52,Louisville,32,Florida State,true,false,false,false,52,Cardinal Stadium,Louisville,Kentucky,Saturday Afternoon +7,2706,6,60,Michigan State,129,Wisconsin,true,false,false,false,60,Spartan Stadium,East Lansing,Michigan,Saturday Afternoon +7,2706,6,67,Nebraska,82,Oregon,true,false,false,false,67,"Memorial Stadium, Tom Osborne Field",Lincoln,Nebraska,Saturday Afternoon +7,2706,6,79,Oklahoma State,43,Iowa State,true,false,false,false,79,Boone Pickens Stadium,Stillwater,Oklahoma,Saturday Afternoon +7,2706,6,102,Texas A&M,3,Alabama,true,false,false,false,102,Kyle Field,College Station,Texas,Saturday Afternoon +7,2706,6,117,UTSA,27,East Carolina,true,false,false,false,117,Alamodome,San Antonio,Texas,Saturday Afternoon +7,2706,6,119,Utah State,83,Oregon State,true,false,false,false,119,Merlin Olsen Field at Maverik Stadium,Logan,Utah,Saturday Afternoon +7,2706,6,126,West Virginia,24,Colorado,true,false,false,false,126,Mountaineer Field at Milan Puskar Stadium,Morgantown,West Virginia,Saturday Afternoon +7,2706,6,128,Western Michigan,76,Ohio,true,false,false,false,128,Waldo Stadium,Kalamazoo,Michigan,Saturday Afternoon +7,2706,6,174,Furman,180,Western Carolina,true,false,false,false,174,Paladin Stadium,Greenville,SC,Saturday Afternoon +7,2706,6,175,Samford,179,East Tennessee State,true,false,false,false,175,Seibert Stadium,Homewood,AL,Saturday Afternoon +7,2706,6,181,Mercer,178,Chattanooga,true,false,false,false,181,Five Star Stadium,Macon,GA,Saturday Afternoon +7,2706,6,216,Towson,210,Monmouth,true,false,false,false,241,Johnny Unitas Stadiumn,Towson,MD,Saturday Afternoon +7,2706,6,245,Valparaiso,235,Butler,true,false,true,false,270,Brown Field,Valparaiso,IN,Saturday Afternoon +7,2706,6,251,Northwestern State,246,Houston Christian,true,false,false,false,276,Harry Turpin Stadium,Natchitotches,LA,Saturday Afternoon +7,2706,6,254,UT Rio Grande Valley,252,SE Louisiana,true,false,false,false,279,Robert and Janet Vackar Stadium,Edinburg,TX,Saturday Afternoon +7,2706,6,265,Chicago State,234,Wagner,true,false,false,false,290,SeatGeek Stadium,Chicago,IL,Saturday Afternoon +7,2706,6,7,Arkansas,78,Oklahoma,true,false,false,false,7,"Donald W. Reynolds Razorback Stadium, Frank Broyles Field",Fayetteville,Arkansas,Saturday Evening +7,2706,6,17,BYU,98,TCU,true,false,false,false,17,LaVell Edwards Stadium,Provo,Utah,Saturday Evening +7,2706,6,42,Iowa,115,USC,true,false,false,false,42,Kinnick Stadium,Iowa City,Iowa,Saturday Evening +7,2706,6,49,Louisiana,131,James Madison,true,false,false,false,49,Cajun Field,Lafayette,Louisiana,Saturday Evening +7,2706,6,55,Maryland,74,Northwestern,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Saturday Evening +7,2706,6,66,NC State,97,Syracuse,true,false,false,false,66,Wayne Day Family Field at Carter-Finley Stadium,Raleigh,North Carolina,Saturday Evening +7,2706,6,71,North Carolina,22,Clemson,true,false,false,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Evening +7,2706,6,90,San Jose State,130,Wyoming,true,false,false,false,90,CEFCU Stadium,San Jose,California,Saturday Evening +7,2706,6,121,Virginia,57,Miami (FL),true,false,false,false,121,David A. Harrison III Field at Scott Stadium,Charlottesville,Virginia,Saturday Evening +7,2706,6,144,South Dakota State,135,Youngstown State,true,false,false,false,144,Dana J. Dykhouse Stadium,Brookings,SD,Saturday Evening +7,2706,6,145,South Dakota,141,Southern Illinois,true,false,false,false,145,DakotaDome,Vermillion,SD,Saturday Evening +7,2706,6,159,Montana,161,Northern Arizona,true,false,false,false,159,Washington-Grizzly Stadium,Missoula,MT,Saturday Evening +7,2706,6,248,Lamar,250,Nicholls,true,false,false,false,273,Provost Umphrey Stadium,Beaumont,TX,Saturday Evening +7,2706,6,21,Cincinnati,45,Kansas State,true,false,false,false,21,Nippert Stadium,Cincinnati,Ohio,Saturday Morning +7,2706,6,29,FIU,133,Sam Houston State,true,false,false,false,29,Riccardo Silva Stadium,Miami,Florida,Saturday Morning +7,2706,6,65,Navy,31,Florida Atlantic,true,false,false,false,65,Navy-Marine Corps Memorial Stadium,Annapolis,Maryland,Saturday Morning +7,2706,6,88,Rutgers,84,Penn State,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Saturday Morning +7,2706,6,99,Temple,20,Charlotte,true,false,false,false,99,Lincoln Financial Field,Philadelphia,Pennsylvania,Saturday Morning +7,2706,6,151,Lehigh,214,Richmond,true,false,false,false,151,Goodman Stadium,Bethlehem,PA,Saturday Morning +7,2706,6,167,Columbia,166,Brown,true,false,false,false,167,Lawrence A. Wien Stadium,New York,NY,Saturday Morning +7,2706,6,193,Mississippi Valley State,189,Arkansas-Pine Bluff,true,false,false,false,193,Rice-Totten Stadium,Itta Bena,MS,Saturday Morning +7,2706,6,233,Stonehill,227,Central Connecticut,true,false,false,false,258,W.B. Mason Stadium,Easton,MA,Saturday Morning +7,2706,6,240,Morehead State,242,San Diego,true,false,false,false,265,Jayne Stadium,Morehead,KY,Saturday Morning +7,2706,6,1,Air Force,73,Northern Illinois,true,false,false,false,1,Falcon Stadium,Colorado Springs,Colorado,Saturday Night +7,2706,6,5,Arizona,104,Texas Tech,true,false,false,false,5,Arizona Stadium,Tucson,Arizona,Saturday Night +7,2706,6,6,Arizona State,39,Houston,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Night +7,2706,6,12,Baylor,118,Utah,true,false,false,false,12,McLane Stadium,Waco,Texas,Saturday Night +7,2706,6,111,UCLA,59,Michigan,true,false,false,false,111,Rose Bowl Stadium,Los Angeles,California,Saturday Night +7,2706,6,125,Washington State,25,Colorado State,true,false,false,false,125,Martin Stadium,Pullman,Washington,Saturday Night +7,2706,6,142,North Dakota,136,Indiana State,true,false,false,false,142,Alerus Center,Grand Forks,ND,Saturday Night +7,2706,6,158,Idaho State,155,Cal Poly,true,false,false,false,158,Holt Arena,Pocatello,ID,Saturday Night +7,2706,6,185,Prairie View A&M,188,Alabama A&M,true,false,false,false,185,Blackshear Field,Prairie View,TX,Saturday Night +7,2706,6,4,Appalachian State,95,Southern Miss,true,false,false,false,4,Kidd Brewer Stadium,Boone,North Carolina,Thursday Night +7,2706,6,19,Central Michigan,15,Bowling Green,true,false,false,false,19,Kelly/Shorts Stadium,Mount Pleasant,Michigan,Thursday Night +7,2706,6,23,Coastal Carolina,106,Troy,true,false,false,false,23,Brooks Stadium,Conway,South Carolina,Thursday Night +7,2706,6,26,Duke,122,Virginia Tech,true,false,false,false,26,Brooks Field at Wallace Wade Stadium,Durham,North Carolina,Thursday Night +7,2706,6,56,Memphis,72,North Texas,true,false,false,false,56,Liberty Bowl Memorial Stadium,Memphis,Tennessee,Thursday Night +7,2706,6,61,Middle Tennessee,134,Kennesaw State,true,false,false,false,61,Johnny Red Floyd Stadium,Murfreesboro,Tennessee,Thursday Night +7,2706,6,80,Old Dominion,36,Georgia State,true,true,false,false,80,Foreman Field at S. B. Ballard Stadium,Norfolk,Virginia,Thursday Night +7,2706,6,81,Ole Miss,10,Auburn,true,false,false,false,81,Vaught-Hemingway Stadium at Hollingsworth Field,Oxford,Mississippi,Thursday Night +7,2706,6,86,Purdue,77,Ohio State,true,false,false,false,86,Ross-Ade Stadium,West Lafayette,Indiana,Thursday Night +7,2706,6,114,UNLV,38,Hawaii,true,false,false,false,114,Allegient Stadium,Las Vegas,Nevada,Thursday Night +7,2706,6,123,Wake Forest,37,Georgia Tech,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Thursday Night +7,2706,6,132,Jacksonville State,127,Western Kentucky,true,false,false,false,132,Burgess-Snow Field at JSU Stadium,Jacksonville,Alabama,Thursday Night +7,2706,6,154,UC Davis,157,Idaho,true,false,false,false,154,UC Davis Health Stadium,Davis,CA,Thursday Night +7,2706,6,164,Sacramento State,105,Toledo,true,false,false,false,164,Hornet Stadium,Sacramento,CA,Thursday Night +7,2706,6,177,Wofford,201,Tennessee Tech,true,false,false,false,177,Gibbs Stadium,Spartanburg,SC,Thursday Night +7,2706,6,186,Alcorn State,184,Bethune-Cookman,true,false,false,false,186,Spinks-Casem Stadium,Lorman,MS,Thursday Night +7,2706,6,194,Jackson State,191,Alabama State,true,true,false,false,194,Mississippi Veterans Memorial Stadium,Jackson,MS,Thursday Night +7,2706,6,206,Delaware,70,New Mexico State,true,false,false,false,231,Delaware Stadium,Newark,DE,Thursday Night +7,2706,6,209,Maine,212,North Carolina A&T,true,false,false,false,234,Harold Alfond Sports Stadium,Orono,ME,Thursday Night +7,2706,6,211,New Hampshire,205,Campbell,true,false,false,false,236,Wildcat Stadium,Durham,NH,Thursday Night +7,2706,6,230,Mercyhurst,228,Duquesne,true,false,false,false,255,Saxon Stadium,Erie,PA,Thursday Night +7,2706,6,231,Robert Morris,266,New Haven,true,false,false,false,256,Joe Walton Stadium,Moon Township,PA,Thursday Night +7,2706,6,236,Davidson,244,Stetson,true,false,false,false,261,Richardson Stadium,Davidson,NC,Thursday Night +7,2707,7,8,Arkansas State,35,Georgia Southern,true,false,false,false,8,Centennial Bank Stadium,Jonesboro,Arkansas,Friday Night +7,2707,7,49,Louisiana,51,Louisiana Tech,true,true,true,false,49,Cajun Field,Lafayette,Louisiana,Friday Night +7,2707,7,83,Oregon State,103,Texas State,true,false,false,false,83,Reser Stadium,Corvallis,Oregon,Friday Night +7,2707,7,108,Tulsa,9,Army,true,false,false,false,108,Skelly Field at H. A. Chapman Stadium,Tulsa,Oklahoma,Friday Night +7,2707,7,137,Illinois State,141,Southern Illinois,true,false,false,false,137,Hancock Stadium,Normal,IL,Friday Night +7,2707,7,144,South Dakota State,140,Northern Iowa,true,false,false,false,144,Dana J. Dykhouse Stadium,Brookings,SD,Friday Night +7,2707,7,146,Western Illinois,197,Gardner-Webb,true,false,false,false,146,Hanson Field,Macomb,IL,Friday Night +7,2707,7,154,UC Davis,159,Montana,true,false,false,false,154,UC Davis Health Stadium,Davis,CA,Friday Night +7,2707,7,156,Eastern Washington,161,Northern Arizona,true,false,false,false,156,Roos Field,Cheney,WA,Friday Night +7,2707,7,157,Idaho,160,Montana State,true,false,false,false,157,Kibbie Dome,Moscow,ID,Friday Night +7,2707,7,162,Northern Colorado,165,Weber State,true,false,false,false,162,Nottingham Field,Greeley,CO,Friday Night +7,2707,7,199,Southeast Missouri State,200,Tennessee State,true,false,false,false,224,Houck Stadium,Cape Girardeau,MO,Friday Night +7,2707,7,251,Northwestern State,252,SE Louisiana,true,false,true,false,276,Harry Turpin Stadium,Natchitotches,LA,Friday Night +7,2707,7,263,Utah Tech,155,Cal Poly,true,false,false,false,288,Greater Zion STadium,St. George,UT,Friday Night +7,2707,7,15,Bowling Green,164,Sacramento State,true,false,false,false,15,Doyt L. Perry Stadium,Bowling Green,Ohio,Saturday Afternoon +7,2707,7,18,California,32,Florida State,true,false,false,false,18,California Memorial Stadium,Berkeley,California,Saturday Afternoon +7,2707,7,29,FIU,138,Missouri State,true,false,false,false,29,Riccardo Silva Stadium,Miami,Florida,Saturday Afternoon +7,2707,7,47,Kentucky,63,Mississippi State,true,false,false,false,47,Kroger Field at C.M. Newton Grounds,Lexington,Kentucky,Saturday Afternoon +7,2707,7,64,Missouri,53,LSU,true,false,false,false,64,Faurot Field at Memorial Stadium,Columbia,Missouri,Saturday Afternoon +7,2707,7,67,Nebraska,124,Washington,true,false,false,false,67,"Memorial Stadium, Tom Osborne Field",Lincoln,Nebraska,Saturday Afternoon +7,2707,7,74,Northwestern,111,UCLA,true,false,false,false,74,Ryan Field,Evanston,Illinois,Saturday Afternoon +7,2707,7,76,Ohio,19,Central Michigan,true,false,false,false,76,Peden Stadium,Athens,Ohio,Saturday Afternoon +7,2707,7,79,Oklahoma State,44,Kansas,true,false,false,false,79,Boone Pickens Stadium,Stillwater,Oklahoma,Saturday Afternoon +7,2707,7,80,Old Dominion,23,Coastal Carolina,true,true,false,false,80,Foreman Field at S. B. Ballard Stadium,Norfolk,Virginia,Saturday Afternoon +7,2707,7,101,Texas,78,Oklahoma,true,false,true,true,0,,,,Saturday Afternoon +7,2707,7,104,Texas Tech,98,TCU,true,false,true,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Afternoon +7,2707,7,134,Kennesaw State,48,Liberty,true,false,false,false,134,Fifth Third Bank Stadium,Kennesaw,Georgia,Saturday Afternoon +7,2707,7,142,North Dakota,139,Murray State,true,false,false,false,142,Alerus Center,Grand Forks,ND,Saturday Afternoon +7,2707,7,180,Western Carolina,179,East Tennessee State,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Saturday Afternoon +7,2707,7,181,Mercer,182,VMI,true,false,false,false,181,Five Star Stadium,Macon,GA,Saturday Afternoon +7,2707,7,189,Arkansas-Pine Bluff,190,Florida A&M,true,false,false,false,189,Simmons Bank Field,Pine Bluff,AR,Saturday Afternoon +7,2707,7,202,UT Martin,195,Charleston Southern,true,false,false,false,227,Graham Stadium,Martin,TN,Saturday Afternoon +7,2707,7,212,North Carolina A&T,203,Albany,true,false,false,false,237,Truist Stadium,Greensboro,NC,Saturday Afternoon +7,2707,7,216,Towson,209,Maine,true,false,false,false,241,Johnny Unitas Stadiumn,Towson,MD,Saturday Afternoon +7,2707,7,218,William & Mary,152,Fordham,true,false,false,false,243,Water J. Zable Stadium,Williamsburg,VA,Saturday Afternoon +7,2707,7,220,Sacred Heart,208,Hampton,true,false,false,false,245,Campus Field,Fairfield,CT,Saturday Afternoon +7,2707,7,236,Davidson,239,Marist,true,false,false,false,261,Richardson Stadium,Davidson,NC,Saturday Afternoon +7,2707,7,266,New Haven,234,Wagner,true,false,false,false,291,Ralph F. DellaCamera Stadium,New Haven,CT,Saturday Afternoon +7,2707,7,24,Colorado,39,Houston,true,false,false,false,24,Folsom Field,Boulder,Colorado,Saturday Evening +7,2707,7,26,Duke,57,Miami (FL),true,false,false,false,26,Brooks Field at Wallace Wade Stadium,Durham,North Carolina,Saturday Evening +7,2707,7,38,Hawaii,116,UTEP,true,false,false,false,38,Aloha Stadium,Honolulu,Hawai'i,Saturday Evening +7,2707,7,41,Indiana,129,Wisconsin,true,false,false,false,41,Memorial Stadium,Bloomington,Indiana,Saturday Evening +7,2707,7,42,Iowa,62,Minnesota,true,false,true,false,42,Kinnick Stadium,Iowa City,Iowa,Saturday Evening +7,2707,7,59,Michigan,82,Oregon,true,false,false,false,59,Michigan Stadium,Ann Arbor,Michigan,Saturday Evening +7,2707,7,72,North Texas,31,Florida Atlantic,true,false,false,false,72,Apogee Stadium,Denton,Texas,Saturday Evening +7,2707,7,96,Stanford,22,Clemson,true,false,false,false,96,Stanford Stadium,Stanford,California,Saturday Evening +7,2707,7,107,Tulane,65,Navy,true,false,false,false,107,Barry B. Benson Field at Yulman Stadium,New Orleans,Louisiana,Saturday Evening +7,2707,7,123,Wake Forest,122,Virginia Tech,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Saturday Evening +7,2707,7,163,Portland State,158,Idaho State,true,false,false,false,163,Hillsboro Stadium,Portland,OR,Saturday Evening +7,2707,7,243,St. Thomas,240,Morehead State,true,false,false,false,268,O'Shaughnessy Stadium,Saint Paul,MN,Saturday Evening +7,2707,7,246,Houston Christian,253,East Texas A&M,true,false,false,false,271,Husky Stadium,Houston,TX,Saturday Evening +7,2707,7,261,Stephen F. Austin,247,Incarnate Word,true,false,false,false,286,Homer Bryce Stadium,Nacogdoches,TX,Saturday Evening +7,2707,7,16,Buffalo,11,Ball State,true,false,false,false,16,UB Stadium,Buffalo,New York,Saturday Morning +7,2707,7,37,Georgia Tech,66,NC State,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Saturday Morning +7,2707,7,85,Pittsburgh,91,SMU,true,false,false,false,85,Heinz Field,Pittsburgh,Pennsylvania,Saturday Morning +7,2707,7,88,Rutgers,77,Ohio State,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Saturday Morning +7,2707,7,100,Tennessee,7,Arkansas,true,false,false,false,100,Neyland Stadium,Knoxville,Tennessee,Saturday Morning +7,2707,7,110,UCF,126,West Virginia,true,false,false,false,110,Bounce House,Orlando,Florida,Saturday Morning +7,2707,7,120,Vanderbilt,34,Georgia,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Saturday Morning +7,2707,7,184,Bethune-Cookman,185,Prairie View A&M,true,false,false,false,184,Daytona Stadium,Daytona Beach,FL,Saturday Morning +7,2707,7,194,Jackson State,192,Texas Southern,true,false,false,false,194,Mississippi Veterans Memorial Stadium,Jackson,MS,Saturday Morning +7,2707,7,211,New Hampshire,210,Monmouth,true,false,false,false,236,Wildcat Stadium,Durham,NH,Saturday Morning +7,2707,7,215,Stony Brook,213,Rhode Island,true,false,false,false,240,Kenneth P. LaValle Stadium,Stony Brook,NY,Saturday Morning +7,2707,7,227,Central Connecticut,228,Duquesne,true,false,false,false,252,Arute Field,New Britain,CT,Saturday Morning +7,2707,7,17,BYU,5,Arizona,true,false,false,false,17,LaVell Edwards Stadium,Provo,Utah,Saturday Night +7,2707,7,40,Illinois,55,Maryland,true,false,false,false,40,Memorial Stadium,Urbana Champaign,Illinois,Saturday Night +7,2707,7,68,Nevada,1,Air Force,true,false,false,false,68,Mackay Stadium,Reno,Nevada,Saturday Night +7,2707,7,70,New Mexico State,127,Western Kentucky,true,false,false,false,70,Aggie Memorial Stadium,Las Cruces,New Mexico,Saturday Night +7,2707,7,87,Rice,117,UTSA,true,false,false,false,87,Rice Stadium,Houston,Texas,Saturday Night +7,2707,7,102,Texas A&M,81,Ole Miss,true,false,false,false,102,Kyle Field,College Station,Texas,Saturday Night +7,2707,7,119,Utah State,25,Colorado State,true,false,false,false,119,Merlin Olsen Field at Maverik Stadium,Logan,Utah,Saturday Night +7,2707,7,125,Washington State,13,Boise State,true,false,false,false,125,Martin Stadium,Pullman,Washington,Saturday Night +7,2707,7,130,Wyoming,73,Northern Illinois,true,false,false,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Saturday Night +7,2707,7,143,North Dakota State,69,New Mexico,true,false,false,false,143,Fargodome,Fargo,ND,Saturday Night +7,2707,7,242,San Diego,241,Presbyterian,true,false,false,false,267,Torero Stadium,San Diego,CA,Saturday Night +7,2707,7,249,McNeese,248,Lamar,true,false,true,false,274,Cowboy Stadium,Lake Charles,LA,Saturday Night +7,2707,7,3,Alabama,93,South Carolina,true,false,false,false,3,Bryant-Denny Stadium,Tuscaloosa,Alabama,Thursday Night +7,2707,7,4,Appalachian State,92,South Alabama,true,false,false,false,4,Kidd Brewer Stadium,Boone,North Carolina,Thursday Night +7,2707,7,27,East Carolina,109,UAB,true,false,false,false,27,Bagwell Field at Dowdy-Ficklen Stadium,Greenville,North Carolina,Thursday Night +7,2707,7,46,Kent State,128,Western Michigan,true,false,false,false,46,Dix Stadium,Kent,Ohio,Thursday Night +7,2707,7,86,Purdue,115,USC,true,false,false,false,86,Ross-Ade Stadium,West Lafayette,Indiana,Thursday Night +7,2707,7,94,South Florida,20,Charlotte,true,false,false,false,94,Raymond James Stadium,Tampa,Florida,Thursday Night +7,2707,7,95,Southern Miss,106,Troy,true,true,false,false,95,Carlisle-Faulkner Field at M.M. Roberts Stadium,Hattiesburg,Mississippi,Thursday Night +7,2707,7,97,Syracuse,121,Virginia,true,false,false,false,97,Carrier Dome,Syracuse,New York,Thursday Night +7,2707,7,113,UMass,105,Toledo,true,false,false,false,113,Warren McGuirk Alumni Stadium,Amherst,Massachusetts,Thursday Night +7,2707,7,131,James Madison,50,Louisiana Monroe,true,false,false,false,131,Bridgeforth Stadium,Harrisonburg,Virginia,Thursday Night +7,2707,7,147,Bucknell,214,Richmond,true,false,false,false,147,Christy Mathewson-Memorial Stadium,Lewisburg,PA,Thursday Night +7,2707,7,169,Dartmouth,167,Columbia,true,false,false,false,169,Memorial Field,Hanover,NH,Thursday Night +7,2707,7,171,Harvard,170,Pennsylvania,true,false,true,false,171,Harvard Stadium,Cambridge,MA,Thursday Night +7,2707,7,174,Furman,201,Tennessee Tech,true,false,false,false,174,Paladin Stadium,Greenville,SC,Thursday Night +7,2707,7,175,Samford,176,The Citadel,true,false,false,false,175,Seibert Stadium,Homewood,AL,Thursday Night +7,2707,7,178,Chattanooga,177,Wofford,true,false,false,false,178,Finley Stadium,Chattanooga,TN,Thursday Night +7,2707,7,188,Alabama A&M,186,Alcorn State,true,false,false,false,188,Louis Crews Stadium,Huntsville,AL,Thursday Night +7,2707,7,191,Alabama State,193,Mississippi Valley State,true,true,false,false,191,New ASU Stadium,Montgomery,AL,Thursday Night +7,2707,7,205,Campbell,204,Bryant,true,false,false,false,230,Barker-Lane Stadium,Buies Creek,NC,Thursday Night +7,2707,7,206,Delaware,133,Sam Houston State,true,false,false,false,231,Delaware Stadium,Newark,DE,Thursday Night +7,2707,7,233,Stonehill,265,Chicago State,true,false,false,false,258,W.B. Mason Stadium,Easton,MA,Thursday Night +7,2707,7,237,Dayton,235,Butler,true,false,false,false,262,Welcome Stadium,Dayton,OH,Thursday Night +7,2708,8,1,Air Force,116,UTEP,true,false,false,false,1,Falcon Stadium,Colorado Springs,Colorado,Friday Night +7,2708,8,42,Iowa,111,UCLA,true,false,false,false,42,Kinnick Stadium,Iowa City,Iowa,Friday Night +7,2708,8,50,Louisiana Monroe,51,Louisiana Tech,true,true,true,false,50,Joe Aillet Stadium,Monroe,Louisiana,Friday Night +7,2708,8,69,New Mexico,114,UNLV,true,false,false,false,69,Dreamstyle Stadium,Albuquerque,New Mexico,Friday Night +7,2708,8,87,Rice,20,Charlotte,true,false,false,false,87,Rice Stadium,Houston,Texas,Friday Night +7,2708,8,133,Sam Houston State,127,Western Kentucky,true,false,false,false,133,Bowers Stadium,Huntsville,Texas,Friday Night +7,2708,8,144,South Dakota State,136,Indiana State,true,false,false,false,144,Dana J. Dykhouse Stadium,Brookings,SD,Friday Night +7,2708,8,165,Weber State,156,Eastern Washington,true,false,false,false,165,Stewart Stadium,Ogden,UT,Friday Night +7,2708,8,183,Grambling,184,Bethune-Cookman,true,false,false,false,183,Eddie G. Robinson Memorial Stadium,Grambling,LA,Friday Night +7,2708,8,250,Nicholls,251,Northwestern State,true,false,true,false,275,Manning Field at John L. Guidry Stadium,Thibodaux,LA,Friday Night +7,2708,8,260,Southern Utah,263,Utah Tech,true,false,true,false,285,Eccles Coliseum,Cedar City,UT,Friday Night +7,2708,8,262,Tarleton State,269,West Florida,true,false,false,false,287,Memorial Stadium,Stephenville,TX,Friday Night +7,2708,8,15,Bowling Green,2,Akron,true,false,false,false,15,Doyt L. Perry Stadium,Bowling Green,Ohio,Saturday Afternoon +7,2708,8,34,Georgia,63,Mississippi State,true,false,false,false,34,Sanford Stadium,Athens,Georgia,Saturday Afternoon +7,2708,8,39,Houston,104,Texas Tech,true,false,true,false,39,John O'Quinn Field at TDECU Stadium,Houston,Texas,Saturday Afternoon +7,2708,8,48,Liberty,206,Delaware,true,false,false,false,48,Arthur L. Williams Stadium,Lynchburg,Virginia,Saturday Afternoon +7,2708,8,55,Maryland,62,Minnesota,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Saturday Afternoon +7,2708,8,58,Miami (OH),105,Toledo,true,false,false,false,58,Fred C. Yager Stadium,Oxford,Ohio,Saturday Afternoon +7,2708,8,67,Nebraska,88,Rutgers,true,false,false,false,67,"Memorial Stadium, Tom Osborne Field",Lincoln,Nebraska,Saturday Afternoon +7,2708,8,78,Oklahoma,30,Florida,true,false,false,false,78,Gaylord Family - Oklahoma Memorial Stadium at Owen Field,Norman,Oklahoma,Saturday Afternoon +7,2708,8,81,Ole Miss,101,Texas,true,false,false,false,81,Vaught-Hemingway Stadium at Hollingsworth Field,Oxford,Mississippi,Saturday Afternoon +7,2708,8,95,Southern Miss,92,South Alabama,true,true,false,false,95,Carlisle-Faulkner Field at M.M. Roberts Stadium,Hattiesburg,Mississippi,Saturday Afternoon +7,2708,8,100,Tennessee,3,Alabama,true,false,true,false,100,Neyland Stadium,Knoxville,Tennessee,Saturday Afternoon +7,2708,8,107,Tulane,9,Army,true,false,false,false,107,Barry B. Benson Field at Yulman Stadium,New Orleans,Louisiana,Saturday Afternoon +7,2708,8,119,Utah State,13,Boise State,true,false,false,false,119,Merlin Olsen Field at Maverik Stadium,Logan,Utah,Saturday Afternoon +7,2708,8,120,Vanderbilt,7,Arkansas,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Saturday Afternoon +7,2708,8,132,Jacksonville State,138,Missouri State,true,false,false,false,132,Burgess-Snow Field at JSU Stadium,Jacksonville,Alabama,Saturday Afternoon +7,2708,8,135,Youngstown State,141,Southern Illinois,true,false,false,false,135,Stambaugh Stadium,Youngstown,OH,Saturday Afternoon +7,2708,8,148,Colgate,150,Lafayette,true,false,false,false,148,Andy Kerr Stadium,Hamilton,NY,Saturday Afternoon +7,2708,8,168,Cornell,167,Columbia,true,false,false,false,168,Schoellkopf Field,Ithaca,NY,Saturday Afternoon +7,2708,8,227,Central Connecticut,231,Robert Morris,true,false,false,false,252,Arute Field,New Britain,CT,Saturday Afternoon +7,2708,8,234,Wagner,228,Duquesne,true,false,false,false,259,Wagner College Stadium,Staten Island,NY,Saturday Afternoon +7,2708,8,240,Morehead State,244,Stetson,true,false,false,false,265,Jayne Stadium,Morehead,KY,Saturday Afternoon +7,2708,8,253,East Texas A&M,247,Incarnate Word,true,false,false,false,278,Ernest Hawkins Field at Memorial Stadium,Commerce,TX,Saturday Afternoon +7,2708,8,257,Central Arkansas,264,West Georgia,true,false,false,false,282,Estes Stadium,Conway,AR,Saturday Afternoon +7,2708,8,266,New Haven,265,Chicago State,true,false,false,false,291,Ralph F. DellaCamera Stadium,New Haven,CT,Saturday Afternoon +7,2708,8,22,Clemson,37,Georgia Tech,true,false,true,false,22,Frank Howard Field at Clemson Memorial Stadium,Clemson,South Carolina,Saturday Evening +7,2708,8,24,Colorado,44,Kansas,true,false,false,false,24,Folsom Field,Boulder,Colorado,Saturday Evening +7,2708,8,26,Duke,71,North Carolina,true,false,true,false,26,Brooks Field at Wallace Wade Stadium,Durham,North Carolina,Saturday Evening +7,2708,8,33,Fresno State,125,Washington State,true,false,false,false,33,Bulldog Stadium at Jim Sweeney Field,Fresno,California,Saturday Evening +7,2708,8,52,Louisville,85,Pittsburgh,true,false,true,false,52,Cardinal Stadium,Louisville,Kentucky,Saturday Evening +7,2708,8,89,San Diego State,83,Oregon State,true,false,false,false,89,SDCCU Stadium,San Diego,California,Saturday Evening +7,2708,8,103,Texas State,25,Colorado State,true,false,false,false,103,Jim Wacker Field at Bobcat Stadium,San Marcos,Texas,Saturday Evening +7,2708,8,121,Virginia,96,Stanford,true,false,false,false,121,David A. Harrison III Field at Scott Stadium,Charlottesville,Virginia,Saturday Evening +7,2708,8,129,Wisconsin,59,Michigan,true,false,false,false,129,Camp Randall Stadium,Madison,Wisconsin,Saturday Evening +7,2708,8,142,North Dakota,145,South Dakota,true,false,true,false,142,Alerus Center,Grand Forks,ND,Saturday Evening +7,2708,8,160,Montana State,154,UC Davis,true,false,false,false,160,Bobcat Stadium,Bozeman,MT,Saturday Evening +7,2708,8,164,Sacramento State,46,Kent State,true,false,false,false,164,Hornet Stadium,Sacramento,CA,Saturday Evening +7,2708,8,192,Texas Southern,186,Alcorn State,true,true,false,false,192,PNC Stadium,Houston,TX,Saturday Evening +7,2708,8,242,San Diego,237,Dayton,true,false,false,false,267,Torero Stadium,San Diego,CA,Saturday Evening +7,2708,8,56,Memphis,117,UTSA,true,false,false,false,56,Liberty Bowl Memorial Stadium,Memphis,Tennessee,Saturday Morning +7,2708,8,61,Middle Tennessee,70,New Mexico State,true,false,false,false,61,Johnny Red Floyd Stadium,Murfreesboro,Tennessee,Saturday Morning +7,2708,8,84,Penn State,77,Ohio State,true,false,true,false,84,Beaver Stadium,University Park,Pennsylvania,Saturday Morning +7,2708,8,86,Purdue,60,Michigan State,true,false,false,false,86,Ross-Ade Stadium,West Lafayette,Indiana,Saturday Morning +7,2708,8,97,Syracuse,32,Florida State,true,false,false,false,97,Carrier Dome,Syracuse,New York,Saturday Morning +7,2708,8,99,Temple,72,North Texas,true,false,false,false,99,Lincoln Financial Field,Philadelphia,Pennsylvania,Saturday Morning +7,2708,8,171,Harvard,169,Dartmouth,true,false,true,false,171,Harvard Stadium,Cambridge,MA,Saturday Morning +7,2708,8,177,Wofford,174,Furman,true,false,true,false,177,Gibbs Stadium,Spartanburg,SC,Saturday Morning +7,2708,8,188,Alabama A&M,194,Jackson State,true,true,false,false,188,Louis Crews Stadium,Huntsville,AL,Saturday Morning +7,2708,8,193,Mississippi Valley State,190,Florida A&M,true,true,false,false,193,Rice-Totten Stadium,Itta Bena,MS,Saturday Morning +7,2708,8,200,Tennessee State,201,Tennessee Tech,false,false,true,false,225,Hale Stadium,Nashville,TN,Saturday Morning +7,2708,8,211,New Hampshire,216,Towson,true,false,false,false,236,Wildcat Stadium,Durham,NH,Saturday Morning +7,2708,8,220,Sacred Heart,204,Bryant,true,false,false,false,245,Campus Field,Fairfield,CT,Saturday Morning +7,2708,8,229,LIU,230,Mercyhurst,true,false,false,false,254,Bethpage Federal Credit Union Stadium,Brooklyn,NY,Saturday Morning +7,2708,8,235,Butler,239,Marist,true,false,false,false,260,Bud and Jackie Sellick Bowl,Indianapolis,IN,Saturday Morning +7,2708,8,241,Presbyterian,238,Drake,true,false,false,false,266,Bailey Memorial Stadium,Clinton,SC,Saturday Morning +7,2708,8,259,North Alabama,255,Abilene Christian,true,false,false,false,284,Braly Municipal Stadium,Florence,AL,Saturday Morning +7,2708,8,53,LSU,93,South Carolina,true,false,false,false,53,Tiger Stadium,Baton Rouge,Louisiana,Saturday Night +7,2708,8,64,Missouri,10,Auburn,true,false,false,false,64,Faurot Field at Memorial Stadium,Columbia,Missouri,Saturday Night +7,2708,8,68,Nevada,73,Northern Illinois,true,false,false,false,68,Mackay Stadium,Reno,Nevada,Saturday Night +7,2708,8,74,Northwestern,41,Indiana,true,false,false,false,74,Ryan Field,Evanston,Illinois,Saturday Night +7,2708,8,115,USC,40,Illinois,true,false,false,false,115,Los Angeles Memorial Coliseum,Los Angeles,California,Saturday Night +7,2708,8,118,Utah,5,Arizona,true,false,false,false,118,Rice-Eccles Stadium,Salt Lake City,Utah,Saturday Night +7,2708,8,124,Washington,82,Oregon,true,false,true,false,124,Alaska Airlines Field at Husky Stadium,Seattle,Washington,Saturday Night +7,2708,8,130,Wyoming,143,North Dakota State,true,false,false,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Saturday Night +7,2708,8,137,Illinois State,140,Northern Iowa,true,false,false,false,137,Hancock Stadium,Normal,IL,Saturday Night +7,2708,8,157,Idaho,159,Montana,true,false,true,false,157,Kibbie Dome,Moscow,ID,Saturday Night +7,2708,8,189,Arkansas-Pine Bluff,187,Southern,true,true,false,false,189,Simmons Bank Field,Pine Bluff,AR,Saturday Night +7,2708,8,198,Lindenwood,146,Western Illinois,true,false,false,false,223,Hunter STadium,St. Charles,MO,Saturday Night +7,2708,8,248,Lamar,254,UT Rio Grande Valley,true,false,false,false,273,Provost Umphrey Stadium,Beaumont,TX,Saturday Night +7,2708,8,252,SE Louisiana,249,McNeese,true,false,false,false,277,Strawberry Stadium,Hammond,LA,Saturday Night +7,2708,8,11,Ball State,76,Ohio,true,false,false,false,11,Scheumann Stadium,Muncie,Indiana,Thursday Night +7,2708,8,19,Central Michigan,113,UMass,true,false,false,false,19,Kelly/Shorts Stadium,Mount Pleasant,Michigan,Thursday Night +7,2708,8,21,Cincinnati,126,West Virginia,true,false,true,false,21,Nippert Stadium,Cincinnati,Ohio,Thursday Night +7,2708,8,27,East Carolina,94,South Florida,true,false,false,false,27,Bagwell Field at Dowdy-Ficklen Stadium,Greenville,North Carolina,Thursday Night +7,2708,8,31,Florida Atlantic,109,UAB,true,false,false,false,31,FAU Stadium,Boca Raton,Florida,Thursday Night +7,2708,8,54,Marshall,23,Coastal Carolina,true,true,false,false,54,Joan C. Edwards Stadium,Huntington,West Virginia,Thursday Night +7,2708,8,57,Miami (FL),14,Boston College,true,false,false,false,57,Hard Rock Stadium,Coral Gables,Florida,Thursday Night +7,2708,8,80,Old Dominion,35,Georgia Southern,true,true,false,false,80,Foreman Field at S. B. Ballard Stadium,Norfolk,Virginia,Thursday Night +7,2708,8,106,Troy,8,Arkansas State,true,true,false,false,106,Veterans Memorial Stadium at Larry Blakeney Field,Troy,Alabama,Thursday Night +7,2708,8,110,UCF,79,Oklahoma State,true,false,false,false,110,Bounce House,Orlando,Florida,Thursday Night +7,2708,8,122,Virginia Tech,91,SMU,true,false,false,false,122,Worsham Field at Lane Stadium,Blacksburg,Virginia,Thursday Night +7,2708,8,128,Western Michigan,28,Eastern Michigan,true,false,true,false,128,Waldo Stadium,Kalamazoo,Michigan,Thursday Night +7,2708,8,131,James Madison,36,Georgia State,true,true,false,false,131,Bridgeforth Stadium,Harrisonburg,Virginia,Thursday Night +7,2708,8,134,Kennesaw State,29,FIU,true,false,false,false,134,Fifth Third Bank Stadium,Kennesaw,Georgia,Thursday Night +7,2708,8,147,Bucknell,151,Lehigh,true,false,false,false,147,Christy Mathewson-Memorial Stadium,Lewisburg,PA,Thursday Night +7,2708,8,149,Holy Cross,217,Villanova,true,false,false,false,149,Fitton Field,Worcester,MA,Thursday Night +7,2708,8,153,Georgetown,152,Fordham,true,false,false,false,153,Cooper Field,Washington,DC,Thursday Night +7,2708,8,158,Idaho State,161,Northern Arizona,true,false,false,false,158,Holt Arena,Pocatello,ID,Thursday Night +7,2708,8,166,Brown,172,Princeton,true,false,false,false,166,Brown Stadium,Providence,RI,Thursday Night +7,2708,8,173,Yale,170,Pennsylvania,true,false,false,false,173,Yale Bowl,New Haven,CT,Thursday Night +7,2708,8,175,Samford,178,Chattanooga,true,false,false,false,175,Seibert Stadium,Homewood,AL,Thursday Night +7,2708,8,176,The Citadel,180,Western Carolina,true,false,false,false,176,Johnson Hagood Stadium,Charleston,SC,Thursday Night +7,2708,8,182,VMI,179,East Tennessee State,true,false,false,false,182,Foster Stadium,Lexington,VA,Thursday Night +7,2708,8,202,UT Martin,196,Eastern Illinois,true,false,false,false,227,Graham Stadium,Martin,TN,Thursday Night +7,2708,8,205,Campbell,213,Rhode Island,true,false,false,false,230,Barker-Lane Stadium,Buies Creek,NC,Thursday Night +7,2708,8,207,Elon,215,Stony Brook,true,false,false,false,232,Rhodes Stadium,Elon,NC,Thursday Night +7,2708,8,209,Maine,208,Hampton,true,false,false,false,234,Harold Alfond Sports Stadium,Orono,ME,Thursday Night +7,2708,8,210,Monmouth,212,North Carolina A&T,true,false,false,false,235,Kessler Field,West Long Branch,NJ,Thursday Night +7,2708,8,221,Delaware State,226,South Carolina State,true,false,false,false,246,Alumni Stadium,Dover,DE,Thursday Night +7,2708,8,258,Eastern Kentucky,256,Austin Peay,true,false,false,false,283,Roy Kidd Stadium,Richmond,KY,Thursday Night +7,2709,9,7,Arkansas,101,Texas,true,false,true,false,7,"Donald W. Reynolds Razorback Stadium, Frank Broyles Field",Fayetteville,Arkansas,Friday Night +7,2709,9,50,Louisiana Monroe,54,Marshall,true,false,false,false,50,Joe Aillet Stadium,Monroe,Louisiana,Friday Night +7,2709,9,62,Minnesota,67,Nebraska,true,false,true,false,62,TCF Bank Stadium,Minneapolis,Minnesota,Friday Night +7,2709,9,73,Northern Illinois,116,UTEP,true,false,false,false,73,Brigham Field at Huskie Stadium,DeKalb,Illinois,Friday Night +7,2709,9,74,Northwestern,124,Washington,true,false,false,false,74,Ryan Field,Evanston,Illinois,Friday Night +7,2709,9,82,Oregon,42,Iowa,true,false,false,false,82,Autzen Stadium,Eugene,Oregon,Friday Night +7,2709,9,104,Texas Tech,110,UCF,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Friday Night +7,2709,9,117,UTSA,107,Tulane,true,false,false,false,117,Alamodome,San Antonio,Texas,Friday Night +7,2709,9,137,Illinois State,145,South Dakota,true,false,false,false,137,Hancock Stadium,Normal,IL,Friday Night +7,2709,9,165,Weber State,154,UC Davis,true,false,false,false,165,Stewart Stadium,Ogden,UT,Friday Night +7,2709,9,189,Arkansas-Pine Bluff,186,Alcorn State,true,true,false,false,189,Simmons Bank Field,Pine Bluff,AR,Friday Night +7,2709,9,199,Southeast Missouri State,197,Gardner-Webb,true,false,false,false,224,Houck Stadium,Cape Girardeau,MO,Friday Night +7,2709,9,238,Drake,242,San Diego,true,false,false,false,263,Drake Stadium,Des Moines,IA,Friday Night +7,2709,9,249,McNeese,261,Stephen F. Austin,true,false,false,false,274,Cowboy Stadium,Lake Charles,LA,Friday Night +7,2709,9,254,UT Rio Grande Valley,246,Houston Christian,true,false,false,false,279,Robert and Janet Vackar Stadium,Edinburg,TX,Friday Night +7,2709,9,255,Abilene Christian,258,Eastern Kentucky,true,false,false,false,280,Anthony Field at Wildcat Stadium,Abilene,TX,Friday Night +7,2709,9,260,Southern Utah,163,Portland State,true,false,false,false,285,Eccles Coliseum,Cedar City,UT,Friday Night +7,2709,9,24,Colorado,17,BYU,true,false,false,false,24,Folsom Field,Boulder,Colorado,Saturday Afternoon +7,2709,9,26,Duke,52,Louisville,true,false,false,false,26,Brooks Field at Wallace Wade Stadium,Durham,North Carolina,Saturday Afternoon +7,2709,9,43,Iowa State,12,Baylor,true,false,false,false,43,Jack Trice Stadium,Ames,Iowa,Saturday Afternoon +7,2709,9,46,Kent State,58,Miami (OH),true,false,false,false,46,Dix Stadium,Kent,Ohio,Saturday Afternoon +7,2709,9,77,Ohio State,115,USC,true,false,false,false,77,Ohio Stadium,Columbus,Ohio,Saturday Afternoon +7,2709,9,80,Old Dominion,4,Appalachian State,true,true,false,false,80,Foreman Field at S. B. Ballard Stadium,Norfolk,Virginia,Saturday Afternoon +7,2709,9,88,Rutgers,40,Illinois,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Saturday Afternoon +7,2709,9,89,San Diego State,25,Colorado State,true,false,false,false,89,SDCCU Stadium,San Diego,California,Saturday Afternoon +7,2709,9,103,Texas State,13,Boise State,true,false,false,false,103,Jim Wacker Field at Bobcat Stadium,San Marcos,Texas,Saturday Afternoon +7,2709,9,123,Wake Forest,32,Florida State,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Saturday Afternoon +7,2709,9,126,West Virginia,6,Arizona State,true,false,false,false,126,Mountaineer Field at Milan Puskar Stadium,Morgantown,West Virginia,Saturday Afternoon +7,2709,9,136,Indiana State,135,Youngstown State,true,false,false,false,136,Memorial Stadium,Terre Haute,IN,Saturday Afternoon +7,2709,9,139,Murray State,144,South Dakota State,true,false,false,false,139,Roy Stewart Stadium,Murray,KY,Saturday Afternoon +7,2709,9,150,Lafayette,147,Bucknell,true,false,false,false,150,Fisher Stadium,Easton,PA,Saturday Afternoon +7,2709,9,175,Samford,182,VMI,true,false,false,false,175,Seibert Stadium,Homewood,AL,Saturday Afternoon +7,2709,9,180,Western Carolina,177,Wofford,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Saturday Afternoon +7,2709,9,195,Charleston Southern,196,Eastern Illinois,true,false,false,false,220,Buccaneer Field,Bules Creek,NC,Saturday Afternoon +7,2709,9,217,Villanova,148,Colgate,true,false,false,false,242,Villanova Stadium,Philadelphia,PA,Saturday Afternoon +7,2709,9,228,Duquesne,266,New Haven,true,false,false,false,253,Arthur J. Rooney Athletic Field,Pittsburgh,PA,Saturday Afternoon +7,2709,9,229,LIU,227,Central Connecticut,true,false,false,false,254,Bethpage Federal Credit Union Stadium,Brooklyn,NY,Saturday Afternoon +7,2709,9,231,Robert Morris,230,Mercyhurst,true,false,false,false,256,Joe Walton Stadium,Moon Township,PA,Saturday Afternoon +7,2709,9,236,Davidson,235,Butler,true,false,false,false,261,Richardson Stadium,Davidson,NC,Saturday Afternoon +7,2709,9,257,Central Arkansas,256,Austin Peay,true,false,false,false,282,Estes Stadium,Conway,AR,Saturday Afternoon +7,2709,9,10,Auburn,93,South Carolina,true,false,false,false,10,Pat Dye Field at Jordan-Hare Stadium,Auburn,Alabama,Saturday Evening +7,2709,9,44,Kansas,98,TCU,true,false,false,false,44,David Booth Kansas Memorial Stadium,Lawrence,Kansas,Saturday Evening +7,2709,9,53,LSU,34,Georgia,true,false,false,false,53,Tiger Stadium,Baton Rouge,Louisiana,Saturday Evening +7,2709,9,63,Mississippi State,78,Oklahoma,true,false,false,false,63,Davis Wade Stadium at Scott Field,Starkville,Mississippi,Saturday Evening +7,2709,9,83,Oregon State,33,Fresno State,true,false,false,false,83,Reser Stadium,Corvallis,Oregon,Saturday Evening +7,2709,9,85,Pittsburgh,96,Stanford,true,false,false,false,85,Heinz Field,Pittsburgh,Pennsylvania,Saturday Evening +7,2709,9,90,San Jose State,143,North Dakota State,true,false,false,false,90,CEFCU Stadium,San Jose,California,Saturday Evening +7,2709,9,133,Sam Houston State,138,Missouri State,true,false,false,false,133,Bowers Stadium,Huntsville,Texas,Saturday Evening +7,2709,9,162,Northern Colorado,158,Idaho State,true,false,false,false,162,Nottingham Field,Greeley,CO,Saturday Evening +7,2709,9,247,Incarnate Word,250,Nicholls,true,false,false,false,272,Gayle and Tom Benson Stadium,San Antonio,TX,Saturday Evening +7,2709,9,248,Lamar,253,East Texas A&M,true,false,false,false,273,Provost Umphrey Stadium,Beaumont,TX,Saturday Evening +7,2709,9,263,Utah Tech,160,Montana State,true,false,false,false,288,Greater Zion STadium,St. George,UT,Saturday Evening +7,2709,9,14,Boston College,121,Virginia,true,false,false,false,14,Alumni Stadium,Chestnut Hill,Massachusetts,Saturday Morning +7,2709,9,19,Central Michigan,28,Eastern Michigan,true,false,true,false,19,Kelly/Shorts Stadium,Mount Pleasant,Michigan,Saturday Morning +7,2709,9,47,Kentucky,102,Texas A&M,true,false,false,false,47,Kroger Field at C.M. Newton Grounds,Lexington,Kentucky,Saturday Morning +7,2709,9,65,Navy,27,East Carolina,true,false,false,false,65,Navy-Marine Corps Memorial Stadium,Annapolis,Maryland,Saturday Morning +7,2709,9,66,NC State,91,SMU,true,false,false,false,66,Wayne Day Family Field at Carter-Finley Stadium,Raleigh,North Carolina,Saturday Morning +7,2709,9,71,North Carolina,18,California,true,false,false,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Morning +7,2709,9,113,UMass,2,Akron,true,false,false,false,113,Warren McGuirk Alumni Stadium,Amherst,Massachusetts,Saturday Morning +7,2709,9,127,Western Kentucky,206,Delaware,true,false,false,false,127,L. T. Smith Stadium at Jimmy Feix Field,Bowling Green,Kentucky,Saturday Morning +7,2709,9,151,Lehigh,153,Georgetown,true,false,false,false,151,Goodman Stadium,Bethlehem,PA,Saturday Morning +7,2709,9,172,Princeton,167,Columbia,true,false,false,false,172,Princeton Stadium,Princeton,NJ,Saturday Morning +7,2709,9,174,Furman,179,East Tennessee State,true,false,false,false,174,Paladin Stadium,Greenville,SC,Saturday Morning +7,2709,9,193,Mississippi Valley State,188,Alabama A&M,true,true,false,false,193,Rice-Totten Stadium,Itta Bena,MS,Saturday Morning +7,2709,9,194,Jackson State,184,Bethune-Cookman,true,true,false,false,194,Mississippi Veterans Memorial Stadium,Jackson,MS,Saturday Morning +7,2709,9,213,Rhode Island,220,Sacred Heart,true,false,false,false,238,Meade Stadium,Kingston,RI,Saturday Morning +7,2709,9,216,Towson,204,Bryant,true,false,false,false,241,Johnny Unitas Stadiumn,Towson,MD,Saturday Morning +7,2709,9,225,North Carolina Central,223,Morgan State,true,false,false,false,250,O'Kelly-Riddick Stadium,Durham,NC,Saturday Morning +7,2709,9,226,South Carolina State,224,Norfolk State,true,false,false,false,251,Oliver C. Dawson Stadium,Orangeburg,SC,Saturday Morning +7,2709,9,237,Dayton,239,Marist,true,false,false,false,262,Welcome Stadium,Dayton,OH,Saturday Morning +7,2709,9,264,West Georgia,262,Tarleton State,true,false,false,false,289,University Stadium,Carrollton,GA,Saturday Morning +7,2709,9,38,Hawaii,69,New Mexico,true,false,false,false,38,Aloha Stadium,Honolulu,Hawai'i,Saturday Night +7,2709,9,64,Missouri,3,Alabama,true,false,false,false,64,Faurot Field at Memorial Stadium,Columbia,Missouri,Saturday Night +7,2709,9,72,North Texas,109,UAB,true,false,false,false,72,Apogee Stadium,Denton,Texas,Saturday Night +7,2709,9,111,UCLA,129,Wisconsin,true,false,false,false,111,Rose Bowl Stadium,Los Angeles,California,Saturday Night +7,2709,9,161,Northern Arizona,155,Cal Poly,true,false,false,false,161,Walkup Skydome,Flagstaff,AZ,Saturday Night +7,2709,9,192,Texas Southern,191,Alabama State,true,false,false,false,192,PNC Stadium,Houston,TX,Saturday Night +7,2709,9,198,Lindenwood,200,Tennessee State,true,false,false,false,223,Hunter STadium,St. Charles,MO,Saturday Night +7,2709,9,243,St. Thomas,244,Stetson,true,false,false,false,268,O'Shaughnessy Stadium,Saint Paul,MN,Saturday Night +7,2709,9,15,Bowling Green,16,Buffalo,true,false,false,false,15,Doyt L. Perry Stadium,Bowling Green,Ohio,Thursday Night +7,2709,9,20,Charlotte,9,Army,true,false,false,false,20,McColl-Richardson Field at Jerry Richardson Stadium,Charlotte,North Carolina,Thursday Night +7,2709,9,23,Coastal Carolina,131,James Madison,true,true,false,false,23,Brooks Stadium,Conway,South Carolina,Thursday Night +7,2709,9,31,Florida Atlantic,94,South Florida,true,false,false,false,31,FAU Stadium,Boca Raton,Florida,Thursday Night +7,2709,9,48,Liberty,61,Middle Tennessee,true,false,false,false,48,Arthur L. Williams Stadium,Lynchburg,Virginia,Thursday Night +7,2709,9,59,Michigan,60,Michigan State,true,false,true,false,59,Michigan Stadium,Ann Arbor,Michigan,Thursday Night +7,2709,9,84,Penn State,86,Purdue,true,false,false,false,84,Beaver Stadium,University Park,Pennsylvania,Thursday Night +7,2709,9,92,South Alabama,51,Louisiana Tech,true,true,false,false,92,Ladd-Peebles Stadium,Mobile,Alabama,Thursday Night +7,2709,9,95,Southern Miss,8,Arkansas State,true,true,false,false,95,Carlisle-Faulkner Field at M.M. Roberts Stadium,Hattiesburg,Mississippi,Thursday Night +7,2709,9,99,Temple,56,Memphis,true,false,false,false,99,Lincoln Financial Field,Philadelphia,Pennsylvania,Thursday Night +7,2709,9,106,Troy,49,Louisiana,true,true,false,false,106,Veterans Memorial Stadium at Larry Blakeney Field,Troy,Alabama,Thursday Night +7,2709,9,114,UNLV,1,Air Force,true,false,false,false,114,Allegient Stadium,Las Vegas,Nevada,Thursday Night +7,2709,9,120,Vanderbilt,30,Florida,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Thursday Night +7,2709,9,128,Western Michigan,164,Sacramento State,true,false,false,false,128,Waldo Stadium,Kalamazoo,Michigan,Thursday Night +7,2709,9,132,Jacksonville State,29,FIU,true,false,false,false,132,Burgess-Snow Field at JSU Stadium,Jacksonville,Alabama,Thursday Night +7,2709,9,134,Kennesaw State,70,New Mexico State,true,false,false,false,134,Fifth Third Bank Stadium,Kennesaw,Georgia,Thursday Night +7,2709,9,157,Idaho,156,Eastern Washington,true,false,false,false,157,Kibbie Dome,Moscow,ID,Thursday Night +7,2709,9,168,Cornell,173,Yale,true,false,false,false,168,Schoellkopf Field,Ithaca,NY,Thursday Night +7,2709,9,170,Pennsylvania,169,Dartmouth,true,false,false,false,170,Franklin Field,Philadelphia,PA,Thursday Night +7,2709,9,176,The Citadel,178,Chattanooga,true,false,false,false,176,Johnson Hagood Stadium,Charleston,SC,Thursday Night +7,2709,9,190,Florida A&M,187,Southern,true,false,false,false,190,Bragg Memorial Stadium,Tallahassee,FL,Thursday Night +7,2709,9,201,Tennessee Tech,202,UT Martin,false,false,true,false,226,Tucker Stadium,Cookeville,TN,Thursday Night +7,2709,9,203,Albany,211,New Hampshire,true,false,false,false,228,Tom & Mary Casey Stadium,Albany,NY,Thursday Night +7,2709,9,205,Campbell,208,Hampton,true,false,false,false,230,Barker-Lane Stadium,Buies Creek,NC,Thursday Night +7,2709,9,207,Elon,210,Monmouth,true,false,false,false,232,Rhodes Stadium,Elon,NC,Thursday Night +7,2709,9,215,Stony Brook,212,North Carolina A&T,true,false,false,false,240,Kenneth P. LaValle Stadium,Stony Brook,NY,Thursday Night +7,2709,9,218,William & Mary,149,Holy Cross,true,false,false,false,243,Water J. Zable Stadium,Williamsburg,VA,Thursday Night +7,2709,9,234,Wagner,233,Stonehill,true,false,false,false,259,Wagner College Stadium,Staten Island,NY,Thursday Night +7,2709,9,245,Valparaiso,241,Presbyterian,true,false,false,false,270,Brown Field,Valparaiso,IN,Thursday Night +7,2709,9,269,West Florida,259,North Alabama,true,false,false,false,294,Darrell Gooden Stadium,Pensacola,FL,Thursday Night +7,2710,10,73,Northern Illinois,90,San Jose State,true,false,false,false,73,Brigham Field at Huskie Stadium,DeKalb,Illinois,Friday Night +7,2710,10,98,TCU,24,Colorado,true,false,false,false,98,Amon G. Carter Stadium,Fort Worth,Texas,Friday Night +7,2710,10,102,Texas A&M,78,Oklahoma,true,false,false,false,102,Kyle Field,College Station,Texas,Friday Night +7,2710,10,116,UTEP,69,New Mexico,true,false,false,false,116,Sun Bowl Stadium,El Paso,Texas,Friday Night +7,2710,10,124,Washington,60,Michigan State,true,false,false,false,124,Alaska Airlines Field at Husky Stadium,Seattle,Washington,Friday Night +7,2710,10,133,Sam Houston State,48,Liberty,true,false,false,false,133,Bowers Stadium,Huntsville,Texas,Friday Night +7,2710,10,140,Northern Iowa,141,Southern Illinois,true,false,false,false,140,UNI-Dome,Cedar Falls,IA,Friday Night +7,2710,10,145,South Dakota,136,Indiana State,true,false,false,false,145,DakotaDome,Vermillion,SD,Friday Night +7,2710,10,146,Western Illinois,199,Southeast Missouri State,true,false,false,false,146,Hanson Field,Macomb,IL,Friday Night +7,2710,10,198,Lindenwood,195,Charleston Southern,true,false,false,false,223,Hunter STadium,St. Charles,MO,Friday Night +7,2710,10,247,Incarnate Word,249,McNeese,true,false,false,false,272,Gayle and Tom Benson Stadium,San Antonio,TX,Friday Night +7,2710,10,262,Tarleton State,258,Eastern Kentucky,true,false,false,false,287,Memorial Stadium,Stephenville,TX,Friday Night +7,2710,10,263,Utah Tech,156,Eastern Washington,true,false,false,false,288,Greater Zion STadium,St. George,UT,Friday Night +7,2710,10,11,Ball State,19,Central Michigan,true,false,false,false,11,Scheumann Stadium,Muncie,Indiana,Saturday Afternoon +7,2710,10,21,Cincinnati,43,Iowa State,true,false,false,false,21,Nippert Stadium,Cincinnati,Ohio,Saturday Afternoon +7,2710,10,30,Florida,3,Alabama,true,false,true,false,30,Steve Spurrier-Florida Field at Ben Hill Griffin Stadium,Gainesville,Florida,Saturday Afternoon +7,2710,10,77,Ohio State,111,UCLA,true,false,false,false,77,Ohio Stadium,Columbus,Ohio,Saturday Afternoon +7,2710,10,92,South Alabama,8,Arkansas State,true,true,false,false,92,Ladd-Peebles Stadium,Mobile,Alabama,Saturday Afternoon +7,2710,10,105,Toledo,16,Buffalo,true,false,false,false,105,Glass Bowl,Toledo,Ohio,Saturday Afternoon +7,2710,10,120,Vanderbilt,53,LSU,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Saturday Afternoon +7,2710,10,121,Virginia,32,Florida State,true,false,true,false,121,David A. Harrison III Field at Scott Stadium,Charlottesville,Virginia,Saturday Afternoon +7,2710,10,122,Virginia Tech,52,Louisville,true,false,false,false,122,Worsham Field at Lane Stadium,Blacksburg,Virginia,Saturday Afternoon +7,2710,10,123,Wake Forest,14,Boston College,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Saturday Afternoon +7,2710,10,125,Washington State,103,Texas State,true,false,false,false,125,Martin Stadium,Pullman,Washington,Saturday Afternoon +7,2710,10,126,West Virginia,12,Baylor,true,false,false,false,126,Mountaineer Field at Milan Puskar Stadium,Morgantown,West Virginia,Saturday Afternoon +7,2710,10,131,James Madison,4,Appalachian State,true,true,false,false,131,Bridgeforth Stadium,Harrisonburg,Virginia,Saturday Afternoon +7,2710,10,134,Kennesaw State,127,Western Kentucky,true,false,false,false,134,Fifth Third Bank Stadium,Kennesaw,Georgia,Saturday Afternoon +7,2710,10,150,Lafayette,151,Lehigh,true,false,true,false,150,Fisher Stadium,Easton,PA,Saturday Afternoon +7,2710,10,152,Fordham,217,Villanova,true,false,false,false,152,Jack Coffey Field,Bronx,NY,Saturday Afternoon +7,2710,10,180,Western Carolina,182,VMI,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Saturday Afternoon +7,2710,10,184,Bethune-Cookman,193,Mississippi Valley State,true,true,false,false,184,Daytona Stadium,Daytona Beach,FL,Saturday Afternoon +7,2710,10,187,Southern,186,Alcorn State,true,true,false,false,187,A.W. Mumford Stadium,Baton Rouge,LA,Saturday Afternoon +7,2710,10,209,Maine,220,Sacred Heart,true,false,false,false,234,Harold Alfond Sports Stadium,Orono,ME,Saturday Afternoon +7,2710,10,213,Rhode Island,203,Albany,true,false,false,false,238,Meade Stadium,Kingston,RI,Saturday Afternoon +7,2710,10,228,Duquesne,231,Robert Morris,true,false,false,false,253,Arthur J. Rooney Athletic Field,Pittsburgh,PA,Saturday Afternoon +7,2710,10,229,LIU,233,Stonehill,true,false,false,false,254,Bethpage Federal Credit Union Stadium,Brooklyn,NY,Saturday Afternoon +7,2710,10,243,St. Thomas,236,Davidson,true,false,false,false,268,O'Shaughnessy Stadium,Saint Paul,MN,Saturday Afternoon +7,2710,10,246,Houston Christian,250,Nicholls,true,false,false,false,271,Husky Stadium,Houston,TX,Saturday Afternoon +7,2710,10,253,East Texas A&M,251,Northwestern State,true,false,false,false,278,Ernest Hawkins Field at Memorial Stadium,Commerce,TX,Saturday Afternoon +7,2710,10,264,West Georgia,269,West Florida,true,false,false,false,289,University Stadium,Carrollton,GA,Saturday Afternoon +7,2710,10,1,Air Force,38,Hawaii,true,false,true,false,1,Falcon Stadium,Colorado Springs,Colorado,Saturday Evening +7,2710,10,22,Clemson,18,California,true,false,false,false,22,Frank Howard Field at Clemson Memorial Stadium,Clemson,South Carolina,Saturday Evening +7,2710,10,40,Illinois,84,Penn State,true,false,false,false,40,Memorial Stadium,Urbana Champaign,Illinois,Saturday Evening +7,2710,10,74,Northwestern,115,USC,true,false,false,false,74,Ryan Field,Evanston,Illinois,Saturday Evening +7,2710,10,83,Oregon State,25,Colorado State,true,false,false,false,83,Reser Stadium,Corvallis,Oregon,Saturday Evening +7,2710,10,93,South Carolina,101,Texas,true,false,false,false,93,Williams-Brice Stadium,Columbia,South Carolina,Saturday Evening +7,2710,10,114,UNLV,143,North Dakota State,true,false,false,false,114,Allegient Stadium,Las Vegas,Nevada,Saturday Evening +7,2710,10,129,Wisconsin,42,Iowa,true,false,true,false,129,Camp Randall Stadium,Madison,Wisconsin,Saturday Evening +7,2710,10,144,South Dakota State,137,Illinois State,true,false,false,false,144,Dana J. Dykhouse Stadium,Brookings,SD,Saturday Evening +7,2710,10,161,Northern Arizona,154,UC Davis,true,false,false,false,161,Walkup Skydome,Flagstaff,AZ,Saturday Evening +7,2710,10,192,Texas Southern,183,Grambling,true,true,false,false,192,PNC Stadium,Houston,TX,Saturday Evening +7,2710,10,23,Coastal Carolina,36,Georgia State,true,true,false,false,23,Brooks Stadium,Conway,South Carolina,Saturday Morning +7,2710,10,34,Georgia,7,Arkansas,true,false,false,false,34,Sanford Stadium,Athens,Georgia,Saturday Morning +7,2710,10,37,Georgia Tech,96,Stanford,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Saturday Morning +7,2710,10,47,Kentucky,10,Auburn,true,false,false,false,47,Kroger Field at C.M. Newton Grounds,Lexington,Kentucky,Saturday Morning +7,2710,10,61,Middle Tennessee,132,Jacksonville State,true,false,false,false,61,Johnny Red Floyd Stadium,Murfreesboro,Tennessee,Saturday Morning +7,2710,10,71,North Carolina,91,SMU,true,false,false,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Morning +7,2710,10,81,Ole Miss,64,Missouri,true,false,false,false,81,Vaught-Hemingway Stadium at Hollingsworth Field,Oxford,Mississippi,Saturday Morning +7,2710,10,97,Syracuse,57,Miami (FL),true,false,false,false,97,Carrier Dome,Syracuse,New York,Saturday Morning +7,2710,10,99,Temple,9,Army,true,false,false,false,99,Lincoln Financial Field,Philadelphia,Pennsylvania,Saturday Morning +7,2710,10,106,Troy,50,Louisiana Monroe,true,true,false,false,106,Veterans Memorial Stadium at Larry Blakeney Field,Troy,Alabama,Saturday Morning +7,2710,10,110,UCF,118,Utah,true,false,false,false,110,Bounce House,Orlando,Florida,Saturday Morning +7,2710,10,174,Furman,176,The Citadel,true,false,true,false,174,Paladin Stadium,Greenville,SC,Saturday Morning +7,2710,10,211,New Hampshire,212,North Carolina A&T,true,false,false,false,236,Wildcat Stadium,Durham,NH,Saturday Morning +7,2710,10,214,Richmond,218,William & Mary,true,false,true,false,239,E. Claiborne Robins Stadium,Richmond,VA,Saturday Morning +7,2710,10,216,Towson,207,Elon,true,false,false,false,241,Johnny Unitas Stadiumn,Towson,MD,Saturday Morning +7,2710,10,224,Norfolk State,222,Howard,true,false,false,false,249,"William ""Dick"" Price Stadium",Norfolk,VA,Saturday Morning +7,2710,10,235,Butler,242,San Diego,true,false,false,false,260,Bud and Jackie Sellick Bowl,Indianapolis,IN,Saturday Morning +7,2710,10,244,Stetson,238,Drake,true,false,false,false,269,Spec Martin Memorial Stadium,DeLand,FL,Saturday Morning +7,2710,10,256,Austin Peay,255,Abilene Christian,true,false,false,false,281,Fortera Stadium,Clarksville,TN,Saturday Morning +7,2710,10,44,Kansas,6,Arizona State,true,false,false,false,44,David Booth Kansas Memorial Stadium,Lawrence,Kansas,Saturday Night +7,2710,10,51,Louisiana Tech,80,Old Dominion,true,false,false,false,51,JPS Field at Malone Stadium,Ruston,Louisiana,Saturday Night +7,2710,10,79,Oklahoma State,45,Kansas State,true,false,false,false,79,Boone Pickens Stadium,Stillwater,Oklahoma,Saturday Night +7,2710,10,82,Oregon,88,Rutgers,true,false,false,false,82,Autzen Stadium,Eugene,Oregon,Saturday Night +7,2710,10,89,San Diego State,13,Boise State,true,false,false,false,89,SDCCU Stadium,San Diego,California,Saturday Night +7,2710,10,117,UTSA,31,Florida Atlantic,true,false,false,false,117,Alamodome,San Antonio,Texas,Saturday Night +7,2710,10,119,Utah State,33,Fresno State,true,false,false,false,119,Merlin Olsen Field at Maverik Stadium,Logan,Utah,Saturday Night +7,2710,10,130,Wyoming,68,Nevada,true,false,false,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Saturday Night +7,2710,10,138,Missouri State,70,New Mexico State,true,false,false,false,138,Robert W. Plaster Stadium,Springfield,MO,Saturday Night +7,2710,10,185,Prairie View A&M,189,Arkansas-Pine Bluff,true,true,false,false,185,Blackshear Field,Prairie View,TX,Saturday Night +7,2710,10,257,Central Arkansas,259,North Alabama,true,false,false,false,282,Estes Stadium,Conway,AR,Saturday Night +7,2710,10,261,Stephen F. Austin,254,UT Rio Grande Valley,true,false,false,false,286,Homer Bryce Stadium,Nacogdoches,TX,Saturday Night +7,2710,10,265,Chicago State,227,Central Connecticut,true,false,false,false,290,SeatGeek Stadium,Chicago,IL,Saturday Night +7,2710,10,2,Akron,128,Western Michigan,true,false,false,false,2,InfoCision Stadium-Summa Field,Akron,Ohio,Thursday Night +7,2710,10,20,Charlotte,107,Tulane,true,false,false,false,20,McColl-Richardson Field at Jerry Richardson Stadium,Charlotte,North Carolina,Thursday Night +7,2710,10,26,Duke,66,NC State,true,false,true,false,26,Brooks Field at Wallace Wade Stadium,Durham,North Carolina,Thursday Night +7,2710,10,28,Eastern Michigan,58,Miami (OH),true,false,false,false,28,Rynearson Stadium,Ypsilanti,Michigan,Thursday Night +7,2710,10,54,Marshall,35,Georgia Southern,true,true,false,false,54,Joan C. Edwards Stadium,Huntington,West Virginia,Thursday Night +7,2710,10,55,Maryland,86,Purdue,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Thursday Night +7,2710,10,63,Mississippi State,100,Tennessee,true,false,false,false,63,Davis Wade Stadium at Scott Field,Starkville,Mississippi,Thursday Night +7,2710,10,65,Navy,72,North Texas,true,false,false,false,65,Navy-Marine Corps Memorial Stadium,Annapolis,Maryland,Thursday Night +7,2710,10,76,Ohio,164,Sacramento State,true,false,false,false,76,Peden Stadium,Athens,Ohio,Thursday Night +7,2710,10,94,South Florida,108,Tulsa,true,false,false,false,94,Raymond James Stadium,Tampa,Florida,Thursday Night +7,2710,10,95,Southern Miss,49,Louisiana,true,true,false,false,95,Carlisle-Faulkner Field at M.M. Roberts Stadium,Hattiesburg,Mississippi,Thursday Night +7,2710,10,109,UAB,87,Rice,true,false,false,false,109,Legion Field Stadium,Birmingham,Alabama,Thursday Night +7,2710,10,135,Youngstown State,142,North Dakota,true,false,false,false,135,Stambaugh Stadium,Youngstown,OH,Thursday Night +7,2710,10,148,Colgate,153,Georgetown,true,false,false,false,148,Andy Kerr Stadium,Hamilton,NY,Thursday Night +7,2710,10,155,Cal Poly,157,Idaho,true,false,false,false,155,Alex G. Spanos Stadium,San Luis Obispo,CA,Thursday Night +7,2710,10,158,Idaho State,260,Southern Utah,true,false,false,false,158,Holt Arena,Pocatello,ID,Thursday Night +7,2710,10,162,Northern Colorado,163,Portland State,true,false,false,false,162,Nottingham Field,Greeley,CO,Thursday Night +7,2710,10,166,Brown,169,Dartmouth,true,false,false,false,166,Brown Stadium,Providence,RI,Thursday Night +7,2710,10,168,Cornell,171,Harvard,true,false,false,false,168,Schoellkopf Field,Ithaca,NY,Thursday Night +7,2710,10,172,Princeton,173,Yale,true,false,true,false,172,Princeton Stadium,Princeton,NJ,Thursday Night +7,2710,10,177,Wofford,175,Samford,true,false,false,false,177,Gibbs Stadium,Spartanburg,SC,Thursday Night +7,2710,10,178,Chattanooga,179,East Tennessee State,true,false,false,false,178,Finley Stadium,Chattanooga,TN,Thursday Night +7,2710,10,188,Alabama A&M,191,Alabama State,true,true,true,false,188,Louis Crews Stadium,Huntsville,AL,Thursday Night +7,2710,10,197,Gardner-Webb,196,Eastern Illinois,true,false,false,false,222,Ernest W. Spangler Stadium,Boiling Springs,NC,Thursday Night +7,2710,10,200,Tennessee State,202,UT Martin,true,false,true,false,225,Hale Stadium,Nashville,TN,Thursday Night +7,2710,10,204,Bryant,208,Hampton,true,false,false,false,229,Beirne Stadium,Smithfield,RI,Thursday Night +7,2710,10,221,Delaware State,223,Morgan State,true,false,false,false,246,Alumni Stadium,Dover,DE,Thursday Night +7,2710,10,230,Mercyhurst,234,Wagner,true,false,false,false,255,Saxon Stadium,Erie,PA,Thursday Night +7,2710,10,237,Dayton,245,Valparaiso,true,false,false,false,262,Welcome Stadium,Dayton,OH,Thursday Night +7,2710,10,239,Marist,241,Presbyterian,true,false,false,false,264,Leonidoff Field,Poughkeepsie,NY,Thursday Night +7,2711,11,12,Baylor,44,Kansas,true,false,false,false,12,McLane Stadium,Waco,Texas,Friday Night +7,2711,11,50,Louisiana Monroe,95,Southern Miss,true,true,false,false,50,Joe Aillet Stadium,Monroe,Louisiana,Friday Night +7,2711,11,51,Louisiana Tech,8,Arkansas State,true,true,false,false,51,JPS Field at Malone Stadium,Ruston,Louisiana,Friday Night +7,2711,11,53,LSU,102,Texas A&M,true,false,true,false,53,Tiger Stadium,Baton Rouge,Louisiana,Friday Night +7,2711,11,70,New Mexico State,132,Jacksonville State,true,false,false,false,70,Aggie Memorial Stadium,Las Cruces,New Mexico,Friday Night +7,2711,11,73,Northern Illinois,69,New Mexico,true,false,false,false,73,Brigham Field at Huskie Stadium,DeKalb,Illinois,Friday Night +7,2711,11,78,Oklahoma,120,Vanderbilt,true,false,false,false,78,Gaylord Family - Oklahoma Memorial Stadium at Owen Field,Norman,Oklahoma,Friday Night +7,2711,11,90,San Jose State,1,Air Force,true,false,false,false,90,CEFCU Stadium,San Jose,California,Friday Night +7,2711,11,116,UTEP,68,Nevada,true,false,false,false,116,Sun Bowl Stadium,El Paso,Texas,Friday Night +7,2711,11,146,Western Illinois,200,Tennessee State,true,false,false,false,146,Hanson Field,Macomb,IL,Friday Night +7,2711,11,164,Sacramento State,16,Buffalo,true,false,false,false,164,Hornet Stadium,Sacramento,CA,Friday Night +7,2711,11,192,Texas Southern,187,Southern,true,true,false,false,192,PNC Stadium,Houston,TX,Friday Night +7,2711,11,196,Eastern Illinois,199,Southeast Missouri State,true,false,false,false,221,O'Brien Field,Charleston,IL,Friday Night +7,2711,11,242,San Diego,239,Marist,true,false,false,false,267,Torero Stadium,San Diego,CA,Friday Night +7,2711,11,247,Incarnate Word,254,UT Rio Grande Valley,true,false,false,false,272,Gayle and Tom Benson Stadium,San Antonio,TX,Friday Night +7,2711,11,265,Chicago State,230,Mercyhurst,true,false,false,false,290,SeatGeek Stadium,Chicago,IL,Friday Night +7,2711,11,25,Colorado State,33,Fresno State,true,false,false,false,25,Sonny Lubick Field at Canvas Stadium,Fort Collins,Colorado,Saturday Afternoon +7,2711,11,29,FIU,206,Delaware,true,false,false,false,29,Riccardo Silva Stadium,Miami,Florida,Saturday Afternoon +7,2711,11,36,Georgia State,4,Appalachian State,true,true,false,false,36,Georgia State Stadium,Atlanta,Georgia,Saturday Afternoon +7,2711,11,49,Louisiana,92,South Alabama,true,true,false,false,49,Cajun Field,Lafayette,Louisiana,Saturday Afternoon +7,2711,11,54,Marshall,131,James Madison,true,true,false,false,54,Joan C. Edwards Stadium,Huntington,West Virginia,Saturday Afternoon +7,2711,11,55,Maryland,124,Washington,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Saturday Afternoon +7,2711,11,91,SMU,32,Florida State,true,false,false,false,91,Gerald J. Ford Stadium,University Park,Texas,Saturday Afternoon +7,2711,11,103,Texas State,89,San Diego State,true,false,false,false,103,Jim Wacker Field at Bobcat Stadium,San Marcos,Texas,Saturday Afternoon +7,2711,11,104,Texas Tech,118,Utah,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Afternoon +7,2711,11,105,Toledo,11,Ball State,true,false,false,false,105,Glass Bowl,Toledo,Ohio,Saturday Afternoon +7,2711,11,110,UCF,5,Arizona,true,false,false,false,110,Bounce House,Orlando,Florida,Saturday Afternoon +7,2711,11,134,Kennesaw State,133,Sam Houston State,true,false,false,false,134,Fifth Third Bank Stadium,Kennesaw,Georgia,Saturday Afternoon +7,2711,11,141,Southern Illinois,142,North Dakota,true,false,false,false,141,Saluki Stadium,Carbondale,IL,Saturday Afternoon +7,2711,11,145,South Dakota,144,South Dakota State,true,false,true,false,145,DakotaDome,Vermillion,SD,Saturday Afternoon +7,2711,11,152,Fordham,148,Colgate,true,false,false,false,152,Jack Coffey Field,Bronx,NY,Saturday Afternoon +7,2711,11,169,Dartmouth,173,Yale,true,false,false,false,169,Memorial Field,Hanover,NH,Saturday Afternoon +7,2711,11,181,Mercer,174,Furman,true,false,false,false,181,Five Star Stadium,Macon,GA,Saturday Afternoon +7,2711,11,191,Alabama State,184,Bethune-Cookman,true,true,false,false,191,New ASU Stadium,Montgomery,AL,Saturday Afternoon +7,2711,11,195,Charleston Southern,197,Gardner-Webb,true,false,false,false,220,Buccaneer Field,Bules Creek,NC,Saturday Afternoon +7,2711,11,202,UT Martin,198,Lindenwood,true,false,false,false,227,Graham Stadium,Martin,TN,Saturday Afternoon +7,2711,11,203,Albany,204,Bryant,true,false,false,false,228,Tom & Mary Casey Stadium,Albany,NY,Saturday Afternoon +7,2711,11,212,North Carolina A&T,226,South Carolina State,false,false,true,false,237,Truist Stadium,Greensboro,NC,Saturday Afternoon +7,2711,11,236,Davidson,238,Drake,true,false,false,false,261,Richardson Stadium,Davidson,NC,Saturday Afternoon +7,2711,11,250,Nicholls,261,Stephen F. Austin,true,false,false,false,275,Manning Field at John L. Guidry Stadium,Thibodaux,LA,Saturday Afternoon +7,2711,11,255,Abilene Christian,264,West Georgia,true,false,false,false,280,Anthony Field at Wildcat Stadium,Abilene,TX,Saturday Afternoon +7,2711,11,259,North Alabama,262,Tarleton State,true,false,false,false,284,Braly Municipal Stadium,Florence,AL,Saturday Afternoon +7,2711,11,3,Alabama,47,Kentucky,true,false,false,false,3,Bryant-Denny Stadium,Tuscaloosa,Alabama,Saturday Evening +7,2711,11,6,Arizona State,43,Iowa State,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Evening +7,2711,11,21,Cincinnati,17,BYU,true,false,false,false,21,Nippert Stadium,Cincinnati,Ohio,Saturday Evening +7,2711,11,57,Miami (FL),123,Wake Forest,true,false,false,false,57,Hard Rock Stadium,Coral Gables,Florida,Saturday Evening +7,2711,11,63,Mississippi State,93,South Carolina,true,false,false,false,63,Davis Wade Stadium at Scott Field,Starkville,Mississippi,Saturday Evening +7,2711,11,64,Missouri,7,Arkansas,true,false,true,false,64,Faurot Field at Memorial Stadium,Columbia,Missouri,Saturday Evening +7,2711,11,108,Tulsa,56,Memphis,true,false,false,false,108,Skelly Field at H. A. Chapman Stadium,Tulsa,Oklahoma,Saturday Evening +7,2711,11,130,Wyoming,114,UNLV,true,false,false,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Saturday Evening +7,2711,11,143,North Dakota State,38,Hawaii,true,false,false,false,143,Fargodome,Fargo,ND,Saturday Evening +7,2711,11,162,Northern Colorado,155,Cal Poly,true,false,false,false,162,Nottingham Field,Greeley,CO,Saturday Evening +7,2711,11,252,SE Louisiana,246,Houston Christian,true,false,false,false,277,Strawberry Stadium,Hammond,LA,Saturday Evening +7,2711,11,253,East Texas A&M,249,McNeese,true,false,false,false,278,Ernest Hawkins Field at Memorial Stadium,Commerce,TX,Saturday Evening +7,2711,11,260,Southern Utah,160,Montana State,true,false,false,false,285,Eccles Coliseum,Cedar City,UT,Saturday Evening +7,2711,11,263,Utah Tech,154,UC Davis,true,false,false,false,288,Greater Zion STadium,St. George,UT,Saturday Evening +7,2711,11,10,Auburn,101,Texas,true,false,false,false,10,Pat Dye Field at Jordan-Hare Stadium,Auburn,Alabama,Saturday Morning +7,2711,11,35,Georgia Southern,23,Coastal Carolina,true,true,false,false,35,Allen E. Paulson Stadium,Statesboro,Georgia,Saturday Morning +7,2711,11,60,Michigan State,115,USC,true,false,false,false,60,Spartan Stadium,East Lansing,Michigan,Saturday Morning +7,2711,11,81,Ole Miss,100,Tennessee,true,false,false,false,81,Vaught-Hemingway Stadium at Hollingsworth Field,Oxford,Mississippi,Saturday Morning +7,2711,11,84,Penn State,82,Oregon,true,false,false,false,84,Beaver Stadium,University Park,Pennsylvania,Saturday Morning +7,2711,11,86,Purdue,59,Michigan,true,false,false,false,86,Ross-Ade Stadium,West Lafayette,Indiana,Saturday Morning +7,2711,11,94,South Florida,9,Army,true,false,false,false,94,Raymond James Stadium,Tampa,Florida,Saturday Morning +7,2711,11,122,Virginia Tech,71,North Carolina,true,false,false,false,122,Worsham Field at Lane Stadium,Blacksburg,Virginia,Saturday Morning +7,2711,11,128,Western Michigan,58,Miami (OH),true,false,false,false,128,Waldo Stadium,Kalamazoo,Michigan,Saturday Morning +7,2711,11,149,Holy Cross,153,Georgetown,true,false,false,false,149,Fitton Field,Worcester,MA,Saturday Morning +7,2711,11,170,Pennsylvania,166,Brown,true,false,false,false,170,Franklin Field,Philadelphia,PA,Saturday Morning +7,2711,11,180,Western Carolina,175,Samford,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Saturday Morning +7,2711,11,182,VMI,178,Chattanooga,true,false,false,false,182,Foster Stadium,Lexington,VA,Saturday Morning +7,2711,11,186,Alcorn State,185,Prairie View A&M,true,true,false,false,186,Spinks-Casem Stadium,Lorman,MS,Saturday Morning +7,2711,11,210,Monmouth,205,Campbell,true,false,false,false,235,Kessler Field,West Long Branch,NJ,Saturday Morning +7,2711,11,214,Richmond,150,Lafayette,true,false,false,false,239,E. Claiborne Robins Stadium,Richmond,VA,Saturday Morning +7,2711,11,217,Villanova,151,Lehigh,true,false,false,false,242,Villanova Stadium,Philadelphia,PA,Saturday Morning +7,2711,11,225,North Carolina Central,222,Howard,true,false,false,false,250,O'Kelly-Riddick Stadium,Durham,NC,Saturday Morning +7,2711,11,231,Robert Morris,229,LIU,true,false,false,false,256,Joe Walton Stadium,Moon Township,PA,Saturday Morning +7,2711,11,233,Stonehill,228,Duquesne,true,false,false,false,258,W.B. Mason Stadium,Easton,MA,Saturday Morning +7,2711,11,235,Butler,243,St. Thomas,true,false,false,false,260,Bud and Jackie Sellick Bowl,Indianapolis,IN,Saturday Morning +7,2711,11,45,Kansas State,39,Houston,true,false,false,false,45,Bill Snyder Family Football Stadium,Manhattan,Kansas,Saturday Night +7,2711,11,83,Oregon State,13,Boise State,true,false,false,false,83,Reser Stadium,Corvallis,Oregon,Saturday Night +7,2711,11,87,Rice,72,North Texas,true,false,false,false,87,Rice Stadium,Houston,Texas,Saturday Night +7,2711,11,96,Stanford,26,Duke,true,false,false,false,96,Stanford Stadium,Stanford,California,Saturday Night +7,2711,11,98,TCU,79,Oklahoma State,true,false,false,false,98,Amon G. Carter Stadium,Fort Worth,Texas,Saturday Night +7,2711,11,111,UCLA,88,Rutgers,true,false,false,false,111,Rose Bowl Stadium,Los Angeles,California,Saturday Night +7,2711,11,119,Utah State,125,Washington State,true,false,false,false,119,Merlin Olsen Field at Maverik Stadium,Logan,Utah,Saturday Night +7,2711,11,138,Missouri State,61,Middle Tennessee,true,false,false,false,138,Robert W. Plaster Stadium,Springfield,MO,Saturday Night +7,2711,11,158,Idaho State,156,Eastern Washington,true,false,false,false,158,Holt Arena,Pocatello,ID,Saturday Night +7,2711,11,165,Weber State,161,Northern Arizona,true,false,false,false,165,Stewart Stadium,Ogden,UT,Saturday Night +7,2711,11,189,Arkansas-Pine Bluff,183,Grambling,true,true,false,false,189,Simmons Bank Field,Pine Bluff,AR,Saturday Night +7,2711,11,19,Central Michigan,2,Akron,true,false,false,false,19,Kelly/Shorts Stadium,Mount Pleasant,Michigan,Thursday Night +7,2711,11,20,Charlotte,109,UAB,true,false,false,false,20,McColl-Richardson Field at Jerry Richardson Stadium,Charlotte,North Carolina,Thursday Night +7,2711,11,27,East Carolina,107,Tulane,true,false,false,false,27,Bagwell Field at Dowdy-Ficklen Stadium,Greenville,North Carolina,Thursday Night +7,2711,11,28,Eastern Michigan,46,Kent State,true,false,false,false,28,Rynearson Stadium,Ypsilanti,Michigan,Thursday Night +7,2711,11,31,Florida Atlantic,99,Temple,true,false,false,false,31,FAU Stadium,Boca Raton,Florida,Thursday Night +7,2711,11,37,Georgia Tech,18,California,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Thursday Night +7,2711,11,41,Indiana,62,Minnesota,true,false,false,false,41,Memorial Stadium,Bloomington,Indiana,Thursday Night +7,2711,11,48,Liberty,127,Western Kentucky,true,false,false,false,48,Arthur L. Williams Stadium,Lynchburg,Virginia,Thursday Night +7,2711,11,52,Louisville,97,Syracuse,true,false,false,false,52,Cardinal Stadium,Louisville,Kentucky,Thursday Night +7,2711,11,66,NC State,14,Boston College,true,false,false,false,66,Wayne Day Family Field at Carter-Finley Stadium,Raleigh,North Carolina,Thursday Night +7,2711,11,77,Ohio State,40,Illinois,true,false,true,false,77,Ohio Stadium,Columbus,Ohio,Thursday Night +7,2711,11,121,Virginia,22,Clemson,true,false,false,false,121,David A. Harrison III Field at Scott Stadium,Charlottesville,Virginia,Thursday Night +7,2711,11,135,Youngstown State,140,Northern Iowa,true,false,false,false,135,Stambaugh Stadium,Youngstown,OH,Thursday Night +7,2711,11,136,Indiana State,139,Murray State,true,false,false,false,136,Memorial Stadium,Terre Haute,IN,Thursday Night +7,2711,11,147,Bucknell,218,William & Mary,true,false,false,false,147,Christy Mathewson-Memorial Stadium,Lewisburg,PA,Thursday Night +7,2711,11,157,Idaho,163,Portland State,true,false,false,false,157,Kibbie Dome,Moscow,ID,Thursday Night +7,2711,11,167,Columbia,171,Harvard,true,false,false,false,167,Lawrence A. Wien Stadium,New York,NY,Thursday Night +7,2711,11,168,Cornell,172,Princeton,true,false,false,false,168,Schoellkopf Field,Ithaca,NY,Thursday Night +7,2711,11,179,East Tennessee State,201,Tennessee Tech,true,false,false,false,179,William B. Greene Jr. Stadium,Johnson City,TN,Thursday Night +7,2711,11,190,Florida A&M,188,Alabama A&M,true,true,false,false,190,Bragg Memorial Stadium,Tallahassee,FL,Thursday Night +7,2711,11,208,Hampton,224,Norfolk State,false,false,true,false,233,Armstrong Stadium,Hampton,VA,Thursday Night +7,2711,11,215,Stony Brook,209,Maine,true,false,false,false,240,Kenneth P. LaValle Stadium,Stony Brook,NY,Thursday Night +7,2711,11,220,Sacred Heart,207,Elon,true,false,false,false,245,Campus Field,Fairfield,CT,Thursday Night +7,2711,11,223,Morgan State,216,Towson,false,false,true,false,248,Hughes Stadium,Baltimore,MD,Thursday Night +7,2711,11,227,Central Connecticut,266,New Haven,true,false,false,false,252,Arute Field,New Britain,CT,Thursday Night +7,2711,11,241,Presbyterian,237,Dayton,true,false,false,false,266,Bailey Memorial Stadium,Clinton,SC,Thursday Night +7,2711,11,244,Stetson,245,Valparaiso,true,false,false,false,269,Spec Martin Memorial Stadium,DeLand,FL,Thursday Night +7,2711,11,256,Austin Peay,269,West Florida,true,false,false,false,281,Fortera Stadium,Clarksville,TN,Thursday Night +7,2711,11,258,Eastern Kentucky,257,Central Arkansas,true,false,false,false,283,Roy Kidd Stadium,Richmond,KY,Thursday Night +7,2712,12,24,Colorado,118,Utah,true,false,true,false,24,Folsom Field,Boulder,Colorado,Friday Night +7,2712,12,43,Iowa State,17,BYU,true,false,false,false,43,Jack Trice Stadium,Ames,Iowa,Friday Night +7,2712,12,64,Missouri,78,Oklahoma,true,false,true,false,64,Faurot Field at Memorial Stadium,Columbia,Missouri,Friday Night +7,2712,12,69,New Mexico,1,Air Force,true,false,false,false,69,Dreamstyle Stadium,Albuquerque,New Mexico,Friday Night +7,2712,12,72,North Texas,27,East Carolina,true,false,false,false,72,Apogee Stadium,Denton,Texas,Friday Night +7,2712,12,108,Tulsa,31,Florida Atlantic,true,false,false,false,108,Skelly Field at H. A. Chapman Stadium,Tulsa,Oklahoma,Friday Night +7,2712,12,130,Wyoming,116,UTEP,true,false,false,false,130,Jonah Field at War Memorial Stadium,Laramie,Wyoming,Friday Night +7,2712,12,144,South Dakota State,142,North Dakota,true,false,false,false,144,Dana J. Dykhouse Stadium,Brookings,SD,Friday Night +7,2712,12,155,Cal Poly,154,UC Davis,true,false,true,false,155,Alex G. Spanos Stadium,San Luis Obispo,CA,Friday Night +7,2712,12,161,Northern Arizona,260,Southern Utah,true,false,true,false,161,Walkup Skydome,Flagstaff,AZ,Friday Night +7,2712,12,187,Southern,185,Prairie View A&M,true,true,false,false,187,A.W. Mumford Stadium,Baton Rouge,LA,Friday Night +7,2712,12,189,Arkansas-Pine Bluff,192,Texas Southern,true,true,false,false,189,Simmons Bank Field,Pine Bluff,AR,Friday Night +7,2712,12,251,Northwestern State,261,Stephen F. Austin,true,false,true,false,276,Harry Turpin Stadium,Natchitotches,LA,Friday Night +7,2712,12,253,East Texas A&M,252,SE Louisiana,true,false,false,false,278,Ernest Hawkins Field at Memorial Stadium,Commerce,TX,Friday Night +7,2712,12,6,Arizona State,21,Cincinnati,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Afternoon +7,2712,12,8,Arkansas State,49,Louisiana,true,true,false,false,8,Centennial Bank Stadium,Jonesboro,Arkansas,Saturday Afternoon +7,2712,12,12,Baylor,45,Kansas State,true,false,false,false,12,McLane Stadium,Waco,Texas,Saturday Afternoon +7,2712,12,32,Florida State,57,Miami (FL),true,false,true,false,32,Bobby Bowden Field at Doak S. Campbell Stadium,Tallahassee,Florida,Saturday Afternoon +7,2712,12,33,Fresno State,103,Texas State,true,false,false,false,33,Bulldog Stadium at Jim Sweeney Field,Fresno,California,Saturday Afternoon +7,2712,12,34,Georgia,102,Texas A&M,true,false,false,false,34,Sanford Stadium,Athens,Georgia,Saturday Afternoon +7,2712,12,35,Georgia Southern,131,James Madison,true,true,false,false,35,Allen E. Paulson Stadium,Statesboro,Georgia,Saturday Afternoon +7,2712,12,39,Houston,44,Kansas,true,false,false,false,39,John O'Quinn Field at TDECU Stadium,Houston,Texas,Saturday Afternoon +7,2712,12,52,Louisville,71,North Carolina,true,false,false,false,52,Cardinal Stadium,Louisville,Kentucky,Saturday Afternoon +7,2712,12,58,Miami (OH),19,Central Michigan,true,false,false,false,58,Fred C. Yager Stadium,Oxford,Ohio,Saturday Afternoon +7,2712,12,73,Northern Illinois,143,North Dakota State,true,false,false,false,73,Brigham Field at Huskie Stadium,DeKalb,Illinois,Saturday Afternoon +7,2712,12,104,Texas Tech,79,Oklahoma State,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Afternoon +7,2712,12,107,Tulane,94,South Florida,true,false,false,false,107,Barry B. Benson Field at Yulman Stadium,New Orleans,Louisiana,Saturday Afternoon +7,2712,12,123,Wake Forest,85,Pittsburgh,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Saturday Afternoon +7,2712,12,127,Western Kentucky,138,Missouri State,true,false,false,false,127,L. T. Smith Stadium at Jimmy Feix Field,Bowling Green,Kentucky,Saturday Afternoon +7,2712,12,139,Murray State,137,Illinois State,true,false,false,false,139,Roy Stewart Stadium,Murray,KY,Saturday Afternoon +7,2712,12,196,Eastern Illinois,146,Western Illinois,true,false,true,false,221,O'Brien Field,Charleston,IL,Saturday Afternoon +7,2712,12,230,Mercyhurst,227,Central Connecticut,true,false,false,false,255,Saxon Stadium,Erie,PA,Saturday Afternoon +7,2712,12,233,Stonehill,266,New Haven,true,false,false,false,258,W.B. Mason Stadium,Easton,MA,Saturday Afternoon +7,2712,12,40,Illinois,59,Michigan,true,false,false,false,40,Memorial Stadium,Urbana Champaign,Illinois,Saturday Evening +7,2712,12,68,Nevada,38,Hawaii,true,false,false,false,68,Mackay Stadium,Reno,Nevada,Saturday Evening +7,2712,12,101,Texas,3,Alabama,true,false,false,false,101,Darrell K Royal-Texas Memorial Stadium,Austin,Texas,Saturday Evening +7,2712,12,114,UNLV,90,San Jose State,true,false,false,false,114,Allegient Stadium,Las Vegas,Nevada,Saturday Evening +7,2712,12,115,USC,62,Minnesota,true,false,false,false,115,Los Angeles Memorial Coliseum,Los Angeles,California,Saturday Evening +7,2712,12,124,Washington,129,Wisconsin,true,false,false,false,124,Alaska Airlines Field at Husky Stadium,Seattle,Washington,Saturday Evening +7,2712,12,133,Sam Houston State,132,Jacksonville State,true,false,false,false,133,Bowers Stadium,Huntsville,Texas,Saturday Evening +7,2712,12,140,Northern Iowa,145,South Dakota,true,false,false,false,140,UNI-Dome,Cedar Falls,IA,Saturday Evening +7,2712,12,141,Southern Illinois,136,Indiana State,true,false,false,false,141,Saluki Stadium,Carbondale,IL,Saturday Evening +7,2712,12,156,Eastern Washington,159,Montana,true,false,true,false,156,Roos Field,Cheney,WA,Saturday Evening +7,2712,12,160,Montana State,162,Northern Colorado,true,false,false,false,160,Bobcat Stadium,Bozeman,MT,Saturday Evening +7,2712,12,163,Portland State,263,Utah Tech,true,false,false,false,163,Hillsboro Stadium,Portland,OR,Saturday Evening +7,2712,12,242,San Diego,236,Davidson,true,false,false,false,267,Torero Stadium,San Diego,CA,Saturday Evening +7,2712,12,246,Houston Christian,249,McNeese,true,false,false,false,271,Husky Stadium,Houston,TX,Saturday Evening +7,2712,12,248,Lamar,247,Incarnate Word,true,false,false,false,273,Provost Umphrey Stadium,Beaumont,TX,Saturday Evening +7,2712,12,250,Nicholls,254,UT Rio Grande Valley,true,false,false,false,275,Manning Field at John L. Guidry Stadium,Thibodaux,LA,Saturday Evening +7,2712,12,255,Abilene Christian,257,Central Arkansas,true,false,false,false,280,Anthony Field at Wildcat Stadium,Abilene,TX,Saturday Evening +7,2712,12,265,Chicago State,231,Robert Morris,true,false,false,false,290,SeatGeek Stadium,Chicago,IL,Saturday Evening +7,2712,12,10,Auburn,30,Florida,true,false,true,false,10,Pat Dye Field at Jordan-Hare Stadium,Auburn,Alabama,Saturday Morning +7,2712,12,14,Boston College,26,Duke,true,false,false,false,14,Alumni Stadium,Chestnut Hill,Massachusetts,Saturday Morning +7,2712,12,36,Georgia State,54,Marshall,true,true,false,false,36,Georgia State Stadium,Atlanta,Georgia,Saturday Morning +7,2712,12,63,Mississippi State,120,Vanderbilt,true,false,false,false,63,Davis Wade Stadium at Scott Field,Starkville,Mississippi,Saturday Morning +7,2712,12,86,Purdue,111,UCLA,true,false,false,false,86,Ross-Ade Stadium,West Lafayette,Indiana,Saturday Morning +7,2712,12,88,Rutgers,74,Northwestern,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Saturday Morning +7,2712,12,93,South Carolina,47,Kentucky,true,false,false,false,93,Williams-Brice Stadium,Columbia,South Carolina,Saturday Morning +7,2712,12,105,Toledo,28,Eastern Michigan,true,false,false,false,105,Glass Bowl,Toledo,Ohio,Saturday Morning +7,2712,12,113,UMass,164,Sacramento State,true,false,false,false,113,Warren McGuirk Alumni Stadium,Amherst,Massachusetts,Saturday Morning +7,2712,12,148,Colgate,147,Bucknell,true,false,false,false,148,Andy Kerr Stadium,Hamilton,NY,Saturday Morning +7,2712,12,150,Lafayette,153,Georgetown,true,false,false,false,150,Fisher Stadium,Easton,PA,Saturday Morning +7,2712,12,166,Brown,173,Yale,true,false,false,false,166,Brown Stadium,Providence,RI,Saturday Morning +7,2712,12,179,East Tennessee State,181,Mercer,true,false,false,false,179,William B. Greene Jr. Stadium,Johnson City,TN,Saturday Morning +7,2712,12,188,Alabama A&M,184,Bethune-Cookman,true,true,false,false,188,Louis Crews Stadium,Huntsville,AL,Saturday Morning +7,2712,12,197,Gardner-Webb,198,Lindenwood,true,false,false,false,222,Ernest W. Spangler Stadium,Boiling Springs,NC,Saturday Morning +7,2712,12,201,Tennessee Tech,175,Samford,true,false,false,false,226,Tucker Stadium,Cookeville,TN,Saturday Morning +7,2712,12,207,Elon,205,Campbell,true,false,false,false,232,Rhodes Stadium,Elon,NC,Saturday Morning +7,2712,12,208,Hampton,212,North Carolina A&T,true,false,false,false,233,Armstrong Stadium,Hampton,VA,Saturday Morning +7,2712,12,211,New Hampshire,220,Sacred Heart,true,false,false,false,236,Wildcat Stadium,Durham,NH,Saturday Morning +7,2712,12,213,Rhode Island,210,Monmouth,true,false,false,false,238,Meade Stadium,Kingston,RI,Saturday Morning +7,2712,12,218,William & Mary,217,Villanova,true,false,false,false,243,Water J. Zable Stadium,Williamsburg,VA,Saturday Morning +7,2712,12,224,Norfolk State,225,North Carolina Central,true,false,false,false,249,"William ""Dick"" Price Stadium",Norfolk,VA,Saturday Morning +7,2712,12,244,Stetson,241,Presbyterian,true,false,false,false,269,Spec Martin Memorial Stadium,DeLand,FL,Saturday Morning +7,2712,12,5,Arizona,126,West Virginia,true,false,false,false,5,Arizona Stadium,Tucson,Arizona,Saturday Night +7,2712,12,13,Boise State,25,Colorado State,true,false,false,false,13,Albertsons Stadium,Boise,Idaho,Saturday Night +7,2712,12,18,California,91,SMU,true,false,true,false,18,California Memorial Stadium,Berkeley,California,Saturday Night +7,2712,12,50,Louisiana Monroe,92,South Alabama,true,true,false,false,50,Joe Aillet Stadium,Monroe,Louisiana,Saturday Night +7,2712,12,51,Louisiana Tech,106,Troy,true,true,false,false,51,JPS Field at Malone Stadium,Ruston,Louisiana,Saturday Night +7,2712,12,82,Oregon,41,Indiana,true,false,false,false,82,Autzen Stadium,Eugene,Oregon,Saturday Night +7,2712,12,89,San Diego State,119,Utah State,true,false,false,false,89,SDCCU Stadium,San Diego,California,Saturday Night +7,2712,12,96,Stanford,97,Syracuse,true,false,false,false,96,Stanford Stadium,Stanford,California,Saturday Night +7,2712,12,125,Washington State,83,Oregon State,true,false,true,false,125,Martin Stadium,Pullman,Washington,Saturday Night +7,2712,12,243,St. Thomas,239,Marist,true,false,false,false,268,O'Shaughnessy Stadium,Saint Paul,MN,Saturday Night +7,2712,12,9,Army,56,Memphis,true,false,false,false,9,Blaik Field at Michie Stadium,West Point,New York,Thursday Night +7,2712,12,11,Ball State,2,Akron,true,false,false,false,11,Scheumann Stadium,Muncie,Indiana,Thursday Night +7,2712,12,15,Bowling Green,46,Kent State,true,false,true,false,15,Doyt L. Perry Stadium,Bowling Green,Ohio,Thursday Night +7,2712,12,20,Charlotte,117,UTSA,true,false,false,false,20,McColl-Richardson Field at Jerry Richardson Stadium,Charlotte,North Carolina,Thursday Night +7,2712,12,22,Clemson,122,Virginia Tech,true,false,false,false,22,Frank Howard Field at Clemson Memorial Stadium,Clemson,South Carolina,Thursday Night +7,2712,12,23,Coastal Carolina,4,Appalachian State,true,true,false,false,23,Brooks Stadium,Conway,South Carolina,Thursday Night +7,2712,12,29,FIU,61,Middle Tennessee,true,false,false,false,29,Riccardo Silva Stadium,Miami,Florida,Thursday Night +7,2712,12,55,Maryland,42,Iowa,true,false,false,false,55,Capital One Field at Maryland Stadium,College Park,Maryland,Thursday Night +7,2712,12,65,Navy,87,Rice,true,false,false,false,65,Navy-Marine Corps Memorial Stadium,Annapolis,Maryland,Thursday Night +7,2712,12,66,NC State,121,Virginia,true,false,false,false,66,Wayne Day Family Field at Carter-Finley Stadium,Raleigh,North Carolina,Thursday Night +7,2712,12,76,Ohio,16,Buffalo,true,false,false,false,76,Peden Stadium,Athens,Ohio,Thursday Night +7,2712,12,84,Penn State,67,Nebraska,true,false,false,false,84,Beaver Stadium,University Park,Pennsylvania,Thursday Night +7,2712,12,100,Tennessee,53,LSU,true,false,false,false,100,Neyland Stadium,Knoxville,Tennessee,Thursday Night +7,2712,12,109,UAB,99,Temple,true,false,false,false,109,Legion Field Stadium,Birmingham,Alabama,Thursday Night +7,2712,12,151,Lehigh,149,Holy Cross,true,false,false,false,151,Goodman Stadium,Bethlehem,PA,Thursday Night +7,2712,12,167,Columbia,170,Pennsylvania,true,false,false,false,167,Lawrence A. Wien Stadium,New York,NY,Thursday Night +7,2712,12,168,Cornell,169,Dartmouth,true,false,true,false,168,Schoellkopf Field,Ithaca,NY,Thursday Night +7,2712,12,172,Princeton,171,Harvard,true,false,true,false,172,Princeton Stadium,Princeton,NJ,Thursday Night +7,2712,12,176,The Citadel,177,Wofford,true,false,true,false,176,Johnson Hagood Stadium,Charleston,SC,Thursday Night +7,2712,12,182,VMI,174,Furman,true,false,false,false,182,Foster Stadium,Lexington,VA,Thursday Night +7,2712,12,186,Alcorn State,183,Grambling,true,true,false,false,186,Spinks-Casem Stadium,Lorman,MS,Thursday Night +7,2712,12,191,Alabama State,190,Florida A&M,true,true,false,false,191,New ASU Stadium,Montgomery,AL,Thursday Night +7,2712,12,200,Tennessee State,195,Charleston Southern,true,false,false,false,225,Hale Stadium,Nashville,TN,Thursday Night +7,2712,12,202,UT Martin,199,Southeast Missouri State,true,false,false,false,227,Graham Stadium,Martin,TN,Thursday Night +7,2712,12,203,Albany,215,Stony Brook,true,false,true,false,228,Tom & Mary Casey Stadium,Albany,NY,Thursday Night +7,2712,12,206,Delaware,134,Kennesaw State,true,false,false,false,231,Delaware Stadium,Newark,DE,Thursday Night +7,2712,12,209,Maine,204,Bryant,true,false,false,false,234,Harold Alfond Sports Stadium,Orono,ME,Thursday Night +7,2712,12,214,Richmond,152,Fordham,true,false,false,false,239,E. Claiborne Robins Stadium,Richmond,VA,Thursday Night +7,2712,12,222,Howard,221,Delaware State,true,false,false,false,247,William H. Greene Stadium,Washington,DC,Thursday Night +7,2712,12,223,Morgan State,226,South Carolina State,true,false,false,false,248,Hughes Stadium,Baltimore,MD,Thursday Night +7,2712,12,229,LIU,234,Wagner,true,false,false,false,254,Bethpage Federal Credit Union Stadium,Brooklyn,NY,Thursday Night +7,2712,12,240,Morehead State,237,Dayton,true,false,false,false,265,Jayne Stadium,Morehead,KY,Thursday Night +7,2712,12,245,Valparaiso,238,Drake,true,false,false,false,270,Brown Field,Valparaiso,IN,Thursday Night +7,2712,12,256,Austin Peay,262,Tarleton State,true,false,false,false,281,Fortera Stadium,Clarksville,TN,Thursday Night +7,2712,12,264,West Georgia,259,North Alabama,true,false,false,false,289,University Stadium,Carrollton,GA,Thursday Night +7,2712,12,269,West Florida,258,Eastern Kentucky,true,false,false,false,294,Darrell Gooden Stadium,Pensacola,FL,Thursday Night +7,2713,13,1,Air Force,143,North Dakota State,true,false,false,false,1,Falcon Stadium,Colorado Springs,Colorado,Friday Night +7,2713,13,40,Illinois,124,Washington,true,false,false,false,40,Memorial Stadium,Urbana Champaign,Illinois,Friday Night +7,2713,13,62,Minnesota,82,Oregon,true,false,false,false,62,TCF Bank Stadium,Minneapolis,Minnesota,Friday Night +7,2713,13,69,New Mexico,68,Nevada,true,false,false,false,69,Dreamstyle Stadium,Albuquerque,New Mexico,Friday Night +7,2713,13,138,Missouri State,134,Kennesaw State,true,false,false,false,138,Robert W. Plaster Stadium,Springfield,MO,Friday Night +7,2713,13,157,Idaho,158,Idaho State,true,false,true,false,157,Kibbie Dome,Moscow,ID,Friday Night +7,2713,13,159,Montana,160,Montana State,true,false,true,false,159,Washington-Grizzly Stadium,Missoula,MT,Friday Night +7,2713,13,163,Portland State,156,Eastern Washington,true,false,true,false,163,Hillsboro Stadium,Portland,OR,Friday Night +7,2713,13,251,Northwestern State,247,Incarnate Word,true,false,false,false,276,Harry Turpin Stadium,Natchitotches,LA,Friday Night +7,2713,13,252,SE Louisiana,261,Stephen F. Austin,true,false,false,false,277,Strawberry Stadium,Hammond,LA,Friday Night +7,2713,13,262,Tarleton State,257,Central Arkansas,true,false,false,false,287,Memorial Stadium,Stephenville,TX,Friday Night +7,2713,13,2,Akron,58,Miami (OH),true,false,false,false,2,InfoCision Stadium-Summa Field,Akron,Ohio,Saturday Afternoon +7,2713,13,22,Clemson,32,Florida State,true,false,true,false,22,Frank Howard Field at Clemson Memorial Stadium,Clemson,South Carolina,Saturday Afternoon +7,2713,13,37,Georgia Tech,91,SMU,true,false,false,false,37,Bobby Dodd Stadium at Historic Grant Field,Atlanta,Georgia,Saturday Afternoon +7,2713,13,39,Houston,21,Cincinnati,true,false,false,false,39,John O'Quinn Field at TDECU Stadium,Houston,Texas,Saturday Afternoon +7,2713,13,42,Iowa,59,Michigan,true,false,false,false,42,Kinnick Stadium,Iowa City,Iowa,Saturday Afternoon +7,2713,13,46,Kent State,16,Buffalo,true,false,false,false,46,Dix Stadium,Kent,Ohio,Saturday Afternoon +7,2713,13,48,Liberty,29,FIU,true,false,false,false,48,Arthur L. Williams Stadium,Lynchburg,Virginia,Saturday Afternoon +7,2713,13,53,LSU,101,Texas,true,false,false,false,53,Tiger Stadium,Baton Rouge,Louisiana,Saturday Afternoon +7,2713,13,70,New Mexico State,133,Sam Houston State,true,false,false,false,70,Aggie Memorial Stadium,Las Cruces,New Mexico,Saturday Afternoon +7,2713,13,73,Northern Illinois,114,UNLV,true,false,false,false,73,Brigham Field at Huskie Stadium,DeKalb,Illinois,Saturday Afternoon +7,2713,13,74,Northwestern,60,Michigan State,true,false,false,false,74,Ryan Field,Evanston,Illinois,Saturday Afternoon +7,2713,13,85,Pittsburgh,66,NC State,true,false,false,false,85,Heinz Field,Pittsburgh,Pennsylvania,Saturday Afternoon +7,2713,13,87,Rice,9,Army,true,false,false,false,87,Rice Stadium,Houston,Texas,Saturday Afternoon +7,2713,13,92,South Alabama,106,Troy,true,true,true,false,92,Ladd-Peebles Stadium,Mobile,Alabama,Saturday Afternoon +7,2713,13,102,Texas A&M,64,Missouri,true,false,false,false,102,Kyle Field,College Station,Texas,Saturday Afternoon +7,2713,13,104,Texas Tech,126,West Virginia,true,false,false,false,104,Jones AT&T Stadium,Lubbock,Texas,Saturday Afternoon +7,2713,13,113,UMass,76,Ohio,true,false,false,false,113,Warren McGuirk Alumni Stadium,Amherst,Massachusetts,Saturday Afternoon +7,2713,13,120,Vanderbilt,10,Auburn,true,false,false,false,120,Vanderbilt Stadium,Nashville,Tennessee,Saturday Afternoon +7,2713,13,132,Jacksonville State,206,Delaware,true,false,false,false,132,Burgess-Snow Field at JSU Stadium,Jacksonville,Alabama,Saturday Afternoon +7,2713,13,149,Holy Cross,150,Lafayette,true,false,false,false,149,Fitton Field,Worcester,MA,Saturday Afternoon +7,2713,13,151,Lehigh,152,Fordham,true,false,false,false,151,Goodman Stadium,Bethlehem,PA,Saturday Afternoon +7,2713,13,171,Harvard,166,Brown,true,false,false,false,171,Harvard Stadium,Cambridge,MA,Saturday Afternoon +7,2713,13,178,Chattanooga,174,Furman,true,false,false,false,178,Finley Stadium,Chattanooga,TN,Saturday Afternoon +7,2713,13,183,Grambling,187,Southern,true,true,true,false,183,Eddie G. Robinson Memorial Stadium,Grambling,LA,Saturday Afternoon +7,2713,13,184,Bethune-Cookman,190,Florida A&M,true,true,true,false,184,Daytona Stadium,Daytona Beach,FL,Saturday Afternoon +7,2713,13,196,Eastern Illinois,198,Lindenwood,true,false,false,false,221,O'Brien Field,Charleston,IL,Saturday Afternoon +7,2713,13,199,Southeast Missouri State,195,Charleston Southern,true,false,false,false,224,Houck Stadium,Cape Girardeau,MO,Saturday Afternoon +7,2713,13,207,Elon,213,Rhode Island,true,false,false,false,232,Rhodes Stadium,Elon,NC,Saturday Afternoon +7,2713,13,228,Duquesne,229,LIU,true,false,false,false,253,Arthur J. Rooney Athletic Field,Pittsburgh,PA,Saturday Afternoon +7,2713,13,246,Houston Christian,248,Lamar,true,false,false,false,271,Husky Stadium,Houston,TX,Saturday Afternoon +7,2713,13,7,Arkansas,47,Kentucky,true,false,false,false,7,"Donald W. Reynolds Razorback Stadium, Frank Broyles Field",Fayetteville,Arkansas,Saturday Evening +7,2713,13,17,BYU,44,Kansas,true,false,false,false,17,LaVell Edwards Stadium,Provo,Utah,Saturday Evening +7,2713,13,38,Hawaii,130,Wyoming,true,false,true,false,38,Aloha Stadium,Honolulu,Hawai'i,Saturday Evening +7,2713,13,41,Indiana,84,Penn State,true,false,false,false,41,Memorial Stadium,Bloomington,Indiana,Saturday Evening +7,2713,13,45,Kansas State,5,Arizona,true,false,false,false,45,Bill Snyder Family Football Stadium,Manhattan,Kansas,Saturday Evening +7,2713,13,67,Nebraska,129,Wisconsin,true,false,true,false,67,"Memorial Stadium, Tom Osborne Field",Lincoln,Nebraska,Saturday Evening +7,2713,13,71,North Carolina,14,Boston College,true,false,false,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Evening +7,2713,13,77,Ohio State,55,Maryland,true,false,false,false,77,Ohio Stadium,Columbus,Ohio,Saturday Evening +7,2713,13,78,Oklahoma,81,Ole Miss,true,false,false,false,78,Gaylord Family - Oklahoma Memorial Stadium at Owen Field,Norman,Oklahoma,Saturday Evening +7,2713,13,90,San Jose State,116,UTEP,true,false,false,false,90,CEFCU Stadium,San Jose,California,Saturday Evening +7,2713,13,98,TCU,43,Iowa State,true,false,false,false,98,Amon G. Carter Stadium,Fort Worth,Texas,Saturday Evening +7,2713,13,107,Tulane,72,North Texas,true,false,false,false,107,Barry B. Benson Field at Yulman Stadium,New Orleans,Louisiana,Saturday Evening +7,2713,13,108,Tulsa,20,Charlotte,true,false,false,false,108,Skelly Field at H. A. Chapman Stadium,Tulsa,Oklahoma,Saturday Evening +7,2713,13,117,UTSA,99,Temple,true,false,false,false,117,Alamodome,San Antonio,Texas,Saturday Evening +7,2713,13,122,Virginia Tech,96,Stanford,true,false,false,false,122,Worsham Field at Lane Stadium,Blacksburg,Virginia,Saturday Evening +7,2713,13,123,Wake Forest,52,Louisville,true,false,false,false,123,BB&T Field,Winston-Salem,North Carolina,Saturday Evening +7,2713,13,140,Northern Iowa,142,North Dakota,true,false,false,false,140,UNI-Dome,Cedar Falls,IA,Saturday Evening +7,2713,13,155,Cal Poly,165,Weber State,true,false,false,false,155,Alex G. Spanos Stadium,San Luis Obispo,CA,Saturday Evening +7,2713,13,253,East Texas A&M,250,Nicholls,true,false,false,false,278,Ernest Hawkins Field at Memorial Stadium,Commerce,TX,Saturday Evening +7,2713,13,254,UT Rio Grande Valley,249,McNeese,true,false,false,false,279,Robert and Janet Vackar Stadium,Edinburg,TX,Saturday Evening +7,2713,13,263,Utah Tech,162,Northern Colorado,true,false,false,false,288,Greater Zion STadium,St. George,UT,Saturday Evening +7,2713,13,3,Alabama,63,Mississippi State,true,false,false,false,3,Bryant-Denny Stadium,Tuscaloosa,Alabama,Saturday Morning +7,2713,13,27,East Carolina,31,Florida Atlantic,true,false,false,false,27,Bagwell Field at Dowdy-Ficklen Stadium,Greenville,North Carolina,Saturday Morning +7,2713,13,139,Murray State,141,Southern Illinois,true,false,false,false,139,Roy Stewart Stadium,Murray,KY,Saturday Morning +7,2713,13,170,Pennsylvania,168,Cornell,true,false,true,false,170,Franklin Field,Philadelphia,PA,Saturday Morning +7,2713,13,172,Princeton,169,Dartmouth,true,false,false,false,172,Princeton Stadium,Princeton,NJ,Saturday Morning +7,2713,13,181,Mercer,175,Samford,true,false,false,false,181,Five Star Stadium,Macon,GA,Saturday Morning +7,2713,13,193,Mississippi Valley State,194,Jackson State,true,true,true,false,193,Rice-Totten Stadium,Itta Bena,MS,Saturday Morning +7,2713,13,204,Bryant,212,North Carolina A&T,true,false,false,false,229,Beirne Stadium,Smithfield,RI,Saturday Morning +7,2713,13,209,Maine,211,New Hampshire,true,false,true,false,234,Harold Alfond Sports Stadium,Orono,ME,Saturday Morning +7,2713,13,240,Morehead State,235,Butler,true,false,false,false,265,Jayne Stadium,Morehead,KY,Saturday Morning +7,2713,13,241,Presbyterian,243,St. Thomas,true,false,false,false,266,Bailey Memorial Stadium,Clinton,SC,Saturday Morning +7,2713,13,269,West Florida,255,Abilene Christian,true,false,false,false,294,Darrell Gooden Stadium,Pensacola,FL,Saturday Morning +7,2713,13,6,Arizona State,24,Colorado,true,false,false,false,6,"Sun Devil Stadium, Frank Kush Field",Tempe,Arizona,Saturday Night +7,2713,13,51,Louisiana Tech,95,Southern Miss,true,true,true,false,51,JPS Field at Malone Stadium,Ruston,Louisiana,Saturday Night +7,2713,13,79,Oklahoma State,118,Utah,true,false,false,false,79,Boone Pickens Stadium,Stillwater,Oklahoma,Saturday Night +7,2713,13,115,USC,111,UCLA,true,false,true,false,115,Los Angeles Memorial Coliseum,Los Angeles,California,Saturday Night +7,2713,13,146,Western Illinois,202,UT Martin,true,false,false,false,146,Hanson Field,Macomb,IL,Saturday Night +7,2713,13,4,Appalachian State,54,Marshall,true,true,true,false,4,Kidd Brewer Stadium,Boone,North Carolina,Thursday Night +7,2713,13,28,Eastern Michigan,15,Bowling Green,true,false,false,false,28,Rynearson Stadium,Ypsilanti,Michigan,Thursday Night +7,2713,13,36,Georgia State,35,Georgia Southern,true,true,true,false,36,Georgia State Stadium,Atlanta,Georgia,Thursday Night +7,2713,13,49,Louisiana,50,Louisiana Monroe,true,true,true,false,49,Cajun Field,Lafayette,Louisiana,Thursday Night +7,2713,13,56,Memphis,65,Navy,true,false,false,false,56,Liberty Bowl Memorial Stadium,Memphis,Tennessee,Thursday Night +7,2713,13,57,Miami (FL),18,California,true,false,false,false,57,Hard Rock Stadium,Coral Gables,Florida,Thursday Night +7,2713,13,61,Middle Tennessee,127,Western Kentucky,true,false,true,false,61,Johnny Red Floyd Stadium,Murfreesboro,Tennessee,Thursday Night +7,2713,13,88,Rutgers,86,Purdue,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Thursday Night +7,2713,13,93,South Carolina,30,Florida,true,false,false,false,93,Williams-Brice Stadium,Columbia,South Carolina,Thursday Night +7,2713,13,97,Syracuse,26,Duke,true,false,false,false,97,Carrier Dome,Syracuse,New York,Thursday Night +7,2713,13,105,Toledo,128,Western Michigan,true,false,false,false,105,Glass Bowl,Toledo,Ohio,Thursday Night +7,2713,13,109,UAB,94,South Florida,true,false,false,false,109,Legion Field Stadium,Birmingham,Alabama,Thursday Night +7,2713,13,131,James Madison,80,Old Dominion,true,true,true,false,131,Bridgeforth Stadium,Harrisonburg,Virginia,Thursday Night +7,2713,13,135,Youngstown State,145,South Dakota,true,false,false,false,135,Stambaugh Stadium,Youngstown,OH,Thursday Night +7,2713,13,136,Indiana State,137,Illinois State,true,false,false,false,136,Memorial Stadium,Terre Haute,IN,Thursday Night +7,2713,13,147,Bucknell,217,Villanova,true,false,false,false,147,Christy Mathewson-Memorial Stadium,Lewisburg,PA,Thursday Night +7,2713,13,153,Georgetown,214,Richmond,true,false,false,false,153,Cooper Field,Washington,DC,Thursday Night +7,2713,13,154,UC Davis,260,Southern Utah,true,false,false,false,154,UC Davis Health Stadium,Davis,CA,Thursday Night +7,2713,13,164,Sacramento State,11,Ball State,true,false,true,false,164,Hornet Stadium,Sacramento,CA,Thursday Night +7,2713,13,173,Yale,167,Columbia,true,false,false,false,173,Yale Bowl,New Haven,CT,Thursday Night +7,2713,13,176,The Citadel,182,VMI,true,false,true,false,176,Johnson Hagood Stadium,Charleston,SC,Thursday Night +7,2713,13,179,East Tennessee State,177,Wofford,true,false,false,false,179,William B. Greene Jr. Stadium,Johnson City,TN,Thursday Night +7,2713,13,180,Western Carolina,201,Tennessee Tech,true,false,false,false,180,EJ Whitmire Stadium,Cullowhee,NC,Thursday Night +7,2713,13,197,Gardner-Webb,200,Tennessee State,true,false,false,false,222,Ernest W. Spangler Stadium,Boiling Springs,NC,Thursday Night +7,2713,13,210,Monmouth,208,Hampton,true,false,false,false,235,Kessler Field,West Long Branch,NJ,Thursday Night +7,2713,13,215,Stony Brook,205,Campbell,true,false,false,false,240,Kenneth P. LaValle Stadium,Stony Brook,NY,Thursday Night +7,2713,13,218,William & Mary,148,Colgate,true,false,false,false,243,Water J. Zable Stadium,Williamsburg,VA,Thursday Night +7,2713,13,220,Sacred Heart,203,Albany,true,false,false,false,245,Campus Field,Fairfield,CT,Thursday Night +7,2713,13,224,Norfolk State,221,Delaware State,true,false,false,false,249,"William ""Dick"" Price Stadium",Norfolk,VA,Thursday Night +7,2713,13,226,South Carolina State,225,North Carolina Central,true,false,false,false,251,Oliver C. Dawson Stadium,Orangeburg,SC,Thursday Night +7,2713,13,227,Central Connecticut,234,Wagner,true,false,false,false,252,Arute Field,New Britain,CT,Thursday Night +7,2713,13,231,Robert Morris,233,Stonehill,true,false,false,false,256,Joe Walton Stadium,Moon Township,PA,Thursday Night +7,2713,13,236,Davidson,245,Valparaiso,true,false,false,false,261,Richardson Stadium,Davidson,NC,Thursday Night +7,2713,13,239,Marist,238,Drake,true,false,false,false,264,Leonidoff Field,Poughkeepsie,NY,Thursday Night +7,2713,13,244,Stetson,237,Dayton,true,false,false,false,269,Spec Martin Memorial Stadium,DeLand,FL,Thursday Night +7,2713,13,258,Eastern Kentucky,264,West Georgia,true,false,false,false,283,Roy Kidd Stadium,Richmond,KY,Thursday Night +7,2713,13,259,North Alabama,256,Austin Peay,true,false,false,false,284,Braly Municipal Stadium,Florence,AL,Thursday Night +7,2713,13,266,New Haven,230,Mercyhurst,true,false,false,false,291,Ralph F. DellaCamera Stadium,New Haven,CT,Thursday Night +7,2714,14,19,Central Michigan,128,Western Michigan,true,false,true,false,19,Kelly/Shorts Stadium,Mount Pleasant,Michigan,Friday Night +7,2714,14,58,Miami (OH),76,Ohio,true,false,true,false,58,Fred C. Yager Stadium,Oxford,Ohio,Friday Night +7,2714,14,105,Toledo,15,Bowling Green,true,false,true,false,105,Glass Bowl,Toledo,Ohio,Friday Night +7,2714,14,141,Southern Illinois,144,South Dakota State,true,false,false,false,141,Saluki Stadium,Carbondale,IL,Friday Night +7,2714,14,162,Northern Colorado,161,Northern Arizona,true,false,false,false,162,Nottingham Field,Greeley,CO,Friday Night +7,2714,14,247,Incarnate Word,246,Houston Christian,true,false,false,false,272,Gayle and Tom Benson Stadium,San Antonio,TX,Friday Night +7,2714,14,248,Lamar,252,SE Louisiana,true,false,false,false,273,Provost Umphrey Stadium,Beaumont,TX,Friday Night +7,2714,14,254,UT Rio Grande Valley,251,Northwestern State,true,false,false,false,279,Robert and Janet Vackar Stadium,Edinburg,TX,Friday Night +7,2714,14,267,Guam,268,American Samoa,true,false,true,false,292,National Football Stadium,Mangilao,GM,Friday Night +7,2714,14,7,Arkansas,53,LSU,true,false,true,false,7,"Donald W. Reynolds Razorback Stadium, Frank Broyles Field",Fayetteville,Arkansas,Saturday Afternoon +7,2714,14,12,Baylor,98,TCU,true,false,true,false,12,McLane Stadium,Waco,Texas,Saturday Afternoon +7,2714,14,13,Boise State,33,Fresno State,true,false,true,false,13,Albertsons Stadium,Boise,Idaho,Saturday Afternoon +7,2714,14,44,Kansas,45,Kansas State,true,false,true,false,44,David Booth Kansas Memorial Stadium,Lawrence,Kansas,Saturday Afternoon +7,2714,14,63,Mississippi State,81,Ole Miss,true,false,true,false,63,Davis Wade Stadium at Scott Field,Starkville,Mississippi,Saturday Afternoon +7,2714,14,67,Nebraska,42,Iowa,true,false,true,false,67,"Memorial Stadium, Tom Osborne Field",Lincoln,Nebraska,Saturday Afternoon +7,2714,14,100,Tennessee,120,Vanderbilt,true,false,true,false,100,Neyland Stadium,Knoxville,Tennessee,Saturday Afternoon +7,2714,14,129,Wisconsin,62,Minnesota,true,false,true,false,129,Camp Randall Stadium,Madison,Wisconsin,Saturday Afternoon +7,2714,14,136,Indiana State,140,Northern Iowa,true,false,false,false,136,Memorial Stadium,Terre Haute,IN,Saturday Afternoon +7,2714,14,139,Murray State,145,South Dakota,true,false,false,false,139,Roy Stewart Stadium,Murray,KY,Saturday Afternoon +7,2714,14,167,Columbia,152,Fordham,false,false,true,false,167,Lawrence A. Wien Stadium,New York,NY,Saturday Afternoon +7,2714,14,170,Pennsylvania,172,Princeton,true,false,true,false,170,Franklin Field,Philadelphia,PA,Saturday Afternoon +7,2714,14,177,Wofford,182,VMI,true,false,false,false,177,Gibbs Stadium,Spartanburg,SC,Saturday Afternoon +7,2714,14,178,Chattanooga,180,Western Carolina,true,false,false,false,178,Finley Stadium,Chattanooga,TN,Saturday Afternoon +7,2714,14,181,Mercer,201,Tennessee Tech,true,false,false,false,181,Five Star Stadium,Macon,GA,Saturday Afternoon +7,2714,14,200,Tennessee State,196,Eastern Illinois,true,false,false,false,225,Hale Stadium,Nashville,TN,Saturday Afternoon +7,2714,14,204,Bryant,215,Stony Brook,true,false,false,false,229,Beirne Stadium,Smithfield,RI,Saturday Afternoon +7,2714,14,235,Butler,244,Stetson,true,false,false,false,260,Bud and Jackie Sellick Bowl,Indianapolis,IN,Saturday Afternoon +7,2714,14,237,Dayton,238,Drake,true,false,true,false,262,Welcome Stadium,Dayton,OH,Saturday Afternoon +7,2714,14,239,Marist,240,Morehead State,true,false,false,false,264,Leonidoff Field,Poughkeepsie,NY,Saturday Afternoon +7,2714,14,241,Presbyterian,236,Davidson,true,false,false,false,266,Bailey Memorial Stadium,Clinton,SC,Saturday Afternoon +7,2714,14,245,Valparaiso,243,St. Thomas,true,false,false,false,270,Brown Field,Valparaiso,IN,Saturday Afternoon +7,2714,14,255,Abilene Christian,262,Tarleton State,true,false,false,false,280,Anthony Field at Wildcat Stadium,Abilene,TX,Saturday Afternoon +7,2714,14,3,Alabama,10,Auburn,true,false,true,false,3,Bryant-Denny Stadium,Tuscaloosa,Alabama,Saturday Evening +7,2714,14,5,Arizona,6,Arizona State,true,false,true,false,5,Arizona Stadium,Tucson,Arizona,Saturday Evening +7,2714,14,68,Nevada,114,UNLV,true,false,true,false,68,Mackay Stadium,Reno,Nevada,Saturday Evening +7,2714,14,82,Oregon,83,Oregon State,false,false,true,false,82,Autzen Stadium,Eugene,Oregon,Saturday Evening +7,2714,14,101,Texas,102,Texas A&M,true,false,true,false,101,Darrell K Royal-Texas Memorial Stadium,Austin,Texas,Saturday Evening +7,2714,14,118,Utah,17,BYU,true,false,true,false,118,Rice-Eccles Stadium,Salt Lake City,Utah,Saturday Evening +7,2714,14,121,Virginia,122,Virginia Tech,true,false,true,false,121,David A. Harrison III Field at Scott Stadium,Charlottesville,Virginia,Saturday Evening +7,2714,14,126,West Virginia,85,Pittsburgh,false,false,true,false,126,Mountaineer Field at Milan Puskar Stadium,Morgantown,West Virginia,Saturday Evening +7,2714,14,156,Eastern Washington,260,Southern Utah,true,false,false,false,156,Roos Field,Cheney,WA,Saturday Evening +7,2714,14,159,Montana,155,Cal Poly,true,false,false,false,159,Washington-Grizzly Stadium,Missoula,MT,Saturday Evening +7,2714,14,164,Sacramento State,154,UC Davis,false,false,true,false,164,Hornet Stadium,Sacramento,CA,Saturday Evening +7,2714,14,165,Weber State,157,Idaho,true,false,false,false,165,Stewart Stadium,Ogden,UT,Saturday Evening +7,2714,14,2,Akron,46,Kent State,true,false,true,false,2,InfoCision Stadium-Summa Field,Akron,Ohio,Saturday Morning +7,2714,14,9,Army,65,Navy,true,false,true,false,9,Blaik Field at Michie Stadium,West Point,New York,Saturday Morning +7,2714,14,11,Ball State,73,Northern Illinois,false,false,true,false,11,Scheumann Stadium,Muncie,Indiana,Saturday Morning +7,2714,14,14,Boston College,97,Syracuse,true,false,true,false,14,Alumni Stadium,Chestnut Hill,Massachusetts,Saturday Morning +7,2714,14,32,Florida State,30,Florida,false,false,true,false,32,Bobby Bowden Field at Doak S. Campbell Stadium,Tallahassee,Florida,Saturday Morning +7,2714,14,34,Georgia,37,Georgia Tech,false,false,true,false,34,Sanford Stadium,Athens,Georgia,Saturday Morning +7,2714,14,41,Indiana,86,Purdue,true,false,true,false,41,Memorial Stadium,Bloomington,Indiana,Saturday Morning +7,2714,14,47,Kentucky,52,Louisville,false,false,true,false,47,Kroger Field at C.M. Newton Grounds,Lexington,Kentucky,Saturday Morning +7,2714,14,59,Michigan,77,Ohio State,true,false,true,false,59,Michigan Stadium,Ann Arbor,Michigan,Saturday Morning +7,2714,14,71,North Carolina,66,NC State,true,false,true,false,71,Kenan Memorial Stadium,Chapel Hill,North Carolina,Saturday Morning +7,2714,14,88,Rutgers,55,Maryland,true,false,false,false,88,High Point Solutions Stadium,Piscataway,New Jersey,Saturday Morning +7,2714,14,93,South Carolina,22,Clemson,false,false,true,false,93,Williams-Brice Stadium,Columbia,South Carolina,Saturday Morning +7,2714,14,95,Southern Miss,107,Tulane,false,false,true,false,95,Carlisle-Faulkner Field at M.M. Roberts Stadium,Hattiesburg,Mississippi,Saturday Morning +7,2714,14,166,Brown,168,Cornell,true,false,false,false,166,Brown Stadium,Providence,RI,Saturday Morning +7,2714,14,169,Dartmouth,211,New Hampshire,false,false,true,false,169,Memorial Field,Hanover,NH,Saturday Morning +7,2714,14,179,East Tennessee State,176,The Citadel,true,false,false,false,179,William B. Greene Jr. Stadium,Johnson City,TN,Saturday Morning +7,2714,14,202,UT Martin,197,Gardner-Webb,true,false,false,false,227,Graham Stadium,Martin,TN,Saturday Morning +7,2714,14,205,Campbell,220,Sacred Heart,true,false,false,false,230,Barker-Lane Stadium,Buies Creek,NC,Saturday Morning +7,2714,14,210,Monmouth,209,Maine,true,false,false,false,235,Kessler Field,West Long Branch,NJ,Saturday Morning +7,2714,14,217,Villanova,214,Richmond,true,false,false,false,242,Villanova Stadium,Philadelphia,PA,Saturday Morning +7,2714,14,223,Morgan State,224,Norfolk State,true,false,false,false,248,Hughes Stadium,Baltimore,MD,Saturday Morning +7,2714,14,258,Eastern Kentucky,259,North Alabama,true,false,false,false,283,Roy Kidd Stadium,Richmond,KY,Saturday Morning +7,2714,14,266,New Haven,229,LIU,true,false,false,false,291,Ralph F. DellaCamera Stadium,New Haven,CT,Saturday Morning +7,2714,14,269,West Florida,257,Central Arkansas,true,false,false,false,294,Darrell Gooden Stadium,Pensacola,FL,Saturday Morning +7,2714,14,18,California,96,Stanford,true,false,true,false,18,California Memorial Stadium,Berkeley,California,Saturday Night +7,2714,14,40,Illinois,74,Northwestern,true,false,true,false,40,Memorial Stadium,Urbana Champaign,Illinois,Saturday Night +7,2714,14,69,New Mexico,70,New Mexico State,false,false,true,false,69,Dreamstyle Stadium,Albuquerque,New Mexico,Saturday Night +7,2714,14,96,Stanford,75,Notre Dame,false,false,true,false,96,Stanford Stadium,Stanford,California,Saturday Night +7,2714,14,124,Washington,125,Washington State,false,false,true,false,124,Alaska Airlines Field at Husky Stadium,Seattle,Washington,Saturday Night +7,2714,14,142,North Dakota,137,Illinois State,true,false,false,false,142,Alerus Center,Grand Forks,ND,Saturday Night +7,2714,14,160,Montana State,163,Portland State,true,false,false,false,160,Bobcat Stadium,Bozeman,MT,Saturday Night +7,2714,14,198,Lindenwood,199,Southeast Missouri State,true,false,false,false,223,Hunter STadium,St. Charles,MO,Saturday Night +7,2714,14,261,Stephen F. Austin,253,East Texas A&M,true,false,false,false,286,Homer Bryce Stadium,Nacogdoches,TX,Saturday Night +7,2714,14,4,Appalachian State,35,Georgia Southern,true,true,true,false,4,Kidd Brewer Stadium,Boone,North Carolina,Thursday Night +7,2714,14,16,Buffalo,113,UMass,true,false,true,false,16,UB Stadium,Buffalo,New York,Thursday Night +7,2714,14,31,Florida Atlantic,29,FIU,false,false,true,false,31,FAU Stadium,Boca Raton,Florida,Thursday Night +7,2714,14,56,Memphis,109,UAB,true,false,true,false,56,Liberty Bowl Memorial Stadium,Memphis,Tennessee,Thursday Night +7,2714,14,60,Michigan State,84,Penn State,true,false,true,false,60,Spartan Stadium,East Lansing,Michigan,Thursday Night +7,2714,14,94,South Florida,110,UCF,false,false,true,false,94,Raymond James Stadium,Tampa,Florida,Thursday Night +7,2714,14,103,Texas State,117,UTSA,false,false,true,false,103,Jim Wacker Field at Bobcat Stadium,San Marcos,Texas,Thursday Night +7,2714,14,149,Holy Cross,148,Colgate,true,false,false,false,149,Fitton Field,Worcester,MA,Thursday Night +7,2714,14,153,Georgetown,147,Bucknell,true,false,false,false,153,Cooper Field,Washington,DC,Thursday Night +7,2714,14,171,Harvard,173,Yale,true,false,true,false,171,Harvard Stadium,Cambridge,MA,Thursday Night +7,2714,14,175,Samford,174,Furman,true,false,false,false,175,Seibert Stadium,Homewood,AL,Thursday Night +7,2714,14,193,Mississippi Valley State,183,Grambling,true,false,false,false,193,Rice-Totten Stadium,Itta Bena,MS,Thursday Night +7,2714,14,194,Jackson State,185,Prairie View A&M,true,false,false,false,194,Mississippi Veterans Memorial Stadium,Jackson,MS,Thursday Night +7,2714,14,195,Charleston Southern,146,Western Illinois,true,false,false,false,220,Buccaneer Field,Bules Creek,NC,Thursday Night +7,2714,14,203,Albany,207,Elon,true,false,false,false,228,Tom & Mary Casey Stadium,Albany,NY,Thursday Night +7,2714,14,213,Rhode Island,208,Hampton,true,false,false,false,238,Meade Stadium,Kingston,RI,Thursday Night +7,2714,14,218,William & Mary,150,Lafayette,true,false,false,false,243,Water J. Zable Stadium,Williamsburg,VA,Thursday Night +7,2714,14,221,Delaware State,225,North Carolina Central,true,false,false,false,246,Alumni Stadium,Dover,DE,Thursday Night +7,2714,14,226,South Carolina State,222,Howard,true,false,false,false,251,Oliver C. Dawson Stadium,Orangeburg,SC,Thursday Night +7,2714,14,228,Duquesne,265,Chicago State,true,false,false,false,253,Arthur J. Rooney Athletic Field,Pittsburgh,PA,Thursday Night +7,2714,14,230,Mercyhurst,233,Stonehill,true,false,false,false,255,Saxon Stadium,Erie,PA,Thursday Night +7,2714,14,234,Wagner,231,Robert Morris,true,false,false,false,259,Wagner College Stadium,Staten Island,NY,Thursday Night +7,2714,14,264,West Georgia,256,Austin Peay,true,false,false,false,289,University Stadium,Carrollton,GA,Thursday Night diff --git a/structs/CollegeGame.go b/structs/CollegeGame.go index 01eebad..098d75f 100644 --- a/structs/CollegeGame.go +++ b/structs/CollegeGame.go @@ -148,36 +148,3 @@ type WeatherResponse struct { WindSpeed float64 WindCategory string } - -type GameRequest struct { - gorm.Model - HomeTeamID uint - AwayTeamID uint - SendingTeamID uint - RequestingTeamID uint - IsAccepted bool - IsApproved bool - ArenaID uint - Arena string - IsNeutralSite bool - SeasonID uint - WeekID uint - Week uint -} - -func (g *GameRequest) Accepted() { - g.IsAccepted = true -} - -func (g *GameRequest) Approved() { - g.IsApproved = true -} - -func (g *GameRequest) UpdateRequest(arenaID uint, arena string, isNeutralSite bool, seasonID uint, weekID uint, week uint) { - g.ArenaID = arenaID - g.Arena = arena - g.IsNeutralSite = isNeutralSite - g.SeasonID = seasonID - g.WeekID = weekID - g.Week = week -} diff --git a/structs/GameRequestStructs.go b/structs/GameRequestStructs.go new file mode 100644 index 0000000..9e08632 --- /dev/null +++ b/structs/GameRequestStructs.go @@ -0,0 +1,47 @@ +package structs + +import "github.com/jinzhu/gorm" + +type CFBGameRequest struct { + GameRequest + IsSpringGame bool +} + +type NFLGameRequest struct { + GameRequest + IsPreseason bool +} + +type GameRequest struct { + gorm.Model + HomeTeamID uint + AwayTeamID uint + SendingTeamID uint + RequestingTeamID uint + IsAccepted bool + IsApproved bool + ArenaID uint + Arena string + IsNeutralSite bool + SeasonID uint + WeekID uint + Week uint + Timeslot string +} + +func (g *GameRequest) Accepted() { + g.IsAccepted = true +} + +func (g *GameRequest) Approved() { + g.IsApproved = true +} + +func (g *GameRequest) UpdateRequest(arenaID uint, arena string, isNeutralSite bool, seasonID uint, weekID uint, week uint) { + g.ArenaID = arenaID + g.Arena = arena + g.IsNeutralSite = isNeutralSite + g.SeasonID = seasonID + g.WeekID = weekID + g.Week = week +} diff --git a/structs/RivalStructs.go b/structs/RivalStructs.go index d070677..2749dbd 100644 --- a/structs/RivalStructs.go +++ b/structs/RivalStructs.go @@ -11,4 +11,10 @@ type CollegeRival struct { HasTrophy bool TeamOnePriority uint TeamTwoPriority uint + IsAnnualRivalry bool + ConferenceID uint + PreferredWeek uint8 + Timeslot string + IsNeutralSite bool + StadiumID uint } diff --git a/ts/footballModels.ts b/ts/footballModels.ts index 0d9b6d6..64ed1b0 100644 --- a/ts/footballModels.ts +++ b/ts/footballModels.ts @@ -432,6 +432,7 @@ export class NFLExtensionOffer { IsAccepted: boolean; IsActive: boolean; IsRejected: boolean; + IsTag: boolean; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); @@ -463,6 +464,7 @@ export class NFLExtensionOffer { this.IsAccepted = source["IsAccepted"]; this.IsActive = source["IsActive"]; this.IsRejected = source["IsRejected"]; + this.IsTag = source["IsTag"]; } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -982,6 +984,21 @@ export class NFLPlayer { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; PlayerID: number; TeamID: number; CollegeID: number; @@ -1001,7 +1018,9 @@ export class NFLPlayer { NegotiationRound: number; SigningRound: number; MinimumValue: number; + OriginalMinimumValue: number; AAV: number; + OriginalAAV: number; DraftedTeamID: number; DraftedTeam: string; DraftedRound: number; @@ -1079,6 +1098,21 @@ export class NFLPlayer { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.PlayerID = source["PlayerID"]; this.TeamID = source["TeamID"]; this.CollegeID = source["CollegeID"]; @@ -1098,7 +1132,9 @@ export class NFLPlayer { this.NegotiationRound = source["NegotiationRound"]; this.SigningRound = source["SigningRound"]; this.MinimumValue = source["MinimumValue"]; + this.OriginalMinimumValue = source["OriginalMinimumValue"]; this.AAV = source["AAV"]; + this.OriginalAAV = source["OriginalAAV"]; this.DraftedTeamID = source["DraftedTeamID"]; this.DraftedTeam = source["DraftedTeam"]; this.DraftedRound = source["DraftedRound"]; @@ -1633,6 +1669,7 @@ export class NFLDraftPick { DrafteeID: number; DraftRound: number; DraftNumber: number; + OverallPickNumber: number; TeamID: number; Team: string; OriginalTeamID: number; @@ -1658,6 +1695,7 @@ export class NFLDraftPick { this.DrafteeID = source["DrafteeID"]; this.DraftRound = source["DraftRound"]; this.DraftNumber = source["DraftNumber"]; + this.OverallPickNumber = source["OverallPickNumber"]; this.TeamID = source["TeamID"]; this.Team = source["Team"]; this.OriginalTeamID = source["OriginalTeamID"]; @@ -1986,6 +2024,17 @@ export class CollegeStandings { PostSeasonStatus: string; IsFBS: boolean; Rank: number; + IsConferenceChampion: boolean; + ToucanRank: number; + PreseasonRank: number; + RegularSeasonRank: number; + SOS: number; + SOR: number; + RPI: number; + ConferenceStrengthAdj: number; + Tier1Wins: number; + Tier2Wins: number; + BadLosses: number; TotalWins: number; TotalLosses: number; ConferenceWins: number; @@ -2020,6 +2069,17 @@ export class CollegeStandings { this.PostSeasonStatus = source["PostSeasonStatus"]; this.IsFBS = source["IsFBS"]; this.Rank = source["Rank"]; + this.IsConferenceChampion = source["IsConferenceChampion"]; + this.ToucanRank = source["ToucanRank"]; + this.PreseasonRank = source["PreseasonRank"]; + this.RegularSeasonRank = source["RegularSeasonRank"]; + this.SOS = source["SOS"]; + this.SOR = source["SOR"]; + this.RPI = source["RPI"]; + this.ConferenceStrengthAdj = source["ConferenceStrengthAdj"]; + this.Tier1Wins = source["Tier1Wins"]; + this.Tier2Wins = source["Tier2Wins"]; + this.BadLosses = source["BadLosses"]; this.TotalWins = source["TotalWins"]; this.TotalLosses = source["TotalLosses"]; this.ConferenceWins = source["ConferenceWins"]; @@ -2462,6 +2522,21 @@ export class CollegePlayer { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; PlayerID: number; TeamID: number; TeamAbbr: string; @@ -2540,6 +2615,21 @@ export class CollegePlayer { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.PlayerID = source["PlayerID"]; this.TeamID = source["TeamID"]; this.TeamAbbr = source["TeamAbbr"]; @@ -2581,7 +2671,7 @@ export class CollegeDepthChartPosition { ID: number; CreatedAt: Time; UpdatedAt: Time; - DeletedAt: Time; + DeletedAt: DeletedAt; DepthChartID: number; PlayerID: number; Position: string; @@ -2596,7 +2686,7 @@ export class CollegeDepthChartPosition { this.ID = source["ID"]; this.CreatedAt = this.convertValues(source["CreatedAt"], Time); this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], DeletedAt); this.DepthChartID = source["DepthChartID"]; this.PlayerID = source["PlayerID"]; this.Position = source["Position"]; @@ -2629,7 +2719,7 @@ export class CollegeTeamDepthChart { ID: number; CreatedAt: Time; UpdatedAt: Time; - DeletedAt: Time; + DeletedAt: DeletedAt; TeamID: number; DepthChartPlayers: CollegeDepthChartPosition[]; @@ -2638,7 +2728,7 @@ export class CollegeTeamDepthChart { this.ID = source["ID"]; this.CreatedAt = this.convertValues(source["CreatedAt"], Time); this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], DeletedAt); this.TeamID = source["TeamID"]; this.DepthChartPlayers = this.convertValues(source["DepthChartPlayers"], CollegeDepthChartPosition); } @@ -2665,7 +2755,7 @@ export class CollegeGameplan { ID: number; CreatedAt: Time; UpdatedAt: Time; - DeletedAt: Time; + DeletedAt: DeletedAt; TeamID: number; OffensiveScheme: string; OffRunToPassRatio: number; @@ -2809,7 +2899,7 @@ export class CollegeGameplan { this.ID = source["ID"]; this.CreatedAt = this.convertValues(source["CreatedAt"], Time); this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], DeletedAt); this.TeamID = source["TeamID"]; this.OffensiveScheme = source["OffensiveScheme"]; this.OffRunToPassRatio = source["OffRunToPassRatio"]; @@ -3720,6 +3810,21 @@ export class Recruit { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; HighSchool: string; City: string; State: string; @@ -3800,6 +3905,21 @@ export class Recruit { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.HighSchool = source["HighSchool"]; this.City = source["City"]; this.State = source["State"]; @@ -3850,6 +3970,7 @@ export class RecruitPlayerProfile { PreviousWeekPoints: number; SpendingCount: number; RecruitingEfficiencyScore: number; + PreferenceModifier: number; Scholarship: boolean; ScholarshipRevoked: boolean; AffinityOneEligible: boolean; @@ -3877,6 +3998,7 @@ export class RecruitPlayerProfile { this.PreviousWeekPoints = source["PreviousWeekPoints"]; this.SpendingCount = source["SpendingCount"]; this.RecruitingEfficiencyScore = source["RecruitingEfficiencyScore"]; + this.PreferenceModifier = source["PreferenceModifier"]; this.Scholarship = source["Scholarship"]; this.ScholarshipRevoked = source["ScholarshipRevoked"]; this.AffinityOneEligible = source["AffinityOneEligible"]; @@ -3965,6 +4087,17 @@ export class RecruitingTeamProfile { BigCityAffinity: boolean; MediaSpotlightAffinity: boolean; RisingStarsAffinity: boolean; + ProgramPrestige: number; + ProfessionalPrestige: number; + Traditions: number; + Facilities: number; + Atmosphere: number; + Academics: number; + CampusLife: number; + ConferencePrestige: number; + CoachRating: number; + SeasonMomentum: number; + MediaSpotlight: number; Recruits: RecruitPlayerProfile[]; Affinities: ProfileAffinity[]; @@ -4025,6 +4158,17 @@ export class RecruitingTeamProfile { this.BigCityAffinity = source["BigCityAffinity"]; this.MediaSpotlightAffinity = source["MediaSpotlightAffinity"]; this.RisingStarsAffinity = source["RisingStarsAffinity"]; + this.ProgramPrestige = source["ProgramPrestige"]; + this.ProfessionalPrestige = source["ProfessionalPrestige"]; + this.Traditions = source["Traditions"]; + this.Facilities = source["Facilities"]; + this.Atmosphere = source["Atmosphere"]; + this.Academics = source["Academics"]; + this.CampusLife = source["CampusLife"]; + this.ConferencePrestige = source["ConferencePrestige"]; + this.CoachRating = source["CoachRating"]; + this.SeasonMomentum = source["SeasonMomentum"]; + this.MediaSpotlight = source["MediaSpotlight"]; this.Recruits = this.convertValues(source["Recruits"], RecruitPlayerProfile); this.Affinities = this.convertValues(source["Affinities"], ProfileAffinity); } @@ -4376,6 +4520,21 @@ export class NFLRetiredPlayer { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; PlayerID: number; TeamID: number; CollegeID: number; @@ -4395,7 +4554,9 @@ export class NFLRetiredPlayer { NegotiationRound: number; SigningRound: number; MinimumValue: number; + OriginalMinimumValue: number; AAV: number; + OriginalAAV: number; DraftedTeamID: number; DraftedTeam: string; DraftedRound: number; @@ -4473,6 +4634,21 @@ export class NFLRetiredPlayer { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.PlayerID = source["PlayerID"]; this.TeamID = source["TeamID"]; this.CollegeID = source["CollegeID"]; @@ -4492,7 +4668,9 @@ export class NFLRetiredPlayer { this.NegotiationRound = source["NegotiationRound"]; this.SigningRound = source["SigningRound"]; this.MinimumValue = source["MinimumValue"]; + this.OriginalMinimumValue = source["OriginalMinimumValue"]; this.AAV = source["AAV"]; + this.OriginalAAV = source["OriginalAAV"]; this.DraftedTeamID = source["DraftedTeamID"]; this.DraftedTeam = source["DraftedTeam"]; this.DraftedRound = source["DraftedRound"]; @@ -4711,6 +4889,7 @@ export class NFLGame { IsConferenceChampionship: boolean; IsSuperBowl: boolean; GameComplete: boolean; + IsRevealed: boolean; IsPreseasonGame: boolean; GameTitle: string; NextGameID: number; @@ -4761,6 +4940,7 @@ export class NFLGame { this.IsConferenceChampionship = source["IsConferenceChampionship"]; this.IsSuperBowl = source["IsSuperBowl"]; this.GameComplete = source["GameComplete"]; + this.IsRevealed = source["IsRevealed"]; this.IsPreseasonGame = source["IsPreseasonGame"]; this.GameTitle = source["GameTitle"]; this.NextGameID = source["NextGameID"]; @@ -5113,6 +5293,7 @@ export class CollegeGame { IsPlayoffGame: boolean; IsNationalChampionship: boolean; IsRivalryGame: boolean; + IsRevealed: boolean; GameComplete: boolean; IsSpringGame: boolean; GameTitle: string; @@ -5167,6 +5348,7 @@ export class CollegeGame { this.IsPlayoffGame = source["IsPlayoffGame"]; this.IsNationalChampionship = source["IsNationalChampionship"]; this.IsRivalryGame = source["IsRivalryGame"]; + this.IsRevealed = source["IsRevealed"]; this.GameComplete = source["GameComplete"]; this.IsSpringGame = source["IsSpringGame"]; this.GameTitle = source["GameTitle"]; @@ -5195,191 +5377,15 @@ export class CollegeGame { return a; } } -export class HistoricCollegePlayer { - ID: number; - CreatedAt: Time; - UpdatedAt: Time; - DeletedAt: Time; - FirstName: string; - LastName: string; - Position: string; - Archetype: string; - PreviousTeamID: number; - PreviousTeam: string; - Height: number; - Weight: number; - Age: number; - Stars: number; - Overall: number; - Stamina: number; - Injury: number; - FootballIQ: number; - Speed: number; - Carrying: number; - Agility: number; - Catching: number; - RouteRunning: number; - ZoneCoverage: number; - ManCoverage: number; - Strength: number; - Tackle: number; - PassBlock: number; - RunBlock: number; - PassRush: number; - RunDefense: number; - ThrowPower: number; - ThrowAccuracy: number; - KickAccuracy: number; - KickPower: number; - PuntAccuracy: number; - PuntPower: number; - Progression: number; - Discipline: number; - PotentialGrade: string; - FreeAgency: string; - Personality: string; - RecruitingBias: string; - WorkEthic: string; - AcademicBias: string; - IsInjured: boolean; - InjuryName: string; - InjuryType: string; - WeeksOfRecovery: number; - InjuryReserve: boolean; - PrimeAge: number; - Clutch: number; - Shotgun: number; - PositionTwo: string; - ArchetypeTwo: string; - RelativeID: number; - RelativeType: number; - Notes: string; - PlayerID: number; - TeamID: number; - TeamAbbr: string; - HighSchool: string; - City: string; - State: string; - Year: number; - IsRedshirt: boolean; - IsRedshirting: boolean; - HasGraduated: boolean; - TransferStatus: number; - TransferLikeliness: string; - Stats: CollegePlayerStats[]; - SeasonStats: CollegePlayerSeasonStats; - HasProgressed: boolean; - WillDeclare: boolean; - LegacyID: number; - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.ID = source["ID"]; - this.CreatedAt = this.convertValues(source["CreatedAt"], Time); - this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); - this.FirstName = source["FirstName"]; - this.LastName = source["LastName"]; - this.Position = source["Position"]; - this.Archetype = source["Archetype"]; - this.PreviousTeamID = source["PreviousTeamID"]; - this.PreviousTeam = source["PreviousTeam"]; - this.Height = source["Height"]; - this.Weight = source["Weight"]; - this.Age = source["Age"]; - this.Stars = source["Stars"]; - this.Overall = source["Overall"]; - this.Stamina = source["Stamina"]; - this.Injury = source["Injury"]; - this.FootballIQ = source["FootballIQ"]; - this.Speed = source["Speed"]; - this.Carrying = source["Carrying"]; - this.Agility = source["Agility"]; - this.Catching = source["Catching"]; - this.RouteRunning = source["RouteRunning"]; - this.ZoneCoverage = source["ZoneCoverage"]; - this.ManCoverage = source["ManCoverage"]; - this.Strength = source["Strength"]; - this.Tackle = source["Tackle"]; - this.PassBlock = source["PassBlock"]; - this.RunBlock = source["RunBlock"]; - this.PassRush = source["PassRush"]; - this.RunDefense = source["RunDefense"]; - this.ThrowPower = source["ThrowPower"]; - this.ThrowAccuracy = source["ThrowAccuracy"]; - this.KickAccuracy = source["KickAccuracy"]; - this.KickPower = source["KickPower"]; - this.PuntAccuracy = source["PuntAccuracy"]; - this.PuntPower = source["PuntPower"]; - this.Progression = source["Progression"]; - this.Discipline = source["Discipline"]; - this.PotentialGrade = source["PotentialGrade"]; - this.FreeAgency = source["FreeAgency"]; - this.Personality = source["Personality"]; - this.RecruitingBias = source["RecruitingBias"]; - this.WorkEthic = source["WorkEthic"]; - this.AcademicBias = source["AcademicBias"]; - this.IsInjured = source["IsInjured"]; - this.InjuryName = source["InjuryName"]; - this.InjuryType = source["InjuryType"]; - this.WeeksOfRecovery = source["WeeksOfRecovery"]; - this.InjuryReserve = source["InjuryReserve"]; - this.PrimeAge = source["PrimeAge"]; - this.Clutch = source["Clutch"]; - this.Shotgun = source["Shotgun"]; - this.PositionTwo = source["PositionTwo"]; - this.ArchetypeTwo = source["ArchetypeTwo"]; - this.RelativeID = source["RelativeID"]; - this.RelativeType = source["RelativeType"]; - this.Notes = source["Notes"]; - this.PlayerID = source["PlayerID"]; - this.TeamID = source["TeamID"]; - this.TeamAbbr = source["TeamAbbr"]; - this.HighSchool = source["HighSchool"]; - this.City = source["City"]; - this.State = source["State"]; - this.Year = source["Year"]; - this.IsRedshirt = source["IsRedshirt"]; - this.IsRedshirting = source["IsRedshirting"]; - this.HasGraduated = source["HasGraduated"]; - this.TransferStatus = source["TransferStatus"]; - this.TransferLikeliness = source["TransferLikeliness"]; - this.Stats = this.convertValues(source["Stats"], CollegePlayerStats); - this.SeasonStats = this.convertValues(source["SeasonStats"], CollegePlayerSeasonStats); - this.HasProgressed = source["HasProgressed"]; - this.WillDeclare = source["WillDeclare"]; - this.LegacyID = source["LegacyID"]; - } - - convertValues(a: any, classs: any, asMap: boolean = false): any { - if (!a) { - return a; - } - if (Array.isArray(a)) { - return (a as any[]).map(elem => this.convertValues(elem, classs)); - } else if ("object" === typeof a) { - if (asMap) { - for (const key of Object.keys(a)) { - a[key] = new classs(a[key]); - } - return a; - } - return new classs(a); - } - return a; - } -} export class BootstrapDataLanding { CollegeTeam: CollegeTeam; CollegeRosterMap: {[key: uint]: CollegePlayer[]}; - HistoricCollegePlayers: HistoricCollegePlayer[]; CollegeStandings: CollegeStandings[]; AllCollegeGames: CollegeGame[]; OfficialPolls: CollegePollOfficial[]; TopCFBPassers: CollegePlayer[]; TopCFBRushers: CollegePlayer[]; TopCFBReceivers: CollegePlayer[]; - PortalPlayers: CollegePlayer[]; CollegeInjuryReport: CollegePlayer[]; CollegeNotifications: Notification[]; ProTeam: NFLTeam; @@ -5400,14 +5406,12 @@ export class BootstrapDataLanding { if ('string' === typeof source) source = JSON.parse(source); this.CollegeTeam = this.convertValues(source["CollegeTeam"], CollegeTeam); this.CollegeRosterMap = source["CollegeRosterMap"]; - this.HistoricCollegePlayers = this.convertValues(source["HistoricCollegePlayers"], HistoricCollegePlayer); this.CollegeStandings = this.convertValues(source["CollegeStandings"], CollegeStandings); this.AllCollegeGames = this.convertValues(source["AllCollegeGames"], CollegeGame); this.OfficialPolls = this.convertValues(source["OfficialPolls"], CollegePollOfficial); this.TopCFBPassers = this.convertValues(source["TopCFBPassers"], CollegePlayer); this.TopCFBRushers = this.convertValues(source["TopCFBRushers"], CollegePlayer); this.TopCFBReceivers = this.convertValues(source["TopCFBReceivers"], CollegePlayer); - this.PortalPlayers = this.convertValues(source["PortalPlayers"], CollegePlayer); this.CollegeInjuryReport = this.convertValues(source["CollegeInjuryReport"], CollegePlayer); this.CollegeNotifications = this.convertValues(source["CollegeNotifications"], Notification); this.ProTeam = this.convertValues(source["ProTeam"], NFLTeam); @@ -5549,28 +5553,36 @@ export class NFLTradePreferences { return a; } } -export class NFLTradeOptionObj { +export class CollegePromise { ID: number; - TradeProposalID: number; - NFLTeamID: number; - NFLPlayerID: number; - NFLDraftPickID: number; - OptionType: string; - SalaryPercentage: number; - Player: NFLPlayer; - Draftpick: NFLDraftPick; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: DeletedAt; + TeamID: number; + CollegePlayerID: number; + PromiseType: string; + PromiseWeight: string; + Benchmark: number; + BenchmarkStr: string; + PromiseMade: boolean; + IsFullfilled: boolean; + IsActive: boolean; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.ID = source["ID"]; - this.TradeProposalID = source["TradeProposalID"]; - this.NFLTeamID = source["NFLTeamID"]; - this.NFLPlayerID = source["NFLPlayerID"]; - this.NFLDraftPickID = source["NFLDraftPickID"]; - this.OptionType = source["OptionType"]; - this.SalaryPercentage = source["SalaryPercentage"]; - this.Player = this.convertValues(source["Player"], NFLPlayer); - this.Draftpick = this.convertValues(source["Draftpick"], NFLDraftPick); + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], DeletedAt); + this.TeamID = source["TeamID"]; + this.CollegePlayerID = source["CollegePlayerID"]; + this.PromiseType = source["PromiseType"]; + this.PromiseWeight = source["PromiseWeight"]; + this.Benchmark = source["Benchmark"]; + this.BenchmarkStr = source["BenchmarkStr"]; + this.PromiseMade = source["PromiseMade"]; + this.IsFullfilled = source["IsFullfilled"]; + this.IsActive = source["IsActive"]; } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -5591,140 +5603,20 @@ export class NFLTradeOptionObj { return a; } } -export class NFLTradeProposalDTO { - ID: number; - NFLTeamID: number; - NFLTeam: string; - RecepientTeamID: number; - RecepientTeam: string; - IsTradeAccepted: boolean; - IsTradeRejected: boolean; - NFLTeamTradeOptions: NFLTradeOptionObj[]; - RecepientTeamTradeOptions: NFLTradeOptionObj[]; - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.ID = source["ID"]; - this.NFLTeamID = source["NFLTeamID"]; - this.NFLTeam = source["NFLTeam"]; - this.RecepientTeamID = source["RecepientTeamID"]; - this.RecepientTeam = source["RecepientTeam"]; - this.IsTradeAccepted = source["IsTradeAccepted"]; - this.IsTradeRejected = source["IsTradeRejected"]; - this.NFLTeamTradeOptions = this.convertValues(source["NFLTeamTradeOptions"], NFLTradeOptionObj); - this.RecepientTeamTradeOptions = this.convertValues(source["RecepientTeamTradeOptions"], NFLTradeOptionObj); - } - - convertValues(a: any, classs: any, asMap: boolean = false): any { - if (!a) { - return a; - } - if (Array.isArray(a)) { - return (a as any[]).map(elem => this.convertValues(elem, classs)); - } else if ("object" === typeof a) { - if (asMap) { - for (const key of Object.keys(a)) { - a[key] = new classs(a[key]); - } - return a; - } - return new classs(a); - } - return a; - } -} -export class NFLTeamProposals { - SentTradeProposals: NFLTradeProposalDTO[]; - ReceivedTradeProposals: NFLTradeProposalDTO[]; - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.SentTradeProposals = this.convertValues(source["SentTradeProposals"], NFLTradeProposalDTO); - this.ReceivedTradeProposals = this.convertValues(source["ReceivedTradeProposals"], NFLTradeProposalDTO); - } - - convertValues(a: any, classs: any, asMap: boolean = false): any { - if (!a) { - return a; - } - if (Array.isArray(a)) { - return (a as any[]).map(elem => this.convertValues(elem, classs)); - } else if ("object" === typeof a) { - if (asMap) { - for (const key of Object.keys(a)) { - a[key] = new classs(a[key]); - } - return a; - } - return new classs(a); - } - return a; - } -} -export class CollegePromise { - ID: number; - CreatedAt: Time; - UpdatedAt: Time; - DeletedAt: DeletedAt; - TeamID: number; - CollegePlayerID: number; - PromiseType: string; - PromiseWeight: string; - Benchmark: number; - BenchmarkStr: string; - PromiseMade: boolean; - IsFullfilled: boolean; - IsActive: boolean; - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.ID = source["ID"]; - this.CreatedAt = this.convertValues(source["CreatedAt"], Time); - this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], DeletedAt); - this.TeamID = source["TeamID"]; - this.CollegePlayerID = source["CollegePlayerID"]; - this.PromiseType = source["PromiseType"]; - this.PromiseWeight = source["PromiseWeight"]; - this.Benchmark = source["Benchmark"]; - this.BenchmarkStr = source["BenchmarkStr"]; - this.PromiseMade = source["PromiseMade"]; - this.IsFullfilled = source["IsFullfilled"]; - this.IsActive = source["IsActive"]; - } - - convertValues(a: any, classs: any, asMap: boolean = false): any { - if (!a) { - return a; - } - if (Array.isArray(a)) { - return (a as any[]).map(elem => this.convertValues(elem, classs)); - } else if ("object" === typeof a) { - if (asMap) { - for (const key of Object.keys(a)) { - a[key] = new classs(a[key]); - } - return a; - } - return new classs(a); - } - return a; - } -} -export class BootstrapDataTeamRoster { - ContractMap: {[key: uint]: NFLContract}; - ExtensionMap: {[key: uint]: NFLExtensionOffer}; - CollegePromises: CollegePromise[]; - TradeProposals: NFLTeamProposals; - TradePreferences: {[key: uint]: NFLTradePreferences}; - NFLDraftPicks: NFLDraftPick[]; +export class BootstrapDataTeamRoster { + ContractMap: {[key: uint]: NFLContract}; + ExtensionMap: {[key: uint]: NFLExtensionOffer}; + CollegePromises: CollegePromise[]; + TradeProposals: {[key: uint]: NFLTradeProposal[]}; + TradePreferences: {[key: uint]: NFLTradePreferences}; + NFLDraftPicks: NFLDraftPick[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.ContractMap = this.convertValues(source["ContractMap"], NFLContract, true); this.ExtensionMap = this.convertValues(source["ExtensionMap"], NFLExtensionOffer, true); this.CollegePromises = this.convertValues(source["CollegePromises"], CollegePromise); - this.TradeProposals = this.convertValues(source["TradeProposals"], NFLTeamProposals); + this.TradeProposals = source["TradeProposals"]; this.TradePreferences = this.convertValues(source["TradePreferences"], NFLTradePreferences, true); this.NFLDraftPicks = this.convertValues(source["NFLDraftPicks"], NFLDraftPick); } @@ -5793,6 +5685,21 @@ export class Croot { OverallGrade: string; TotalRank: number; LeadingTeams: LeadingTeams[]; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); @@ -5825,6 +5732,21 @@ export class Croot { this.OverallGrade = source["OverallGrade"]; this.TotalRank = source["TotalRank"]; this.LeadingTeams = this.convertValues(source["LeadingTeams"], LeadingTeams); + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -5907,14 +5829,408 @@ export class BootstrapDataFreeAgency { return a; } } +export class NFLGameRequest { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + HomeTeamID: number; + AwayTeamID: number; + SendingTeamID: number; + RequestingTeamID: number; + IsAccepted: boolean; + IsApproved: boolean; + ArenaID: number; + Arena: string; + IsNeutralSite: boolean; + SeasonID: number; + WeekID: number; + Week: number; + Timeslot: string; + IsPreseason: boolean; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.HomeTeamID = source["HomeTeamID"]; + this.AwayTeamID = source["AwayTeamID"]; + this.SendingTeamID = source["SendingTeamID"]; + this.RequestingTeamID = source["RequestingTeamID"]; + this.IsAccepted = source["IsAccepted"]; + this.IsApproved = source["IsApproved"]; + this.ArenaID = source["ArenaID"]; + this.Arena = source["Arena"]; + this.IsNeutralSite = source["IsNeutralSite"]; + this.SeasonID = source["SeasonID"]; + this.WeekID = source["WeekID"]; + this.Week = source["Week"]; + this.Timeslot = source["Timeslot"]; + this.IsPreseason = source["IsPreseason"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} +export class CFBGameRequest { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + HomeTeamID: number; + AwayTeamID: number; + SendingTeamID: number; + RequestingTeamID: number; + IsAccepted: boolean; + IsApproved: boolean; + ArenaID: number; + Arena: string; + IsNeutralSite: boolean; + SeasonID: number; + WeekID: number; + Week: number; + Timeslot: string; + IsSpringGame: boolean; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.HomeTeamID = source["HomeTeamID"]; + this.AwayTeamID = source["AwayTeamID"]; + this.SendingTeamID = source["SendingTeamID"]; + this.RequestingTeamID = source["RequestingTeamID"]; + this.IsAccepted = source["IsAccepted"]; + this.IsApproved = source["IsApproved"]; + this.ArenaID = source["ArenaID"]; + this.Arena = source["Arena"]; + this.IsNeutralSite = source["IsNeutralSite"]; + this.SeasonID = source["SeasonID"]; + this.WeekID = source["WeekID"]; + this.Week = source["Week"]; + this.Timeslot = source["Timeslot"]; + this.IsSpringGame = source["IsSpringGame"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} +export class Stadium { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + StadiumName: string; + TeamID: number; + TeamAbbr: string; + City: string; + State: string; + Country: string; + Region: string; + WeatherRegion: string; + Capacity: number; + RecordAttendance: number; + FirstSeason: number; + LeagueID: number; + LeagueName: string; + IsDomed: boolean; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.StadiumName = source["StadiumName"]; + this.TeamID = source["TeamID"]; + this.TeamAbbr = source["TeamAbbr"]; + this.City = source["City"]; + this.State = source["State"]; + this.Country = source["Country"]; + this.Region = source["Region"]; + this.WeatherRegion = source["WeatherRegion"]; + this.Capacity = source["Capacity"]; + this.RecordAttendance = source["RecordAttendance"]; + this.FirstSeason = source["FirstSeason"]; + this.LeagueID = source["LeagueID"]; + this.LeagueName = source["LeagueName"]; + this.IsDomed = source["IsDomed"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} +export class HistoricCollegePlayer { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + FirstName: string; + LastName: string; + Position: string; + Archetype: string; + PreviousTeamID: number; + PreviousTeam: string; + Height: number; + Weight: number; + Age: number; + Stars: number; + Overall: number; + Stamina: number; + Injury: number; + FootballIQ: number; + Speed: number; + Carrying: number; + Agility: number; + Catching: number; + RouteRunning: number; + ZoneCoverage: number; + ManCoverage: number; + Strength: number; + Tackle: number; + PassBlock: number; + RunBlock: number; + PassRush: number; + RunDefense: number; + ThrowPower: number; + ThrowAccuracy: number; + KickAccuracy: number; + KickPower: number; + PuntAccuracy: number; + PuntPower: number; + Progression: number; + Discipline: number; + PotentialGrade: string; + FreeAgency: string; + Personality: string; + RecruitingBias: string; + WorkEthic: string; + AcademicBias: string; + IsInjured: boolean; + InjuryName: string; + InjuryType: string; + WeeksOfRecovery: number; + InjuryReserve: boolean; + PrimeAge: number; + Clutch: number; + Shotgun: number; + PositionTwo: string; + ArchetypeTwo: string; + RelativeID: number; + RelativeType: number; + Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; + PlayerID: number; + TeamID: number; + TeamAbbr: string; + HighSchool: string; + City: string; + State: string; + Year: number; + IsRedshirt: boolean; + IsRedshirting: boolean; + HasGraduated: boolean; + TransferStatus: number; + TransferLikeliness: string; + Stats: CollegePlayerStats[]; + SeasonStats: CollegePlayerSeasonStats; + HasProgressed: boolean; + WillDeclare: boolean; + LegacyID: number; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.FirstName = source["FirstName"]; + this.LastName = source["LastName"]; + this.Position = source["Position"]; + this.Archetype = source["Archetype"]; + this.PreviousTeamID = source["PreviousTeamID"]; + this.PreviousTeam = source["PreviousTeam"]; + this.Height = source["Height"]; + this.Weight = source["Weight"]; + this.Age = source["Age"]; + this.Stars = source["Stars"]; + this.Overall = source["Overall"]; + this.Stamina = source["Stamina"]; + this.Injury = source["Injury"]; + this.FootballIQ = source["FootballIQ"]; + this.Speed = source["Speed"]; + this.Carrying = source["Carrying"]; + this.Agility = source["Agility"]; + this.Catching = source["Catching"]; + this.RouteRunning = source["RouteRunning"]; + this.ZoneCoverage = source["ZoneCoverage"]; + this.ManCoverage = source["ManCoverage"]; + this.Strength = source["Strength"]; + this.Tackle = source["Tackle"]; + this.PassBlock = source["PassBlock"]; + this.RunBlock = source["RunBlock"]; + this.PassRush = source["PassRush"]; + this.RunDefense = source["RunDefense"]; + this.ThrowPower = source["ThrowPower"]; + this.ThrowAccuracy = source["ThrowAccuracy"]; + this.KickAccuracy = source["KickAccuracy"]; + this.KickPower = source["KickPower"]; + this.PuntAccuracy = source["PuntAccuracy"]; + this.PuntPower = source["PuntPower"]; + this.Progression = source["Progression"]; + this.Discipline = source["Discipline"]; + this.PotentialGrade = source["PotentialGrade"]; + this.FreeAgency = source["FreeAgency"]; + this.Personality = source["Personality"]; + this.RecruitingBias = source["RecruitingBias"]; + this.WorkEthic = source["WorkEthic"]; + this.AcademicBias = source["AcademicBias"]; + this.IsInjured = source["IsInjured"]; + this.InjuryName = source["InjuryName"]; + this.InjuryType = source["InjuryType"]; + this.WeeksOfRecovery = source["WeeksOfRecovery"]; + this.InjuryReserve = source["InjuryReserve"]; + this.PrimeAge = source["PrimeAge"]; + this.Clutch = source["Clutch"]; + this.Shotgun = source["Shotgun"]; + this.PositionTwo = source["PositionTwo"]; + this.ArchetypeTwo = source["ArchetypeTwo"]; + this.RelativeID = source["RelativeID"]; + this.RelativeType = source["RelativeType"]; + this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; + this.PlayerID = source["PlayerID"]; + this.TeamID = source["TeamID"]; + this.TeamAbbr = source["TeamAbbr"]; + this.HighSchool = source["HighSchool"]; + this.City = source["City"]; + this.State = source["State"]; + this.Year = source["Year"]; + this.IsRedshirt = source["IsRedshirt"]; + this.IsRedshirting = source["IsRedshirting"]; + this.HasGraduated = source["HasGraduated"]; + this.TransferStatus = source["TransferStatus"]; + this.TransferLikeliness = source["TransferLikeliness"]; + this.Stats = this.convertValues(source["Stats"], CollegePlayerStats); + this.SeasonStats = this.convertValues(source["SeasonStats"], CollegePlayerSeasonStats); + this.HasProgressed = source["HasProgressed"]; + this.WillDeclare = source["WillDeclare"]; + this.LegacyID = source["LegacyID"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} export class BootstrapDataScheduling { OfficialPolls: CollegePollOfficial[]; PollSubmission: CollegePollSubmission; + HistoricCollegePlayers: HistoricCollegePlayer[]; + RetiredPlayers: NFLRetiredPlayer[]; + Stadiums: Stadium[]; + CFBGameRequests: CFBGameRequest[]; + NFLGameRequests: NFLGameRequest[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.OfficialPolls = this.convertValues(source["OfficialPolls"], CollegePollOfficial); this.PollSubmission = this.convertValues(source["PollSubmission"], CollegePollSubmission); + this.HistoricCollegePlayers = this.convertValues(source["HistoricCollegePlayers"], HistoricCollegePlayer); + this.RetiredPlayers = this.convertValues(source["RetiredPlayers"], NFLRetiredPlayer); + this.Stadiums = this.convertValues(source["Stadiums"], Stadium); + this.CFBGameRequests = this.convertValues(source["CFBGameRequests"], CFBGameRequest); + this.NFLGameRequests = this.convertValues(source["NFLGameRequests"], NFLGameRequest); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -6098,6 +6414,21 @@ export class NFLDraftee { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; PlayerID: number; HighSchool: string; CollegeID: number; @@ -6195,6 +6526,21 @@ export class NFLDraftee { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.PlayerID = source["PlayerID"]; this.HighSchool = source["HighSchool"]; this.CollegeID = source["CollegeID"]; @@ -6254,13 +6600,17 @@ export class NFLDraftee { export class BootstrapDataDraft { NFLDraftees: NFLDraftee[]; NFLWarRoomMap: {[key: uint]: NFLWarRoom}; - DraftScoutingProfileMap: {[key: uint]: ScoutingProfile}; + DraftScoutingProfileMap: {[key: uint]: ScoutingProfile[]}; + NFLGameplanMap: {[key: uint]: NFLGameplan}; + NFLDraftPicks: NFLDraftPick[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.NFLDraftees = this.convertValues(source["NFLDraftees"], NFLDraftee); this.NFLWarRoomMap = this.convertValues(source["NFLWarRoomMap"], NFLWarRoom, true); - this.DraftScoutingProfileMap = this.convertValues(source["DraftScoutingProfileMap"], ScoutingProfile, true); + this.DraftScoutingProfileMap = source["DraftScoutingProfileMap"]; + this.NFLGameplanMap = this.convertValues(source["NFLGameplanMap"], NFLGameplan, true); + this.NFLDraftPicks = this.convertValues(source["NFLDraftPicks"], NFLDraftPick); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -6355,12 +6705,14 @@ export class BootstrapDataPortal { TeamProfileMap: {[key: string]: RecruitingTeamProfile}; TransferPortalProfiles: TransferPortalProfile[]; CollegePromises: CollegePromise[]; + PortalPlayers: CollegePlayer[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.TeamProfileMap = source["TeamProfileMap"]; this.TransferPortalProfiles = this.convertValues(source["TransferPortalProfiles"], TransferPortalProfile); this.CollegePromises = this.convertValues(source["CollegePromises"], CollegePromise); + this.PortalPlayers = this.convertValues(source["PortalPlayers"], CollegePlayer); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -6492,6 +6844,7 @@ export class BootstrapDataNews { } } export class AwardsModel { + PlayerID: number; TeamID: number; FirstName: string; LastName: string; @@ -6503,6 +6856,7 @@ export class AwardsModel { constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); + this.PlayerID = source["PlayerID"]; this.TeamID = source["TeamID"]; this.FirstName = source["FirstName"]; this.LastName = source["LastName"]; @@ -6571,10 +6925,14 @@ export class AwardsList { } export class BootstrapDataStats { PostSeasonAwards: AwardsList; + HistoricCollegePlayers: HistoricCollegePlayer[]; + RetiredPlayers: NFLRetiredPlayer[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.PostSeasonAwards = this.convertValues(source["PostSeasonAwards"], AwardsList); + this.HistoricCollegePlayers = this.convertValues(source["HistoricCollegePlayers"], HistoricCollegePlayer); + this.RetiredPlayers = this.convertValues(source["RetiredPlayers"], NFLRetiredPlayer); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -6773,6 +7131,100 @@ export class FaceDataResponse { this.HairColor = source["HairColor"]; } } +export class NFLTradeOption { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + TradeProposalID: number; + NFLTeamID: number; + NFLPlayerID: number; + NFLDraftPickID: number; + OptionType: string; + SalaryPercentage: number; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.TradeProposalID = source["TradeProposalID"]; + this.NFLTeamID = source["NFLTeamID"]; + this.NFLPlayerID = source["NFLPlayerID"]; + this.NFLDraftPickID = source["NFLDraftPickID"]; + this.OptionType = source["OptionType"]; + this.SalaryPercentage = source["SalaryPercentage"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} +export class NFLTradeProposal { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + NFLTeamID: number; + NFLTeam: string; + RecepientTeamID: number; + RecepientTeam: string; + IsTradeAccepted: boolean; + IsTradeRejected: boolean; + IsSynced: boolean; + NFLTeamTradeOptions: NFLTradeOption[]; + RecepientTeamTradeOptions: NFLTradeOption[]; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.NFLTeamID = source["NFLTeamID"]; + this.NFLTeam = source["NFLTeam"]; + this.RecepientTeamID = source["RecepientTeamID"]; + this.RecepientTeam = source["RecepientTeam"]; + this.IsTradeAccepted = source["IsTradeAccepted"]; + this.IsTradeRejected = source["IsTradeRejected"]; + this.IsSynced = source["IsSynced"]; + this.NFLTeamTradeOptions = this.convertValues(source["NFLTeamTradeOptions"], NFLTradeOption); + this.RecepientTeamTradeOptions = this.convertValues(source["RecepientTeamTradeOptions"], NFLTradeOption); + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} export class NFLRequest { ID: number; CreatedAt: Time; @@ -6864,11 +7316,15 @@ export class TeamRequest { export class TeamRequestsResponse { CollegeRequests: TeamRequest[]; ProRequests: NFLRequest[]; + AcceptedTrades: NFLTradeProposal[]; + DraftPicks: NFLDraftPick[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.CollegeRequests = this.convertValues(source["CollegeRequests"], TeamRequest); this.ProRequests = this.convertValues(source["ProRequests"], NFLRequest); + this.AcceptedTrades = this.convertValues(source["AcceptedTrades"], NFLTradeProposal); + this.DraftPicks = this.convertValues(source["DraftPicks"], NFLDraftPick); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -6944,6 +7400,21 @@ export class BasePlayer { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); @@ -7001,6 +7472,21 @@ export class BasePlayer { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; } } @@ -7079,66 +7565,7 @@ export class BaseTeam { } -export class Stadium { - ID: number; - CreatedAt: Time; - UpdatedAt: Time; - DeletedAt: Time; - StadiumName: string; - TeamID: number; - TeamAbbr: string; - City: string; - State: string; - Country: string; - Region: string; - WeatherRegion: string; - Capacity: number; - RecordAttendance: number; - FirstSeason: number; - LeagueID: number; - LeagueName: string; - IsDomed: boolean; - - constructor(source: any = {}) { - if ('string' === typeof source) source = JSON.parse(source); - this.ID = source["ID"]; - this.CreatedAt = this.convertValues(source["CreatedAt"], Time); - this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); - this.StadiumName = source["StadiumName"]; - this.TeamID = source["TeamID"]; - this.TeamAbbr = source["TeamAbbr"]; - this.City = source["City"]; - this.State = source["State"]; - this.Country = source["Country"]; - this.Region = source["Region"]; - this.WeatherRegion = source["WeatherRegion"]; - this.Capacity = source["Capacity"]; - this.RecordAttendance = source["RecordAttendance"]; - this.FirstSeason = source["FirstSeason"]; - this.LeagueID = source["LeagueID"]; - this.LeagueName = source["LeagueName"]; - this.IsDomed = source["IsDomed"]; - } - convertValues(a: any, classs: any, asMap: boolean = false): any { - if (!a) { - return a; - } - if (Array.isArray(a)) { - return (a as any[]).map(elem => this.convertValues(elem, classs)); - } else if ("object" === typeof a) { - if (asMap) { - for (const key of Object.keys(a)) { - a[key] = new classs(a[key]); - } - return a; - } - return new classs(a); - } - return a; - } -} @@ -7778,6 +8205,92 @@ export class UpdateTransferPortalBoard { +export class NFLUDFAProfile { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + NFLUDFABoardID: number; + PlayerID: number; + PlayerName: string; + Position: string; + TeamID: number; + TeamAbbr: string; + Points: number; + IsSigned: boolean; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.NFLUDFABoardID = source["NFLUDFABoardID"]; + this.PlayerID = source["PlayerID"]; + this.PlayerName = source["PlayerName"]; + this.Position = source["Position"]; + this.TeamID = source["TeamID"]; + this.TeamAbbr = source["TeamAbbr"]; + this.Points = source["Points"]; + this.IsSigned = source["IsSigned"]; + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} +export class NFLUDFABoard { + ID: number; + CreatedAt: Time; + UpdatedAt: Time; + DeletedAt: Time; + TeamID: number; + TeamAbbr: string; + Profiles: NFLUDFAProfile[]; + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.ID = source["ID"]; + this.CreatedAt = this.convertValues(source["CreatedAt"], Time); + this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); + this.DeletedAt = this.convertValues(source["DeletedAt"], Time); + this.TeamID = source["TeamID"]; + this.TeamAbbr = source["TeamAbbr"]; + this.Profiles = this.convertValues(source["Profiles"], NFLUDFAProfile); + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} export class FreeAgencyOfferDTO { ID: number; @@ -8043,6 +8556,21 @@ export class CollegePlayerResponse { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; TeamID: number; TeamAbbr: string; City: string; @@ -8111,6 +8639,21 @@ export class CollegePlayerResponse { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.TeamID = source["TeamID"]; this.TeamAbbr = source["TeamAbbr"]; this.City = source["City"]; @@ -8197,6 +8740,21 @@ export class NFLPlayerResponse { RelativeID: number; RelativeType: number; Notes: string; + ProgramPref: number; + ProfDevPref: number; + TraditionsPref: number; + FacilitiesPref: number; + AtmospherePref: number; + AcademicsPref: number; + ConferencePref: number; + CoachPref: number; + SeasonMomentumPref: number; + CampusLifePref: number; + ReligionPref: number; + ServiceAcademyPref: number; + SmallTownPref: number; + BigCityPref: number; + MediaSpotlightPref: number; TeamID: number; TeamAbbr: string; City: string; @@ -8266,6 +8824,21 @@ export class NFLPlayerResponse { this.RelativeID = source["RelativeID"]; this.RelativeType = source["RelativeType"]; this.Notes = source["Notes"]; + this.ProgramPref = source["ProgramPref"]; + this.ProfDevPref = source["ProfDevPref"]; + this.TraditionsPref = source["TraditionsPref"]; + this.FacilitiesPref = source["FacilitiesPref"]; + this.AtmospherePref = source["AtmospherePref"]; + this.AcademicsPref = source["AcademicsPref"]; + this.ConferencePref = source["ConferencePref"]; + this.CoachPref = source["CoachPref"]; + this.SeasonMomentumPref = source["SeasonMomentumPref"]; + this.CampusLifePref = source["CampusLifePref"]; + this.ReligionPref = source["ReligionPref"]; + this.ServiceAcademyPref = source["ServiceAcademyPref"]; + this.SmallTownPref = source["SmallTownPref"]; + this.BigCityPref = source["BigCityPref"]; + this.MediaSpotlightPref = source["MediaSpotlightPref"]; this.TeamID = source["TeamID"]; this.TeamAbbr = source["TeamAbbr"]; this.City = source["City"]; @@ -8306,6 +8879,7 @@ export class CollegePlayerCSV { ArchetypeTwo: string; Year: string; Team: string; + PreviousTeam: string; Age: number; Stars: number; HighSchool: string; @@ -8352,6 +8926,7 @@ export class CollegePlayerCSV { this.ArchetypeTwo = source["ArchetypeTwo"]; this.Year = source["Year"]; this.Team = source["Team"]; + this.PreviousTeam = source["PreviousTeam"]; this.Age = source["Age"]; this.Stars = source["Stars"]; this.HighSchool = source["HighSchool"]; @@ -8425,30 +9000,29 @@ export class CollegePlayerCSV { -export class NFLTradeOption { + +export class NFLTradeOptionObj { ID: number; - CreatedAt: Time; - UpdatedAt: Time; - DeletedAt: Time; TradeProposalID: number; NFLTeamID: number; NFLPlayerID: number; NFLDraftPickID: number; OptionType: string; SalaryPercentage: number; + Player: NFLPlayer; + Draftpick: NFLDraftPick; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.ID = source["ID"]; - this.CreatedAt = this.convertValues(source["CreatedAt"], Time); - this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); this.TradeProposalID = source["TradeProposalID"]; this.NFLTeamID = source["NFLTeamID"]; this.NFLPlayerID = source["NFLPlayerID"]; this.NFLDraftPickID = source["NFLDraftPickID"]; this.OptionType = source["OptionType"]; this.SalaryPercentage = source["SalaryPercentage"]; + this.Player = this.convertValues(source["Player"], NFLPlayer); + this.Draftpick = this.convertValues(source["Draftpick"], NFLDraftPick); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -8469,36 +9043,28 @@ export class NFLTradeOption { return a; } } -export class NFLTradeProposal { +export class NFLTradeProposalDTO { ID: number; - CreatedAt: Time; - UpdatedAt: Time; - DeletedAt: Time; NFLTeamID: number; NFLTeam: string; RecepientTeamID: number; RecepientTeam: string; IsTradeAccepted: boolean; IsTradeRejected: boolean; - IsSynced: boolean; - NFLTeamTradeOptions: NFLTradeOption[]; - RecepientTeamTradeOptions: NFLTradeOption[]; + NFLTeamTradeOptions: NFLTradeOptionObj[]; + RecepientTeamTradeOptions: NFLTradeOptionObj[]; constructor(source: any = {}) { if ('string' === typeof source) source = JSON.parse(source); this.ID = source["ID"]; - this.CreatedAt = this.convertValues(source["CreatedAt"], Time); - this.UpdatedAt = this.convertValues(source["UpdatedAt"], Time); - this.DeletedAt = this.convertValues(source["DeletedAt"], Time); this.NFLTeamID = source["NFLTeamID"]; this.NFLTeam = source["NFLTeam"]; this.RecepientTeamID = source["RecepientTeamID"]; this.RecepientTeam = source["RecepientTeam"]; this.IsTradeAccepted = source["IsTradeAccepted"]; this.IsTradeRejected = source["IsTradeRejected"]; - this.IsSynced = source["IsSynced"]; - this.NFLTeamTradeOptions = this.convertValues(source["NFLTeamTradeOptions"], NFLTradeOption); - this.RecepientTeamTradeOptions = this.convertValues(source["RecepientTeamTradeOptions"], NFLTradeOption); + this.NFLTeamTradeOptions = this.convertValues(source["NFLTeamTradeOptions"], NFLTradeOptionObj); + this.RecepientTeamTradeOptions = this.convertValues(source["RecepientTeamTradeOptions"], NFLTradeOptionObj); } convertValues(a: any, classs: any, asMap: boolean = false): any { @@ -8521,8 +9087,34 @@ export class NFLTradeProposal { } +export class NFLTeamProposals { + SentTradeProposals: NFLTradeProposalDTO[]; + ReceivedTradeProposals: NFLTradeProposalDTO[]; + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.SentTradeProposals = this.convertValues(source["SentTradeProposals"], NFLTradeProposalDTO); + this.ReceivedTradeProposals = this.convertValues(source["ReceivedTradeProposals"], NFLTradeProposalDTO); + } + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (Array.isArray(a)) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } +} export class NFLTradePreferencesDTO { NFLTeamID: number; @@ -9157,6 +9749,7 @@ export class Timestamp { AIDepthchartsSync: boolean; AIRecruitingBoardsSynced: boolean; IsFreeAgencyLocked: boolean; + PreDraftPhase: boolean; IsDraftTime: boolean; RunGames: boolean; Y1Capspace: number; @@ -9213,6 +9806,7 @@ export class Timestamp { this.AIDepthchartsSync = source["AIDepthchartsSync"]; this.AIRecruitingBoardsSynced = source["AIRecruitingBoardsSynced"]; this.IsFreeAgencyLocked = source["IsFreeAgencyLocked"]; + this.PreDraftPhase = source["PreDraftPhase"]; this.IsDraftTime = source["IsDraftTime"]; this.RunGames = source["RunGames"]; this.Y1Capspace = source["Y1Capspace"]; diff --git a/util/HelperUtil.go b/util/HelperUtil.go index aad7e28..5bf20c7 100644 --- a/util/HelperUtil.go +++ b/util/HelperUtil.go @@ -10,3 +10,34 @@ func GetWeekID(seasonID uint, week uint) uint { // WeekID should look like 2101 for season 1 week 1, 2102 for season 1 week 2, etc. return (seasonID+2020-2000)*100 + week } + +func GetTimeslot(state string, conferenceID uint) string { + stateKey := GetStateKey(state) + // Implement logic to determine timeslot based on stateKey + switch stateKey { + case "TX", "OK", "AR", "LA", "KS", "IA", "MO", "NE", "SD", "ND", "MN", "WI", "IL", "NM": + if (conferenceID > 7 && conferenceID < 13) || (conferenceID > 13) { + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Evening", "Friday Night", "Friday Night", "Saturday Night"}) + } + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Evening", "Saturday Afternoon", "Friday Night", "Saturday Night"}) + + case "MS", "AL", "GA", "FL", "SC", "NC", "VA", "TN", "KY", "IN", "OH", "MI", "PA", "WV", "MD": + if (conferenceID > 7 && conferenceID < 13) || (conferenceID > 13) { + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Morning", "Thursday Night", "Thursday Night"}) + } + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Evening", "Saturday Morning", "Thursday Night"}) + + case "NY", "NJ", "CT", "RI", "MA", "VT", "NH", "ME": + if (conferenceID > 7 && conferenceID < 13) || (conferenceID > 13) { + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Morning", "Thursday Night", "Thursday Night"}) + } + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Morning", "Saturday Morning", "Thursday Night"}) + + case "WA", "OR", "CA", "NV", "ID", "UT", "AZ", "CO", "MT", "WY", "GM", "AS", "AK", "HI": + if (conferenceID > 7 && conferenceID < 13) || (conferenceID > 13) { + return PickFromStringList([]string{"Saturday Evening", "Saturday Evening", "Friday Night", "Friday Night", "Thursday Night", "Saturday Night"}) + } + return PickFromStringList([]string{"Saturday Afternoon", "Saturday Evening", "Saturday Evening", "Saturday Night", "Saturday Night", "Saturday Night", "Friday Night"}) + } + return "Thursday Night" +}