Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/scouting/backend/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { build, context } from "esbuild";
import { spawn } from "child_process";

const isDev = process.env.NODE_ENV === "DEV";
const isDev = process.env.NODE_ENV !== "DEV";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return before merging


const bundlePath = "dist/bundle.js";

Expand Down
4 changes: 2 additions & 2 deletions apps/scouting/backend/src/climb/score.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import type { ClimbLevel, ScoutingForm } from "@repo/scouting_types";

export const CLIMB_SCORE_VALUES = { L0: 0, L1: 10, L2: 20, L3: 30 };

const TELE_CLIMB_MULTIPLIER = 1;
const AUTO_CLIMB_MULTIPLIER = 1.5;
export const TELE_CLIMB_MULTIPLIER = 1;
export const AUTO_CLIMB_MULTIPLIER = 1.5;
export const calculateAverageClimbScore = (
climbs: ClimbLevel[],
isAuto: boolean,
Expand Down
21 changes: 21 additions & 0 deletions apps/scouting/backend/src/game/calculations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//בס"ד

import { BPS, ScoutingForm } from "@repo/scouting_types";
import {
AUTO_CLIMB_MULTIPLIER,
calculateAverageClimbsScore,
CLIMB_SCORE_VALUES,
TELE_CLIMB_MULTIPLIER,
} from "../climb/score";
import { calculateAverage } from "@repo/array-functions";
import { calculateAverageScoredFuel } from "../fuel/fuel-general";

export const calculateTotalGamePoints = (forms: ScoutingForm[], bpses: BPS[]) =>
calculateAverage(
forms,
(form) =>
CLIMB_SCORE_VALUES[form.auto.climb.level] * AUTO_CLIMB_MULTIPLIER +
CLIMB_SCORE_VALUES[form.tele.climb.level] * TELE_CLIMB_MULTIPLIER +
calculateAverageScoredFuel(forms, "fullGame", bpses),
//Dror: 67676767676767676767676766767676767676767676767676767676767676767676767676767676767677666676766776767676767676767676767
);
13 changes: 10 additions & 3 deletions apps/scouting/backend/src/movement/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

import { calculateSum } from "@repo/array-functions";
import type { ScoutingForm } from "@repo/scouting_types";
import { MovementEvent } from "@repo/scouting_types/rebuilt/Movement";


export const findTimesStuckOnBump = (forms: ScoutingForm[]) => {
return calculateSum(forms, (form) => Number(!form.tele.movement.bumpStuck));
export const findTimesMovementEvent = (
forms: ScoutingForm[],
event: MovementEvent,
) => {
return calculateSum(forms, (form) =>
Number(form.auto.movement[event]) + form.tele.movement[event]
? Number(form.tele.movement[event])
: 0,
);
};
Comment on lines +10 to 16
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) => {
return calculateSum(forms, (form) =>
Number(form.auto.movement[event]) + form.tele.movement[event]
? Number(form.tele.movement[event])
: 0,
);
};
) => calculateSum(forms, (form) =>
Number(form.auto.movement[event]) + form.tele.movement[event]
? Number(form.tele.movement[event])
: 0,
);

26 changes: 25 additions & 1 deletion apps/scouting/backend/src/routes/general-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { mongofyQuery, flatTryCatch } from "@repo/flow-utils";
import { StatusCodes } from "http-status-codes";

