comp30002-project-2/Proj2.hs

125 lines
2.5 KiB
Haskell

--
module Proj2
( Pitch,
toPitch,
feedback,
GameState,
initialGuess,
nextGuess,
)
where
import Data.List
import Data.Set qualified as S
-- datatypes --
type GameState = [[Pitch]]
data Note = A | B | C | D | E | F | G
deriving (Eq, Show, Ord, Enum, Bounded)
data Octave = One | Two | Three
deriving (Eq, Ord, Enum, Bounded)
data Pitch = Pitch
{ note :: Note,
octave :: Octave
}
deriving (Eq, Ord)
instance Show Octave where
show One = "1"
show Two = "2"
show Three = "3"
instance Show Pitch where
show (Pitch note octave) = show note ++ show octave
--
-- required functions --
toPitch :: String -> Maybe Pitch
toPitch [note, octave] = Pitch <$> charToNote note <*> charToOctave octave
where
charToNote :: Char -> Maybe Note
charToNote c =
lookup
c
[ ('A', A),
('B', B),
('C', C),
('D', D),
('E', E),
('F', F),
('G', G)
]
charToOctave :: Char -> Maybe Octave
charToOctave c =
lookup
c
[ ('1', One),
('2', Two),
('3', Three)
]
toPitch _ = Nothing
feedback :: [Pitch] -> [Pitch] -> (Int, Int, Int)
feedback target guess = (length correctPitches, correctNotes, correctOctaves)
where
targetSet = S.fromList target
guessSet = S.fromList guess
correctPitches = S.intersection targetSet guessSet
newTarget = S.difference targetSet correctPitches
newGuess = S.difference guessSet correctPitches
targetNoteSet = S.map note newTarget
guessNoteSet = S.map note newGuess
targetOctaveSet = S.map octave newTarget
guessOctaveSet = S.map octave newGuess
correctNotes = length $ S.intersection targetNoteSet guessNoteSet
correctOctaves = length $ S.intersection targetOctaveSet guessOctaveSet
initialGuess :: ([Pitch], GameState)
initialGuess = (chord, chords)
where
chord : chords = allChords
-- implement me
nextGuess :: ([Pitch], GameState) -> (Int, Int, Int) -> ([Pitch], GameState)
nextGuess (prevGuess, chord : chords) _ = (chord, chords)
--
-- helper functions --
allChords :: [[Pitch]]
allChords =
[ chord
| p1 <- allPitches,
p2 <- allPitches,
p3 <- allPitches,
let chord = [p1, p2, p3],
length (nub chord) == 3,
p1 < p2,
p2 < p3
]
allPitches :: [Pitch]
allPitches =
[ Pitch note octave
| note <- allNotes,
octave <- allOctaves
]
allOctaves :: [Octave]
allOctaves = [minBound .. maxBound]
allNotes :: [Note]
allNotes = [minBound .. maxBound]
--