87 lines
3.7 KiB
TypeScript
87 lines
3.7 KiB
TypeScript
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;
|
||
}
|