From 8ff574a24eba22dca5c5a6bccdd00dcac90ae5a5 Mon Sep 17 00:00:00 2001 From: Lowe Raivio Date: Wed, 8 Jan 2025 16:56:41 +0100 Subject: [PATCH 1/3] Challange complete, extended challange complete --- csharp-scrabble-challenge.Main/Scrabble.cs | 102 +++++++++++++++++++- csharp-scrabble-challenge.Test/CoreTests.cs | 13 +++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index c1ea013..576d21a 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -4,20 +4,116 @@ using System.Reflection.Metadata.Ecma335; using System.Text; using System.Threading.Tasks; +using System.Text.RegularExpressions; namespace csharp_scrabble_challenge.Main { public class Scrabble { + private int _score = 0; public Scrabble(string word) - { - //TODO: do something with the word variable + { + // seperating defining of word and class allows for change of word later... + setWord(word); + } + + private void findAndCalc_doubleLetters(string word, ref int tempScore, ref string stripMultiplierWord) + { + // regex looks for a single letter with braces around it + var doubleLetters = Regex.Matches(word, $"{{[a-z]}}", RegexOptions.IgnoreCase); + foreach (Match d in doubleLetters) + { + stripMultiplierWord = stripMultiplierWord.Replace(d.Value, ""); + tempScore += this.calc_score(d.Value) * 2; + } + } + + private void findAndCalc_trippleLetters(string word, ref int tempScore, ref string stripMultiplierWord) + { + // regex looks for a single letter with brackets around it + var trippleLetters = Regex.Matches(word, $"\\[[a-z]\\]", RegexOptions.IgnoreCase); + foreach (Match t in trippleLetters) + { + stripMultiplierWord = stripMultiplierWord.Replace(t.Value, ""); + tempScore += this.calc_score(t.Value) * 3; + } } + private static string _checkWordMultiplier(string word, out int trippleWord, out int doubleWord) + { + trippleWord = Regex.Count(word, $"^\\[[a-z{{}}]{{2,}}\\]$", RegexOptions.IgnoreCase); + doubleWord = Regex.Count(word, $"^{{[a-z\\[\\]]{{2,}}}}$", RegexOptions.IgnoreCase); + if (doubleWord != 0 || trippleWord != 0) + { + // If word has a multiplier, remove braces/bracets at edges + word = word[1..(word.Length - 1)]; + } + // return word without braces/brackets... + return word; + } + + private int calc_score(string word) + { + var score_1_matchCount = Regex.Count(word, "(A|E|I|O|U|L|N|R|S|T)", RegexOptions.IgnoreCase); + var score_2_matchCount = Regex.Count(word, "(D|G)", RegexOptions.IgnoreCase); + var score_3_matchCount = Regex.Count(word, "(B|C|M|P)", RegexOptions.IgnoreCase); + var score_4_matchCount = Regex.Count(word, "(F|H|V|W|Y)", RegexOptions.IgnoreCase); + var score_5_matchCount = Regex.Count(word, "(K)", RegexOptions.IgnoreCase); + var score_8_matchCount = Regex.Count(word, "(J|X)", RegexOptions.IgnoreCase); + var score_10_matchCount = Regex.Count(word, "(Q|Z)", RegexOptions.IgnoreCase); + + return score_1_matchCount * 1 + + score_2_matchCount * 2 + + score_3_matchCount * 3 + + score_4_matchCount * 4 + + score_5_matchCount * 5 + + score_8_matchCount * 8 + + score_10_matchCount * 10; + } + public void setWord(string word) + { + // Set default value, expect failure as default + this._score = 0; + + // Handle edgecase + if (word.Length == 0) + return; + + int trippleWord, doubleWord; + word = _checkWordMultiplier(word, out trippleWord, out doubleWord); + + int tempScore = 0; + string stripMultiplierWord = word; + + // identify trippleLetters, doubleletters, remove occurances from stripMultiplierWord then sum to tempScore + findAndCalc_trippleLetters(word, ref tempScore, ref stripMultiplierWord); + findAndCalc_doubleLetters(word, ref tempScore, ref stripMultiplierWord); + + + // if stripMultiplierWord contains anything but letters, then the input word was invalid + var invalidInputCount = Regex.Count(stripMultiplierWord, "([^a-z])", RegexOptions.IgnoreCase); + if (invalidInputCount != 0) + return; + + // calculate score for the remaining letters and add to tempScore + tempScore += calc_score(stripMultiplierWord); + + // Finally add any word multipliers + if (doubleWord != 0) + tempScore *= 2; + else if (trippleWord != 0) + tempScore *= 3; + + + // Apply score + this._score = tempScore; + } public int score() { //TODO: score calculation code goes here - throw new NotImplementedException(); //TODO: Remove this line when the code has been written + // ^ Score is now calculated when Scrabble instance is created + return this._score; + } } } diff --git a/csharp-scrabble-challenge.Test/CoreTests.cs b/csharp-scrabble-challenge.Test/CoreTests.cs index f42e402..7d234cc 100644 --- a/csharp-scrabble-challenge.Test/CoreTests.cs +++ b/csharp-scrabble-challenge.Test/CoreTests.cs @@ -12,9 +12,22 @@ public class CoreTests [TestCase("\n\r\t\b\f", 0)] [TestCase("a", 1)] [TestCase("f", 4)] + [TestCase("{f}", 8)] + [TestCase("[f]", 12)] [TestCase("OXyPHEnBUTaZoNE", 41)] [TestCase("quirky", 22)] [TestCase("street", 6)] + [TestCase("[{h}o1s{e}]", 0)] // error case (zero for errors) + [TestCase("{h}ous{e}", 13)] + [TestCase("[{h}ous{e}]", 39)] + [TestCase("[h}ous{e}]", 0)] //Error case (zero for errors) + [TestCase("[{h}ous{e}}]", 0)] //Error case (zero for errors) + [TestCase("[{{h}ous{e}]", 0)] //Error case (zero for errors) + [TestCase("[E}ous{E}]", 0)] //Error case (zero for errors) + [TestCase("]{E}ous{E}]", 0)] //Error case (zero for errors) + [TestCase("]{E}ous{E}[", 0)] //Error case (zero for errors) + [TestCase("[{E}ous{E}[", 0)] //Error case (zero for errors) + public void WordScoreTests(string word, int targetScore) { Assert.AreEqual(this.GetWordScore(word), targetScore); From acef98ef2212dedaa666eda0090e44dc535372dc Mon Sep 17 00:00:00 2001 From: Lowe Raivio Date: Wed, 8 Jan 2025 17:26:12 +0100 Subject: [PATCH 2/3] Fix: bug causing some new tests to fail. Added `Super Extension` --- csharp-scrabble-challenge.Main/Program.cs | 26 ++++++++++++++++++++- csharp-scrabble-challenge.Main/Scrabble.cs | 15 +++++++----- csharp-scrabble-challenge.Test/CoreTests.cs | 1 + 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Program.cs b/csharp-scrabble-challenge.Main/Program.cs index 3751555..66c27cf 100644 --- a/csharp-scrabble-challenge.Main/Program.cs +++ b/csharp-scrabble-challenge.Main/Program.cs @@ -1,2 +1,26 @@ // See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); + + + + +using csharp_scrabble_challenge.Main; + +void main() +{ + string userInput = ""; + var scrabbleApp = new Scrabble(userInput); + Console.WriteLine("Hello, Scrabbler!"); + while (userInput != "/q") + { + + Console.WriteLine("Type a word, press enter, get score. (/q to quit)"); + userInput = Console.ReadLine(); + Console.Clear(); + + scrabbleApp.setWord(userInput); + Console.WriteLine($"`{userInput}` gives: {scrabbleApp.score()} points!"); + } +} + + +main(); \ No newline at end of file diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index 576d21a..9ee5583 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -41,8 +41,8 @@ private void findAndCalc_trippleLetters(string word, ref int tempScore, ref stri private static string _checkWordMultiplier(string word, out int trippleWord, out int doubleWord) { - trippleWord = Regex.Count(word, $"^\\[[a-z{{}}]{{2,}}\\]$", RegexOptions.IgnoreCase); - doubleWord = Regex.Count(word, $"^{{[a-z\\[\\]]{{2,}}}}$", RegexOptions.IgnoreCase); + trippleWord = Regex.Count(word, $"^\\[[a-z{{}}\\]\\[]+\\]$", RegexOptions.IgnoreCase); + doubleWord = Regex.Count(word, $"^{{[a-z{{}}\\[\\]]+}}$", RegexOptions.IgnoreCase); if (doubleWord != 0 || trippleWord != 0) { // If word has a multiplier, remove braces/bracets at edges @@ -79,8 +79,7 @@ public void setWord(string word) if (word.Length == 0) return; - int trippleWord, doubleWord; - word = _checkWordMultiplier(word, out trippleWord, out doubleWord); + int tempScore = 0; string stripMultiplierWord = word; @@ -89,14 +88,18 @@ public void setWord(string word) findAndCalc_trippleLetters(word, ref tempScore, ref stripMultiplierWord); findAndCalc_doubleLetters(word, ref tempScore, ref stripMultiplierWord); + int trippleWord, doubleWord; + //word = _checkWordMultiplier(word, out trippleWord, out doubleWord); + word = _checkWordMultiplier(stripMultiplierWord, out trippleWord, out doubleWord); // if stripMultiplierWord contains anything but letters, then the input word was invalid - var invalidInputCount = Regex.Count(stripMultiplierWord, "([^a-z])", RegexOptions.IgnoreCase); + var invalidInputCount = Regex.Count(word, "([^a-z])", RegexOptions.IgnoreCase); if (invalidInputCount != 0) return; // calculate score for the remaining letters and add to tempScore - tempScore += calc_score(stripMultiplierWord); + tempScore += calc_score(word); + // Finally add any word multipliers if (doubleWord != 0) diff --git a/csharp-scrabble-challenge.Test/CoreTests.cs b/csharp-scrabble-challenge.Test/CoreTests.cs index 7d234cc..e4118c9 100644 --- a/csharp-scrabble-challenge.Test/CoreTests.cs +++ b/csharp-scrabble-challenge.Test/CoreTests.cs @@ -27,6 +27,7 @@ public class CoreTests [TestCase("]{E}ous{E}]", 0)] //Error case (zero for errors) [TestCase("]{E}ous{E}[", 0)] //Error case (zero for errors) [TestCase("[{E}ous{E}[", 0)] //Error case (zero for errors) + [TestCase("[{d}a[d]]", 33)] //Error case (zero for errors) public void WordScoreTests(string word, int targetScore) { From c408169d8867252a0e88dac804ed8925a2381d3a Mon Sep 17 00:00:00 2001 From: Lowe Raivio Date: Wed, 8 Jan 2025 17:41:54 +0100 Subject: [PATCH 3/3] FIX: Added new test that failed. Solved by changing regex to be more greedy (_checkWordMultiplier) --- csharp-scrabble-challenge.Main/Scrabble.cs | 11 ++++++----- csharp-scrabble-challenge.Test/CoreTests.cs | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index 9ee5583..1bf2f24 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -39,17 +39,18 @@ private void findAndCalc_trippleLetters(string word, ref int tempScore, ref stri } } - private static string _checkWordMultiplier(string word, out int trippleWord, out int doubleWord) + private static string _checkWordMultiplier(string in_word, out int trippleWord, out int doubleWord) { - trippleWord = Regex.Count(word, $"^\\[[a-z{{}}\\]\\[]+\\]$", RegexOptions.IgnoreCase); - doubleWord = Regex.Count(word, $"^{{[a-z{{}}\\[\\]]+}}$", RegexOptions.IgnoreCase); + trippleWord = Regex.Count(in_word, $"^\\[[a-z{{}}\\]\\[]*\\]$", RegexOptions.IgnoreCase); + doubleWord = Regex.Count(in_word, $"^{{[a-z{{}}\\[\\]]*}}$", RegexOptions.IgnoreCase); + string retWord = in_word; if (doubleWord != 0 || trippleWord != 0) { // If word has a multiplier, remove braces/bracets at edges - word = word[1..(word.Length - 1)]; + retWord = in_word[1..(in_word.Length - 1)]; } // return word without braces/brackets... - return word; + return retWord; } private int calc_score(string word) diff --git a/csharp-scrabble-challenge.Test/CoreTests.cs b/csharp-scrabble-challenge.Test/CoreTests.cs index e4118c9..0ea4db2 100644 --- a/csharp-scrabble-challenge.Test/CoreTests.cs +++ b/csharp-scrabble-challenge.Test/CoreTests.cs @@ -28,6 +28,7 @@ public class CoreTests [TestCase("]{E}ous{E}[", 0)] //Error case (zero for errors) [TestCase("[{E}ous{E}[", 0)] //Error case (zero for errors) [TestCase("[{d}a[d]]", 33)] //Error case (zero for errors) + [TestCase("[{d}[d]]", 30)] //Error case (zero for errors) public void WordScoreTests(string word, int targetScore) {