From e219a92850e55872f45d78f89aacdf0c66a29375 Mon Sep 17 00:00:00 2001 From: shyye Date: Tue, 13 Aug 2024 17:20:15 +0200 Subject: [PATCH 1/6] Solve Scrabble. --- src/main/java/com/booleanuk/Scrabble.java | 38 +++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index 88108a8..3ae6db2 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -1,12 +1,44 @@ package com.booleanuk; +import java.util.Arrays; +import java.util.List; + public class Scrabble { - public Scrabble(String word) { + private int score = 0; + private String word; + // TODO: Check meaning of final + private final List onePoints = Arrays.asList('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'); + private final List twoPoints = Arrays.asList('D', 'G'); + private final List threePoints = Arrays.asList('B', 'C', 'M', 'P'); + private final List fourPoints = Arrays.asList('F', 'H', 'V', 'W', 'Y'); + private final List fivePoints = Arrays.asList('K'); + private final List eightPoints = Arrays.asList('J', 'X'); + private final List tenPoints = Arrays.asList('Q', 'Z'); + public Scrabble(String word) { + this.word = word.toUpperCase(); } public int score() { - return -1; - } + // Add points to score + for (char character : this.word.toCharArray()) { + if(this.onePoints.contains(character)) { + this.score += 1; + } else if (this.twoPoints.contains(character)) { + this.score += 2; + } else if (this.threePoints.contains(character)) { + this.score += 3; + } else if (this.fourPoints.contains(character)) { + this.score += 4; + } else if (this.fivePoints.contains(character)) { + this.score += 5; + } else if (eightPoints.contains(character)) { + this.score += 8; + } else if (tenPoints.contains(character)) { + this.score += 10; + } + } + return this.score; + } } From cb5e53d76b93b06416650f8fa263feda63db7e35 Mon Sep 17 00:00:00 2001 From: shyye Date: Wed, 14 Aug 2024 21:24:45 +0200 Subject: [PATCH 2/6] Add Extension part, some errors remain --- src/main/java/com/booleanuk/Scrabble.java | 121 ++++++++++++++++++---- 1 file changed, 102 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index 3ae6db2..97cb13d 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -1,11 +1,14 @@ package com.booleanuk; -import java.util.Arrays; -import java.util.List; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Scrabble { private int score = 0; private String word; + + private HashMap pointsMap = new HashMap<>(); // TODO: Check meaning of final private final List onePoints = Arrays.asList('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'); private final List twoPoints = Arrays.asList('D', 'G'); @@ -17,28 +20,108 @@ public class Scrabble { public Scrabble(String word) { this.word = word.toUpperCase(); + + // TODO: Is there a better way? + // Initialize pointsMap for the letters and the corresponding points + onePoints.forEach( letter -> pointsMap.put(letter, 1)); + twoPoints.forEach( letter -> pointsMap.put(letter, 2)); + threePoints.forEach( letter -> pointsMap.put(letter, 3)); + fourPoints.forEach( letter -> pointsMap.put(letter, 4)); + fivePoints.forEach( letter -> pointsMap.put(letter, 5)); + eightPoints.forEach( letter -> pointsMap.put(letter, 8)); + tenPoints.forEach( letter -> pointsMap.put(letter, 10)); + } + + public ArrayList extractLettersWithRegex(String word, String regexPattern) { + // TODO: Should I change to ordinary list to save memory? With just two elements. + ArrayList output = new ArrayList<>(); + + Pattern pattern = Pattern.compile(regexPattern); + Matcher matcher = pattern.matcher(word); + + boolean found = false; + while (matcher.find()) { + System.out.printf("I found the text" + + " \"%s\" starting at " + + "index %d and ending at index %d.%n", + matcher.group(), + matcher.start(), + matcher.end()); + found = true; + //output += matcher.group(); + output.add(matcher.start()); + output.add(matcher.end()); + } + if(!found){ + System.out.printf("No match found.%n"); + } + System.out.println("text: " + output); + return output; + } + + public String extractStringWithRegex(String word, String regexPattern) { + + // Reference: https://docs.oracle.com/javase/tutorial/essential/regex/test_harness.html + String output = ""; + Pattern pattern = Pattern.compile(regexPattern); + Matcher matcher = pattern.matcher(word); + + boolean found = false; + while (matcher.find()) { + System.out.printf("I found the text" + + " \"%s\" starting at " + + "index %d and ending at index %d.%n", + matcher.group(), + matcher.start(), + matcher.end()); + found = true; + output += matcher.group(); + } + if(!found){ + System.out.printf("No match found.%n"); + } + System.out.println("text: " + output); + return output; } public int score() { - // Add points to score - for (char character : this.word.toCharArray()) { - if(this.onePoints.contains(character)) { - this.score += 1; - } else if (this.twoPoints.contains(character)) { - this.score += 2; - } else if (this.threePoints.contains(character)) { - this.score += 3; - } else if (this.fourPoints.contains(character)) { - this.score += 4; - } else if (this.fivePoints.contains(character)) { - this.score += 5; - } else if (eightPoints.contains(character)) { - this.score += 8; - } else if (tenPoints.contains(character)) { - this.score += 10; - } + // Regex patterns + String regexDouble = "\\{.*?\\}"; + String regexTriple = "\\[.*?\\]"; + String regexOnlyLetters = "[a-zA-Z]+"; + String regexNotLetters = "[^a-zA-Z]+"; + String regexNotLettersButBrackets = "[^a-zA-Z\\{\\}\\[\\]]+"; + + // Check if word has invalid tokens + Pattern pattern = Pattern.compile(regexNotLettersButBrackets); + Matcher matcher = pattern.matcher(this.word); + boolean invalidTokens = matcher.find(); + if (invalidTokens) { + return this.score; + } + + // Calculate double points + String doubleLetters = extractStringWithRegex(this.word, regexDouble); + doubleLetters = extractStringWithRegex(doubleLetters, regexOnlyLetters); // Extract only letters, escape brackets + for (char letter : doubleLetters.toCharArray()) { + this.score += pointsMap.get(letter) * 2; } + + // Calculate triple points + String tripleLetters = extractStringWithRegex(this.word, regexTriple); + tripleLetters = extractStringWithRegex(tripleLetters, regexOnlyLetters); // Extract only letters, escape brackets + for (char letter : tripleLetters.toCharArray()) { + this.score += pointsMap.get(letter) * 3; + } + + // Calcualte ordinary/base points + String baseLetters = this.word.replaceAll(regexDouble, ""); // Remove double points + baseLetters = baseLetters.replaceAll(regexTriple, ""); // Remove triple points + for (char letter : baseLetters.toCharArray()) { + this.score += pointsMap.get(letter); + } + return this.score; } } From 8bff7f052e2f6181a5af01bd9bbe39cd1907a26f Mon Sep 17 00:00:00 2001 From: shyye Date: Sat, 17 Aug 2024 09:14:56 +0200 Subject: [PATCH 3/6] Extension part in progress --- src/main/java/com/booleanuk/Scrabble.java | 165 ++++++++++++++++++---- 1 file changed, 136 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index 97cb13d..7513c9e 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -84,44 +84,151 @@ public String extractStringWithRegex(String word, String regexPattern) { return output; } + public boolean extractStringWithRegexBoolean(String word, String regexPattern) { + + // Reference: https://docs.oracle.com/javase/tutorial/essential/regex/test_harness.html + Pattern pattern = Pattern.compile(regexPattern); + Matcher matcher = pattern.matcher(word); + return matcher.find(); + } + public int score() { // Regex patterns + // Regex tips https://regexr.com/ String regexDouble = "\\{.*?\\}"; String regexTriple = "\\[.*?\\]"; - String regexOnlyLetters = "[a-zA-Z]+"; + String regexNotValidDouble = "\\}.*?\\{|\\{.*?\\]"; + String regexNotValidTriple = "\\].*?\\[|\\[.*?\\}"; +// String regexTriple = "\\[[^\\[].*?\\]"; + String regexLetters = "[a-zA-Z]+"; + String regexWordsWithSpecialCharacters = "[^a-zA-Z]+"; // Can include letters, special charaacters, brackets +// String regexOnlyLetters = "(?=[a-zA-Z]+)(?=[^a-zA-Z]+)"; // WRONG String regexNotLetters = "[^a-zA-Z]+"; String regexNotLettersButBrackets = "[^a-zA-Z\\{\\}\\[\\]]+"; + String regexInvalidBracketsLeftSquare = "\\[{1}"; // Check if only appear once + String regexInvalidBracketsLeftCurly = "\\{{1}"; + String regexInvalidBracketsRightSquare = "\\]{1}"; + String regexInvalidBracketsRightCurly = "\\}{ 1}"; + // TODO check if can replace with + String regexInvalidSingleBracket = "(\\{|\\})(\\[|\\]){1}"; + String regexDuplicationOfLetters = "(\\w)\\1+"; // A sequence of the same letter e.g. "ll" in he{ll}o + + boolean isDouble = extractStringWithRegexBoolean(this.word, regexDouble); + boolean isTriple = extractStringWithRegexBoolean(this.word, regexTriple); + boolean isOnlyLetters = !extractStringWithRegexBoolean(this.word, regexWordsWithSpecialCharacters); // Is only letters if it is NOT a word with mixed letters, special characters and brackets + + if (isDouble || isTriple || isOnlyLetters) { + + if (isDouble) { + // Extract double letters, brackets included + String doubleLetters = extractStringWithRegex(this.word, regexDouble); + + // Check for invalid duplication of letters inside brakcets, e.g. he{ll}o + boolean invalidDuplication = extractStringWithRegexBoolean(doubleLetters, regexDuplicationOfLetters); + if (invalidDuplication) { + return 0; + } + + // Extract only letters, escape brackets + doubleLetters = extractStringWithRegex(doubleLetters, regexLetters); + // Calculate double points + for (char letter : doubleLetters.toCharArray()) { + this.score += pointsMap.get(letter) * 2; + } + } + + if (isTriple) { + // Extract triple letters, brackets included + String tripleLetters = extractStringWithRegex(this.word, regexTriple); + + // Check for invalid duplication of letters inside brakcets, e.g. he{ll}o + boolean invalidDuplication = extractStringWithRegexBoolean(tripleLetters, regexDuplicationOfLetters); + if (invalidDuplication) { + return 0; + } + + // Extract only letters, escape brackets + tripleLetters = extractStringWithRegex(tripleLetters, regexLetters); + // Calculate triple points + for (char letter : tripleLetters.toCharArray()) { + this.score += pointsMap.get(letter) * 3; + } + } + + // Calculate ordinary/base points + String baseLetters = this.word.replaceAll(regexDouble, ""); // Remove double points + baseLetters = baseLetters.replaceAll(regexTriple, ""); // Remove triple points + for (char letter : baseLetters.toCharArray()) { + this.score += pointsMap.get(letter); + } - // Check if word has invalid tokens - Pattern pattern = Pattern.compile(regexNotLettersButBrackets); - Matcher matcher = pattern.matcher(this.word); - boolean invalidTokens = matcher.find(); - if (invalidTokens) { return this.score; } - - // Calculate double points - String doubleLetters = extractStringWithRegex(this.word, regexDouble); - doubleLetters = extractStringWithRegex(doubleLetters, regexOnlyLetters); // Extract only letters, escape brackets - for (char letter : doubleLetters.toCharArray()) { - this.score += pointsMap.get(letter) * 2; - } - - // Calculate triple points - String tripleLetters = extractStringWithRegex(this.word, regexTriple); - tripleLetters = extractStringWithRegex(tripleLetters, regexOnlyLetters); // Extract only letters, escape brackets - for (char letter : tripleLetters.toCharArray()) { - this.score += pointsMap.get(letter) * 3; - } - - // Calcualte ordinary/base points - String baseLetters = this.word.replaceAll(regexDouble, ""); // Remove double points - baseLetters = baseLetters.replaceAll(regexTriple, ""); // Remove triple points - for (char letter : baseLetters.toCharArray()) { - this.score += pointsMap.get(letter); - } - - return this.score; + return 0; + + + // Check invalid brackets +// boolean invalidDouble = extractStringWithRegexBoolean(this.word, regexNotValidDouble); +// boolean invalidTripel = extractStringWithRegexBoolean(this.word, regexNotValidTriple); +// if (invalidDouble || invalidTripel) { +// return this.score; +// } + + // Check if there is only one occurence of { [ ] or }, with the help of an XOR gate (exclusive or) +// boolean invalidBracketLeftSquare = extractStringWithRegexBoolean(this.word, regexInvalidBracketsLeftSquare); +// boolean invalidBracketLeftCurly = extractStringWithRegexBoolean(this.word, regexInvalidBracketsLeftCurly); +// boolean invalidBracketRightSquare = extractStringWithRegexBoolean(this.word, regexInvalidBracketsRightSquare); +// boolean invalidBracketRightCurly = extractStringWithRegexBoolean(this.word, regexInvalidBracketsRightCurly); +// if (invalidBracketLeftSquare ^ invalidBracketRightSquare) { +// return this.score; +// } +// if (invalidBracketLeftCurly ^ invalidBracketRightCurly) { +// return this.score; +// } + + // Check invalid when there is only one single bracket +// boolean invalidSingleBracket = extractStringWithRegexBoolean(this.word, regexInvalidSingleBracket); +// if (invalidSingleBracket) { +// return this.score; +// } +// +// // Check if word has invalid tokens +// boolean invalidTokens = extractStringWithRegexBoolean(this.word, regexNotLettersButBrackets); +// if (invalidTokens) { +// return 0; +// } +// +// // Invalid double letters in brackets e.g. "he{ll}o +// boolean invalidDoubleLettersInsideBrackets; +// +// // Double points +// String doubleLetters = extractStringWithRegex(this.word, regexDouble); +// // Check if invalid +// invalidDoubleLettersInsideBrackets = extractStringWithRegexBoolean(doubleLetters, regexSameLetterSequence); +// if (invalidDoubleLettersInsideBrackets) { +// return this.score; +// } +// // Calculate double points +// doubleLetters = extractStringWithRegex(doubleLetters, regexOnlyLetters); // Extract only letters, escape brackets +// for (char letter : doubleLetters.toCharArray()) { +// this.score += pointsMap.get(letter) * 2; +// } +// +// // Calculate triple points +// String tripleLetters = extractStringWithRegex(this.word, regexTriple); +// tripleLetters = extractStringWithRegex(tripleLetters, regexOnlyLetters); // Extract only letters, escape brackets +// for (char letter : tripleLetters.toCharArray()) { +// this.score += pointsMap.get(letter) * 3; +// } +// +// // Calcualte ordinary/base points +// String baseLetters = this.word.replaceAll(regexDouble, ""); // Remove double points +// baseLetters = baseLetters.replaceAll(regexTriple, ""); // Remove triple points +// for (char letter : baseLetters.toCharArray()) { +// this.score += pointsMap.get(letter); +// } + +// return this.score; } } From 6405936c8c93bdfcba033631c6889349e935ebf1 Mon Sep 17 00:00:00 2001 From: shyye Date: Sat, 17 Aug 2024 09:48:21 +0200 Subject: [PATCH 4/6] Extension part in progress --- src/main/java/com/booleanuk/Scrabble.java | 29 ++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index 7513c9e..eec3ace 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -109,7 +109,19 @@ public int score() { String regexInvalidBracketsLeftSquare = "\\[{1}"; // Check if only appear once String regexInvalidBracketsLeftCurly = "\\{{1}"; String regexInvalidBracketsRightSquare = "\\]{1}"; - String regexInvalidBracketsRightCurly = "\\}{ 1}"; + String regexInvalidBracketsRightCurly = "\\}{1}"; + + + + // Check for single occurrence of single bracket + String regexLeftSquareBracket = "\\[{1}"; + String regexRightSquareBracket = "\\]{1}"; + String regexLeftCurlyBracket = "\\{{1}"; + String regexRightCurlyBracket = "\\}{1}"; + + + + // TODO check if can replace with String regexInvalidSingleBracket = "(\\{|\\})(\\[|\\]){1}"; String regexDuplicationOfLetters = "(\\w)\\1+"; // A sequence of the same letter e.g. "ll" in he{ll}o @@ -130,6 +142,13 @@ public int score() { return 0; } + // Check for invalid single square brackets: if one but not both appear, with XOR (exclusive or) + boolean leftBracket = extractStringWithRegexBoolean(doubleLetters, regexLeftSquareBracket); + boolean rightBracket = extractStringWithRegexBoolean(doubleLetters, regexRightSquareBracket); + if (leftBracket ^ rightBracket) { + return 0; + } + // Extract only letters, escape brackets doubleLetters = extractStringWithRegex(doubleLetters, regexLetters); // Calculate double points @@ -148,6 +167,14 @@ public int score() { return 0; } + // TODO: Refactor duplicate code + // Check for invalid single curly brackets: if one but not both appear, with XOR (exclusive or) + boolean leftBracket = extractStringWithRegexBoolean(tripleLetters, regexLeftCurlyBracket); + boolean rightBracket = extractStringWithRegexBoolean(tripleLetters, regexRightCurlyBracket); + if (leftBracket ^ rightBracket) { + return 0; + } + // Extract only letters, escape brackets tripleLetters = extractStringWithRegex(tripleLetters, regexLetters); // Calculate triple points From 59aaa27d46b17ddd17d98add553d2f25bc7eec45 Mon Sep 17 00:00:00 2001 From: shyye Date: Sat, 17 Aug 2024 10:12:22 +0200 Subject: [PATCH 5/6] Extension part before refactor calculatePoints --- src/main/java/com/booleanuk/Scrabble.java | 40 ++++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index eec3ace..2b7ec53 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -7,6 +7,7 @@ public class Scrabble { private int score = 0; private String word; + private String regexLetters; private HashMap pointsMap = new HashMap<>(); // TODO: Check meaning of final @@ -30,6 +31,9 @@ public Scrabble(String word) { fivePoints.forEach( letter -> pointsMap.put(letter, 5)); eightPoints.forEach( letter -> pointsMap.put(letter, 8)); tenPoints.forEach( letter -> pointsMap.put(letter, 10)); + + // Regex expressions + this.regexLetters = "[a-zA-Z]+"; } public ArrayList extractLettersWithRegex(String word, String regexPattern) { @@ -92,6 +96,23 @@ public boolean extractStringWithRegexBoolean(String word, String regexPattern) { return matcher.find(); } + /** + * Calculate points for the given string of letters, the string should be provided with the surrounding brackets. + * After calculation, the function updates the score + * @param strLettersWithBrackets E.g. {[dog]}, [d]o{g} etc. + */ + public void calculatePoints(String strLettersWithBrackets) { + + // Extract only letters, escape brackets + strLettersWithBrackets = extractStringWithRegex(strLettersWithBrackets, this.regexLetters); + + // Calculate double points + for (char letter : strLettersWithBrackets.toCharArray()) { + this.score += pointsMap.get(letter) * 2; + } + } + + public int score() { // Regex patterns @@ -101,7 +122,7 @@ public int score() { String regexNotValidDouble = "\\}.*?\\{|\\{.*?\\]"; String regexNotValidTriple = "\\].*?\\[|\\[.*?\\}"; // String regexTriple = "\\[[^\\[].*?\\]"; - String regexLetters = "[a-zA-Z]+"; +// String regexLetters = "[a-zA-Z]+"; String regexWordsWithSpecialCharacters = "[^a-zA-Z]+"; // Can include letters, special charaacters, brackets // String regexOnlyLetters = "(?=[a-zA-Z]+)(?=[^a-zA-Z]+)"; // WRONG String regexNotLetters = "[^a-zA-Z]+"; @@ -136,7 +157,7 @@ public int score() { // Extract double letters, brackets included String doubleLetters = extractStringWithRegex(this.word, regexDouble); - // Check for invalid duplication of letters inside brakcets, e.g. he{ll}o + // Check for invalid duplication of letters inside brackets, e.g. he{ll}o boolean invalidDuplication = extractStringWithRegexBoolean(doubleLetters, regexDuplicationOfLetters); if (invalidDuplication) { return 0; @@ -149,19 +170,20 @@ public int score() { return 0; } - // Extract only letters, escape brackets - doubleLetters = extractStringWithRegex(doubleLetters, regexLetters); - // Calculate double points - for (char letter : doubleLetters.toCharArray()) { - this.score += pointsMap.get(letter) * 2; - } +// // Extract only letters, escape brackets +// doubleLetters = extractStringWithRegex(doubleLetters, regexLetters); +// // Calculate double points +// for (char letter : doubleLetters.toCharArray()) { +// this.score += pointsMap.get(letter) * 2; +// } + calculatePoints(doubleLetters); } if (isTriple) { // Extract triple letters, brackets included String tripleLetters = extractStringWithRegex(this.word, regexTriple); - // Check for invalid duplication of letters inside brakcets, e.g. he{ll}o + // Check for invalid duplication of letters inside brackets, e.g. he{ll}o boolean invalidDuplication = extractStringWithRegexBoolean(tripleLetters, regexDuplicationOfLetters); if (invalidDuplication) { return 0; From 7c1375ef782646da698a1d6f5b79ac60f0a0c8c0 Mon Sep 17 00:00:00 2001 From: shyye Date: Sat, 17 Aug 2024 12:05:14 +0200 Subject: [PATCH 6/6] Solve Extension Part for Scrabble --- src/main/java/com/booleanuk/Scrabble.java | 160 +++++----------------- 1 file changed, 34 insertions(+), 126 deletions(-) diff --git a/src/main/java/com/booleanuk/Scrabble.java b/src/main/java/com/booleanuk/Scrabble.java index 2b7ec53..bd453fd 100644 --- a/src/main/java/com/booleanuk/Scrabble.java +++ b/src/main/java/com/booleanuk/Scrabble.java @@ -36,33 +36,14 @@ public Scrabble(String word) { this.regexLetters = "[a-zA-Z]+"; } - public ArrayList extractLettersWithRegex(String word, String regexPattern) { - // TODO: Should I change to ordinary list to save memory? With just two elements. - ArrayList output = new ArrayList<>(); - - Pattern pattern = Pattern.compile(regexPattern); - Matcher matcher = pattern.matcher(word); - - boolean found = false; - while (matcher.find()) { - System.out.printf("I found the text" + - " \"%s\" starting at " + - "index %d and ending at index %d.%n", - matcher.group(), - matcher.start(), - matcher.end()); - found = true; - //output += matcher.group(); - output.add(matcher.start()); - output.add(matcher.end()); - } - if(!found){ - System.out.printf("No match found.%n"); - } - System.out.println("text: " + output); - return output; - } - + /** + * Outputs string after regex is applied to it. + * Most of the code is from Oracle's Java tutorial at: https://docs.oracle.com/javase/tutorial/essential/regex/test_harness.html + * It prints out information about the findings from the regex expression. + * @param word + * @param regexPattern + * @return + */ public String extractStringWithRegex(String word, String regexPattern) { // Reference: https://docs.oracle.com/javase/tutorial/essential/regex/test_harness.html @@ -101,38 +82,26 @@ public boolean extractStringWithRegexBoolean(String word, String regexPattern) { * After calculation, the function updates the score * @param strLettersWithBrackets E.g. {[dog]}, [d]o{g} etc. */ - public void calculatePoints(String strLettersWithBrackets) { + public void calculatePoints(String strLettersWithBrackets, int pointMultiplier) { // Extract only letters, escape brackets strLettersWithBrackets = extractStringWithRegex(strLettersWithBrackets, this.regexLetters); // Calculate double points for (char letter : strLettersWithBrackets.toCharArray()) { - this.score += pointsMap.get(letter) * 2; + this.score += pointsMap.get(letter) * pointMultiplier; } } - public int score() { - // Regex patterns + // Regex patterns TODO: Should put this in the constructor as well // Regex tips https://regexr.com/ String regexDouble = "\\{.*?\\}"; String regexTriple = "\\[.*?\\]"; - String regexNotValidDouble = "\\}.*?\\{|\\{.*?\\]"; - String regexNotValidTriple = "\\].*?\\[|\\[.*?\\}"; -// String regexTriple = "\\[[^\\[].*?\\]"; -// String regexLetters = "[a-zA-Z]+"; - String regexWordsWithSpecialCharacters = "[^a-zA-Z]+"; // Can include letters, special charaacters, brackets -// String regexOnlyLetters = "(?=[a-zA-Z]+)(?=[^a-zA-Z]+)"; // WRONG - String regexNotLetters = "[^a-zA-Z]+"; - String regexNotLettersButBrackets = "[^a-zA-Z\\{\\}\\[\\]]+"; - String regexInvalidBracketsLeftSquare = "\\[{1}"; // Check if only appear once - String regexInvalidBracketsLeftCurly = "\\{{1}"; - String regexInvalidBracketsRightSquare = "\\]{1}"; - String regexInvalidBracketsRightCurly = "\\}{1}"; - + // Can include letters, special characters, brackets + String regexWordsWithSpecialCharacters = "[^a-zA-Z]+"; // Check for single occurrence of single bracket String regexLeftSquareBracket = "\\[{1}"; @@ -140,12 +109,8 @@ public int score() { String regexLeftCurlyBracket = "\\{{1}"; String regexRightCurlyBracket = "\\}{1}"; - - - - // TODO check if can replace with - String regexInvalidSingleBracket = "(\\{|\\})(\\[|\\]){1}"; - String regexDuplicationOfLetters = "(\\w)\\1+"; // A sequence of the same letter e.g. "ll" in he{ll}o + // A sequence of the same letter e.g. "ll" in he{ll}o + String regexDuplicationOfLetters = "(\\w)\\1+"; boolean isDouble = extractStringWithRegexBoolean(this.word, regexDouble); boolean isTriple = extractStringWithRegexBoolean(this.word, regexTriple); @@ -170,13 +135,24 @@ public int score() { return 0; } -// // Extract only letters, escape brackets -// doubleLetters = extractStringWithRegex(doubleLetters, regexLetters); -// // Calculate double points -// for (char letter : doubleLetters.toCharArray()) { -// this.score += pointsMap.get(letter) * 2; -// } - calculatePoints(doubleLetters); + // Check if this double point sequence contains a sequence of nested triple points, + // if that is the case: + // - calculate triple points first + boolean containsTriple = extractStringWithRegexBoolean(doubleLetters, regexTriple); + if (containsTriple) { + // Calculate nested triple separately (the letters are first tripled (*3) and then doubled (*2) + String nestedTriple = extractStringWithRegex(doubleLetters, regexTriple); + calculatePoints(nestedTriple, 3*2); + + // Remove it from doubleLetters to avoid duplication of points + doubleLetters = doubleLetters.replace(nestedTriple, ""); + } + // Calculate double points + calculatePoints(doubleLetters, 2); + + // Remove this pair of curly brackets (Double points) and its content to avoid duplicated points {...} when moving on to checking triple points in next section + String originalDoubleLetters = extractStringWithRegex(this.word, regexDouble); + this.word = this.word.replace(originalDoubleLetters, ""); } if (isTriple) { @@ -197,12 +173,8 @@ public int score() { return 0; } - // Extract only letters, escape brackets - tripleLetters = extractStringWithRegex(tripleLetters, regexLetters); // Calculate triple points - for (char letter : tripleLetters.toCharArray()) { - this.score += pointsMap.get(letter) * 3; - } + calculatePoints(tripleLetters, 3); } // Calculate ordinary/base points @@ -215,69 +187,5 @@ public int score() { return this.score; } return 0; - - - // Check invalid brackets -// boolean invalidDouble = extractStringWithRegexBoolean(this.word, regexNotValidDouble); -// boolean invalidTripel = extractStringWithRegexBoolean(this.word, regexNotValidTriple); -// if (invalidDouble || invalidTripel) { -// return this.score; -// } - - // Check if there is only one occurence of { [ ] or }, with the help of an XOR gate (exclusive or) -// boolean invalidBracketLeftSquare = extractStringWithRegexBoolean(this.word, regexInvalidBracketsLeftSquare); -// boolean invalidBracketLeftCurly = extractStringWithRegexBoolean(this.word, regexInvalidBracketsLeftCurly); -// boolean invalidBracketRightSquare = extractStringWithRegexBoolean(this.word, regexInvalidBracketsRightSquare); -// boolean invalidBracketRightCurly = extractStringWithRegexBoolean(this.word, regexInvalidBracketsRightCurly); -// if (invalidBracketLeftSquare ^ invalidBracketRightSquare) { -// return this.score; -// } -// if (invalidBracketLeftCurly ^ invalidBracketRightCurly) { -// return this.score; -// } - - // Check invalid when there is only one single bracket -// boolean invalidSingleBracket = extractStringWithRegexBoolean(this.word, regexInvalidSingleBracket); -// if (invalidSingleBracket) { -// return this.score; -// } -// -// // Check if word has invalid tokens -// boolean invalidTokens = extractStringWithRegexBoolean(this.word, regexNotLettersButBrackets); -// if (invalidTokens) { -// return 0; -// } -// -// // Invalid double letters in brackets e.g. "he{ll}o -// boolean invalidDoubleLettersInsideBrackets; -// -// // Double points -// String doubleLetters = extractStringWithRegex(this.word, regexDouble); -// // Check if invalid -// invalidDoubleLettersInsideBrackets = extractStringWithRegexBoolean(doubleLetters, regexSameLetterSequence); -// if (invalidDoubleLettersInsideBrackets) { -// return this.score; -// } -// // Calculate double points -// doubleLetters = extractStringWithRegex(doubleLetters, regexOnlyLetters); // Extract only letters, escape brackets -// for (char letter : doubleLetters.toCharArray()) { -// this.score += pointsMap.get(letter) * 2; -// } -// -// // Calculate triple points -// String tripleLetters = extractStringWithRegex(this.word, regexTriple); -// tripleLetters = extractStringWithRegex(tripleLetters, regexOnlyLetters); // Extract only letters, escape brackets -// for (char letter : tripleLetters.toCharArray()) { -// this.score += pointsMap.get(letter) * 3; -// } -// -// // Calcualte ordinary/base points -// String baseLetters = this.word.replaceAll(regexDouble, ""); // Remove double points -// baseLetters = baseLetters.replaceAll(regexTriple, ""); // Remove triple points -// for (char letter : baseLetters.toCharArray()) { -// this.score += pointsMap.get(letter); -// } - -// return this.score; } }