diff --git a/csharp-scrabble-challenge.Main/Program.cs b/csharp-scrabble-challenge.Main/Program.cs index 3751555..83bb555 100644 --- a/csharp-scrabble-challenge.Main/Program.cs +++ b/csharp-scrabble-challenge.Main/Program.cs @@ -1,2 +1,8 @@ // See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using csharp_scrabble_challenge.Main; +//string a = "1String"; +Scrabble s = new Scrabble("[OXyPHEnBUTaZoNE]"); + +Console.WriteLine(s.score()); + + diff --git a/csharp-scrabble-challenge.Main/Scrabble.cs b/csharp-scrabble-challenge.Main/Scrabble.cs index c1ea013..5758863 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.Dynamic; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Text; @@ -9,15 +10,280 @@ namespace csharp_scrabble_challenge.Main { public class Scrabble { + string _word { get; set; } + Dictionary, int> _letterScore { get; set; } public Scrabble(string word) - { + { //TODO: do something with the word variable - } + _word = word; + + List group1 = new List + { + 'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T', + }; + + List group2 = new List + { + 'D', 'G' + }; + + List group3 = new List + { + 'B', 'C', 'M', 'P' + }; + + List group4 = new List + { + 'F', 'H', 'V', 'W', 'Y' + }; + + List group5 = new List + { + 'K' + }; + + List group6 = new List + { + 'J', 'X' + }; + + List group7 = new List + { + 'Q', 'Z' + }; + + _letterScore = new Dictionary, int> + { + {group1, 1}, {group2, 2 }, {group3, 3 }, {group4, 4}, {group5, 5 }, {group6, 8 }, {group7, 10} + }; + } public int score() { - //TODO: score calculation code goes here - throw new NotImplementedException(); //TODO: Remove this line when the code has been written + Tuple word_evaluation = Evaluate(_word, "", "", 0); //Returns a tuple of (score, rest) + if (word_evaluation.Item2.Length > 0) + { + // Only legal rest is a score-double of a word: "{}" + if (word_evaluation.Item2 == "{}") + { + return word_evaluation.Item1 * 2; + } + else if (word_evaluation.Item2 == "[]") + { + return word_evaluation.Item1 * 3; + } + + return 0; + } + + return word_evaluation.Item1; + } + + // Splits the string into parts that can be scored individually + public Tuple Evaluate(string to_evaluate, string currently_evaluating, string rest, int currentScore) + { + Console.WriteLine(currentScore); + if (to_evaluate.Length == 0) + { + return new Tuple(currentScore, rest); + } + char next_char = to_evaluate[0]; + List starter_brackets = new List + { + '{', '[' + }; + List end_brackets = new List + { + '}', ']' + }; + + //init calculation variable + Tuple calculation = Tuple.Create(0, ""); + + + if (!char.IsLetter(next_char)) + { + //New part to evaluate + if (starter_brackets.Contains(next_char)) + { + // We start at a new evaluation part without completing the last + if (currently_evaluating.Length > 0) + { + rest += currently_evaluating; + currently_evaluating = ""; + } + return Evaluate(to_evaluate.Substring(1), currently_evaluating + next_char, rest, currentScore); + } + + //Currently_evaluating part is ready for score calculation + else if (end_brackets.Contains(next_char)) + { + if (currently_evaluating.Length > 0) + { + currently_evaluating += next_char; + calculation = Calculate_score(currently_evaluating); //Tuple of (score, rest) + + return Evaluate(to_evaluate.Substring(1), "", rest += calculation.Item2, currentScore += calculation.Item1); + } + // The bracket is just added to the rest if the currently_evaluating part is empty (nothing to evaluate) + return Evaluate(to_evaluate.Substring(1), "", rest += next_char, currentScore); + } + + } + if (char.IsLetter(next_char)) + { + next_char = char.ToUpper(next_char); + if (currently_evaluating.Length == 0) //Part complete: Calculate now + { + calculation = Calculate_score(currently_evaluating + next_char); // Tuple of (score, rest) + + return Evaluate(to_evaluate.Substring(1), "", rest + calculation.Item2, currentScore += calculation.Item1); + } + // Add letter to currently_evaluating so it can be evaluated later + return Evaluate(to_evaluate.Substring(1), currently_evaluating += next_char, rest, currentScore); + } + + // This part should never be reached, atleast within the rules + return new Tuple(0, string.Empty); + } + + //Calculates the score of an substring (a part) + public Tuple Calculate_score(string part) + { + int result = 0; + + if (part.Length == 1) + { + return new Tuple(_letterScore.Where(x => x.Key.Contains(part[0])).FirstOrDefault().Value, ""); + } + if (part.Length > 1) + { + int scaling = 1; + if (part.First() == '{' && part.Last() == '}') + { + return new Tuple (sum_letter_scores(part)*2, ""); + } + + else if (part.First() == '[' && part.Last() == ']') + { + return new Tuple(sum_letter_scores(part)*3, ""); + } + + + + } + + return new Tuple (result, part); + + } + + private int sum_letter_scores(string substring) + { + int score = 0; + for (int i = 1; i < substring.Length; i++) + { + score += _letterScore.Where(x => x.Key.Contains(substring[i])).FirstOrDefault().Value; + } + return score; + } + + + + + + + + + + + + + + + + + + + + + + + public int mscore() + { + if (_word.Length == 0) + { + return 0; + } + int totalScore = 0; + int nextLetterScore = 0; + + //init wordscaling + int wordscaling = 1; + if (_word.First() == '{' && _word.Last() == '}') + { + wordscaling = 2; + _word = _word.Substring(0, _word.Length - 2); + } + + else if (_word.First() == '[' && _word.Last() == ']') + { + wordscaling = 3; + _word = _word.Substring(0, _word.Length - 2); + + } + + + for (int i = 0; i < _word.Length; i++) + { + nextLetterScore = 0; + char bigC = char.ToUpper(_word[i]); + + + if (char.IsLetter(bigC)) + { + nextLetterScore = _letterScore.Where(x => x.Key.Contains(bigC)).FirstOrDefault().Value; + } + else if (bigC == '{') + { + if ((_word.Length > i + 2)) + { + if (_word[i+2] == '}') + { + bigC = char.ToUpper(_word[i+1]); + nextLetterScore = _letterScore.Where(x => x.Key.Contains(bigC)).FirstOrDefault().Value * 2; + } + } + + } + + else if (bigC == '[') + { + if ((_word.Length > i + 2)) + { + if (_word[i + 2] == ']') + { + bigC = char.ToUpper(_word[i + 1]); + nextLetterScore = _letterScore.Where(x => x.Key.Contains(bigC)).FirstOrDefault().Value * 3; + } + } + } + + else + { + return 0; + } + + totalScore += nextLetterScore; + } + + return totalScore * wordscaling; + } + + + + } + + } diff --git a/csharp-scrabble-challenge.Test/ExtensionTests.cs b/csharp-scrabble-challenge.Test/ExtensionTests.cs index 8eb37dc..ee037bf 100644 --- a/csharp-scrabble-challenge.Test/ExtensionTests.cs +++ b/csharp-scrabble-challenge.Test/ExtensionTests.cs @@ -11,7 +11,10 @@ namespace csharp_scrabble_challenge.Test [TestFixture] public class ExtensionTests { - + [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("{street}", 12)] //extension double word [TestCase("[street]", 18)] //extension triple word [TestCase("{quirky}", 44)] //extension double word