From c42fe422f6eec044533b860d06eb0a56caffb77a Mon Sep 17 00:00:00 2001 From: MHande Date: Wed, 6 Aug 2025 15:55:56 +0200 Subject: [PATCH 1/5] added comment --- csharp-scrabble-challenge.Main/Scrabble.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index c1ea013..0504e83 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -12,6 +12,7 @@ public class Scrabble public Scrabble(string word) { //TODO: do something with the word variable + // hi } public int score() From 950ba86d1fe5f77393fc61ca0fe90211caa6c7fc Mon Sep 17 00:00:00 2001 From: Mathias Handeland Date: Wed, 6 Aug 2025 18:46:23 +0200 Subject: [PATCH 2/5] finished the first part of the exercise --- csharp-scrabble-challenge.Main/Program.cs | 6 ++-- csharp-scrabble-challenge.Main/Scrabble.cs | 34 ++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Program.cs b/csharp-scrabble-challenge.Main/Program.cs index 3751555..3aeabe4 100644 --- a/csharp-scrabble-challenge.Main/Program.cs +++ b/csharp-scrabble-challenge.Main/Program.cs @@ -1,2 +1,4 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using csharp_scrabble_challenge.Main; + +Scrabble s = new Scrabble("d{o}g"); +Console.WriteLine(s.score()); // Output the score to the console \ No newline at end of file diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index 0504e83..369d912 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.Metrics; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Text; @@ -9,16 +10,39 @@ namespace csharp_scrabble_challenge.Main { public class Scrabble { + private string _word; + private readonly Dictionary _letterValues = new Dictionary + { + {'A', 1}, {'B', 3}, {'C', 3}, {'D', 2}, {'E', 1}, + {'F', 4}, {'G', 2}, {'H', 4}, {'I', 1}, {'J', 8}, + {'K', 5}, {'L', 1}, {'M', 3}, {'N', 1}, {'O', 1}, + {'P', 3}, {'Q', 10}, {'R', 1}, {'S', 1}, {'T', 1}, + {'U', 1}, {'V', 4}, {'W', 4}, {'X', 8}, {'Y', 4}, + {'Z', 10} + }; + private int _totalScore = 0; + public Scrabble(string word) { - //TODO: do something with the word variable - // hi + _word = word; } public int score() { - //TODO: score calculation code goes here - throw new NotImplementedException(); //TODO: Remove this line when the code has been written + foreach (char letter in _word.ToUpper()) + { + if (_letterValues.TryGetValue(letter, out int value)) // check if the letter exists and retrive its value + { + _totalScore += value; + } + else + { + _totalScore += 0; // Things that are not letters and not in the dict will be ignored and do not contribute to the score + } + } + + return _totalScore; } + } -} +} \ No newline at end of file From b7f7aa2629a98f2fb1116cc0864d59117d471adc Mon Sep 17 00:00:00 2001 From: Mathias Handeland Date: Wed, 6 Aug 2025 19:11:38 +0200 Subject: [PATCH 3/5] started on extended task --- csharp-scrabble-challenge.Main/Scrabble.cs | 39 +++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index 369d912..e186bb5 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -20,29 +20,44 @@ public class Scrabble {'U', 1}, {'V', 4}, {'W', 4}, {'X', 8}, {'Y', 4}, {'Z', 10} }; - private int _totalScore = 0; public Scrabble(string word) - { + { _word = word; } public int score() { - foreach (char letter in _word.ToUpper()) + int _totalScore = 0; + int index = 0; + + while (index < _word.Length) { - if (_letterValues.TryGetValue(letter, out int value)) // check if the letter exists and retrive its value + char currentChar = _word[index]; + + if (currentChar == '{' || currentChar == '[') { - _totalScore += value; + int multiplier = (currentChar == '{') ? 2 : 3; + index++; // Move past the opening brace or bracket to the letter that has double or triple score + + // check that the character after the letter inside brackets is also a closing bracket + if (index < _word.Length && (_word[index + 1] == '}' || _word[index + 1] == ']')) + { + // Get the letter and its score + if (_letterValues.TryGetValue(currentChar, out int baseValue)) + { + _totalScore += baseValue * multiplier; + } + + } + index += 2; // Move past the letter and the closing brace or bracket + } - else + else if (_letterValues.TryGetValue(currentChar, out int value)) { - _totalScore += 0; // Things that are not letters and not in the dict will be ignored and do not contribute to the score + _totalScore += value; } + index++; } - return _totalScore; - } - - } -} \ No newline at end of file + } \ No newline at end of file From f322a30d9204d6e0bf2c4b028a9293ee5911ac7e Mon Sep 17 00:00:00 2001 From: Mathias Handeland Date: Wed, 6 Aug 2025 19:21:59 +0200 Subject: [PATCH 4/5] passed 3 first tests --- csharp-scrabble-challenge.Main/Scrabble.cs | 25 +++++++++++++------ .../ExtensionTests.cs | 25 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index e186bb5..6e9a52b 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -38,26 +38,35 @@ public int score() if (currentChar == '{' || currentChar == '[') { int multiplier = (currentChar == '{') ? 2 : 3; - index++; // Move past the opening brace or bracket to the letter that has double or triple score + index++; // Move to the letter inside the brackets // check that the character after the letter inside brackets is also a closing bracket - if (index < _word.Length && (_word[index + 1] == '}' || _word[index + 1] == ']')) + if (index < _word.Length && (index + 1 < _word.Length) && (_word[index + 1] == '}' || _word[index + 1] == ']')) { - // Get the letter and its score - if (_letterValues.TryGetValue(currentChar, out int baseValue)) + // retrieve the letter inside and its score + char letter = Char.ToUpper(_word[index]); + if (_letterValues.TryGetValue(letter, out int baseValue)) { _totalScore += baseValue * multiplier; } } + index += 2; // Move past the letter and the closing brace or bracket } - else if (_letterValues.TryGetValue(currentChar, out int value)) + else { - _totalScore += value; + char letter = Char.ToUpper(_word[index]); + if (_letterValues.TryGetValue(letter, out int value)) + { + _totalScore += value; + } + + index++; // Move to the next character } - index++; } return _totalScore; - } \ No newline at end of file + } + } +} \ No newline at end of file diff --git a/csharp-scrabble-challenge.Test/ExtensionTests.cs b/csharp-scrabble-challenge.Test/ExtensionTests.cs index 8eb37dc..6d11bda 100644 --- a/csharp-scrabble-challenge.Test/ExtensionTests.cs +++ b/csharp-scrabble-challenge.Test/ExtensionTests.cs @@ -12,15 +12,24 @@ namespace csharp_scrabble_challenge.Test public class ExtensionTests { - [TestCase("{street}", 12)] //extension double word - [TestCase("[street]", 18)] //extension triple word - [TestCase("{quirky}", 44)] //extension double word - [TestCase("[quirky]", 66)] //extension triple word - [TestCase("{OXyPHEnBUTaZoNE}", 82)] - [TestCase("[OXyPHEnBUTaZoNE]", 123)] - public void ExtendedCriteriaTests(string word, int targetScore) + [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("", 0)] + [TestCase(" ", 0)] + [TestCase(" \t\n", 0)] + [TestCase("\n\r\t\b\f", 0)] + [TestCase("a", 1)] + [TestCase("f", 4)] + [TestCase("OXyPHEnBUTaZoNE", 41)] + [TestCase("quirky", 22)] + [TestCase("street", 6)] + public void WordScoreTests(string word, int targetScore) { - Assert.AreEqual(this.GetWordScore(word), targetScore); + Scrabble scrabble = new Scrabble(word); + + Assert.That(scrabble.score(), Is.EqualTo(targetScore)); } private int GetWordScore(string word) => new Scrabble(word).score(); From 587c5437b7a05cc7270375ade7bd963c996ecb5c Mon Sep 17 00:00:00 2001 From: Mathias Handeland Date: Thu, 7 Aug 2025 10:35:27 +0200 Subject: [PATCH 5/5] Finished implementing double and triple letter score logic --- csharp-scrabble-challenge.Main/Program.cs | 2 +- csharp-scrabble-challenge.Main/Scrabble.cs | 93 +++++++++++++++++++--- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/csharp-scrabble-challenge.Main/Program.cs b/csharp-scrabble-challenge.Main/Program.cs index 3aeabe4..aa523cc 100644 --- a/csharp-scrabble-challenge.Main/Program.cs +++ b/csharp-scrabble-challenge.Main/Program.cs @@ -1,4 +1,4 @@ using csharp_scrabble_challenge.Main; -Scrabble s = new Scrabble("d{o}g"); +Scrabble s = new Scrabble("[{h}ous{e}]"); Console.WriteLine(s.score()); // Output the score to the console \ No newline at end of file diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index 6e9a52b..0b25547 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -20,6 +20,8 @@ public class Scrabble {'U', 1}, {'V', 4}, {'W', 4}, {'X', 8}, {'Y', 4}, {'Z', 10} }; + private List _validBrackets = new List { '{', '}', '[', ']' }; + private Stack _bracketStack = new Stack(); public Scrabble(string word) { @@ -28,45 +30,112 @@ public Scrabble(string word) public int score() { - int _totalScore = 0; + int totalScore = 0; int index = 0; + // check if word is valid + if (!IsValidWord(_word)) + { + return 0; // Invalid word, return 0 as total score + } + while (index < _word.Length) { char currentChar = _word[index]; - if (currentChar == '{' || currentChar == '[') + if (currentChar == '{') { - int multiplier = (currentChar == '{') ? 2 : 3; + + int multiplier = 2; // this is potentially a double score word + index++; // Move past the curly bracket to the letter inside the brackets + + // check that the character after the letter inside brackets is the correct closing bracket + if ((index + 1 < _word.Length) && (_word[index + 1] == '}')) + { + // retrieve the letter inside and its base value score + char letter = Char.ToUpper(_word[index]); + if (_letterValues.TryGetValue(letter, out int baseValue)) + { + totalScore += (baseValue * multiplier); + } + index += 2; // move past the letter and the closing brace or bracket + } + + continue; // move to next iteration since no closing bracket was found + } + + else if (currentChar == '[') + { + int multiplier = 3; // this is potentially a triple score word index++; // Move to the letter inside the brackets - // check that the character after the letter inside brackets is also a closing bracket - if (index < _word.Length && (index + 1 < _word.Length) && (_word[index + 1] == '}' || _word[index + 1] == ']')) + // check that the character after the letter inside brackets is also the right closing bracket + if ((index + 1 < _word.Length) && (_word[index + 1] == ']')) { - // retrieve the letter inside and its score + // retrieve the letter inside and its base value score char letter = Char.ToUpper(_word[index]); if (_letterValues.TryGetValue(letter, out int baseValue)) { - _totalScore += baseValue * multiplier; + totalScore += baseValue * multiplier; } + index += 2; // move past the letter and the closing brace or bracket } - index += 2; // Move past the letter and the closing brace or bracket - + continue; // move to next iteration since no closing bracket was found } + else { char letter = Char.ToUpper(_word[index]); if (_letterValues.TryGetValue(letter, out int value)) { - _totalScore += value; + totalScore += value; } - index++; // Move to the next character + index++; // Move to the next character in the word } } - return _totalScore; + return totalScore; + } + + private bool IsValidWord(string word) + { + Stack bracketStack = new Stack(); + + // base check: if a character is not present in dictionary or a valid bracket, we return 0 + foreach (char c in word) + { + if (!char.IsLetter(c) && !_validBrackets.Contains(c)) + { + return false; // Invalid character found + } + } + + // check for balanced brackets + foreach (char c in word) + { + if (c == '{' || c == '[') + { + bracketStack.Push(c); + } + else if (c == '}' || c == ']') + { + if (bracketStack.Count == 0) + { + return false; + } + char openingBracket = bracketStack.Pop(); + if ((c == '}' && openingBracket != '{') || + (c == ']' && openingBracket != '[')) + { + return false; + } + } + } + + // If stack is empty, all brackets are balanced + return bracketStack.Count == 0; } } } \ No newline at end of file