import {
EPA,
excludeNoShowForms,
TeamOPR,
type BPS,
type GeneralData,
type ScoutingForm,
Expand All @@ -19,12 +21,18 @@ import { calculateAverageClimbsScore } from "../climb/score";
import { formsToFuelData } from "../fuel/fuel-general";
import { getAllBPSes } from "./bps-router";
import { isEmpty } from "@repo/array-functions";
import { findTimesMovementEvent } from "../movement/stats";
import { fetchTeamsCOPRs } from "./tba-router";
import { getTeamsEPAs } from "../middleware/epa";
import { calculateTotalGamePoints } from "../game/calculations";

export const generalRouter = Router();

const formsToGeneralData = (
forms: ScoutingForm[],
bpses: Record<string, BPS[]>,
coprs?: TeamOPR,
epa?: EPA,
) => {
const calculatedFuel: TeamNumberAndFuelData = formsToFuelData(bpses)(forms);

Expand All @@ -34,18 +42,34 @@ const formsToGeneralData = (
const teamForms = forms.filter(
(form) => form.teamNumber.toString() === teamNumber,
);
const resultOPR = {} as TeamOPR;
const resultEPA = {} as EPA;

fetchTeamsCOPRs({ teamNumber: resultOPR });
getTeamsEPAs({ teamNumber: resultEPA });

const generalData: GeneralData = {
teamNumber: Number(teamNumber),
fuelData: fuelData,
highestClimbLevel: findMaxClimbLevel(teamForms),
avarageClimbPoints: {
fullGame:
calculateAverageClimbsScore(teamForms).auto +
calculateAverageClimbsScore(teamForms).tele,
auto: calculateAverageClimbsScore(teamForms).auto,
tele: calculateAverageClimbsScore(teamForms).tele,
highestClimbLevel: findMaxClimbLevel(teamForms),
},
copr: resultOPR.fuelTotal,
movement: {
passTrenchCount: findTimesMovementEvent(teamForms, "trenchPass"),
passBumpCount: findTimesMovementEvent(teamForms, "bumpPass"),
stuckBumpCount: findTimesMovementEvent(teamForms, "bumpStuck"),
},
epa: resultEPA.breakdown.total_points,
averagePointsPerMatch: calculateTotalGamePoints(
teamForms,
bpses[teamNumber],
),
};

return generalData;
Expand Down
36 changes: 18 additions & 18 deletions apps/scouting/backend/src/routes/tinder-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
import { Router } from "express";
import { pipe } from "fp-ts/lib/function";
import { getFormsCollection } from "./forms-router";
import {
flatMap,
filterOrElse,
map,
fold,
bindTo,
} from "fp-ts/lib/TaskEither";
import { flatMap, filterOrElse, map, fold, bindTo } from "fp-ts/lib/TaskEither";
import { flatTryCatch, foldResponse, mongofyQuery } from "@repo/flow-utils";
import { StatusCodes } from "http-status-codes";
import {
Expand All @@ -22,7 +16,7 @@ import {
formsToFuelData,
} from "../fuel/fuel-general";
import { findMaxClimbLevel } from "../climb/calculations";
import { findTimesStuckOnBump } from "../movement/stats";
import { findTimesMovementEvent } from "../movement/stats";
import { isSingleTeam } from "../verification/functions";
import { getTeamBPSes } from "./bps-router";
import { firstElement, isEmpty } from "@repo/array-functions";
Expand All @@ -37,7 +31,7 @@ const createTinder = (forms: ScoutingForm[], bpses: Record<string, BPS[]>) => ({
maxClimbLevel: findMaxClimbLevel(forms),
},
movement: {
stuckOnBump: findTimesStuckOnBump(forms),
stuckOnBump: findTimesMovementEvent(forms, "bumpStuck"),
},
});

Expand All @@ -51,10 +45,13 @@ tinderRouter.get("/", (req, res) =>
reason: `DB Error: ${error}`,
}),
),
filterOrElse((forms) => !isEmpty(forms), () => ({
status: StatusCodes.BAD_REQUEST,
reason: "Tinder Team Error: No forms match the query.",
})),
filterOrElse(
(forms) => !isEmpty(forms),
() => ({
status: StatusCodes.BAD_REQUEST,
reason: "Tinder Team Error: No forms match the query.",
}),
),
filterOrElse(isSingleTeam, () => ({
status: StatusCodes.BAD_REQUEST,
reason:
Expand All @@ -63,11 +60,14 @@ tinderRouter.get("/", (req, res) =>

map(excludeNoShowForms),

filterOrElse((forms) => !isEmpty(forms), () => ({
status: StatusCodes.BAD_REQUEST,
reason:
"Tinder Team Error: No valid scouting data (all matches marked no-show).",
})),
filterOrElse(
(forms) => !isEmpty(forms),
() => ({
status: StatusCodes.BAD_REQUEST,
reason:
"Tinder Team Error: No valid scouting data (all matches marked no-show).",
}),
),

flatMap((forms) =>
getTeamBPSes({ [firstElement(forms).teamNumber]: forms }),
Expand Down
22 changes: 16 additions & 6 deletions apps/scouting/frontend/src/strategy/tabs/GeneralDataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ interface TableRow {
generalFuelData: GeneralFuelData;
}

export type Column = FuelEvents | "climb" | "max climb";

export type Column =
| FuelEvents
| "climb"
| "max climb"
| "copr"
| "epa"
| "average points";
type DataValue = ClimbLevel | number | undefined;

type DataAccessor = (row: GeneralData, gameTime: GameTime) => DataValue;
Expand All @@ -36,7 +41,10 @@ const columnToKey: Record<Column, DataAccessor> = {
missed: (row, gameTime) => row.fuelData[gameTime].missed,
passed: (row, gameTime) => row.fuelData[gameTime].passed,
climb: (row, gameTime) => row.avarageClimbPoints[gameTime],
"max climb": (row) => row.highestClimbLevel,
"max climb": (row) => row.avarageClimbPoints.highestClimbLevel,
copr: (row) => row.copr,
epa: (row) => row.epa,
"average points": (row) => row.averagePointsPerMatch,
};

const fetchGeneralData = async (filters = {}) => {
Expand Down Expand Up @@ -113,12 +121,14 @@ export const GeneralDataTable: React.FC<GeneralDataTableProps> = ({
<span className="font-black text-emerald-400">{info.getValue()}</span>
),
}),

createColumn("copr", "text-blue-400 font-medium"),
createColumn("epa", "text-yellow-400 font-medium"),
createColumn("average points", "text-cyan-400 font-medium"),
createColumn("scored", "text-emerald-400 font-bold"),
createColumn("missed", "text-rose-500/90 font-medium"),
createColumn("passed", "text-orange-400 font-medium"),
createColumn("climb", "text-purple-400 font-bold"),
createColumn("max climb", "text-slate-400 uppercase text-[10px]"),
createColumn("missed", "text-rose-500/90 font-medium"),
createColumn("passed", "text-orange-400 font-medium"),
],
[gameTime, sorting],
);
Expand Down
3 changes: 2 additions & 1 deletion packages/scouting_types/rebuilt/Movement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const defaultMovement: t.TypeOf<typeof autoMovementCodec> = {
bumpStuck: false,
};

export type MovementEvent = keyof typeof defaultMovement;
export type AutoMovement = t.TypeOf<typeof autoMovementCodec>;
export type TeleMovement = t.TypeOf<typeof teleMovementCodec>
export type TeleMovement = t.TypeOf<typeof teleMovementCodec>;
export type Movement = AutoMovement | TeleMovement;
21 changes: 1 addition & 20 deletions packages/scouting_types/rebuilt/fuel/FuelTypes.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
//בס"ד

import { GeneralFuelData } from "../general";
import type { ClimbLevel, Point } from "../scouting_form";

export interface GeneralFuelData {
fullGame: FuelObject;
auto: FuelObject;
tele: FuelObject;
}

export interface GeneralClimbData {
fullGame: number;
auto: number;
tele: number;
}

export interface GeneralData {
teamNumber: number;
fuelData: GeneralFuelData;
highestClimbLevel: ClimbLevel;
avarageClimbPoints: GeneralClimbData;
}

export type GameTime = keyof GeneralFuelData;


export type FuelEvents = "scored" | "shot" | "missed" | "passed";

export type FuelObject = GameObject<
Expand Down
31 changes: 31 additions & 0 deletions packages/scouting_types/rebuilt/general/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { FuelObject } from "../fuel";
import { ClimbLevel } from "../scouting_form";

export interface GeneralFuelData {
fullGame: FuelObject;
auto: FuelObject;
tele: FuelObject;
}

export interface GeneralClimbData {
fullGame: number;
auto: number;
tele: number;
highestClimbLevel: ClimbLevel;
}

interface GeneralMovementData {
passTrenchCount: number;
passBumpCount: number;
stuckBumpCount: number;
}

export interface GeneralData {
teamNumber: number;
fuelData: GeneralFuelData;
avarageClimbPoints: GeneralClimbData;
movement: GeneralMovementData;
copr: number | undefined;
epa: number;
averagePointsPerMatch: number;
}
1 change: 1 addition & 0 deletions packages/scouting_types/rebuilt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export type * from "./tinder";
export * from "./bps";
export * from "./super_scout";
export * from "./picklist";
export * from "./general";