lots of exercises in java... from https://github.com/exercism/java

MinesweeperBoard.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Set;
  4. import java.util.stream.Collectors;
  5. final class MinesweeperBoard {
  6. private static final char MINE_CHAR = '*';
  7. private static final char SPACE_CHAR = ' ';
  8. private final List<String> rawRepresentation;
  9. private final int numberOfRows;
  10. private final int numberOfColumns;
  11. MinesweeperBoard(final List<String> rawRepresentation) {
  12. validateInputBoard(rawRepresentation);
  13. this.rawRepresentation = rawRepresentation;
  14. this.numberOfRows = rawRepresentation.size();
  15. this.numberOfColumns = rawRepresentation.isEmpty() ? 0 : rawRepresentation.get(0).length();
  16. }
  17. List<String> getAnnotatedRepresentation() throws IllegalArgumentException {
  18. final List<String> result = new ArrayList<>();
  19. for (int rowNumber = 0; rowNumber < numberOfRows; rowNumber++) {
  20. result.add(getAnnotatedRow(rowNumber));
  21. }
  22. return result;
  23. }
  24. private String getAnnotatedRow(final int rowNumber) {
  25. String result = "";
  26. for (int columnNumber = 0; columnNumber < numberOfColumns; columnNumber++) {
  27. result += getCellAnnotation(rowNumber, columnNumber);
  28. }
  29. return result;
  30. }
  31. private char getCellAnnotation(final int rowNumber, final int columnNumber) {
  32. // If (rowNumber, columnNumber) is a mine, we're done.
  33. if (rawRepresentation.get(rowNumber).charAt(columnNumber) == MINE_CHAR) {
  34. return MINE_CHAR;
  35. }
  36. final int mineCount = computeMineCountAround(rowNumber, columnNumber);
  37. // If computed count is positive, add it to the annotated row. Otherwise, add a blank space.
  38. return mineCount > 0 ? Character.forDigit(mineCount, 10) : SPACE_CHAR;
  39. }
  40. private int computeMineCountAround(final int rowNumber, final int columnNumber) {
  41. int result = 0;
  42. // Compute row and column ranges to inspect (respecting board edges).
  43. final int minRowToInspect = Math.max(rowNumber - 1, 0);
  44. final int maxRowToInspect = Math.min(rowNumber + 1, numberOfRows - 1);
  45. final int minColToInspect = Math.max(columnNumber - 1, 0);
  46. final int maxColToInspect = Math.min(columnNumber + 1, numberOfColumns - 1);
  47. // Count mines in the cells surrounding (row, col).
  48. for (int rowToInspect = minRowToInspect; rowToInspect <= maxRowToInspect; rowToInspect++) {
  49. for (int colToInspect = minColToInspect; colToInspect <= maxColToInspect; colToInspect++) {
  50. if (rawRepresentation.get(rowToInspect).charAt(colToInspect) == MINE_CHAR) {
  51. result += 1;
  52. }
  53. }
  54. }
  55. return result;
  56. }
  57. private void validateInputBoard(final List<String> inputBoard) throws IllegalArgumentException {
  58. validateInputBoardIsNotNull(inputBoard);
  59. if (inputBoard.isEmpty()) {
  60. return;
  61. }
  62. validateInputBoardCharacters(inputBoard);
  63. validateInputBoardColumnCounts(inputBoard);
  64. }
  65. private void validateInputBoardIsNotNull(final List<String> inputBoard) throws IllegalArgumentException {
  66. if (inputBoard == null) {
  67. throw new IllegalArgumentException("Input board may not be null.");
  68. }
  69. }
  70. private void validateInputBoardCharacters(final List<String> inputBoard) throws IllegalArgumentException {
  71. final String allBoardCharacters = String.join("", inputBoard);
  72. if (!allBoardCharacters.matches("^[ *]*$")) {
  73. throw new IllegalArgumentException("Input board can only contain the characters ' ' and '*'.");
  74. }
  75. }
  76. private void validateInputBoardColumnCounts(final List<String> inputBoard) throws IllegalArgumentException {
  77. final Set<Integer> setOfColumnCounts = inputBoard.stream().map(String::length).collect(Collectors.toSet());
  78. if (setOfColumnCounts.size() > 1) {
  79. throw new IllegalArgumentException("Input board rows must all have the same number of columns.");
  80. }
  81. }
  82. }