Cette semaine, c'est Nicolas qui vous propose un #KataOfTheWeek : Compteur de points au tennis.
Briefing du Kata : Rappel rapide des règles :
- Pour gagner un match, il faut gagner deux sets (trois pour certains tournois pour les hommes mais on ne va pas s'attarder là dessus).
- Pour gagner un set, il faut gagner normalement 6 jeux.
- On est forcé d'avoir un écart de deux points pour gagner un set. 5-5 nous envoie à 7-5 pour gagner le set.
- En revanche, "6-6" va entraîner un tie-break. Ceci consiste à démarrer un jeu où on compte les points de 1 en 1 et le premier joueur à atteindre 7 points avec 2 points d'écart gagne le tie-break et le set par la même occasion.
- Pour gagner un jeu il faut marquer 4 balles avec deux points d'écart.
- Les points d'un jeu sont comptés dans l'ordre suivant: 0, 15, 30, 40
- Si il y a "40-40", on parle d'égalité. Il faudra alors marquer deux points consécutifs pour remporter le jeu. Si un joueur marque un point, ce dernier prend l'avantage (av). Si l'adversaire marque à son tour, on retourne à "40-40".
Le but du kata consiste à partir d'une chaîne de caractères composée d'une suite de 1 et de 2, représentant les balles marquées par chaque joueur, de donner le score correspondant au format suivant:
- "S1-S2 P1-P2 X1-X2" si le match est encore en cours
- "Player X Win !" si on a un gagnant.
S1 = Nombre de set gagné par 1 S2 = Nombre de set gagné par 2 P1 = Nombre de jeux du set courant gagné par 1 P2 = Nombre de jeux du set courant gagné par 2 X1 = Nombre de balles du jeu courant gagné par 1 X2 = Nombre de balles du jeu courant gagné par 2
Exemple : "11111111" : "0-0 2-0 0-0" "112111111112" : "0-0 2-0 30-15" "11212212121" : "0-0 0-0 av-40" "111111111111111111112222222222222222222211112222111111" : "0-0 6-6 6-0" "111111111111111111111111111111111111111111111111" : "Player 1 Win !"
Saurez-vous résoudre le problème ?
Bon courage !
Et voici une solution proposée par l'auteur en JavaScript :
const cleanSet = partie => ({P1:{...partie.P1,J:0,X:0},P2:{...partie.P2,J:0,X:0}});
const cleanGame = partie => ({P1:{...partie.P1,X:0},P2:{...partie.P2,X:0}});
const setIsWin = partie => {
if ((partie.P1.J > 6)||(partie.P1.J > 5 && (partie.P1.J - partie.P2.J) > 1)) {
return cleanSet({...partie, P1: {...partie.P1, S:partie.P1.S+1}});
} else if ((partie.P2.J > 6)||(partie.P2.J > 5 && (partie.P2.J - partie.P1.J) > 1)) {
return cleanSet({...partie, P2: {...partie.P2, S:partie.P2.S+1}});
}
return partie;
}
const gameIsWin = (partie) => {
let min = 3;
if (partie.P1.J === 6 && partie.P1.J === partie.P2.J) {
min = 6;
}
if (partie.P1.X > min && (partie.P1.X - partie.P2.X) > 1) {
return cleanGame({...partie, P1: {...partie.P1, J:partie.P1.J+1}});
} else if (partie.P2.X > min && (partie.P2.X - partie.P1.X) > 1) {
return cleanGame({...partie, P2: {...partie.P2, J:partie.P2.J+1}});
}
if (min === 3 && partie.P1.X > min && partie.P1.X === partie.P2.X) {
return {P1:{...partie.P1,X:min},P2:{...partie.P2,X:min}};
}
return partie;
}
const printPoints = (x) => {
switch(x) {
case 4: return 'av';
case 3: return '40';
case 2: return '30';
case 1: return '15';
default: return '0';
}
return '0';
}
const printCurrentGame = (partie) => {
if (partie.P1.J === 6 && partie.P1.J === partie.P2.J) {
return `${partie.P1.X}-${partie.P2.X}`;
}
return `${printPoints(partie.P1.X)}-${printPoints(partie.P2.X)}`;
}
const stringifyScore = (stringOfPoints) => {
let partie = {P1:{S:0,J:0,X:0},P2:{S:0,J:0,X:0}};
let current;
for (i in stringOfPoints) {
current = stringOfPoints[i];
if (current === '1') {
partie = {...partie,P1:{...partie.P1,X:((partie.P1.X)+1)}}
} else {
partie = {...partie,P2:{...partie.P2,X:((partie.P2.X)+1)}}
}
partie = setIsWin(gameIsWin(partie));
if (partie.P1.S === 2 || partie.P2.S === 2) {
return `Player ${current} Win !`
}
}
return `${partie.P1.S}-${partie.P2.S} ${partie.P1.J}-${partie.P2.J} ${printCurrentGame(partie)}`
}
Votre équipe TakiVeille