Handle duplicate yellows + better rule testing
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
/// The length of Wordle words.
|
/// The length of Wordle words.
|
||||||
pub const WordLen = 5;
|
pub const WordLen = 5;
|
||||||
|
|
||||||
@@ -19,8 +21,11 @@ pub const Clues = [WordLen]Clue;
|
|||||||
|
|
||||||
/// Guesses a word given a solution and returns the clues.
|
/// Guesses a word given a solution and returns the clues.
|
||||||
pub fn checkGuess(guess: Word, solution: Word) Clues {
|
pub fn checkGuess(guess: Word, solution: Word) Clues {
|
||||||
// init clues
|
// init clues, defaulting to gray clues
|
||||||
var clues: Clues = undefined;
|
var clues: Clues = @splat(Clue.Gray);
|
||||||
|
|
||||||
|
// track which letters have been used for yellow clues
|
||||||
|
var duplicates: [WordLen]bool = @splat(false);
|
||||||
|
|
||||||
// compare each letter pairwise
|
// compare each letter pairwise
|
||||||
for (guess, 0..) |guessLetter, idx| {
|
for (guess, 0..) |guessLetter, idx| {
|
||||||
@@ -30,13 +35,11 @@ pub fn checkGuess(guess: Word, solution: Word) Clues {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default to a gray clue
|
|
||||||
clues[idx] = Clue.Gray;
|
|
||||||
|
|
||||||
// if a matching letter in the solution can be found, write yellow
|
// if a matching letter in the solution can be found, write yellow
|
||||||
for (solution) |solutionLetter| {
|
for (solution, &duplicates) |solutionLetter, *duplicate| {
|
||||||
if (guessLetter == solutionLetter) {
|
if (guessLetter == solutionLetter and !duplicate.*) {
|
||||||
clues[idx] = Clue.Yellow;
|
clues[idx] = Clue.Yellow;
|
||||||
|
duplicate.* = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,30 +57,26 @@ pub fn strToWord(str: WordLiteral) Word {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Asserts that two word literals produce the expected clues.
|
/// Asserts that two word literals produce the expected clues.
|
||||||
fn expectGuessClues(guess: WordLiteral, solution: WordLiteral, expectClues: WordLiteral) error{Mismatch}!void {
|
fn expectGuessClues(guess: WordLiteral, solution: WordLiteral, expectClues: WordLiteral) !void {
|
||||||
// convert literals to the non-null word type
|
// convert literals to the non-null word type
|
||||||
const guessWord = strToWord(guess);
|
const guessWord = strToWord(guess);
|
||||||
const solutionWord = strToWord(solution);
|
const solutionWord = strToWord(solution);
|
||||||
const expectCluesWord = strToWord(expectClues);
|
|
||||||
|
|
||||||
// check the guess and produce clues
|
// check the guess and produce clues
|
||||||
const clues = checkGuess(guessWord, solutionWord);
|
const clues = checkGuess(guessWord, solutionWord);
|
||||||
|
|
||||||
// confirm that the expected clues match the clues
|
// convert the clues to a word
|
||||||
for (clues, expectCluesWord) |clue, expectedChar| {
|
var cluesWord: Word = undefined;
|
||||||
// convert character to associated clue variant
|
for (clues, &cluesWord) |src, *dst| {
|
||||||
const expected = switch (expectedChar) {
|
dst.* = switch (src) {
|
||||||
' ' => Clue.Gray,
|
Clue.Gray => ' ',
|
||||||
'Y' => Clue.Yellow,
|
Clue.Yellow => 'Y',
|
||||||
'G' => Clue.Green,
|
Clue.Green => 'G',
|
||||||
else => unreachable,
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// if clues don't match, return an error
|
// test the equality of the strings
|
||||||
if (expected != clue) {
|
try std.testing.expectEqualStrings(&cluesWord, expectClues);
|
||||||
return error.Mismatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "full match" {
|
test "full match" {
|
||||||
@@ -92,6 +91,10 @@ test "no match" {
|
|||||||
try expectGuessClues("salet", "fuzzy", " ");
|
try expectGuessClues("salet", "fuzzy", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
test "duplicate letters" {
|
test "anagram" {
|
||||||
try expectGuessClues("fuzzy", "zesty", " Y ");
|
try expectGuessClues("beats", "abets", "YYYGG");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "duplicate letters" {
|
||||||
|
try expectGuessClues("fuzzy", "zesty", " Y G");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user