Files
football-next/lib/teamValidation.ts
a.alinaghipour aa9ed69dd2 first commit
2026-04-05 15:53:20 +03:30

87 lines
3.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export const FORMATIONS: Record<string, { def: number; mid: number; fwd: number }> = {
"4-3-3": { def: 4, mid: 3, fwd: 3 },
"4-4-2": { def: 4, mid: 4, fwd: 2 },
"4-5-1": { def: 4, mid: 5, fwd: 1 },
"3-5-2": { def: 3, mid: 5, fwd: 2 },
"3-4-3": { def: 3, mid: 4, fwd: 3 },
"5-3-2": { def: 5, mid: 3, fwd: 2 },
"5-4-1": { def: 5, mid: 4, fwd: 1 },
};
export type FormationKey = keyof typeof FORMATIONS;
// تعداد مورد نیاز هر پست = ترکیب + 1 ذخیره
export function requiredPerPosition(formation: string) {
const fmt = FORMATIONS[formation] ?? FORMATIONS["4-3-3"];
return {
GK: 2, // 1 اصلی + 1 ذخیره
DEF: fmt.def + 1,
MID: fmt.mid + 1,
FWD: fmt.fwd + 1,
};
}
export type PlayerLike = { position: string; isBench: boolean };
export function validateTeamComposition(
players: PlayerLike[],
formation: string
): { valid: boolean; errors: string[] } {
const fmt = FORMATIONS[formation] ?? FORMATIONS["4-3-3"];
const errors: string[] = [];
const starters = players.filter((p) => !p.isBench);
const bench = players.filter((p) => p.isBench);
// تعداد کل
if (players.length !== 15) {
errors.push(`تیم باید دقیقاً ۱۵ بازیکن داشته باشد (الان: ${players.length})`);
}
// ترکیب اصلی
const startersByPos = countByPos(starters);
if (startersByPos.GK !== 1) errors.push("باید دقیقاً ۱ دروازه‌بان اصلی داشته باشی");
if (startersByPos.DEF !== fmt.def) errors.push(`باید ${fmt.def} مدافع اصلی داشته باشی (الان: ${startersByPos.DEF ?? 0})`);
if (startersByPos.MID !== fmt.mid) errors.push(`باید ${fmt.mid} هافبک اصلی داشته باشی (الان: ${startersByPos.MID ?? 0})`);
if (startersByPos.FWD !== fmt.fwd) errors.push(`باید ${fmt.fwd} مهاجم اصلی داشته باشی (الان: ${startersByPos.FWD ?? 0})`);
// ذخیره‌ها - هر پست باید ۱ ذخیره داشته باشه
const benchByPos = countByPos(bench);
if ((benchByPos.GK ?? 0) < 1) errors.push("باید ۱ دروازه‌بان ذخیره داشته باشی");
if ((benchByPos.DEF ?? 0) < 1) errors.push("باید حداقل ۱ مدافع ذخیره داشته باشی");
if ((benchByPos.MID ?? 0) < 1) errors.push("باید حداقل ۱ هافبک ذخیره داشته باشی");
if ((benchByPos.FWD ?? 0) < 1) errors.push("باید حداقل ۱ مهاجم ذخیره داشته باشی");
return { valid: errors.length === 0, errors };
}
function countByPos(players: PlayerLike[]): Record<string, number> {
return players.reduce((acc, p) => {
acc[p.position] = (acc[p.position] ?? 0) + 1;
return acc;
}, {} as Record<string, number>);
}
// وقتی ترکیب عوض میشه، چک کن آیا بازیکنان فعلی با ترکیب جدید سازگارن
export function getFormationChangeIssues(
players: PlayerLike[],
oldFormation: string,
newFormation: string
): string[] {
const oldFmt = FORMATIONS[oldFormation] ?? FORMATIONS["4-3-3"];
const newFmt = FORMATIONS[newFormation] ?? FORMATIONS["4-3-3"];
const issues: string[] = [];
const starters = players.filter((p) => !p.isBench);
const byPos = countByPos(starters);
if ((byPos.DEF ?? 0) > newFmt.def)
issues.push(`باید ${(byPos.DEF ?? 0) - newFmt.def} مدافع رو به ذخیره ببری یا حذف کنی`);
if ((byPos.MID ?? 0) > newFmt.mid)
issues.push(`باید ${(byPos.MID ?? 0) - newFmt.mid} هافبک رو به ذخیره ببری یا حذف کنی`);
if ((byPos.FWD ?? 0) > newFmt.fwd)
issues.push(`باید ${(byPos.FWD ?? 0) - newFmt.fwd} مهاجم رو به ذخیره ببری یا حذف کنی`);
return issues;
}