fix: nextguess was not implemented to account for duplicate notes/octaves

This commit is contained in:
wi11-holdsworth 2025-10-01 12:51:55 +10:00
parent e9710a5bf8
commit efc8ac3116

View file

@ -12,6 +12,7 @@ where
import Data.List
import Data.Set qualified as S
import Debug.Trace
-- datatypes --
@ -69,20 +70,24 @@ toPitch _ = Nothing
feedback :: [Pitch] -> [Pitch] -> (Int, Int, Int)
feedback target guess = (length correctPitches, correctNotes, correctOctaves)
where
-- since pitches are unique in a guess,
-- we can use set math to count how many are correct
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
newTarget = S.toList $ S.difference targetSet correctPitches
newGuess = S.toList $ S.difference guessSet correctPitches
correctNotes = length $ S.intersection targetNoteSet guessNoteSet
correctOctaves = length $ S.intersection targetOctaveSet guessOctaveSet
(targetNotes, guessNotes) = (map note newTarget, map note newGuess)
(targetOctaves, guessOctaves) = (map octave newTarget, map octave newGuess)
-- since notes and octaves are not unique in a guess,
-- we can compare the guess to all possible permutations of the target
-- and count the pairwise note/octave matches
correctNotes = matches targetNotes guessNotes
correctOctaves = matches targetOctaves guessOctaves
initialGuess :: ([Pitch], GameState)
initialGuess = (chord, chords)
@ -122,4 +127,10 @@ allOctaves = [minBound .. maxBound]
allNotes :: [Note]
allNotes = [minBound .. maxBound]
matches :: (Eq a, Show a) => [a] -> [a] -> Int
matches xs ys = maximum permutationMatches
where
permutationMatches = map (pairwiseMatches xs) (permutations ys)
pairwiseMatches xs ys = length $ filter (uncurry (==)) $ zip xs ys
--