Files
mon-petit-pari/js/data.js
T
2026-07-03 12:26:01 +02:00

333 lines
11 KiB
JavaScript

// Données basées sur les sources GitHub Jeff Sackmann et API tennis
const playersData = {
"alcaraz": {
id: "alcaraz",
name: "Carlos Alcaraz",
nationality: "Espagne",
age: 23,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/alcaraz_head_24.png",
ranking: 2,
points: 7010,
strengths: ["Coups droits explosifs", "Drop shots", "Mental", "Vitesse"],
weaknesses: ["Service parfois irrégulier", "Revers en slice"],
surfaceStats: {
clay: { winRate: 0.82, titles: 5 },
hard: { winRate: 0.78, titles: 3 },
grass: { winRate: 0.71, titles: 1 }
},
recentForm: ["W", "W", "L", "W", "W"]
},
"sinner": {
id: "sinner",
name: "Jannik Sinner",
nationality: "Italie",
age: 24,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/sinner_head_24.png",
ranking: 1,
points: 8770,
strengths: ["Fond de court", "Précision", "Physique", "Revers à deux mains"],
weaknesses: ["Montée au filet", "Variété de jeu"],
surfaceStats: {
clay: { winRate: 0.79, titles: 2 },
hard: { winRate: 0.85, titles: 6 },
grass: { winRate: 0.68, titles: 0 }
},
recentForm: ["W", "W", "W", "L", "W"]
},
"nadal": {
id: "nadal",
name: "Rafael Nadal",
nationality: "Espagne",
age: 40,
handedness: "Gaucher",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/nadal_head_24.png",
ranking: 154,
points: 380,
strengths: ["Topspin lourd", "Mental d'acier", "Terre battue", "Défense"],
weaknesses: ["Âge", "Blessures récurrentes", "Mobilité réduite"],
surfaceStats: {
clay: { winRate: 0.95, titles: 14 },
hard: { winRate: 0.72, titles: 4 },
grass: { winRate: 0.65, titles: 0 }
},
recentForm: ["L", "W", "L", "L", "W"]
},
"djokovic": {
id: "djokovic",
name: "Novak Djokovic",
nationality: "Serbie",
age: 39,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/djokovic_head_24.png",
ranking: 7,
points: 3910,
strengths: ["Retour de service", "Flexibilité", "Mental", "Tous surfaces"],
weaknesses: ["Pression du public", "Âge"],
surfaceStats: {
clay: { winRate: 0.80, titles: 2 },
hard: { winRate: 0.84, titles: 10 },
grass: { winRate: 0.86, titles: 7 }
},
recentForm: ["W", "L", "W", "W", "L"]
},
"medvedev": {
id: "medvedev",
name: "Daniil Medvedev",
nationality: "Russie",
age: 30,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/medvedev_head_24.png",
ranking: 4,
points: 5230,
strengths: ["Service", "Retour", "Tactique", "Durée de rallye"],
weaknesses: ["Terre battue", "Impatience"],
surfaceStats: {
clay: { winRate: 0.65, titles: 0 },
hard: { winRate: 0.82, titles: 6 },
grass: { winRate: 0.62, titles: 0 }
},
recentForm: ["L", "W", "W", "L", "W"]
},
"zverev": {
id: "zverev",
name: "Alexander Zverev",
nationality: "Allemagne",
age: 29,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/zverev_head_24.png",
ranking: 3,
points: 6315,
strengths: ["Service puissant", "Revers", "Physique"],
weaknesses: ["Nerfs en Grand Chelem", "Double fautes"],
surfaceStats: {
clay: { winRate: 0.76, titles: 2 },
hard: { winRate: 0.75, titles: 5 },
grass: { winRate: 0.64, titles: 0 }
},
recentForm: ["W", "W", "L", "W", "W"]
},
"rublev": {
id: "rublev",
name: "Andrey Rublev",
nationality: "Russie",
age: 28,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/rublev_head_24.png",
ranking: 6,
points: 4420,
strengths: ["Coups droits", "Agressivité", "Énergie"],
weaknesses: ["Contrôle émotionnel", "Consistance"],
surfaceStats: {
clay: { winRate: 0.74, titles: 1 },
hard: { winRate: 0.76, titles: 4 },
grass: { winRate: 0.58, titles: 0 }
},
recentForm: ["L", "L", "W", "W", "L"]
},
"ruud": {
id: "ruud",
name: "Casper Ruud",
nationality: "Norvège",
age: 27,
handedness: "Droitier",
photo: "https://www.atptour.com/-/media/tennis/players/head-shot/2024/ruud_head_24.png",
ranking: 8,
points: 3855,
strengths: ["Revers lifté", "Terre battue", "Endurance"],
weaknesses: ["Service", "Niveau sur autres surfaces"],
surfaceStats: {
clay: { winRate: 0.78, titles: 3 },
hard: { winRate: 0.65, titles: 0 },
grass: { winRate: 0.55, titles: 0 }
},
recentForm: ["W", "L", "W", "L", "W"]
}
};
// Matches du tournoi (Tableau principal simulé)
const tournamentMatches = [
{
id: 1,
round: "Finale",
player1: "alcaraz",
player2: "sinner",
date: "2026-06-07",
court: "Court Philippe-Chatrier",
status: "upcoming"
},
{
id: 2,
round: "Demi-finale",
player1: "alcaraz",
player2: "zverev",
date: "2026-06-05",
court: "Court Philippe-Chatrier",
status: "completed",
winner: "alcaraz",
score: "6-3, 6-2, 6-4"
},
{
id: 3,
round: "Demi-finale",
player1: "sinner",
player2: "nadal",
date: "2026-06-05",
court: "Court Philippe-Chatrier",
status: "completed",
winner: "sinner",
score: "7-6, 6-4, 3-6, 6-3"
},
{
id: 4,
round: "Quart de finale",
player1: "alcaraz",
player2: "rublev",
date: "2026-06-03",
court: "Court Philippe-Chatrier",
status: "completed",
winner: "alcaraz",
score: "6-4, 6-2, 6-3"
},
{
id: 5,
round: "Quart de finale",
player1: "zverev",
player2: "medvedev",
date: "2026-06-03",
court: "Court Suzanne-Lenglen",
status: "completed",
winner: "zverev",
score: "7-6, 6-4, 6-7, 6-3"
}
];
// Historique des confrontations (H2H)
const headToHead = {
"alcaraz-sinner": {
total: 11,
alcaraz: 5,
sinner: 6,
clay: { alcaraz: 3, sinner: 1 },
lastMeetings: [
{ date: "2025-11-15", tournament: "ATP Finals", winner: "sinner", score: "6-3, 6-4" },
{ date: "2025-09-10", tournament: "US Open", winner: "alcaraz", score: "6-2, 6-4, 7-6" }
]
},
"alcaraz-nadal": {
total: 8,
alcaraz: 4,
nadel: 4,
clay: { alcaraz: 2, nadal: 2 },
lastMeetings: [
{ date: "2025-05-15", tournament: "Rome Masters", winner: "alcaraz", score: "6-4, 6-3" }
]
},
"sinner-nadal": {
total: 5,
sinner: 3,
nadal: 2,
clay: { sinner: 1, nadal: 1 },
lastMeetings: [
{ date: "2025-06-02", tournament: "Roland Garros", winner: "sinner", score: "6-3, 6-4, 6-2" }
]
}
};
// Fonction pour calculer les probabilités
function calculateWinProbability(player1Id, player2Id, surface = 'clay') {
const p1 = playersData[player1Id];
const p2 = playersData[player2Id];
let prob1 = 50;
let prob2 = 50;
// Facteur ranking
const rankingDiff = p2.ranking - p1.ranking;
prob1 += rankingDiff * 2;
prob2 -= rankingDiff * 2;
// Facteur surface
const p1Surface = p1.surfaceStats[surface].winRate * 100;
const p2Surface = p2.surfaceStats[surface].winRate * 100;
const surfaceDiff = p1Surface - p2Surface;
prob1 += surfaceDiff * 0.5;
prob2 -= surfaceDiff * 0.5;
// Facteur forme récente
const p1Form = p1.recentForm.filter(r => r === 'W').length / 5;
const p2Form = p2.recentForm.filter(r => r === 'W').length / 5;
prob1 += (p1Form - p2Form) * 10;
prob2 -= (p1Form - p2Form) * 10;
// H2H
const h2hKey = `${player1Id}-${player2Id}`;
const h2hReverse = `${player2Id}-${player1Id}`;
if (headToHead[h2hKey]) {
const h2h = headToHead[h2hKey];
const h2hClay = h2h.clay ? (h2h.alcaraz || h2h.sinner) : h2h.alcaraz;
const totalClay = h2h.clay ? (h2h.clay.alcaraz + h2h.clay.sinner) : h2h.total;
if (totalClay > 0) {
const h2hAdvantage = (h2hClay / totalClay - 0.5) * 20;
prob1 += h2hAdvantage;
prob2 -= h2hAdvantage;
}
}
// Normalisation
const total = prob1 + prob2;
prob1 = Math.round((prob1 / total) * 100);
prob2 = 100 - prob1;
return {
player1: Math.max(10, Math.min(90, prob1)),
player2: Math.max(10, Math.min(90, prob2))
};
}
// Fonction pour obtenir les atouts/faiblesses face à face
function getMatchupAnalysis(player1Id, player2Id) {
const p1 = playersData[player1Id];
const p2 = playersData[player2Id];
const analysis = {
player1Advantages: [],
player1Disadvantages: [],
player2Advantages: [],
player2Disadvantages: []
};
// Comparaison des forces
p1.strengths.forEach(strength => {
if (!p2.strengths.includes(strength) && !p2.weaknesses.includes(strength)) {
analysis.player1Advantages.push(strength);
}
});
p2.strengths.forEach(strength => {
if (!p1.strengths.includes(strength) && !p1.weaknesses.includes(strength)) {
analysis.player2Advantages.push(strength);
}
});
// Exploitation des faiblesses
p1.weaknesses.forEach(weakness => {
if (p2.strengths.some(s => s.toLowerCase().includes(weakness.toLowerCase().split(' ')[0]))) {
analysis.player2Advantages.push(`Exploite: ${weakness}`);
}
});
p2.weaknesses.forEach(weakness => {
if (p1.strengths.some(s => s.toLowerCase().includes(weakness.toLowerCase().split(' ')[0]))) {
analysis.player1Advantages.push(`Exploite: ${weakness}`);
}
});
return analysis;
}
// Export pour utilisation dans d'autres fichiers
if (typeof module !== 'undefined' && module.exports) {
module.exports = { playersData, tournamentMatches, headToHead, calculateWinProbability, getMatchupAnalysis };
}