0votos

Kata Tennis en Haskell

por josejuan hace 6 años

Controla todas las reglas (punto, juego, set y partido; no controla muerte súbita, pero ésta es un "añadido" a las reglas que depende de cada torneo) con un número arbitrario de sets.

En esta kata nos divertiremos implementando las reglas del tennis algo simplificadas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
-- Describe los datos de un partido de tenis: 
data Player = Player 
  Int     -- Sets ganados. 
  Int     -- Juegos ganados. 
  Int     -- Puntos ganados. 
  deriving Show 
 
data Match = Match 
  Player  -- Jugador A 
  Player  -- Jugador B 
  Int        -- El primero que gana X sets 
  deriving Show 
 
data State = Playing     -- Están jugando 
           | WinAPlayer  -- Gana el jugador A 
           | WinBPlayer  -- Gana el jugador B 
           deriving (Eq, Show) 
 
-- Constructor: 
startMatch sets = Match (Player 0 0 0) (Player 0 0 0) sets 
 
-- Incrementa un juego en el jugador A: 
addPointA (Match (Player sA gA pA) (Player sB gB pB) fO) = 
  case (pA, pB) of 
    ( 0,  _) -> otro 15 pB 
    (15,  _) -> otro 30 pB 
    (30,  _) -> otro 40 pB 
    (40,  0) -> gana 
    (40, 15) -> gana 
    (40, 30) -> gana 
    (40, 40) -> otro 50 pB 
    (40, 50) -> otro 40 40 
    (50,  _) -> gana 
  where otro pA' pB' = Match (Player sA  gA      pA') (Player sB gB pB') fO 
        gana         = Match (Player sA (gA + 1)   0) (Player sB gB   0) fO 
 
-- Incrementa un juego en el jugador B: 
addPointB (Match jA jB fO) = Match jA' jB' fO where (Match jB' jA' _) = addPointA (Match jB jA fO) 
 
-- Ajusta los juegos para conseguir sets: 
normalizeSets m@(Match (Player sA gA pA) (Player sB gB pB) fO) 
  | gA > 5 && gA > gB + 1 = Match (Player (sA + 1) 0 0) (Player  sB      0 0) fO 
  | gB > 5 && gB > gA + 1 = Match (Player  sA      0 0) (Player (sB + 1) 0 0) fO 
  | True                  = m 
 
-- Mira el estado de un partido 
getState (Match (Player sA _ _) (Player sB _ _) fO) 
  | sA >= fO = WinAPlayer 
  | sB >= fO = WinBPlayer 
  | True     = Playing 
 
-- Avanza el juego según gana puntos uno u otro jugador, si alguno gana, se detiene 
playMatch m [] = m 
playMatch m (w:ws) = 
  if getState m /= Playing 
    then m 
    else (playMatch . normalizeSets . (if w == 'A' then addPointA else addPointB)) m ws 
 
-- Jugar hasta ganar (e indica el ganador) 
playCompleteMatch sets w = (getState s, s) where s = playMatch (startMatch sets) w 
 
 
 
 
 
 
 
{-- ========== usage =================================== 
 
*Main> playCompleteMatch 2 "BBAABAABABABABBABAABAAAAABBBABBABABAABABBBAABAABBA" 
(Playing,Match (Player 0 2 15) (Player 0 1 30) 2) 
 
*Main> playCompleteMatch 2 "BBAABAABABABABBABAABAAAAABBBABBABABAABABBBAABAABBABBBBABABABBABAABBBABABBABBABABABBABABBAABAABABABABBABAAAAAAAABAABBAAAABABABABABAABABABABABABAABABABABAAAAABBBABBABABAABABBBAABAABBABBBBABABABBABAABBBABABBABBABABABBABA" 
(WinBPlayer,Match (Player 1 0 0) (Player 2 0 0) 2) 
 
--} 

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.