Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions MaimThatTune.Server/Controllers/MusicController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ public IActionResult GuessArtist([FromBody] GuessRequest request)
return NotFound();
}

var isCorrect = SloppyAnswerComparer.AreCloseEnough(request.Guess, metadata.Artist)
|| SloppyAnswerComparer.AreCloseEnough(request.Guess, metadata.Title);
var isCorrect = SloppyAnswerComparer.AreCloseEnough(metadata.Artist, request.Guess)
|| SloppyAnswerComparer.AreCloseEnough(metadata.Title, request.Guess);

// Remove the track from the map after guessing
_trackMetadataMap.TryRemove(request.TrackId, out _);
Expand Down
2 changes: 1 addition & 1 deletion MusicFinder/RandomTrackPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public static class RandomTrackPicker
{
private static readonly Random _random = new();
private static readonly string[] _invalidGenres = { "$RECYCLE.BIN", "_Incoming", "_Playlists", "Music Cache", "Uncategorized", "Utilities", "Various Artists", };
private static readonly string[] _invalidGenres = { "$RECYCLE.BIN", "_Incoming", "_Playlists", "Music Cache", "Ryan", "Uncategorized", "Utilities", "Various Artists", };


/// <summary>
Expand Down
28 changes: 21 additions & 7 deletions MusicFinder/SloppyAnswerComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,37 @@ public static bool AreCloseEnough(string? answer, string? guess)
return false;
}

answer = NormalizeString(answer);
guess = NormalizeString(guess);
string cleanAnswer = NormalizeString(answer);
string cleanGuess = NormalizeString(guess);

if (guess.Length == 0)
if (cleanGuess.Length == 0)
{
return false;
}

if (answer == guess)
if (cleanAnswer == cleanGuess)
{
return true;
}

// Allow for minor typos using Levenshtein distance
int distance = LevenshteinDistance(answer, guess);
int maxAllowedDistance = Math.Max(1, answer.Length / 5); // Allow 1 typo or 20% of the length
return distance <= maxAllowedDistance;
int distance = LevenshteinDistance(cleanAnswer, cleanGuess);
int maxAllowedDistance = Math.Max(1, cleanAnswer.Length / 5); // Allow 1 typo or 20% of the string length

if (distance <= maxAllowedDistance)
{
return true;
}

// This might be an awkward multiple artist or "featuring" case, try splitting and checking just the first part of the guess/answer
string[] funkyIndicators = [",", ";", " feat ", " feat.", " featuring ", "(feat", " ft", "(ft", "&"];

if (distance > maxAllowedDistance && funkyIndicators.Any(indicator => answer.Contains(indicator, StringComparison.OrdinalIgnoreCase)))
{
return AreCloseEnough(answer.Split(funkyIndicators, StringSplitOptions.RemoveEmptyEntries)[0].Trim(), guess);
}

return false;
}

/// <summary>
Expand Down
43 changes: 36 additions & 7 deletions MusicFinderTests/SloppyAnswerComparerTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

using MusicFinder;

namespace MusicFinderTests
Expand Down Expand Up @@ -41,14 +42,42 @@ public void AreCloseEnough_PunctuationAndWhitespace_ReturnsTrue()
}

[TestMethod]
public void AreCloseEnough_NullOrEmpty_ReturnsFalse()
[DataRow("The Beatles (feat. Nine Inch Nails)", "The Beetles")]
[DataRow("The Beatles, Ozzy Osborne, and Doris Day", "The Beetles")]
[DataRow("The Beatles; Glen Gould; Metallica", "Beatles")]
[DataRow("Blur & Debby Gibson", "Blur")]
[DataRow("Gwar - featuring Doris Day", "Gwar")]
[DataRow("Gwar (feat. Doris Day)", "Gwar")]
public void AreCloseEnough_MessyExtraArtist_ReturnsTrue(string answer, string guess)
{
var result = SloppyAnswerComparer.AreCloseEnough(answer, guess);
Assert.IsTrue(result);
}

// string[] funkyIndicators = [",", ";", " feat ", " feat.", " featuring ", "(feat", " ft.", "(ft", "&"];

[TestMethod]
[DataRow("Head Like a Hole feat. Doris Day", "Head Like a Hole")]
[DataRow("Head Like a Hole, featuring Doris Day", "Head Like a Hole")]
[DataRow("Head Like a Hole (featuring Doris Day)", "Head Like a Hole")]
[DataRow("Head Like a Hole (ft. Doris Day)", "Head Like a Hole")]
[DataRow("Lithium - ft Doris Day)", "Lithium")]
public void AreCloseEnough_MessyTrackWithFeaturing_ReturnsTrue(string answer, string guess)
{
var result = SloppyAnswerComparer.AreCloseEnough(answer, guess);
Assert.IsTrue(result);
}

[TestMethod]
[DataRow(null, "test guess")]
[DataRow("test artist", null)]
[DataRow("", "test guess")]
[DataRow("test artist", "")]
[DataRow("test artist", "?")] // Only punctuation (boils down to an empty string)
[DataRow("X", "??????")]
public void AreCloseEnough_NullOrEmpty_ReturnsFalse(string? answer, string? guess)
{
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough(null, "test guess"));
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough("test artist", null));
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough("", "test guess"));
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough("test artist", ""));
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough("test artist", "?")); // Only punctuation (boils down to an empty string)
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough("X", "??????"));
Assert.IsFalse(SloppyAnswerComparer.AreCloseEnough(answer, guess));
}

[TestMethod]
Expand Down
1 change: 0 additions & 1 deletion maimthattune.client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,4 @@ function App() {
</div>
);
}

export default App;
Loading