{- Problema urmărește modelarea parțială a unui joc de Rock-Paper-Scissors. Este un joc în 2, unde la fiecare rundă fiecare jucător alege una din cele 3 mutări (Rock, Paper sau Scissors). Rock bate Scissors, Paper bate Rock, Scissors bate Paper, celelalte combinații rezultând în meci egal. -} {- 1a. (3p) Se dă tipul de date Move care reprezintă o mutare a jocului. Definiți tipul Game care reprezintă un joc de Rock-Paper-Scissors ca pe o listă de runde (o rundă e caracterizată de 2 mutări - pentru cei 2 jucători). -} data Move = Rock | Paper | Scissors deriving (Eq, Show) data Game = Game [(Move, Move)] {- 1b. (7p) Adăugați tipul Move la clasa Ord în conformitate cu logica jocului (Rock bate Scissors, Paper bate Rock, Scissors bate Paper, etc.). Pentru aceasta, este suficient să supraîncărcați operatorul <=. -} instance Ord Move where Rock <= other = other /= Scissors Paper <= other = other /= Rock Scissors <= other = other /= Paper {- 2. (10p) Implementați funcția mostUsed, care primește un Game și un jucător (1 sau 2), și întoarce mutarea utilizată cel mai des de acel jucător de-a lungul jocului. Obs: în caz de egalitate, întoarceți ce mutare doriți din cele folosite cel mai des. -} mostUsed :: Game -> Int -> Move mostUsed (Game game) player = snd $ maximum [rocks, papers, scissors] where moves = map (if player == 1 then fst else snd) game count move = length $ filter (== move) moves rocks = (count Rock, Rock) papers = (count Paper, Paper) scissors = (count Scissors, Scissors) {- 3. (10p) Implementați funcția winner, care primește un Game și întoarce: * 0, dacă jocul s-a încheiat la egalitate * 1, dacă a câștigat primul jucător * 2, dacă a câștigat al doilea jucător Obs: Jocul este câștigat de jucătorul care câștigă mai multe runde. -} winner :: Game -> Int winner (Game game) | result < 0 = 2 | result > 0 = 1 | otherwise = 0 where result = sum [ x | (a, b) <- game, a /= b, let x = if a < b then -1 else 1 ] {- Barem: 1a: 1p: folosirea corectă a lui data (sau modificarea în type și folosirea corectă) 1.5p: reprezentarea unei runde 0.5p: reprezentarea ca listă de runde 1b: 1p: folosirea mecanismului de instanțiere 2p: comportamentul pentru mutări de tip Rock 2p: ... Paper 2p: ... Scissors 2: 2p: extragerea mutărilor jucătorului de interes 3p: numărarea mutărilor de un anumit tip 1p: ... al doilea tip 1p: ... al treilea tip 2p: găsirea maximului dintre cele 3 rezultate 1p: returul de tip Move 3: 2p: extragerea celor 2 elemente care constituie perechea de mutări din fiecare rundă 2p: compararea lor pentru identificarea câștigătorului rundei (cu <, > sau ceva echivalent) 1p: neluarea în calcul a rundelor încheiate la egalitate 4p: numărarea și determinarea diferenței între numărul de runde câștigate de fiecare 1p: returul de tip Int -}