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 c1ea013..1bf2f24 100644 --- a/csharp-scrabble-challenge.Main/Scrabble.cs +++ b/csharp-scrabble-challenge.Main/Scrabble.cs @@ -4,20 +4,120 @@ 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 in_word, out int trippleWord, out int doubleWord) + { + 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 + retWord = in_word[1..(in_word.Length - 1)]; + } + // return word without braces/brackets... + return retWord; + } + + 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 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); + + 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(word, "([^a-z])", RegexOptions.IgnoreCase); + if (invalidInputCount != 0) + return; + + // calculate score for the remaining letters and add to tempScore + tempScore += calc_score(word); + + + // 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..0ea4db2 100644 --- a/csharp-scrabble-challenge.Test/CoreTests.cs +++ b/csharp-scrabble-challenge.Test/CoreTests.cs @@ -12,9 +12,24 @@ 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) + [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) { Assert.AreEqual(this.GetWordScore(word), targetScore);