-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from Acr515/development
Version 2025.0.0
- Loading branch information
Showing
32 changed files
with
2,721 additions
and
395 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import React, { useState } from 'react'; | ||
import Input from 'components/Input'; | ||
import { EndgameResult } from 'data/game_specific/performanceObject/2025'; | ||
|
||
/** | ||
* An array that stores all categories as strings that have data | ||
*/ | ||
export const GameDataCategories = [ | ||
"auto", "teleop", "endgame" | ||
]; | ||
|
||
/** | ||
* A dictionary of form inputs that scouts fill with data. The HTML ID of each element is named very carefully: | ||
* * The first phrase should be "Form_" | ||
* * ... followed by the section of the performance object to populate which will generally be "auto," "teleop," or "endgame," and another score | ||
* * ... followed lastly by the scoring section to fill (i.e. if data should go into the "upperGoal" area, that should be the final section of the ID) | ||
* | ||
* Additionally contains a boolean property `defenseFields` that decides whether or not the generic defense fields should appear. | ||
*/ | ||
export const GameDataInputs = { | ||
AutonomousSection: ({edit}) => <> | ||
<Input | ||
label="Leave (Autocross)" | ||
id="Form_auto_leave" | ||
isCheckbox={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.leave : undefined} | ||
/> | ||
<h3>Algae</h3> | ||
<Input | ||
label="Algae in Processor (Low)" | ||
id="Form_auto_algaeLow" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.algaeLow : undefined} | ||
/> | ||
<Input | ||
label="Algae in Net (High)" | ||
id="Form_auto_algaeHigh" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.algaeHigh : undefined} | ||
/> | ||
<h3>Coral</h3> | ||
<Input | ||
label="Coral in Trough (Level 1)" | ||
id="Form_auto_coralL1" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.coralL1 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 2" | ||
id="Form_auto_coralL2" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.coralL2 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 3" | ||
id="Form_auto_coralL3" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.coralL3 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 4" | ||
id="Form_auto_coralL4" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.auto.coralL4 : undefined} | ||
/> | ||
</>, | ||
TeleopSection: ({edit}) => <> | ||
<h3>Algae</h3> | ||
<Input | ||
label="Algae in Processor (Low)" | ||
id="Form_teleop_algaeLow" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.algaeLow : undefined} | ||
/> | ||
<Input | ||
label="Algae in Net (High)" | ||
id="Form_teleop_algaeHigh" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.algaeHigh : undefined} | ||
/> | ||
<h3>Coral</h3> | ||
<Input | ||
label="Coral in Trough (Level 1)" | ||
id="Form_teleop_coralL1" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.coralL1 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 2" | ||
id="Form_teleop_coralL2" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.coralL2 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 3" | ||
id="Form_teleop_coralL3" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.coralL3 : undefined} | ||
/> | ||
<Input | ||
label="Coral on Level 4" | ||
id="Form_teleop_coralL4" | ||
isNumerical={true} | ||
prefill={edit.isEdit ? edit.data.performance.teleop.coralL4 : undefined} | ||
/> | ||
</>, | ||
EndgameSection: ({edit}) => { | ||
const [endgameState, setEndgameState] = useState(edit.isEdit ? (edit.data.performance.endgame.state == EndgameResult.HARMONIZED ? EndgameResult.ONSTAGE : edit.data.performance.endgame.state) : undefined); | ||
|
||
return <> | ||
<Input | ||
label="Climb" | ||
id="Form_endgame_state" | ||
optionList={[ | ||
{ value: EndgameResult.NONE, label: EndgameResult.NONE }, | ||
{ value: EndgameResult.PARK, label: EndgameResult.PARK }, | ||
{ value: EndgameResult.SHALLOW_CAGE, label: EndgameResult.SHALLOW_CAGE }, | ||
{ value: EndgameResult.DEEP_CAGE, label: EndgameResult.DEEP_CAGE }, | ||
]} | ||
onInput={e => setEndgameState(e.target.value)} | ||
required={true} | ||
prefill={endgameState} | ||
/> | ||
<Input | ||
label="Tried to climb but failed?" | ||
id="Form_endgame_failedAttempt" | ||
isCheckbox={true} | ||
prefill={edit.isEdit ? edit.data.performance.endgame.failedAttempt : undefined} | ||
/> | ||
</> | ||
}, | ||
NotesSection: ({edit}) => <> | ||
<Input | ||
label="This team missed or dropped a majority of the game pieces they attempted to score" | ||
id="Form_notes_misses" | ||
isCheckbox={true} | ||
prefill={edit.isEdit ? edit.data.performance.notes.misses : undefined} | ||
/> | ||
<Input | ||
label="This team picked coral up off the floor" | ||
id="Form_notes_floorPickup" | ||
isCheckbox={true} | ||
prefill={edit.isEdit ? edit.data.performance.notes.floorPickup : undefined} | ||
/> | ||
</>, | ||
defenseFields: true | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import React from "react"; | ||
import GraphTogglerSet_Universal, { GraphToggler, GraphInfo } from "./_Universal"; | ||
import ScoreCalculator from "data/game_specific/ScoreCalculator/2025"; | ||
import { getTeamData } from "data/SearchData"; | ||
import { Method, sortTeamData } from "util/sortData"; | ||
|
||
/** | ||
* A set of buttons used to toggle which performance graph is being shown on a team's details page. | ||
*/ | ||
export default function GraphTogglerSet({activeIndex, stateFuncs, teamNumber}) { | ||
let data = sortTeamData(getTeamData(teamNumber).data, Method.MatchAscending); | ||
|
||
// Calculate cycles per game | ||
let piecesLabels = []; | ||
data.forEach(form => { piecesLabels.push(form.matchNumber); }); | ||
let piecesData = []; | ||
data.forEach(form => { piecesData.push(ScoreCalculator.Auto.getPieces(form) + ScoreCalculator.Teleop.getPieces(form)); }); | ||
let piecesGraphInfo = new GraphInfo( | ||
piecesData, piecesLabels, | ||
{ | ||
title: { text: "Match #" } | ||
}, | ||
{ | ||
suggestedMin: 0, | ||
suggestedMax: 12, | ||
title: { text: "Cycles" } | ||
}, | ||
[ 177, 65, 73 ] | ||
); | ||
|
||
// Calculate auto scores per game | ||
let autoLabels = []; | ||
data.forEach(form => { autoLabels.push(form.matchNumber); }); | ||
let autoData = []; | ||
data.forEach(form => { autoData.push((ScoreCalculator.Auto.getScore(form))); }); | ||
let autocrossGraphInfo = new GraphInfo( | ||
autoData, autoLabels, | ||
{ | ||
title: { text: "Match #" } | ||
}, | ||
{ | ||
suggestedMin: 0, | ||
suggestedMax: 8, | ||
ticks: { | ||
precision: 0 | ||
}, | ||
title: { text: "Auto score" } | ||
}, | ||
[ 204, 201, 57 ] | ||
); | ||
|
||
return ( | ||
<> | ||
<GraphTogglerSet_Universal | ||
activeIndex={activeIndex} | ||
stateFuncs={stateFuncs} | ||
teamNumber={teamNumber} | ||
/> | ||
<GraphToggler | ||
graphInfo={piecesGraphInfo} | ||
label="Cycles/game" | ||
index={1} | ||
activeIndex={activeIndex} | ||
stateFuncs={stateFuncs} | ||
/> | ||
<GraphToggler | ||
graphInfo={autocrossGraphInfo} | ||
label="Auto/game" | ||
index={2} | ||
activeIndex={activeIndex} | ||
stateFuncs={stateFuncs} | ||
/> | ||
</> | ||
) | ||
} |
25 changes: 25 additions & 0 deletions
25
src/components/game_specific/PlayoffHelperTeamCell/2025.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from "react"; | ||
import PlayoffHelperTeamCell from "./_Universal"; | ||
import { getOrdinalSuffix } from "util/getOrdinalSuffix"; | ||
|
||
/** | ||
* Renders a game-specific set of cells to be populated under every team who is a candidate to be picked. | ||
* @param {PlayoffTeam} team The team who the cells belong to | ||
*/ | ||
export default function PlayoffHelperTeamCellSet({ team }) { | ||
|
||
const defenseScore = team.powerScores.WellRounded.Defense == 0 ? "--" : team.powerScores.Defensive.Defense; | ||
const defenseRanking = team.powerScores.WellRounded.Defense == 0 ? "" : getOrdinalSuffix(team.powerScoreRankings.Defense); | ||
|
||
return ( | ||
<> | ||
<PlayoffHelperTeamCell value={team.rpi.RPI} place={getOrdinalSuffix(team.rpi.ranking)} label={`RPI (${team.rpi.rating})`} /> | ||
<PlayoffHelperTeamCell value={team.powerScores.WellRounded.Autonomous} place={getOrdinalSuffix(team.powerScoreRankings.Autonomous)} label={"Autonomous"} /> | ||
<PlayoffHelperTeamCell value={team.powerScores.WellRounded.Coral} place={getOrdinalSuffix(team.powerScoreRankings.Coral)} label={"Coral Scoring"} /> | ||
<PlayoffHelperTeamCell value={team.powerScores.WellRounded.Algae} place={getOrdinalSuffix(team.powerScoreRankings.Algae)} label={"Algae Scoring"} /> | ||
<PlayoffHelperTeamCell value={team.powerScores.WellRounded.Endgame} place={getOrdinalSuffix(team.powerScoreRankings.Endgame)} label={"Endgame"} /> | ||
<PlayoffHelperTeamCell value={defenseScore} place={defenseRanking} label={"Defense"} /> | ||
<PlayoffHelperTeamCell value={team.cycleRate} place={getOrdinalSuffix(team.cycleRateRanking)} label={`Cycles / Game`} /> | ||
</> | ||
) | ||
} |
37 changes: 37 additions & 0 deletions
37
src/components/game_specific/SimulatorInsightRowSet/2025.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from "react"; | ||
import SimulatorInsightRow from "components/SimulatorInsightRow"; | ||
import ScoreCalculator from "data/game_specific/ScoreCalculator/2025"; | ||
|
||
export default function SimulatorInsightRowSet({sim, winner, loser}) { | ||
|
||
// Find best game piece scorers | ||
let winnerBestScorer = -1, loserBestScorer = -1; | ||
const getBestPieceScorers = teamColor => { | ||
let bestTeleopScore = -100; | ||
let bestScorer = -1; | ||
sim.averageMatch[teamColor].teamPerformances.forEach(team => { | ||
let score = ScoreCalculator.Teleop.getScore({ performance: team }); | ||
|
||
// Normally this section would decide to pick whoever climbs the highest on average if the two best robots score the same # of points | ||
// But there's no endgame | ||
if (score > bestTeleopScore) { | ||
bestTeleopScore = score; | ||
bestScorer = team.teamNumber; | ||
} | ||
}); | ||
return bestScorer; | ||
}; | ||
winnerBestScorer = getBestPieceScorers(winner.colorName); | ||
loserBestScorer = getBestPieceScorers(loser.colorName); | ||
|
||
return <> | ||
<SimulatorInsightRow | ||
label="Strongest Piece Scorer" | ||
winnerValue={winnerBestScorer} | ||
winnerColor={winner.color} | ||
loserValue={loserBestScorer} | ||
loserColor={loser.color} | ||
hyperlinkTeams | ||
/> | ||
</> | ||
} |
Oops, something went wrong.