Skip to content

Commit

Permalink
Optimize Wordle game processing logic
Browse files Browse the repository at this point in the history
This update modifies Wordle game classes to improve performance and readability. The 'ProcessGuess' has been refactored to use ICollection instead of List for indices storage. In 'WordleGuessExtensions', new utility methods 'GenerateCharIndicesMap' and 'MarkSpecificLetter' have been added. These additions help streamline the process of handling letters and their indices.
  • Loading branch information
EpicOfficer committed Apr 15, 2024
1 parent 2b7ab67 commit f37e20d
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 f37e20d

Please sign in to comment.