Skip to content

Commit

Permalink
Merge pull request #34 from EpicOfficer/FEATURE/Wordle
Browse files Browse the repository at this point in the history
Optimize Wordle game processing logic
  • Loading branch information
EpicOfficer authored Apr 16, 2024
2 parents 2b7ab67 + f37e20d commit 299439d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Blink3.Core/Extensions/WordleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public static class WordleExtensions
/// <param name="guess">The word guess entered by a player.</param>
public static void ProcessGuess(this Wordle wordle, WordleGuess guess)
{
List<int> correctIndices = [];
List<int> misplacedIndices = [];
ICollection<int> correctIndices = [];
ICollection<int> misplacedIndices = [];

guess.MarkCorrectLetters(wordle, correctIndices);
guess.MarkMisplacedLetters(wordle, correctIndices, misplacedIndices);
Expand Down
72 changes: 57 additions & 15 deletions Blink3.Core/Extensions/WordleGuessExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Blink3.Core.Entities;
using Blink3.Core.Enums;

// ReSharper disable SuggestBaseTypeForParameter

namespace Blink3.Core.Extensions;

/// <summary>
Expand Down Expand Up @@ -39,27 +41,67 @@ public static void MarkMisplacedLetters(this WordleGuess guess, Wordle wordle,
{
string word = guess.Word;
string wordToGuess = wordle.WordToGuess;
Dictionary<char, int> checkedLettersCount = new(); // number of times a letter has been processed

for (int i = 0; i < word.Length; i++)
{
char letter = word[i];
if (guess.Letters[i].State == WordleLetterStateEnum.Correct) continue;
Dictionary<char, int> checkedLettersCount = new();
Dictionary<char, List<int>> charIndicesMap = GenerateCharIndicesMap(wordToGuess);

checkedLettersCount.TryAdd(letter, 0);
int letterOccurrences = wordToGuess.AllIndexesOf(letter).Count;
for (int i = 0; i < word.Length; i++)
MarkSpecificLetter(guess, word, correctIndices, misplacedIndices, checkedLettersCount, charIndicesMap, i);
}

if (checkedLettersCount[letter] >= letterOccurrences) continue;
checkedLettersCount[letter]++;
/// <summary>
/// Generates a character indices map for a given word.
/// </summary>
/// <param name="wordToGuess">The word to generate the character indices map for.</param>
/// <returns>A dictionary with characters as keys and lists of indices as values.</returns>
private static Dictionary<char, List<int>> GenerateCharIndicesMap(string wordToGuess)
{
Dictionary<char, List<int>> charIndicesMap = new(wordToGuess.Length);

List<int> indices = wordToGuess.AllIndexesOf(letter);
foreach (int index in indices.Where(index =>
!(correctIndices.Contains(index) || misplacedIndices.Contains(index))))
for (int i = 0; i < wordToGuess.Length; i++)
{
if (!charIndicesMap.TryGetValue(wordToGuess[i], out List<int>? value))
{
guess.Letters[i].State = WordleLetterStateEnum.Misplaced;
misplacedIndices.Add(index);
break;
value = new List<int>();
charIndicesMap[wordToGuess[i]] = value;
}

value.Add(i);
}

return charIndicesMap;
}

/// <summary>
/// Marks a specific letter in the WordleGuess object based on given parameters.
/// </summary>
/// <param name="guess">The WordleGuess object</param>
/// <param name="word">The word from the guess</param>
/// <param name="correctIndices">The collection of correct indices</param>
/// <param name="misplacedIndices">The collection of misplaced indices</param>
/// <param name="checkedLettersCount">The dictionary of checked letters count</param>
/// <param name="charIndicesMap">The dictionary mapping characters to indices</param>
/// <param name="i">The index of the letter to mark</param>
private static void MarkSpecificLetter(WordleGuess guess, string word, ICollection<int> correctIndices,
ICollection<int> misplacedIndices, Dictionary<char, int> checkedLettersCount,
Dictionary<char, List<int>> charIndicesMap, int i)
{
char letter = word[i];
if (guess.Letters[i].State == WordleLetterStateEnum.Correct) return;

checkedLettersCount.TryAdd(letter, 0);
checkedLettersCount[letter]++;

if (!charIndicesMap.TryGetValue(letter, out List<int>? value)) return;

foreach (int index in value.Where(index =>
!correctIndices.Contains(index) && !misplacedIndices.Contains(index)))
{
guess.Letters[i].State = WordleLetterStateEnum.Misplaced;
misplacedIndices.Add(index);
break;
}

if (checkedLettersCount[letter] >= value.Count) charIndicesMap.Remove(letter);
}
}

0 comments on commit 299439d

Please sign in to comment.