You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.8 KiB

  1. package de.edu.hsfulda.ciip.tdd;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. public class BownlingCalculator {
  5. private static final int SINGLE_DIGIT = 0;
  6. private static final int STRIKE_SECOND_NEXT_THROW = 2;
  7. private static final int STRIKE_NEXT_THROW = 1;
  8. private static final String STRIKE = "X (\\d)(\\d)";
  9. private static final int PINS_IN_FRAME = 10;
  10. private static final String SPARE = "(\\d)/ (\\d)";
  11. private static final String INCOMPLETE_FRAME = "\\d";
  12. @FunctionalInterface
  13. private interface FrameCalculator {
  14. int evaluate(Matcher frameStructure);
  15. }
  16. private static final int SPARE_FRAME_FOLLOWING_THROW = 2;
  17. private static final int SPARE_FRAME_FIRST_THROW = 1;
  18. public int evaluate(String listOfThrows) {
  19. int sum = 0;
  20. sum += evaluateFrames(listOfThrows, INCOMPLETE_FRAME,
  21. singleDigit -> convertMatchToInt(singleDigit, SINGLE_DIGIT));
  22. sum += evaluateFrames(listOfThrows, SPARE, // trailing line comments for formatting
  23. spare -> PINS_IN_FRAME //
  24. - convertMatchToInt(spare, SPARE_FRAME_FIRST_THROW)
  25. + convertMatchToInt(spare, SPARE_FRAME_FOLLOWING_THROW));
  26. sum += evaluateFrames(listOfThrows, STRIKE, //
  27. strike -> PINS_IN_FRAME //
  28. + convertMatchToInt(strike, STRIKE_NEXT_THROW) //
  29. + convertMatchToInt(strike, STRIKE_SECOND_NEXT_THROW));
  30. return sum;
  31. }
  32. private int convertMatchToInt(Matcher strike, int groupIndex) {
  33. return Integer.parseInt(strike.group(groupIndex));
  34. }
  35. private int evaluateFrames(String listOfThrows, String frameStructurePattern, FrameCalculator frameCalculator) {
  36. Matcher singleDigit = Pattern.compile(frameStructurePattern).matcher(listOfThrows);
  37. int frameValue = 0;
  38. while (singleDigit.find()) {
  39. frameValue += frameCalculator.evaluate(singleDigit);
  40. }
  41. return frameValue;
  42. }
  43. }