From e30cf5675bdea6feffe9ddce8aee16371874821c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 22:49:56 +0900 Subject: [PATCH 01/35] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README 내용 추가 - 기능 목록 --- docs/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29bb2d..367bbac010d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,27 @@ +## 기능 목록 +- [ ] 게임 시작 + - [ ] 게임 시작 메시지 출력 +- [ ] 다리 길이 설정 + - [ ] 다리 길이 입력요청 메시지 출력 + - [ ] 다리 길이 입력 + - [ ] 입력값 숫자 여부 검증 + - [ ] 입력 숫자 3 이상 20 이하 숫자인지 검증 +- [ ] 다리 생성 + - [ ] 길이에 따른 랜덤 다리 생성 +- [ ] 플레이어 이동 + - [ ] 이동할 칸 입력 + - [ ] 입력값이 U 혹은 D 인지 검증 + - [ ] 이동 가능한 칸인 경우 O 표시 + - [ ] 이동 불가능한 칸인 경우 X 표시 + - [ ] 현황 출력 +- [ ] 게임 성공 여부 판단 + - [ ] 이동 불가능한 칸으로 이동한 경우 실패 + - [ ] 모두 이동 가능한 칸으로만 이동한 경우 성공 + - [ ] 성공 메시지 출력 + - [ ] 총 시도 횟수 출력 +- [ ] 실패시 게임 재시작 여부 판단 + - [ ] 게임 재시작 여부 입력 + - [ ] 입력값 R 혹은 Q 인지 검증 +- [ ] 게임 재시작 + - [ ] 게임 시도 횟수 증가 +- [ ] 게임 종료 From 635f27af7f2d4cb6eb6448ae4e3ff634e3db6c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:07:02 +0900 Subject: [PATCH 02/35] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=EC=99=80=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 클래스 추가 - BridgeGameManager - ComponentFactory --- docs/README.md | 29 +++++++++++++++++++++ src/main/java/bridge/Application.java | 3 ++- src/main/java/bridge/BridgeGameManager.java | 15 +++++++++++ src/main/java/bridge/ComponentFactory.java | 16 ++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/main/java/bridge/BridgeGameManager.java create mode 100644 src/main/java/bridge/ComponentFactory.java diff --git a/docs/README.md b/docs/README.md index 367bbac010d..88defaf9f32 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,3 +25,32 @@ - [ ] 게임 재시작 - [ ] 게임 시도 횟수 증가 - [ ] 게임 종료 + +## 구현 클래스 목록 +- BridgeGame + - move() + - retry() + +- BridgeGameManager + - playBridgeGame() 게임 실행 + +- BridgeMaker + - makeBridge() + +- BridgeNumberGenerator + - generate() + +- BridgeRandomNumberGenerator + - generate() + +- InputView + - readBridgeSize() + - readMoving() + - readGameCommand() + +- OutputView + - printMap() + - printResult() + +- ComponentFactory + - bridgeGameManager() BridgeGameManager 생성 diff --git a/src/main/java/bridge/Application.java b/src/main/java/bridge/Application.java index 5cb72dfd3de..cab94bae395 100644 --- a/src/main/java/bridge/Application.java +++ b/src/main/java/bridge/Application.java @@ -3,6 +3,7 @@ public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + final ComponentFactory componentFactory = new ComponentFactory(); + componentFactory.bridgeGameManager().playBridgeGame(); } } diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java new file mode 100644 index 00000000000..425db90b9f5 --- /dev/null +++ b/src/main/java/bridge/BridgeGameManager.java @@ -0,0 +1,15 @@ +package bridge; + +public class BridgeGameManager { + private final InputView inputView; + private final OutputView outputView; + + public BridgeGameManager(final InputView inputView, final OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void playBridgeGame() { + + } +} diff --git a/src/main/java/bridge/ComponentFactory.java b/src/main/java/bridge/ComponentFactory.java new file mode 100644 index 00000000000..a703b389859 --- /dev/null +++ b/src/main/java/bridge/ComponentFactory.java @@ -0,0 +1,16 @@ +package bridge; + +public class ComponentFactory { + + public BridgeGameManager bridgeGameManager() { + return new BridgeGameManager(inputView(), outputView()); + } + + private OutputView outputView() { + return new OutputView(); + } + + private InputView inputView() { + return new InputView(); + } +} From 5051033ee24ea30d997813743770d125460b32a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:10:36 +0900 Subject: [PATCH 03/35] =?UTF-8?q?feat(BridgeGameMessage):=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=97=B4=EA=B1=B0?= =?UTF-8?q?=ED=98=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 열거형 추가 - BridgeGameMessage --- docs/README.md | 4 ++++ src/main/java/bridge/BridgeGameMessage.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/main/java/bridge/BridgeGameMessage.java diff --git a/docs/README.md b/docs/README.md index 88defaf9f32..eade621dea1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,3 +54,7 @@ - ComponentFactory - bridgeGameManager() BridgeGameManager 생성 + +## 열거형 목록 +- BridgeGameMessage + - 게임 메시지 diff --git a/src/main/java/bridge/BridgeGameMessage.java b/src/main/java/bridge/BridgeGameMessage.java new file mode 100644 index 00000000000..73dbfc373eb --- /dev/null +++ b/src/main/java/bridge/BridgeGameMessage.java @@ -0,0 +1,18 @@ +package bridge; + +public enum BridgeGameMessage { + START_GAME("다리 건너기 게임을 시작합니다."), + BRIDGE_LENGTH_REQUEST("다리의 길이를 입력해주세요.") + ; + + private final String message; + + BridgeGameMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return this.message; + } +} From 473ee6b12de07facc3bf3f5bf64387242e536e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:19:32 +0900 Subject: [PATCH 04/35] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A6=AC=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 다리 길이 입력 --- docs/README.md | 2 ++ src/main/java/bridge/BridgeGameManager.java | 9 +++++++++ src/main/java/bridge/BridgeGameMessage.java | 2 +- src/main/java/bridge/InputView.java | 5 ++++- src/main/java/bridge/OutputView.java | 8 ++++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index eade621dea1..fa9f323c03f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -49,6 +49,8 @@ - readGameCommand() - OutputView + - printGameStart() + - printBridgeLengthRequest() - printMap() - printResult() diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index 425db90b9f5..3dda04cab24 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -10,6 +10,15 @@ public BridgeGameManager(final InputView inputView, final OutputView outputView) } public void playBridgeGame() { + outputView.printGameStart(); + playUntilGameEnd(); + } + private void playUntilGameEnd() { + boolean gameRunning = true; + while (gameRunning) { + outputView.printBridgeLengthRequest(); + final int bridgeLength = inputView.readBridgeSize(); + } } } diff --git a/src/main/java/bridge/BridgeGameMessage.java b/src/main/java/bridge/BridgeGameMessage.java index 73dbfc373eb..3e6ce3ef973 100644 --- a/src/main/java/bridge/BridgeGameMessage.java +++ b/src/main/java/bridge/BridgeGameMessage.java @@ -1,7 +1,7 @@ package bridge; public enum BridgeGameMessage { - START_GAME("다리 건너기 게임을 시작합니다."), + START_GAME("다리 건너기 게임을 시작합니다.\n"), BRIDGE_LENGTH_REQUEST("다리의 길이를 입력해주세요.") ; diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index c3911c8a8e7..1d94ce7471e 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -1,5 +1,7 @@ package bridge; +import camp.nextstep.edu.missionutils.Console; + /** * 사용자로부터 입력을 받는 역할을 한다. */ @@ -9,7 +11,8 @@ public class InputView { * 다리의 길이를 입력받는다. */ public int readBridgeSize() { - return 0; + final String input = Console.readLine(); + return Integer.parseInt(input); } /** diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index 69a433a6285..a0e1da0513c 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -5,6 +5,14 @@ */ public class OutputView { + public void printGameStart() { + System.out.println(BridgeGameMessage.START_GAME); + } + + public void printBridgeLengthRequest() { + System.out.println(BridgeGameMessage.BRIDGE_LENGTH_REQUEST); + } + /** * 현재까지 이동한 다리의 상태를 정해진 형식에 맞춰 출력한다. *

From 419acb9a134ab225492877da842e229fe876ebaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:24:39 +0900 Subject: [PATCH 05/35] =?UTF-8?q?feat(InputValidator):=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EA=B0=92=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - InputValidator 추가 - 다리 길이 입력값 검증 추가 --- docs/README.md | 3 +++ src/main/java/bridge/InputValidator.java | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/main/java/bridge/InputValidator.java diff --git a/docs/README.md b/docs/README.md index fa9f323c03f..0a07e1907b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,6 +48,9 @@ - readMoving() - readGameCommand() +- InputValidator + - validateBridgeLengthInput() 다리 길이 입력값 검증 + - OutputView - printGameStart() - printBridgeLengthRequest() diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java new file mode 100644 index 00000000000..840cda58d07 --- /dev/null +++ b/src/main/java/bridge/InputValidator.java @@ -0,0 +1,19 @@ +package bridge; + +public class InputValidator { + private static final String NUMERIC_MATCHER = "[0-9]+"; + + public void validateBridgeLengthInput(final String input) { + if (isBlankInput(input) || isNotNumeric(input)) { + throw new IllegalArgumentException(); + } + } + + private boolean isNotNumeric(final String input) { + return !input.matches(NUMERIC_MATCHER); + } + + private boolean isBlankInput(final String input) { + return input.isBlank(); + } +} From bf74380c7fdc7a7b142515a98c3647f413edd9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:26:38 +0900 Subject: [PATCH 06/35] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A6=AC=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 적용 - 다리 길이 입력값 검증 메서드 연결 --- src/main/java/bridge/ComponentFactory.java | 6 +++++- src/main/java/bridge/InputView.java | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/bridge/ComponentFactory.java b/src/main/java/bridge/ComponentFactory.java index a703b389859..a0f0566f140 100644 --- a/src/main/java/bridge/ComponentFactory.java +++ b/src/main/java/bridge/ComponentFactory.java @@ -11,6 +11,10 @@ private OutputView outputView() { } private InputView inputView() { - return new InputView(); + return new InputView(inputValidator()); + } + + private InputValidator inputValidator() { + return new InputValidator(); } } diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index 1d94ce7471e..55b36980783 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -6,12 +6,18 @@ * 사용자로부터 입력을 받는 역할을 한다. */ public class InputView { + private final InputValidator inputValidator; + + public InputView(final InputValidator inputValidator) { + this.inputValidator = inputValidator; + } /** * 다리의 길이를 입력받는다. */ public int readBridgeSize() { final String input = Console.readLine(); + inputValidator.validateBridgeLengthInput(input); return Integer.parseInt(input); } From bc6ba2dee54d5dca3861cc19f0ca07625148e5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:43:55 +0900 Subject: [PATCH 07/35] =?UTF-8?q?feat(BridgeType):=20=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=97=B4=EA=B1=B0=ED=98=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 열거형 추가 - BridgeType --- docs/README.md | 3 +++ src/main/java/bridge/BridgeType.java | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/main/java/bridge/BridgeType.java diff --git a/docs/README.md b/docs/README.md index 0a07e1907b5..35745952271 100644 --- a/docs/README.md +++ b/docs/README.md @@ -63,3 +63,6 @@ ## 열거형 목록 - BridgeGameMessage - 게임 메시지 + +- BridgeType + - 다리의 윗 칸과 아래칸 diff --git a/src/main/java/bridge/BridgeType.java b/src/main/java/bridge/BridgeType.java new file mode 100644 index 00000000000..0534fc2ac05 --- /dev/null +++ b/src/main/java/bridge/BridgeType.java @@ -0,0 +1,22 @@ +package bridge; + +public enum BridgeType { + UPPER("U", 1), + LOWER("D", 0); + + private final String symbol; + private final Integer classifier; + + BridgeType(final String symbol, final Integer classifier) { + this.symbol = symbol; + this.classifier = classifier; + } + + public Integer getClassifier() { + return this.classifier; + } + + public String getSymbol() { + return this.symbol; + } +} From 0c94cf9d7e45b74eb804a178260e008c1be11fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:51:17 +0900 Subject: [PATCH 08/35] =?UTF-8?q?feat(ErrorMessage):=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=97=B4=EA=B1=B0=ED=98=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 열거형 추가 - ErrorMessage --- src/main/java/bridge/ErrorMessage.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/bridge/ErrorMessage.java diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/ErrorMessage.java new file mode 100644 index 00000000000..845ab410139 --- /dev/null +++ b/src/main/java/bridge/ErrorMessage.java @@ -0,0 +1,19 @@ +package bridge; + +public enum ErrorMessage { + NOT_NUMERIC_INPUT("숫자만 입력 가능합니다."), + BLANK_INPUT("입력값이 비어있습니다."), + + ; + private final String message; + private static final String ERROR_PREFIX = "[ERROR] "; + + ErrorMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return ERROR_PREFIX + this.message; + } +} From 6fe804b978b5305f548d15b7666a1b92ffc0ead0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Sun, 13 Aug 2023 23:52:27 +0900 Subject: [PATCH 09/35] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예외 메시지 적용 - InputValidator --- docs/README.md | 3 +++ src/main/java/bridge/InputValidator.java | 17 ++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 35745952271..a190433f5c6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -66,3 +66,6 @@ - BridgeType - 다리의 윗 칸과 아래칸 + +- ErrorMessage + - 에러 메시지 diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java index 840cda58d07..605faeeca1c 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/InputValidator.java @@ -4,16 +4,19 @@ public class InputValidator { private static final String NUMERIC_MATCHER = "[0-9]+"; public void validateBridgeLengthInput(final String input) { - if (isBlankInput(input) || isNotNumeric(input)) { - throw new IllegalArgumentException(); - } + validateNumeric(input); + validateNotBlank(input); } - private boolean isNotNumeric(final String input) { - return !input.matches(NUMERIC_MATCHER); + private void validateNumeric(final String input) { + if (!input.matches(NUMERIC_MATCHER)) { + throw new IllegalArgumentException(ErrorMessage.NOT_NUMERIC_INPUT.toString()); + } } - private boolean isBlankInput(final String input) { - return input.isBlank(); + private void validateNotBlank(final String input) { + if (input.isBlank()) { + throw new IllegalArgumentException(ErrorMessage.BLANK_INPUT.toString()); + } } } From e38682aa04f3302bae8162465641f48cc7224a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:04:25 +0900 Subject: [PATCH 10/35] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A6=AC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 다리 생성 --- src/main/java/bridge/BridgeMaker.java | 12 ++++++++++-- src/main/java/bridge/BridgeType.java | 14 ++++++++------ src/main/java/bridge/ErrorMessage.java | 3 +-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/BridgeMaker.java index 27e9f2cfa7f..09542e98682 100644 --- a/src/main/java/bridge/BridgeMaker.java +++ b/src/main/java/bridge/BridgeMaker.java @@ -1,12 +1,13 @@ package bridge; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * 다리의 길이를 입력 받아서 다리를 생성해주는 역할을 한다. */ public class BridgeMaker { - private final BridgeNumberGenerator bridgeNumberGenerator; public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) { @@ -18,6 +19,13 @@ public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) { * @return 입력받은 길이에 해당하는 다리 모양. 위 칸이면 "U", 아래 칸이면 "D"로 표현해야 한다. */ public List makeBridge(int size) { - return null; + return IntStream.range(0, size) + .mapToObj(i -> getBridgeSymbol()) + .collect(Collectors.toList()); + } + + private String getBridgeSymbol() { + final int randomNumber = bridgeNumberGenerator.generate(); + return BridgeType.getSymbolByClassifier(randomNumber); } } diff --git a/src/main/java/bridge/BridgeType.java b/src/main/java/bridge/BridgeType.java index 0534fc2ac05..e259ae6e0e6 100644 --- a/src/main/java/bridge/BridgeType.java +++ b/src/main/java/bridge/BridgeType.java @@ -1,5 +1,7 @@ package bridge; +import java.util.Arrays; + public enum BridgeType { UPPER("U", 1), LOWER("D", 0); @@ -12,11 +14,11 @@ public enum BridgeType { this.classifier = classifier; } - public Integer getClassifier() { - return this.classifier; - } - - public String getSymbol() { - return this.symbol; + public static String getSymbolByClassifier(final int classifier) { + return Arrays.stream(BridgeType.values()) + .filter(bridgeType -> bridgeType.classifier.equals(classifier)) + .findAny() + .map(bridgeType -> bridgeType.symbol) + .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.INVALID_CLASSIFIER.toString())); } } diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/ErrorMessage.java index 845ab410139..d090ef3608c 100644 --- a/src/main/java/bridge/ErrorMessage.java +++ b/src/main/java/bridge/ErrorMessage.java @@ -3,8 +3,7 @@ public enum ErrorMessage { NOT_NUMERIC_INPUT("숫자만 입력 가능합니다."), BLANK_INPUT("입력값이 비어있습니다."), - - ; + INVALID_CLASSIFIER("다리의 숫자 값이 올바르지 않습니다."); private final String message; private static final String ERROR_PREFIX = "[ERROR] "; From 307de4a53e227213068a45f08bf38c8932228f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:05:03 +0900 Subject: [PATCH 11/35] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=EA=B0=92=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 수정 - 입력값 숫자 검증 --- src/main/java/bridge/InputValidator.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java index 605faeeca1c..76bd29b1363 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/InputValidator.java @@ -1,7 +1,6 @@ package bridge; public class InputValidator { - private static final String NUMERIC_MATCHER = "[0-9]+"; public void validateBridgeLengthInput(final String input) { validateNumeric(input); @@ -9,11 +8,19 @@ public void validateBridgeLengthInput(final String input) { } private void validateNumeric(final String input) { - if (!input.matches(NUMERIC_MATCHER)) { + if (hasNonNumber(input)) { throw new IllegalArgumentException(ErrorMessage.NOT_NUMERIC_INPUT.toString()); } } + private boolean hasNonNumber(final String input) { + return !input.chars().allMatch(this::isNumber); + } + + private boolean isNumber(int character) { + return '0' <= character && character <= '9'; + } + private void validateNotBlank(final String input) { if (input.isBlank()) { throw new IllegalArgumentException(ErrorMessage.BLANK_INPUT.toString()); From fb017adf559ee857eff175f7043afb59e187ba45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:22:33 +0900 Subject: [PATCH 12/35] =?UTF-8?q?refactor:=20=EC=97=B4=EA=B1=B0=ED=98=95?= =?UTF-8?q?=20=EC=83=81=EC=88=98=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - BridgeType 열거형 상수 이름 변경 --- src/main/java/bridge/BridgeMaker.java | 13 +++++++------ src/main/java/bridge/BridgeType.java | 12 +++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/BridgeMaker.java index 09542e98682..f35119b87f3 100644 --- a/src/main/java/bridge/BridgeMaker.java +++ b/src/main/java/bridge/BridgeMaker.java @@ -8,9 +8,10 @@ * 다리의 길이를 입력 받아서 다리를 생성해주는 역할을 한다. */ public class BridgeMaker { + private static final int RANGE_START = 0; private final BridgeNumberGenerator bridgeNumberGenerator; - public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) { + public BridgeMaker(final BridgeNumberGenerator bridgeNumberGenerator) { this.bridgeNumberGenerator = bridgeNumberGenerator; } @@ -18,14 +19,14 @@ public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) { * @param size 다리의 길이 * @return 입력받은 길이에 해당하는 다리 모양. 위 칸이면 "U", 아래 칸이면 "D"로 표현해야 한다. */ - public List makeBridge(int size) { - return IntStream.range(0, size) - .mapToObj(i -> getBridgeSymbol()) + public List makeBridge(final int size) { + return IntStream.range(RANGE_START, size) + .mapToObj(i -> getBridgeDirection()) .collect(Collectors.toList()); } - private String getBridgeSymbol() { + private String getBridgeDirection() { final int randomNumber = bridgeNumberGenerator.generate(); - return BridgeType.getSymbolByClassifier(randomNumber); + return BridgeType.getDirectionByClassifier(randomNumber); } } diff --git a/src/main/java/bridge/BridgeType.java b/src/main/java/bridge/BridgeType.java index e259ae6e0e6..d3d204aafb0 100644 --- a/src/main/java/bridge/BridgeType.java +++ b/src/main/java/bridge/BridgeType.java @@ -3,22 +3,20 @@ import java.util.Arrays; public enum BridgeType { - UPPER("U", 1), - LOWER("D", 0); + U(1), + D(0); - private final String symbol; private final Integer classifier; - BridgeType(final String symbol, final Integer classifier) { - this.symbol = symbol; + BridgeType(final Integer classifier) { this.classifier = classifier; } - public static String getSymbolByClassifier(final int classifier) { + public static String getDirectionByClassifier(final int classifier) { return Arrays.stream(BridgeType.values()) .filter(bridgeType -> bridgeType.classifier.equals(classifier)) .findAny() - .map(bridgeType -> bridgeType.symbol) + .map(Enum::toString) .orElseThrow(() -> new IllegalArgumentException(ErrorMessage.INVALID_CLASSIFIER.toString())); } } From 2796c7b10b6dd8f17d51fc594cee1a6c8e56eeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:24:36 +0900 Subject: [PATCH 13/35] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A6=AC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 다리 생성 기능 BridgeGameManager에 적용 - ComponentFactory 메서드 추가 --- src/main/java/bridge/BridgeGameManager.java | 11 ++++++++--- src/main/java/bridge/ComponentFactory.java | 10 +++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index 3dda04cab24..bef8185de3d 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -1,12 +1,16 @@ package bridge; +import java.util.List; + public class BridgeGameManager { private final InputView inputView; private final OutputView outputView; + private final BridgeMaker bridgeMaker; - public BridgeGameManager(final InputView inputView, final OutputView outputView) { + public BridgeGameManager(final InputView inputView, final OutputView outputView, final BridgeMaker bridgeMaker) { this.inputView = inputView; this.outputView = outputView; + this.bridgeMaker = bridgeMaker; } public void playBridgeGame() { @@ -15,10 +19,11 @@ public void playBridgeGame() { } private void playUntilGameEnd() { - boolean gameRunning = true; - while (gameRunning) { + boolean isGameRunning = true; + while (isGameRunning) { outputView.printBridgeLengthRequest(); final int bridgeLength = inputView.readBridgeSize(); + final List bridgeDirections = bridgeMaker.makeBridge(bridgeLength); } } } diff --git a/src/main/java/bridge/ComponentFactory.java b/src/main/java/bridge/ComponentFactory.java index a0f0566f140..166e9002bf2 100644 --- a/src/main/java/bridge/ComponentFactory.java +++ b/src/main/java/bridge/ComponentFactory.java @@ -3,7 +3,7 @@ public class ComponentFactory { public BridgeGameManager bridgeGameManager() { - return new BridgeGameManager(inputView(), outputView()); + return new BridgeGameManager(inputView(), outputView(), bridgeMaker()); } private OutputView outputView() { @@ -17,4 +17,12 @@ private InputView inputView() { private InputValidator inputValidator() { return new InputValidator(); } + + private BridgeMaker bridgeMaker() { + return new BridgeMaker(bridgeNumberGenerator()); + } + + private BridgeNumberGenerator bridgeNumberGenerator() { + return new BridgeRandomNumberGenerator(); + } } From 0438955cce358c6b429e3a7b26dee60b97053e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:31:12 +0900 Subject: [PATCH 14/35] =?UTF-8?q?feat(Bridge):=20Bridge=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 클래스 추가 - Bridge --- docs/README.md | 3 +++ src/main/java/bridge/Bridge.java | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/main/java/bridge/Bridge.java diff --git a/docs/README.md b/docs/README.md index a190433f5c6..57705f07291 100644 --- a/docs/README.md +++ b/docs/README.md @@ -60,6 +60,9 @@ - ComponentFactory - bridgeGameManager() BridgeGameManager 생성 +- Bridge + - create() Bridge 객체 생성 팩토리 메서드 + ## 열거형 목록 - BridgeGameMessage - 게임 메시지 diff --git a/src/main/java/bridge/Bridge.java b/src/main/java/bridge/Bridge.java new file mode 100644 index 00000000000..7b47811033d --- /dev/null +++ b/src/main/java/bridge/Bridge.java @@ -0,0 +1,16 @@ +package bridge; + +import java.util.Collections; +import java.util.List; + +public final class Bridge { + private final List directions; + + private Bridge(final List directions) { + this.directions = Collections.unmodifiableList(directions); + } + + public static Bridge create(final List directions) { + return new Bridge(directions); + } +} From bdcf2a20eeb742d6f690d79488236b33f668071a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:45:20 +0900 Subject: [PATCH 15/35] =?UTF-8?q?feat(MoveResult):=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=97=B4=EA=B1=B0=ED=98=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 열거형 추가 - MoveResult --- src/main/java/bridge/MoveResult.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/bridge/MoveResult.java diff --git a/src/main/java/bridge/MoveResult.java b/src/main/java/bridge/MoveResult.java new file mode 100644 index 00000000000..945526eb967 --- /dev/null +++ b/src/main/java/bridge/MoveResult.java @@ -0,0 +1,9 @@ +package bridge; + +public enum MoveResult { + KEEP_GOING, FAILED, SUCCESS; + + public boolean isContinue() { + return this == KEEP_GOING; + } +} From 5635d8b66ae72eb602387e90db0dba8879ab83ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:46:05 +0900 Subject: [PATCH 16/35] =?UTF-8?q?docs(README):=20README=EC=97=90=20?= =?UTF-8?q?=EC=97=B4=EA=B1=B0=ED=98=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README 내용 추가 - MoveResult --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index 57705f07291..9cb621bc57e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -72,3 +72,6 @@ - ErrorMessage - 에러 메시지 + +- MoveResult + - 이동 결과 From 2c4c22b99af2f28ce29bcd4391d8e3b16dde1ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:52:57 +0900 Subject: [PATCH 17/35] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=ED=95=A0=20?= =?UTF-8?q?=EC=B9=B8=20=EC=9E=85=EB=A0=A5=20=EC=9A=94=EC=B2=AD=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 이동할 칸 입력 요청 메시지 출력 --- docs/README.md | 1 + src/main/java/bridge/BridgeGameMessage.java | 4 ++-- src/main/java/bridge/OutputView.java | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9cb621bc57e..690422c36ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,6 +56,7 @@ - printBridgeLengthRequest() - printMap() - printResult() + - printMovingRequest() 이동할 칸 입력 요청 출력 - ComponentFactory - bridgeGameManager() BridgeGameManager 생성 diff --git a/src/main/java/bridge/BridgeGameMessage.java b/src/main/java/bridge/BridgeGameMessage.java index 3e6ce3ef973..31c48d43a9e 100644 --- a/src/main/java/bridge/BridgeGameMessage.java +++ b/src/main/java/bridge/BridgeGameMessage.java @@ -2,8 +2,8 @@ public enum BridgeGameMessage { START_GAME("다리 건너기 게임을 시작합니다.\n"), - BRIDGE_LENGTH_REQUEST("다리의 길이를 입력해주세요.") - ; + BRIDGE_LENGTH_REQUEST("다리의 길이를 입력해주세요."), + MOVE_DIRECTION_REQUEST("이동할 칸을 선택해주세요. (위: %s, 아래: %s)"); private final String message; diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index a0e1da0513c..1cb7dda8f01 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -28,4 +28,8 @@ public void printMap() { */ public void printResult() { } + + public void printMovingRequest() { + System.out.println(String.format(BridgeGameMessage.MOVE_DIRECTION_REQUEST.toString(), BridgeType.U, BridgeType.D)); + } } From 8e0336bce282589da1c2f83436893a667dba2fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 00:58:39 +0900 Subject: [PATCH 18/35] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=20=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=20=EC=9E=85=EB=A0=A5=20=EB=B0=8F=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 이동 방향 입력 - 이동 방향 입력값 검증 --- src/main/java/bridge/ErrorMessage.java | 3 ++- src/main/java/bridge/InputValidator.java | 13 +++++++++++++ src/main/java/bridge/InputView.java | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/ErrorMessage.java index d090ef3608c..d4a8d9de0de 100644 --- a/src/main/java/bridge/ErrorMessage.java +++ b/src/main/java/bridge/ErrorMessage.java @@ -3,7 +3,8 @@ public enum ErrorMessage { NOT_NUMERIC_INPUT("숫자만 입력 가능합니다."), BLANK_INPUT("입력값이 비어있습니다."), - INVALID_CLASSIFIER("다리의 숫자 값이 올바르지 않습니다."); + INVALID_CLASSIFIER("다리의 숫자 값이 올바르지 않습니다."), + INVALID_MOVE_DIRECTION("이동 방향 입력값은 %s 혹은 %s 입니다."); private final String message; private static final String ERROR_PREFIX = "[ERROR] "; diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java index 76bd29b1363..12c17e4351e 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/InputValidator.java @@ -1,5 +1,7 @@ package bridge; +import java.util.Objects; + public class InputValidator { public void validateBridgeLengthInput(final String input) { @@ -26,4 +28,15 @@ private void validateNotBlank(final String input) { throw new IllegalArgumentException(ErrorMessage.BLANK_INPUT.toString()); } } + + public void validateMovingInput(final String input) { + validateNotBlank(input); + validateMoveDirection(input); + } + + private void validateMoveDirection(final String input) { + if (!input.equals(BridgeType.U.toString()) && !input.equals(BridgeType.D.toString())) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_MOVE_DIRECTION.toString(), BridgeType.U, BridgeType.D)); + } + } } diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index 55b36980783..c45bbd900c2 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -25,7 +25,9 @@ public int readBridgeSize() { * 사용자가 이동할 칸을 입력받는다. */ public String readMoving() { - return null; + final String input = Console.readLine(); + inputValidator.validateMovingInput(input); + return input; } /** From 2ca340fc42d5d165b0ad68e4be25480c400f5c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 01:21:58 +0900 Subject: [PATCH 19/35] =?UTF-8?q?feat(ResultStatus):=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=20=EC=97=B4=EA=B1=B0=ED=98=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 열거형 추가 - ResultStatus --- docs/README.md | 3 +++ src/main/java/bridge/ResultStatus.java | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 src/main/java/bridge/ResultStatus.java diff --git a/docs/README.md b/docs/README.md index 690422c36ea..4dee7396974 100644 --- a/docs/README.md +++ b/docs/README.md @@ -76,3 +76,6 @@ - MoveResult - 이동 결과 + +- ResultStatus + - 결과 상태 diff --git a/src/main/java/bridge/ResultStatus.java b/src/main/java/bridge/ResultStatus.java new file mode 100644 index 00000000000..f8ac3e750c8 --- /dev/null +++ b/src/main/java/bridge/ResultStatus.java @@ -0,0 +1,5 @@ +package bridge; + +public enum ResultStatus { + O, X +} From da08a5cea160032cad536d00dd4e77860e602e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 01:22:52 +0900 Subject: [PATCH 20/35] =?UTF-8?q?feat(Result):=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 도메인 클래스 추가 - Result --- docs/README.md | 3 +++ src/main/java/bridge/Result.java | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/main/java/bridge/Result.java diff --git a/docs/README.md b/docs/README.md index 4dee7396974..e3220070935 100644 --- a/docs/README.md +++ b/docs/README.md @@ -64,6 +64,9 @@ - Bridge - create() Bridge 객체 생성 팩토리 메서드 +- Result + - addResultStatus() 결과 상태 추가 + ## 열거형 목록 - BridgeGameMessage - 게임 메시지 diff --git a/src/main/java/bridge/Result.java b/src/main/java/bridge/Result.java new file mode 100644 index 00000000000..1c84d3e2d0c --- /dev/null +++ b/src/main/java/bridge/Result.java @@ -0,0 +1,16 @@ +package bridge; + +import java.util.ArrayList; +import java.util.List; + +public class Result { + private final List resultStatusList; + + public Result() { + this.resultStatusList = new ArrayList<>(); + } + + public void addResultStatus(final ResultStatus resultStatus) { + this.resultStatusList.add(resultStatus); + } +} From c858e4d88705c549da05975b0c7d12493c4685c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 01:26:20 +0900 Subject: [PATCH 21/35] =?UTF-8?q?refactor:=20result=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 클래스 이름 리팩토링 - Result -> GameResult - ResultStatus -> GameResultStatus --- src/main/java/bridge/GameResult.java | 16 ++++++++++++++++ src/main/java/bridge/GameResultStatus.java | 5 +++++ src/main/java/bridge/Result.java | 16 ---------------- src/main/java/bridge/ResultStatus.java | 5 ----- 4 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 src/main/java/bridge/GameResult.java create mode 100644 src/main/java/bridge/GameResultStatus.java delete mode 100644 src/main/java/bridge/Result.java delete mode 100644 src/main/java/bridge/ResultStatus.java diff --git a/src/main/java/bridge/GameResult.java b/src/main/java/bridge/GameResult.java new file mode 100644 index 00000000000..0f50bdc222b --- /dev/null +++ b/src/main/java/bridge/GameResult.java @@ -0,0 +1,16 @@ +package bridge; + +import java.util.ArrayList; +import java.util.List; + +public class GameResult { + private final List gameResultStatusList; + + public GameResult() { + this.gameResultStatusList = new ArrayList<>(); + } + + public void addResultStatus(final GameResultStatus gameResultStatus) { + this.gameResultStatusList.add(gameResultStatus); + } +} diff --git a/src/main/java/bridge/GameResultStatus.java b/src/main/java/bridge/GameResultStatus.java new file mode 100644 index 00000000000..01283d6448c --- /dev/null +++ b/src/main/java/bridge/GameResultStatus.java @@ -0,0 +1,5 @@ +package bridge; + +public enum GameResultStatus { + O, X +} diff --git a/src/main/java/bridge/Result.java b/src/main/java/bridge/Result.java deleted file mode 100644 index 1c84d3e2d0c..00000000000 --- a/src/main/java/bridge/Result.java +++ /dev/null @@ -1,16 +0,0 @@ -package bridge; - -import java.util.ArrayList; -import java.util.List; - -public class Result { - private final List resultStatusList; - - public Result() { - this.resultStatusList = new ArrayList<>(); - } - - public void addResultStatus(final ResultStatus resultStatus) { - this.resultStatusList.add(resultStatus); - } -} diff --git a/src/main/java/bridge/ResultStatus.java b/src/main/java/bridge/ResultStatus.java deleted file mode 100644 index f8ac3e750c8..00000000000 --- a/src/main/java/bridge/ResultStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package bridge; - -public enum ResultStatus { - O, X -} From 77d58230e5aea5dc21f984248cfdfbc4cad919e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 01:30:37 +0900 Subject: [PATCH 22/35] =?UTF-8?q?refactor:=20=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=96=B8?= =?UTF-8?q?=EC=96=B4=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 도메인 언어 수정 - bridge length -> bridge size --- docs/README.md | 4 ++-- src/main/java/bridge/BridgeGameMessage.java | 2 +- src/main/java/bridge/InputValidator.java | 4 +--- src/main/java/bridge/InputView.java | 2 +- src/main/java/bridge/OutputView.java | 4 ++-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index e3220070935..ce1ff405e1e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -49,11 +49,11 @@ - readGameCommand() - InputValidator - - validateBridgeLengthInput() 다리 길이 입력값 검증 + - validateBridgeSizeInput() 다리 길이 입력값 검증 - OutputView - printGameStart() - - printBridgeLengthRequest() + - printBridgeSizeRequest() - printMap() - printResult() - printMovingRequest() 이동할 칸 입력 요청 출력 diff --git a/src/main/java/bridge/BridgeGameMessage.java b/src/main/java/bridge/BridgeGameMessage.java index 31c48d43a9e..bf5a6ed3429 100644 --- a/src/main/java/bridge/BridgeGameMessage.java +++ b/src/main/java/bridge/BridgeGameMessage.java @@ -2,7 +2,7 @@ public enum BridgeGameMessage { START_GAME("다리 건너기 게임을 시작합니다.\n"), - BRIDGE_LENGTH_REQUEST("다리의 길이를 입력해주세요."), + BRIDGE_SIZE_REQUEST("다리의 길이를 입력해주세요."), MOVE_DIRECTION_REQUEST("이동할 칸을 선택해주세요. (위: %s, 아래: %s)"); private final String message; diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java index 12c17e4351e..f32ff37e7b8 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/InputValidator.java @@ -1,10 +1,8 @@ package bridge; -import java.util.Objects; - public class InputValidator { - public void validateBridgeLengthInput(final String input) { + public void validateBridgeSizeInput(final String input) { validateNumeric(input); validateNotBlank(input); } diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index c45bbd900c2..13c1a46d18b 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -17,7 +17,7 @@ public InputView(final InputValidator inputValidator) { */ public int readBridgeSize() { final String input = Console.readLine(); - inputValidator.validateBridgeLengthInput(input); + inputValidator.validateBridgeSizeInput(input); return Integer.parseInt(input); } diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index 1cb7dda8f01..241b6114600 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -9,8 +9,8 @@ public void printGameStart() { System.out.println(BridgeGameMessage.START_GAME); } - public void printBridgeLengthRequest() { - System.out.println(BridgeGameMessage.BRIDGE_LENGTH_REQUEST); + public void printBridgeSizeRequest() { + System.out.println(BridgeGameMessage.BRIDGE_SIZE_REQUEST); } /** From 062aa123fc9b182cdd49ffc1da33c3484eae71d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 01:54:46 +0900 Subject: [PATCH 23/35] =?UTF-8?q?feat(MoveResultMapper):=20mapper=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 클래스 추가 - MoveResultMapper --- docs/README.md | 25 +++++++++------- src/main/java/bridge/MoveResultMapper.java | 34 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 src/main/java/bridge/MoveResultMapper.java diff --git a/docs/README.md b/docs/README.md index ce1ff405e1e..706384da511 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,16 +1,16 @@ ## 기능 목록 -- [ ] 게임 시작 - - [ ] 게임 시작 메시지 출력 -- [ ] 다리 길이 설정 - - [ ] 다리 길이 입력요청 메시지 출력 - - [ ] 다리 길이 입력 - - [ ] 입력값 숫자 여부 검증 - - [ ] 입력 숫자 3 이상 20 이하 숫자인지 검증 -- [ ] 다리 생성 - - [ ] 길이에 따른 랜덤 다리 생성 +- [x] 게임 시작 + - [x] 게임 시작 메시지 출력 +- [x] 다리 길이 설정 + - [x] 다리 길이 입력요청 메시지 출력 + - [x] 다리 길이 입력 + - [x] 입력값 숫자 여부 검증 + - [x] 입력 숫자 3 이상 20 이하 숫자인지 검증 +- [x] 다리 생성 + - [x] 길이에 따른 랜덤 다리 생성 - [ ] 플레이어 이동 - - [ ] 이동할 칸 입력 - - [ ] 입력값이 U 혹은 D 인지 검증 + - [x] 이동할 칸 입력 + - [x] 입력값이 U 혹은 D 인지 검증 - [ ] 이동 가능한 칸인 경우 O 표시 - [ ] 이동 불가능한 칸인 경우 X 표시 - [ ] 현황 출력 @@ -67,6 +67,9 @@ - Result - addResultStatus() 결과 상태 추가 +- MoveResultMapper + - mapToMoveResult() MoveResult로 매핑 + ## 열거형 목록 - BridgeGameMessage - 게임 메시지 diff --git a/src/main/java/bridge/MoveResultMapper.java b/src/main/java/bridge/MoveResultMapper.java new file mode 100644 index 00000000000..6e6f5e40538 --- /dev/null +++ b/src/main/java/bridge/MoveResultMapper.java @@ -0,0 +1,34 @@ +package bridge; + +public class MoveResultMapper { + private static MoveResultMapper INSTANCE; + private MoveResultMapper() {} + + public static MoveResultMapper getInstance() { + if (INSTANCE == null) { + INSTANCE = new MoveResultMapper(); + } + return INSTANCE; + } + + public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answer, final int leftSize) { + if (leftSize == 0) { + return checkSuccess(input, answer); + } + return checkKeepGoing(input, answer); + } + + private MoveResult checkKeepGoing(final BridgeType input, final BridgeType answer) { + if (input == answer) { + return MoveResult.KEEP_GOING; + } + return MoveResult.FAILED; + } + + private MoveResult checkSuccess(final BridgeType input, final BridgeType answer) { + if (input == answer) { + return MoveResult.SUCCESS; + } + return MoveResult.FAILED; + } +} From 5741ff2467369650345d0bdb3f39c527d86fe7e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 02:00:47 +0900 Subject: [PATCH 24/35] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=EC=97=AC=EB=B6=80=20=ED=8C=90=EB=B3=84=20=EB=B0=8F?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 이동 가능 여부 판별 - 이동 가능 여부 저장 --- docs/README.md | 4 ++-- src/main/java/bridge/Bridge.java | 20 ++++++++++++------ src/main/java/bridge/BridgeGame.java | 28 ++++++++++++++++++++++++-- src/main/java/bridge/ErrorMessage.java | 3 ++- src/main/java/bridge/MoveResult.java | 4 ++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index 706384da511..372a63127d2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,8 +11,8 @@ - [ ] 플레이어 이동 - [x] 이동할 칸 입력 - [x] 입력값이 U 혹은 D 인지 검증 - - [ ] 이동 가능한 칸인 경우 O 표시 - - [ ] 이동 불가능한 칸인 경우 X 표시 + - [x] 이동 가능한 칸인 경우 O 표시 + - [x] 이동 불가능한 칸인 경우 X 표시 - [ ] 현황 출력 - [ ] 게임 성공 여부 판단 - [ ] 이동 불가능한 칸으로 이동한 경우 실패 diff --git a/src/main/java/bridge/Bridge.java b/src/main/java/bridge/Bridge.java index 7b47811033d..011903d4344 100644 --- a/src/main/java/bridge/Bridge.java +++ b/src/main/java/bridge/Bridge.java @@ -1,16 +1,24 @@ package bridge; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; -public final class Bridge { +public class Bridge { + private static final int FIRST_ELEMENT_INDEX = 0; private final List directions; - private Bridge(final List directions) { - this.directions = Collections.unmodifiableList(directions); + public Bridge(final List directions) { + this.directions = new ArrayList<>(directions); } - public static Bridge create(final List directions) { - return new Bridge(directions); + public BridgeType getFirstElement() { + if (directions.isEmpty()) { + throw new IllegalArgumentException(ErrorMessage.NO_ELEMENT_LEFT.toString()); + } + return BridgeType.valueOf(directions.remove(FIRST_ELEMENT_INDEX)); + } + + public int getLeftSize() { + return directions.size(); } } diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java index 834c1c8362b..84791f9a870 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/BridgeGame.java @@ -1,16 +1,32 @@ package bridge; +import java.util.List; + /** * 다리 건너기 게임을 관리하는 클래스 */ public class BridgeGame { + private final Bridge bridge; + private final GameResult gameResult; + + public BridgeGame(final List bridgeDirections) { + this.bridge = new Bridge(bridgeDirections); + this.gameResult = new GameResult(); + } /** * 사용자가 칸을 이동할 때 사용하는 메서드 *

* 이동을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public void move() { + public MoveResult move(final String movingInput) { + final BridgeType inputBridgeType = BridgeType.valueOf(movingInput); + final BridgeType answerBridgeType = bridge.getFirstElement(); + + final MoveResultMapper moveResultMapper = MoveResultMapper.getInstance(); + final MoveResult moveResult = moveResultMapper.mapToMoveResult(inputBridgeType, answerBridgeType, bridge.getLeftSize()); + addGameResultStatus(moveResult); + return moveResult; } /** @@ -18,6 +34,14 @@ public void move() { *

* 재시작을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public void retry() { + public boolean retry() { + return true; + } + + private void addGameResultStatus(final MoveResult moveResult) { + if (moveResult.isFailed()) { + gameResult.addResultStatus(GameResultStatus.X); + } + gameResult.addResultStatus(GameResultStatus.O); } } diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/ErrorMessage.java index d4a8d9de0de..c33b7137671 100644 --- a/src/main/java/bridge/ErrorMessage.java +++ b/src/main/java/bridge/ErrorMessage.java @@ -4,7 +4,8 @@ public enum ErrorMessage { NOT_NUMERIC_INPUT("숫자만 입력 가능합니다."), BLANK_INPUT("입력값이 비어있습니다."), INVALID_CLASSIFIER("다리의 숫자 값이 올바르지 않습니다."), - INVALID_MOVE_DIRECTION("이동 방향 입력값은 %s 혹은 %s 입니다."); + INVALID_MOVE_DIRECTION("이동 방향 입력값은 %s 혹은 %s 입니다."), + NO_ELEMENT_LEFT("리스트의 원소가 없습니다."); private final String message; private static final String ERROR_PREFIX = "[ERROR] "; diff --git a/src/main/java/bridge/MoveResult.java b/src/main/java/bridge/MoveResult.java index 945526eb967..7fd56f9996d 100644 --- a/src/main/java/bridge/MoveResult.java +++ b/src/main/java/bridge/MoveResult.java @@ -6,4 +6,8 @@ public enum MoveResult { public boolean isContinue() { return this == KEEP_GOING; } + + public boolean isFailed() { + return this == FAILED; + } } From 86e3674dca1610128cc54a856800399cbad5521d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 02:44:23 +0900 Subject: [PATCH 25/35] =?UTF-8?q?feat:=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=20=EC=9D=B4=EB=8F=99=20=EA=B8=B0=EB=8A=A5=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=20map=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 플레이어 이동 - 결과 map 출력 --- docs/README.md | 11 +++--- src/main/java/bridge/Bridge.java | 11 +++--- src/main/java/bridge/BridgeGame.java | 38 +++++++++++++++++---- src/main/java/bridge/BridgeGameManager.java | 37 +++++++++++++++++--- src/main/java/bridge/GameResult.java | 11 ++++++ src/main/java/bridge/GameResultStatus.java | 12 ++++++- src/main/java/bridge/OutputView.java | 3 +- 7 files changed, 101 insertions(+), 22 deletions(-) diff --git a/docs/README.md b/docs/README.md index 372a63127d2..f78ad9018a8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,12 +8,12 @@ - [x] 입력 숫자 3 이상 20 이하 숫자인지 검증 - [x] 다리 생성 - [x] 길이에 따른 랜덤 다리 생성 -- [ ] 플레이어 이동 +- [x] 플레이어 이동 - [x] 이동할 칸 입력 - [x] 입력값이 U 혹은 D 인지 검증 - [x] 이동 가능한 칸인 경우 O 표시 - [x] 이동 불가능한 칸인 경우 X 표시 - - [ ] 현황 출력 + - [x] 현황 출력 - [ ] 게임 성공 여부 판단 - [ ] 이동 불가능한 칸으로 이동한 경우 실패 - [ ] 모두 이동 가능한 칸으로만 이동한 경우 성공 @@ -30,6 +30,7 @@ - BridgeGame - move() - retry() + - getGameResultMap() result map 문자열 반환 - BridgeGameManager - playBridgeGame() 게임 실행 @@ -64,8 +65,10 @@ - Bridge - create() Bridge 객체 생성 팩토리 메서드 -- Result +- GameResult - addResultStatus() 결과 상태 추가 + - getFirstBridgeElement() 다리의 첫번째 요소 조회 + - getBridgeLeftSize() 다리 잔여 사이즈 조회 - MoveResultMapper - mapToMoveResult() MoveResult로 매핑 @@ -83,5 +86,5 @@ - MoveResult - 이동 결과 -- ResultStatus +- GameResultStatus - 결과 상태 diff --git a/src/main/java/bridge/Bridge.java b/src/main/java/bridge/Bridge.java index 011903d4344..128f87c1678 100644 --- a/src/main/java/bridge/Bridge.java +++ b/src/main/java/bridge/Bridge.java @@ -4,18 +4,21 @@ import java.util.List; public class Bridge { - private static final int FIRST_ELEMENT_INDEX = 0; private final List directions; public Bridge(final List directions) { this.directions = new ArrayList<>(directions); } - public BridgeType getFirstElement() { - if (directions.isEmpty()) { + public BridgeType getNextElement(final int currentIndex) { + validateIndex(currentIndex); + return BridgeType.valueOf(directions.get(currentIndex)); + } + + private void validateIndex(final int currentIndex) { + if (directions.size() <= currentIndex) { throw new IllegalArgumentException(ErrorMessage.NO_ELEMENT_LEFT.toString()); } - return BridgeType.valueOf(directions.remove(FIRST_ELEMENT_INDEX)); } public int getLeftSize() { diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java index 84791f9a870..451268c22b6 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/BridgeGame.java @@ -6,12 +6,17 @@ * 다리 건너기 게임을 관리하는 클래스 */ public class BridgeGame { + private static final String LINE_DELIMETER = "\n"; + private final GameResult upperGameResult; + private final GameResult lowerGameResult; private final Bridge bridge; - private final GameResult gameResult; + private Integer currentIndex; public BridgeGame(final List bridgeDirections) { this.bridge = new Bridge(bridgeDirections); - this.gameResult = new GameResult(); + this.upperGameResult = new GameResult(); + this.lowerGameResult = new GameResult(); + initCurrentIndex(); } /** @@ -21,11 +26,11 @@ public BridgeGame(final List bridgeDirections) { */ public MoveResult move(final String movingInput) { final BridgeType inputBridgeType = BridgeType.valueOf(movingInput); - final BridgeType answerBridgeType = bridge.getFirstElement(); + final BridgeType answerBridgeType = bridge.getNextElement(currentIndex++); final MoveResultMapper moveResultMapper = MoveResultMapper.getInstance(); final MoveResult moveResult = moveResultMapper.mapToMoveResult(inputBridgeType, answerBridgeType, bridge.getLeftSize()); - addGameResultStatus(moveResult); + addGameResultStatus(moveResult, answerBridgeType); return moveResult; } @@ -38,10 +43,29 @@ public boolean retry() { return true; } - private void addGameResultStatus(final MoveResult moveResult) { + private void addGameResultStatus(final MoveResult moveResult, final BridgeType answerBridgeType) { if (moveResult.isFailed()) { - gameResult.addResultStatus(GameResultStatus.X); + addToValidGameResult(answerBridgeType, GameResultStatus.X); + return; } - gameResult.addResultStatus(GameResultStatus.O); + addToValidGameResult(answerBridgeType, GameResultStatus.O); + } + + private void addToValidGameResult(final BridgeType answerBridgeType, final GameResultStatus gameResultStatus) { + if (answerBridgeType.equals(BridgeType.U)) { + upperGameResult.addResultStatus(gameResultStatus); + lowerGameResult.addResultStatus(GameResultStatus.NONE); + return; + } + upperGameResult.addResultStatus(GameResultStatus.NONE); + lowerGameResult.addResultStatus(gameResultStatus); + } + + public String getGameResultMap() { + return this.upperGameResult + LINE_DELIMETER + this.lowerGameResult; + } + + private void initCurrentIndex() { + this.currentIndex = 0; } } diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index bef8185de3d..bbb19796c5a 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -1,8 +1,7 @@ package bridge; -import java.util.List; - public class BridgeGameManager { + private static final int TRY_INITIAL_COUNT = 1; private final InputView inputView; private final OutputView outputView; private final BridgeMaker bridgeMaker; @@ -20,10 +19,38 @@ public void playBridgeGame() { private void playUntilGameEnd() { boolean isGameRunning = true; + int tryCount = TRY_INITIAL_COUNT; while (isGameRunning) { - outputView.printBridgeLengthRequest(); - final int bridgeLength = inputView.readBridgeSize(); - final List bridgeDirections = bridgeMaker.makeBridge(bridgeLength); + final BridgeGame bridgeGame = makeBridgeGameWithSize(); + isGameRunning = moveAndGetRetryStatus(bridgeGame); + if (isGameRunning) { + tryCount++; + } + } + } + + private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { + boolean isContinue = true; + while (isContinue) { + final MoveResult moveResult = tryMove(bridgeGame); + outputView.printMap(bridgeGame.getGameResultMap()); + if (moveResult.isFailed()) { + return bridgeGame.retry(); + } + isContinue = moveResult.isContinue(); } + return false; + } + + private BridgeGame makeBridgeGameWithSize() { + outputView.printBridgeSizeRequest(); + final int bridgeSize = inputView.readBridgeSize(); + return new BridgeGame(bridgeMaker.makeBridge(bridgeSize)); + } + + private MoveResult tryMove(final BridgeGame bridgeGame) { + outputView.printMovingRequest(); + final String movingInput = inputView.readMoving(); + return bridgeGame.move(movingInput); } } diff --git a/src/main/java/bridge/GameResult.java b/src/main/java/bridge/GameResult.java index 0f50bdc222b..c681adb05a9 100644 --- a/src/main/java/bridge/GameResult.java +++ b/src/main/java/bridge/GameResult.java @@ -2,8 +2,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class GameResult { + private static final String START_TAG = "[ "; + private static final String END_TAG = " ]"; + private static final String SEPARATOR = " | "; private final List gameResultStatusList; public GameResult() { @@ -13,4 +17,11 @@ public GameResult() { public void addResultStatus(final GameResultStatus gameResultStatus) { this.gameResultStatusList.add(gameResultStatus); } + + @Override + public String toString() { + return START_TAG + gameResultStatusList.stream() + .map(GameResultStatus::toString) + .collect(Collectors.joining(SEPARATOR)) + END_TAG; + } } diff --git a/src/main/java/bridge/GameResultStatus.java b/src/main/java/bridge/GameResultStatus.java index 01283d6448c..d31c27904cd 100644 --- a/src/main/java/bridge/GameResultStatus.java +++ b/src/main/java/bridge/GameResultStatus.java @@ -1,5 +1,15 @@ package bridge; public enum GameResultStatus { - O, X + O, X, NONE; + + private static final String BLANK = " "; + + @Override + public String toString() { + if (this == NONE) { + return BLANK; + } + return this.name(); + } } diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index 241b6114600..17f4aadc0a4 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -18,7 +18,8 @@ public void printBridgeSizeRequest() { *

* 출력을 위해 필요한 메서드의 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public void printMap() { + public void printMap(final String gameResultMap) { + System.out.println(gameResultMap); } /** From 4bd7b8e7a994e48e158721a093f8281b82755e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 03:06:13 +0900 Subject: [PATCH 26/35] =?UTF-8?q?feat:=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능 추가 - 재시도 여부 입력 기능 - 재시도 기능 --- docs/README.md | 22 +++++++++---------- src/main/java/bridge/Bridge.java | 4 ++-- src/main/java/bridge/BridgeGame.java | 12 +++++++--- src/main/java/bridge/BridgeGameManager.java | 11 ++++++++-- ...ridgeGameMessage.java => GameMessage.java} | 8 ++++--- src/main/java/bridge/GameResult.java | 4 ++++ src/main/java/bridge/InputView.java | 5 +++++ src/main/java/bridge/OutputView.java | 14 +++++++++--- src/main/java/bridge/RetryCommand.java | 5 +++++ 9 files changed, 61 insertions(+), 24 deletions(-) rename src/main/java/bridge/{BridgeGameMessage.java => GameMessage.java} (58%) create mode 100644 src/main/java/bridge/RetryCommand.java diff --git a/docs/README.md b/docs/README.md index f78ad9018a8..9a223be8689 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,17 +14,17 @@ - [x] 이동 가능한 칸인 경우 O 표시 - [x] 이동 불가능한 칸인 경우 X 표시 - [x] 현황 출력 -- [ ] 게임 성공 여부 판단 - - [ ] 이동 불가능한 칸으로 이동한 경우 실패 - - [ ] 모두 이동 가능한 칸으로만 이동한 경우 성공 - - [ ] 성공 메시지 출력 - - [ ] 총 시도 횟수 출력 -- [ ] 실패시 게임 재시작 여부 판단 - - [ ] 게임 재시작 여부 입력 +- [x] 게임 성공 여부 판단 + - [x] 이동 불가능한 칸으로 이동한 경우 실패 + - [x] 모두 이동 가능한 칸으로만 이동한 경우 성공 + - [x] 성공 메시지 출력 + - [x] 총 시도 횟수 출력 +- [x] 실패시 게임 재시작 여부 판단 + - [x] 게임 재시작 여부 입력 - [ ] 입력값 R 혹은 Q 인지 검증 -- [ ] 게임 재시작 - - [ ] 게임 시도 횟수 증가 -- [ ] 게임 종료 +- [x] 게임 재시작 + - [x] 게임 시도 횟수 증가 +- [x] 게임 종료 ## 구현 클래스 목록 - BridgeGame @@ -74,7 +74,7 @@ - mapToMoveResult() MoveResult로 매핑 ## 열거형 목록 -- BridgeGameMessage +- GameMessage - 게임 메시지 - BridgeType diff --git a/src/main/java/bridge/Bridge.java b/src/main/java/bridge/Bridge.java index 128f87c1678..ec0f42b0cf5 100644 --- a/src/main/java/bridge/Bridge.java +++ b/src/main/java/bridge/Bridge.java @@ -21,7 +21,7 @@ private void validateIndex(final int currentIndex) { } } - public int getLeftSize() { - return directions.size(); + public int getLeftSize(final int currentIndex) { + return directions.size() - currentIndex; } } diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java index 451268c22b6..0d121c17e13 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/BridgeGame.java @@ -29,7 +29,7 @@ public MoveResult move(final String movingInput) { final BridgeType answerBridgeType = bridge.getNextElement(currentIndex++); final MoveResultMapper moveResultMapper = MoveResultMapper.getInstance(); - final MoveResult moveResult = moveResultMapper.mapToMoveResult(inputBridgeType, answerBridgeType, bridge.getLeftSize()); + final MoveResult moveResult = moveResultMapper.mapToMoveResult(inputBridgeType, answerBridgeType, bridge.getLeftSize(currentIndex)); addGameResultStatus(moveResult, answerBridgeType); return moveResult; } @@ -39,8 +39,14 @@ public MoveResult move(final String movingInput) { *

* 재시작을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public boolean retry() { - return true; + public boolean retry(final String retryInput) { + if (retryInput.equals(RetryCommand.R.toString())) { + initCurrentIndex(); + upperGameResult.clearResult(); + lowerGameResult.clearResult(); + return true; + } + return false; } private void addGameResultStatus(final MoveResult moveResult, final BridgeType answerBridgeType) { diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index bbb19796c5a..61de14bf5a6 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -20,13 +20,14 @@ public void playBridgeGame() { private void playUntilGameEnd() { boolean isGameRunning = true; int tryCount = TRY_INITIAL_COUNT; + final BridgeGame bridgeGame = makeBridgeGameWithSize(); while (isGameRunning) { - final BridgeGame bridgeGame = makeBridgeGameWithSize(); isGameRunning = moveAndGetRetryStatus(bridgeGame); if (isGameRunning) { tryCount++; } } + outputView.printSuccess(tryCount); } private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { @@ -35,13 +36,19 @@ private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { final MoveResult moveResult = tryMove(bridgeGame); outputView.printMap(bridgeGame.getGameResultMap()); if (moveResult.isFailed()) { - return bridgeGame.retry(); + return checkRetryOrNot(bridgeGame); } isContinue = moveResult.isContinue(); } return false; } + private boolean checkRetryOrNot(final BridgeGame bridgeGame) { + outputView.printRetryRequest(); + final String retryInput = inputView.readRetry(); + return bridgeGame.retry(retryInput); + } + private BridgeGame makeBridgeGameWithSize() { outputView.printBridgeSizeRequest(); final int bridgeSize = inputView.readBridgeSize(); diff --git a/src/main/java/bridge/BridgeGameMessage.java b/src/main/java/bridge/GameMessage.java similarity index 58% rename from src/main/java/bridge/BridgeGameMessage.java rename to src/main/java/bridge/GameMessage.java index bf5a6ed3429..768434da39d 100644 --- a/src/main/java/bridge/BridgeGameMessage.java +++ b/src/main/java/bridge/GameMessage.java @@ -1,13 +1,15 @@ package bridge; -public enum BridgeGameMessage { +public enum GameMessage { START_GAME("다리 건너기 게임을 시작합니다.\n"), BRIDGE_SIZE_REQUEST("다리의 길이를 입력해주세요."), - MOVE_DIRECTION_REQUEST("이동할 칸을 선택해주세요. (위: %s, 아래: %s)"); + MOVE_DIRECTION_REQUEST("이동할 칸을 선택해주세요. (위: %s, 아래: %s)"), + SUCCESS("게임 성공 여부: 성공\n총 시도한 횟수: %s"), + RETRY_REQUEST("게임을 다시 시도할지 여부를 입력해주세요. (재시도: %s, 종료: %s)"); private final String message; - BridgeGameMessage(String message) { + GameMessage(String message) { this.message = message; } diff --git a/src/main/java/bridge/GameResult.java b/src/main/java/bridge/GameResult.java index c681adb05a9..1d58d7f6d5c 100644 --- a/src/main/java/bridge/GameResult.java +++ b/src/main/java/bridge/GameResult.java @@ -24,4 +24,8 @@ public String toString() { .map(GameResultStatus::toString) .collect(Collectors.joining(SEPARATOR)) + END_TAG; } + + public void clearResult() { + this.gameResultStatusList.clear(); + } } diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index 13c1a46d18b..156bbc0897f 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -36,4 +36,9 @@ public String readMoving() { public String readGameCommand() { return null; } + + public String readRetry() { + final String input = Console.readLine(); + return input; + } } diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index 17f4aadc0a4..9de20319082 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -6,11 +6,11 @@ public class OutputView { public void printGameStart() { - System.out.println(BridgeGameMessage.START_GAME); + System.out.println(GameMessage.START_GAME); } public void printBridgeSizeRequest() { - System.out.println(BridgeGameMessage.BRIDGE_SIZE_REQUEST); + System.out.println(GameMessage.BRIDGE_SIZE_REQUEST); } /** @@ -31,6 +31,14 @@ public void printResult() { } public void printMovingRequest() { - System.out.println(String.format(BridgeGameMessage.MOVE_DIRECTION_REQUEST.toString(), BridgeType.U, BridgeType.D)); + System.out.println(String.format(GameMessage.MOVE_DIRECTION_REQUEST.toString(), BridgeType.U, BridgeType.D)); + } + + public void printSuccess(final int tryCount) { + System.out.println(String.format(GameMessage.SUCCESS.toString(), tryCount)); + } + + public void printRetryRequest() { + System.out.println(String.format(GameMessage.RETRY_REQUEST.toString(), RetryCommand.R, RetryCommand.Q)); } } diff --git a/src/main/java/bridge/RetryCommand.java b/src/main/java/bridge/RetryCommand.java new file mode 100644 index 00000000000..d7cde10b049 --- /dev/null +++ b/src/main/java/bridge/RetryCommand.java @@ -0,0 +1,5 @@ +package bridge; + +public enum RetryCommand { + R, Q +} From 7d7ab12a97d58c9f61d5050659fc539a6edbd8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 03:42:43 +0900 Subject: [PATCH 27/35] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EC=99=80=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - TryCount 도메인 추가 - 상수 추가 - 결과 map 위치 오류 수정 --- docs/README.md | 6 ++++- src/main/java/bridge/BridgeGame.java | 29 ++++++++++++++------- src/main/java/bridge/BridgeGameManager.java | 13 +++++---- src/main/java/bridge/BridgeMaker.java | 5 ++++ src/main/java/bridge/ErrorMessage.java | 5 +++- src/main/java/bridge/InputValidator.java | 10 ++++++- src/main/java/bridge/InputView.java | 5 +--- src/main/java/bridge/OutputView.java | 7 ++--- src/main/java/bridge/TryCount.java | 19 ++++++++++++++ 9 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 src/main/java/bridge/TryCount.java diff --git a/docs/README.md b/docs/README.md index 9a223be8689..ddcdc059249 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,7 +21,7 @@ - [x] 총 시도 횟수 출력 - [x] 실패시 게임 재시작 여부 판단 - [x] 게임 재시작 여부 입력 - - [ ] 입력값 R 혹은 Q 인지 검증 + - [x] 입력값 R 혹은 Q 인지 검증 - [x] 게임 재시작 - [x] 게임 시도 횟수 증가 - [x] 게임 종료 @@ -73,6 +73,10 @@ - MoveResultMapper - mapToMoveResult() MoveResult로 매핑 +- TryCount + - increment() 시도 횟수 증가 + - toString() 시도 횟수 문자열로 반환 + ## 열거형 목록 - GameMessage - 게임 메시지 diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java index 0d121c17e13..96e54e9950b 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/BridgeGame.java @@ -6,7 +6,8 @@ * 다리 건너기 게임을 관리하는 클래스 */ public class BridgeGame { - private static final String LINE_DELIMETER = "\n"; + private static final String LINE_DELIMITER = "\n"; + private static final int INITIAL_INDEX = 0; private final GameResult upperGameResult; private final GameResult lowerGameResult; private final Bridge bridge; @@ -51,27 +52,35 @@ public boolean retry(final String retryInput) { private void addGameResultStatus(final MoveResult moveResult, final BridgeType answerBridgeType) { if (moveResult.isFailed()) { - addToValidGameResult(answerBridgeType, GameResultStatus.X); + addToProperGameResult(answerBridgeType, GameResultStatus.X, false); return; } - addToValidGameResult(answerBridgeType, GameResultStatus.O); + addToProperGameResult(answerBridgeType, GameResultStatus.O, true); } - private void addToValidGameResult(final BridgeType answerBridgeType, final GameResultStatus gameResultStatus) { + private void addToProperGameResult(final BridgeType answerBridgeType, final GameResultStatus gameResultStatus, final boolean isSuccess) { if (answerBridgeType.equals(BridgeType.U)) { - upperGameResult.addResultStatus(gameResultStatus); - lowerGameResult.addResultStatus(GameResultStatus.NONE); + addResultStatus(isSuccess, gameResultStatus, GameResultStatus.NONE); return; } - upperGameResult.addResultStatus(GameResultStatus.NONE); - lowerGameResult.addResultStatus(gameResultStatus); + addResultStatus(isSuccess, GameResultStatus.NONE, gameResultStatus); + } + + private void addResultStatus(final boolean isSuccess, final GameResultStatus resultStatus, final GameResultStatus oppositeStatus) { + if (isSuccess) { + upperGameResult.addResultStatus(resultStatus); + lowerGameResult.addResultStatus(oppositeStatus); + return; + } + upperGameResult.addResultStatus(oppositeStatus); + lowerGameResult.addResultStatus(resultStatus); } public String getGameResultMap() { - return this.upperGameResult + LINE_DELIMETER + this.lowerGameResult; + return this.upperGameResult + LINE_DELIMITER + this.lowerGameResult; } private void initCurrentIndex() { - this.currentIndex = 0; + this.currentIndex = INITIAL_INDEX; } } diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index 61de14bf5a6..f574a38f884 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -1,7 +1,6 @@ package bridge; public class BridgeGameManager { - private static final int TRY_INITIAL_COUNT = 1; private final InputView inputView; private final OutputView outputView; private final BridgeMaker bridgeMaker; @@ -19,15 +18,15 @@ public void playBridgeGame() { private void playUntilGameEnd() { boolean isGameRunning = true; - int tryCount = TRY_INITIAL_COUNT; + final TryCount tryCount = new TryCount(); final BridgeGame bridgeGame = makeBridgeGameWithSize(); while (isGameRunning) { isGameRunning = moveAndGetRetryStatus(bridgeGame); if (isGameRunning) { - tryCount++; + tryCount.increment(); } } - outputView.printSuccess(tryCount); + outputView.printResult(tryCount); } private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { @@ -36,16 +35,16 @@ private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { final MoveResult moveResult = tryMove(bridgeGame); outputView.printMap(bridgeGame.getGameResultMap()); if (moveResult.isFailed()) { - return checkRetryOrNot(bridgeGame); + return checkRetry(bridgeGame); } isContinue = moveResult.isContinue(); } return false; } - private boolean checkRetryOrNot(final BridgeGame bridgeGame) { + private boolean checkRetry(final BridgeGame bridgeGame) { outputView.printRetryRequest(); - final String retryInput = inputView.readRetry(); + final String retryInput = inputView.readGameCommand(); return bridgeGame.retry(retryInput); } diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/BridgeMaker.java index f35119b87f3..1eacb71d794 100644 --- a/src/main/java/bridge/BridgeMaker.java +++ b/src/main/java/bridge/BridgeMaker.java @@ -9,6 +9,8 @@ */ public class BridgeMaker { private static final int RANGE_START = 0; + private static final int MIN_BRIDGE_SIZE = 3; + private static final int MAX_BRIDGE_SIZE = 20; private final BridgeNumberGenerator bridgeNumberGenerator; public BridgeMaker(final BridgeNumberGenerator bridgeNumberGenerator) { @@ -20,6 +22,9 @@ public BridgeMaker(final BridgeNumberGenerator bridgeNumberGenerator) { * @return 입력받은 길이에 해당하는 다리 모양. 위 칸이면 "U", 아래 칸이면 "D"로 표현해야 한다. */ public List makeBridge(final int size) { + if (size < MIN_BRIDGE_SIZE || MAX_BRIDGE_SIZE < size) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_BRIDGE_SIZE.toString(), MIN_BRIDGE_SIZE, MAX_BRIDGE_SIZE)); + } return IntStream.range(RANGE_START, size) .mapToObj(i -> getBridgeDirection()) .collect(Collectors.toList()); diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/ErrorMessage.java index c33b7137671..d4b5a865ab4 100644 --- a/src/main/java/bridge/ErrorMessage.java +++ b/src/main/java/bridge/ErrorMessage.java @@ -5,7 +5,10 @@ public enum ErrorMessage { BLANK_INPUT("입력값이 비어있습니다."), INVALID_CLASSIFIER("다리의 숫자 값이 올바르지 않습니다."), INVALID_MOVE_DIRECTION("이동 방향 입력값은 %s 혹은 %s 입니다."), - NO_ELEMENT_LEFT("리스트의 원소가 없습니다."); + NO_ELEMENT_LEFT("리스트의 원소가 없습니다."), + INVALID_RETRY_COMMAND("재시도 여부 입력값은 %s 혹은 %s 입니다."), + INVALID_BRIDGE_SIZE("다리의 길이는 %d 이상, %d 이하입니다."); + private final String message; private static final String ERROR_PREFIX = "[ERROR] "; diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/InputValidator.java index f32ff37e7b8..c3465703a3d 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/InputValidator.java @@ -1,6 +1,8 @@ package bridge; public class InputValidator { + private static final Character START_NUMBER = '0'; + private static final Character END_NUMBER = '9'; public void validateBridgeSizeInput(final String input) { validateNumeric(input); @@ -18,7 +20,7 @@ private boolean hasNonNumber(final String input) { } private boolean isNumber(int character) { - return '0' <= character && character <= '9'; + return START_NUMBER <= character && character <= END_NUMBER; } private void validateNotBlank(final String input) { @@ -37,4 +39,10 @@ private void validateMoveDirection(final String input) { throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_MOVE_DIRECTION.toString(), BridgeType.U, BridgeType.D)); } } + + public void validateGameCommandInput(final String input) { + if (!input.equals(RetryCommand.R.toString()) && !input.equals(RetryCommand.Q.toString())) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_RETRY_COMMAND.toString(), RetryCommand.R, RetryCommand.Q)); + } + } } diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java index 156bbc0897f..8cd35110631 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/InputView.java @@ -34,11 +34,8 @@ public String readMoving() { * 사용자가 게임을 다시 시도할지 종료할지 여부를 입력받는다. */ public String readGameCommand() { - return null; - } - - public String readRetry() { final String input = Console.readLine(); + inputValidator.validateGameCommandInput(input); return input; } } diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index 9de20319082..a30782e8316 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -27,17 +27,14 @@ public void printMap(final String gameResultMap) { *

* 출력을 위해 필요한 메서드의 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public void printResult() { + public void printResult(final TryCount tryCount) { + System.out.println(String.format(GameMessage.SUCCESS.toString(), tryCount)); } public void printMovingRequest() { System.out.println(String.format(GameMessage.MOVE_DIRECTION_REQUEST.toString(), BridgeType.U, BridgeType.D)); } - public void printSuccess(final int tryCount) { - System.out.println(String.format(GameMessage.SUCCESS.toString(), tryCount)); - } - public void printRetryRequest() { System.out.println(String.format(GameMessage.RETRY_REQUEST.toString(), RetryCommand.R, RetryCommand.Q)); } diff --git a/src/main/java/bridge/TryCount.java b/src/main/java/bridge/TryCount.java new file mode 100644 index 00000000000..6296f8c3552 --- /dev/null +++ b/src/main/java/bridge/TryCount.java @@ -0,0 +1,19 @@ +package bridge; + +public class TryCount { + private static final int INITIAL_COUNT = 1; + private int count; + + public TryCount() { + this.count = INITIAL_COUNT; + } + + @Override + public String toString() { + return String.valueOf(this.count); + } + + public void increment() { + this.count++; + } +} From bd71b0f66530d9e513d0138c6ad63db9d1a30d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 04:10:51 +0900 Subject: [PATCH 28/35] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=8B=B1=EA=B8=80=ED=86=A4=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - MoveResultMapper 싱글톤 제거 - 불필요 메서드 제거 --- src/main/java/bridge/BridgeGame.java | 5 +- src/main/java/bridge/BridgeGameManager.java | 51 ++++++++++++--------- src/main/java/bridge/BridgeMaker.java | 4 +- src/main/java/bridge/GameMessage.java | 3 +- src/main/java/bridge/MoveResult.java | 10 +--- src/main/java/bridge/MoveResultMapper.java | 12 +---- src/main/java/bridge/OutputView.java | 8 +++- 7 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java index 96e54e9950b..47e6fd99c72 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/BridgeGame.java @@ -10,6 +10,7 @@ public class BridgeGame { private static final int INITIAL_INDEX = 0; private final GameResult upperGameResult; private final GameResult lowerGameResult; + private final MoveResultMapper moveResultMapper; // 요구사항에 의해 한 번만 생성될 것이므로 싱글톤으로 구현하지 않음 private final Bridge bridge; private Integer currentIndex; @@ -17,6 +18,7 @@ public BridgeGame(final List bridgeDirections) { this.bridge = new Bridge(bridgeDirections); this.upperGameResult = new GameResult(); this.lowerGameResult = new GameResult(); + this.moveResultMapper = new MoveResultMapper(); initCurrentIndex(); } @@ -29,7 +31,6 @@ public MoveResult move(final String movingInput) { final BridgeType inputBridgeType = BridgeType.valueOf(movingInput); final BridgeType answerBridgeType = bridge.getNextElement(currentIndex++); - final MoveResultMapper moveResultMapper = MoveResultMapper.getInstance(); final MoveResult moveResult = moveResultMapper.mapToMoveResult(inputBridgeType, answerBridgeType, bridge.getLeftSize(currentIndex)); addGameResultStatus(moveResult, answerBridgeType); return moveResult; @@ -51,7 +52,7 @@ public boolean retry(final String retryInput) { } private void addGameResultStatus(final MoveResult moveResult, final BridgeType answerBridgeType) { - if (moveResult.isFailed()) { + if (moveResult == MoveResult.FAILED) { addToProperGameResult(answerBridgeType, GameResultStatus.X, false); return; } diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/BridgeGameManager.java index f574a38f884..15056dd5eb7 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/BridgeGameManager.java @@ -13,7 +13,11 @@ public BridgeGameManager(final InputView inputView, final OutputView outputView, public void playBridgeGame() { outputView.printGameStart(); - playUntilGameEnd(); + try { + playUntilGameEnd(); + } catch (IllegalArgumentException e) { + outputView.printErrorMessage(e.getMessage()); + } } private void playUntilGameEnd() { @@ -26,26 +30,7 @@ private void playUntilGameEnd() { tryCount.increment(); } } - outputView.printResult(tryCount); - } - - private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { - boolean isContinue = true; - while (isContinue) { - final MoveResult moveResult = tryMove(bridgeGame); - outputView.printMap(bridgeGame.getGameResultMap()); - if (moveResult.isFailed()) { - return checkRetry(bridgeGame); - } - isContinue = moveResult.isContinue(); - } - return false; - } - - private boolean checkRetry(final BridgeGame bridgeGame) { - outputView.printRetryRequest(); - final String retryInput = inputView.readGameCommand(); - return bridgeGame.retry(retryInput); + outputView.printResult(tryCount, bridgeGame.getGameResultMap()); } private BridgeGame makeBridgeGameWithSize() { @@ -54,9 +39,33 @@ private BridgeGame makeBridgeGameWithSize() { return new BridgeGame(bridgeMaker.makeBridge(bridgeSize)); } + private boolean moveAndGetRetryStatus(final BridgeGame bridgeGame) { + while (true) { + final MoveResult moveResult = tryMove(bridgeGame); + if (moveResult != MoveResult.CONTINUE) { + return getRetryStatus(bridgeGame, moveResult); + } + outputView.printMap(bridgeGame.getGameResultMap()); + } + } + private MoveResult tryMove(final BridgeGame bridgeGame) { outputView.printMovingRequest(); final String movingInput = inputView.readMoving(); return bridgeGame.move(movingInput); } + + private boolean getRetryStatus(final BridgeGame bridgeGame, final MoveResult moveResult) { + if (moveResult == MoveResult.SUCCESS) { + return false; + } + outputView.printMap(bridgeGame.getGameResultMap()); + return checkRetry(bridgeGame); + } + + private boolean checkRetry(final BridgeGame bridgeGame) { + outputView.printRetryRequest(); + final String retryInput = inputView.readGameCommand(); + return bridgeGame.retry(retryInput); + } } diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/BridgeMaker.java index 1eacb71d794..682962eceee 100644 --- a/src/main/java/bridge/BridgeMaker.java +++ b/src/main/java/bridge/BridgeMaker.java @@ -8,7 +8,7 @@ * 다리의 길이를 입력 받아서 다리를 생성해주는 역할을 한다. */ public class BridgeMaker { - private static final int RANGE_START = 0; + private static final int START_INDEX = 0; private static final int MIN_BRIDGE_SIZE = 3; private static final int MAX_BRIDGE_SIZE = 20; private final BridgeNumberGenerator bridgeNumberGenerator; @@ -25,7 +25,7 @@ public List makeBridge(final int size) { if (size < MIN_BRIDGE_SIZE || MAX_BRIDGE_SIZE < size) { throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_BRIDGE_SIZE.toString(), MIN_BRIDGE_SIZE, MAX_BRIDGE_SIZE)); } - return IntStream.range(RANGE_START, size) + return IntStream.range(START_INDEX, size) .mapToObj(i -> getBridgeDirection()) .collect(Collectors.toList()); } diff --git a/src/main/java/bridge/GameMessage.java b/src/main/java/bridge/GameMessage.java index 768434da39d..579bf1bfc64 100644 --- a/src/main/java/bridge/GameMessage.java +++ b/src/main/java/bridge/GameMessage.java @@ -5,7 +5,8 @@ public enum GameMessage { BRIDGE_SIZE_REQUEST("다리의 길이를 입력해주세요."), MOVE_DIRECTION_REQUEST("이동할 칸을 선택해주세요. (위: %s, 아래: %s)"), SUCCESS("게임 성공 여부: 성공\n총 시도한 횟수: %s"), - RETRY_REQUEST("게임을 다시 시도할지 여부를 입력해주세요. (재시도: %s, 종료: %s)"); + RETRY_REQUEST("게임을 다시 시도할지 여부를 입력해주세요. (재시도: %s, 종료: %s)"), + FINAL_RESULT("최종 게임 결과"); private final String message; diff --git a/src/main/java/bridge/MoveResult.java b/src/main/java/bridge/MoveResult.java index 7fd56f9996d..853af41e439 100644 --- a/src/main/java/bridge/MoveResult.java +++ b/src/main/java/bridge/MoveResult.java @@ -1,13 +1,5 @@ package bridge; public enum MoveResult { - KEEP_GOING, FAILED, SUCCESS; - - public boolean isContinue() { - return this == KEEP_GOING; - } - - public boolean isFailed() { - return this == FAILED; - } + CONTINUE, FAILED, SUCCESS; } diff --git a/src/main/java/bridge/MoveResultMapper.java b/src/main/java/bridge/MoveResultMapper.java index 6e6f5e40538..6aaa1e644de 100644 --- a/src/main/java/bridge/MoveResultMapper.java +++ b/src/main/java/bridge/MoveResultMapper.java @@ -1,16 +1,6 @@ package bridge; public class MoveResultMapper { - private static MoveResultMapper INSTANCE; - private MoveResultMapper() {} - - public static MoveResultMapper getInstance() { - if (INSTANCE == null) { - INSTANCE = new MoveResultMapper(); - } - return INSTANCE; - } - public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answer, final int leftSize) { if (leftSize == 0) { return checkSuccess(input, answer); @@ -20,7 +10,7 @@ public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answe private MoveResult checkKeepGoing(final BridgeType input, final BridgeType answer) { if (input == answer) { - return MoveResult.KEEP_GOING; + return MoveResult.CONTINUE; } return MoveResult.FAILED; } diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java index a30782e8316..260b496d689 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/OutputView.java @@ -27,7 +27,9 @@ public void printMap(final String gameResultMap) { *

* 출력을 위해 필요한 메서드의 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ - public void printResult(final TryCount tryCount) { + public void printResult(final TryCount tryCount, final String gameResultMap) { + System.out.println(GameMessage.FINAL_RESULT); + printMap(gameResultMap); System.out.println(String.format(GameMessage.SUCCESS.toString(), tryCount)); } @@ -38,4 +40,8 @@ public void printMovingRequest() { public void printRetryRequest() { System.out.println(String.format(GameMessage.RETRY_REQUEST.toString(), RetryCommand.R, RetryCommand.Q)); } + + public void printErrorMessage(final String message) { + System.out.println(message); + } } From 8d4fb2b7b9ae9a23e20c10e43d340b685b8a0dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 04:12:02 +0900 Subject: [PATCH 29/35] =?UTF-8?q?docs(README):=20=EC=97=B4=EA=B1=B0?= =?UTF-8?q?=ED=98=95=20=EB=82=B4=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README 내용 추가 - 열거형 RetryCommand --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index ddcdc059249..f91c6c226b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -92,3 +92,6 @@ - GameResultStatus - 결과 상태 + +- RetryCommand + - 재시도 입력값 From 2271ade295c8392b59c0620e57cdd4b31050b26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 10:54:26 +0900 Subject: [PATCH 30/35] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - 패키지 분리 --- README.md | 2 +- src/main/java/bridge/Application.java | 2 ++ src/main/java/bridge/{ => constant}/BridgeType.java | 2 +- src/main/java/bridge/{ => constant}/ErrorMessage.java | 2 +- src/main/java/bridge/{ => constant}/GameMessage.java | 2 +- .../java/bridge/{ => constant}/GameResultStatus.java | 2 +- src/main/java/bridge/{ => constant}/MoveResult.java | 2 +- src/main/java/bridge/{ => constant}/RetryCommand.java | 2 +- src/main/java/bridge/{ => domain}/Bridge.java | 5 ++++- src/main/java/bridge/{ => domain}/BridgeGame.java | 8 +++++++- src/main/java/bridge/{ => domain}/GameResult.java | 4 +++- src/main/java/bridge/{ => domain}/TryCount.java | 2 +- src/main/java/bridge/{ => factory}/BridgeMaker.java | 6 +++++- src/main/java/bridge/{ => factory}/ComponentFactory.java | 9 ++++++++- src/main/java/bridge/{ => factory}/MoveResultMapper.java | 5 ++++- src/main/java/bridge/{ => io}/InputValidator.java | 6 +++++- src/main/java/bridge/{ => io}/InputView.java | 2 +- src/main/java/bridge/{ => io}/OutputView.java | 7 ++++++- .../java/bridge/{ => manager}/BridgeGameManager.java | 9 ++++++++- .../java/bridge/{ => utils}/BridgeNumberGenerator.java | 2 +- .../bridge/{ => utils}/BridgeRandomNumberGenerator.java | 2 +- src/test/java/bridge/ApplicationTest.java | 2 ++ 22 files changed, 65 insertions(+), 20 deletions(-) rename src/main/java/bridge/{ => constant}/BridgeType.java (95%) rename src/main/java/bridge/{ => constant}/ErrorMessage.java (96%) rename src/main/java/bridge/{ => constant}/GameMessage.java (96%) rename src/main/java/bridge/{ => constant}/GameResultStatus.java (90%) rename src/main/java/bridge/{ => constant}/MoveResult.java (70%) rename src/main/java/bridge/{ => constant}/RetryCommand.java (60%) rename src/main/java/bridge/{ => domain}/Bridge.java (88%) rename src/main/java/bridge/{ => domain}/BridgeGame.java (94%) rename src/main/java/bridge/{ => domain}/GameResult.java (92%) rename src/main/java/bridge/{ => domain}/TryCount.java (93%) rename src/main/java/bridge/{ => factory}/BridgeMaker.java (90%) rename src/main/java/bridge/{ => factory}/ComponentFactory.java (72%) rename src/main/java/bridge/{ => factory}/MoveResultMapper.java (88%) rename src/main/java/bridge/{ => io}/InputValidator.java (92%) rename src/main/java/bridge/{ => io}/InputView.java (98%) rename src/main/java/bridge/{ => io}/OutputView.java (90%) rename src/main/java/bridge/{ => manager}/BridgeGameManager.java (91%) rename src/main/java/bridge/{ => utils}/BridgeNumberGenerator.java (79%) rename src/main/java/bridge/{ => utils}/BridgeRandomNumberGenerator.java (94%) diff --git a/README.md b/README.md index 8ab62a91992..8d0b64dba0a 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ public class BridgeMaker { ### BridgeRandomNumberGenerator 클래스 -- Random 값 추출은 제공된 `bridge.BridgeRandomNumberGenerator`의 `generate()`를 활용한다. +- Random 값 추출은 제공된 `bridge.utils.BridgeRandomNumberGenerator`의 `generate()`를 활용한다. - `BridgeRandomNumberGenerator`, `BridgeNumberGenerator` 클래스의 코드는 변경할 수 없다. #### 사용 예시 diff --git a/src/main/java/bridge/Application.java b/src/main/java/bridge/Application.java index cab94bae395..11c5d6831b3 100644 --- a/src/main/java/bridge/Application.java +++ b/src/main/java/bridge/Application.java @@ -1,5 +1,7 @@ package bridge; +import bridge.factory.ComponentFactory; + public class Application { public static void main(String[] args) { diff --git a/src/main/java/bridge/BridgeType.java b/src/main/java/bridge/constant/BridgeType.java similarity index 95% rename from src/main/java/bridge/BridgeType.java rename to src/main/java/bridge/constant/BridgeType.java index d3d204aafb0..9c2777319da 100644 --- a/src/main/java/bridge/BridgeType.java +++ b/src/main/java/bridge/constant/BridgeType.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; import java.util.Arrays; diff --git a/src/main/java/bridge/ErrorMessage.java b/src/main/java/bridge/constant/ErrorMessage.java similarity index 96% rename from src/main/java/bridge/ErrorMessage.java rename to src/main/java/bridge/constant/ErrorMessage.java index d4b5a865ab4..6c5353eaec4 100644 --- a/src/main/java/bridge/ErrorMessage.java +++ b/src/main/java/bridge/constant/ErrorMessage.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; public enum ErrorMessage { NOT_NUMERIC_INPUT("숫자만 입력 가능합니다."), diff --git a/src/main/java/bridge/GameMessage.java b/src/main/java/bridge/constant/GameMessage.java similarity index 96% rename from src/main/java/bridge/GameMessage.java rename to src/main/java/bridge/constant/GameMessage.java index 579bf1bfc64..d14c7edd671 100644 --- a/src/main/java/bridge/GameMessage.java +++ b/src/main/java/bridge/constant/GameMessage.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; public enum GameMessage { START_GAME("다리 건너기 게임을 시작합니다.\n"), diff --git a/src/main/java/bridge/GameResultStatus.java b/src/main/java/bridge/constant/GameResultStatus.java similarity index 90% rename from src/main/java/bridge/GameResultStatus.java rename to src/main/java/bridge/constant/GameResultStatus.java index d31c27904cd..a06fe00b8ec 100644 --- a/src/main/java/bridge/GameResultStatus.java +++ b/src/main/java/bridge/constant/GameResultStatus.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; public enum GameResultStatus { O, X, NONE; diff --git a/src/main/java/bridge/MoveResult.java b/src/main/java/bridge/constant/MoveResult.java similarity index 70% rename from src/main/java/bridge/MoveResult.java rename to src/main/java/bridge/constant/MoveResult.java index 853af41e439..9a789f68603 100644 --- a/src/main/java/bridge/MoveResult.java +++ b/src/main/java/bridge/constant/MoveResult.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; public enum MoveResult { CONTINUE, FAILED, SUCCESS; diff --git a/src/main/java/bridge/RetryCommand.java b/src/main/java/bridge/constant/RetryCommand.java similarity index 60% rename from src/main/java/bridge/RetryCommand.java rename to src/main/java/bridge/constant/RetryCommand.java index d7cde10b049..dc13ab4c3c3 100644 --- a/src/main/java/bridge/RetryCommand.java +++ b/src/main/java/bridge/constant/RetryCommand.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.constant; public enum RetryCommand { R, Q diff --git a/src/main/java/bridge/Bridge.java b/src/main/java/bridge/domain/Bridge.java similarity index 88% rename from src/main/java/bridge/Bridge.java rename to src/main/java/bridge/domain/Bridge.java index ec0f42b0cf5..2819987a645 100644 --- a/src/main/java/bridge/Bridge.java +++ b/src/main/java/bridge/domain/Bridge.java @@ -1,4 +1,7 @@ -package bridge; +package bridge.domain; + +import bridge.constant.BridgeType; +import bridge.constant.ErrorMessage; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/domain/BridgeGame.java similarity index 94% rename from src/main/java/bridge/BridgeGame.java rename to src/main/java/bridge/domain/BridgeGame.java index 47e6fd99c72..ef3b2341301 100644 --- a/src/main/java/bridge/BridgeGame.java +++ b/src/main/java/bridge/domain/BridgeGame.java @@ -1,4 +1,10 @@ -package bridge; +package bridge.domain; + +import bridge.constant.BridgeType; +import bridge.constant.GameResultStatus; +import bridge.constant.MoveResult; +import bridge.constant.RetryCommand; +import bridge.factory.MoveResultMapper; import java.util.List; diff --git a/src/main/java/bridge/GameResult.java b/src/main/java/bridge/domain/GameResult.java similarity index 92% rename from src/main/java/bridge/GameResult.java rename to src/main/java/bridge/domain/GameResult.java index 1d58d7f6d5c..c13d6369092 100644 --- a/src/main/java/bridge/GameResult.java +++ b/src/main/java/bridge/domain/GameResult.java @@ -1,4 +1,6 @@ -package bridge; +package bridge.domain; + +import bridge.constant.GameResultStatus; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/bridge/TryCount.java b/src/main/java/bridge/domain/TryCount.java similarity index 93% rename from src/main/java/bridge/TryCount.java rename to src/main/java/bridge/domain/TryCount.java index 6296f8c3552..c1083d8f0b3 100644 --- a/src/main/java/bridge/TryCount.java +++ b/src/main/java/bridge/domain/TryCount.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.domain; public class TryCount { private static final int INITIAL_COUNT = 1; diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/factory/BridgeMaker.java similarity index 90% rename from src/main/java/bridge/BridgeMaker.java rename to src/main/java/bridge/factory/BridgeMaker.java index 682962eceee..ec09abfb380 100644 --- a/src/main/java/bridge/BridgeMaker.java +++ b/src/main/java/bridge/factory/BridgeMaker.java @@ -1,4 +1,8 @@ -package bridge; +package bridge.factory; + +import bridge.utils.BridgeNumberGenerator; +import bridge.constant.BridgeType; +import bridge.constant.ErrorMessage; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/bridge/ComponentFactory.java b/src/main/java/bridge/factory/ComponentFactory.java similarity index 72% rename from src/main/java/bridge/ComponentFactory.java rename to src/main/java/bridge/factory/ComponentFactory.java index 166e9002bf2..46b77b65b22 100644 --- a/src/main/java/bridge/ComponentFactory.java +++ b/src/main/java/bridge/factory/ComponentFactory.java @@ -1,4 +1,11 @@ -package bridge; +package bridge.factory; + +import bridge.manager.BridgeGameManager; +import bridge.utils.BridgeNumberGenerator; +import bridge.utils.BridgeRandomNumberGenerator; +import bridge.io.InputValidator; +import bridge.io.InputView; +import bridge.io.OutputView; public class ComponentFactory { diff --git a/src/main/java/bridge/MoveResultMapper.java b/src/main/java/bridge/factory/MoveResultMapper.java similarity index 88% rename from src/main/java/bridge/MoveResultMapper.java rename to src/main/java/bridge/factory/MoveResultMapper.java index 6aaa1e644de..c858418d021 100644 --- a/src/main/java/bridge/MoveResultMapper.java +++ b/src/main/java/bridge/factory/MoveResultMapper.java @@ -1,4 +1,7 @@ -package bridge; +package bridge.factory; + +import bridge.constant.BridgeType; +import bridge.constant.MoveResult; public class MoveResultMapper { public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answer, final int leftSize) { diff --git a/src/main/java/bridge/InputValidator.java b/src/main/java/bridge/io/InputValidator.java similarity index 92% rename from src/main/java/bridge/InputValidator.java rename to src/main/java/bridge/io/InputValidator.java index c3465703a3d..774f45da1fe 100644 --- a/src/main/java/bridge/InputValidator.java +++ b/src/main/java/bridge/io/InputValidator.java @@ -1,4 +1,8 @@ -package bridge; +package bridge.io; + +import bridge.constant.BridgeType; +import bridge.constant.ErrorMessage; +import bridge.constant.RetryCommand; public class InputValidator { private static final Character START_NUMBER = '0'; diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/io/InputView.java similarity index 98% rename from src/main/java/bridge/InputView.java rename to src/main/java/bridge/io/InputView.java index 8cd35110631..44e25c37d3a 100644 --- a/src/main/java/bridge/InputView.java +++ b/src/main/java/bridge/io/InputView.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.io; import camp.nextstep.edu.missionutils.Console; diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/io/OutputView.java similarity index 90% rename from src/main/java/bridge/OutputView.java rename to src/main/java/bridge/io/OutputView.java index 260b496d689..90d117f0f23 100644 --- a/src/main/java/bridge/OutputView.java +++ b/src/main/java/bridge/io/OutputView.java @@ -1,4 +1,9 @@ -package bridge; +package bridge.io; + +import bridge.domain.TryCount; +import bridge.constant.BridgeType; +import bridge.constant.GameMessage; +import bridge.constant.RetryCommand; /** * 사용자에게 게임 진행 상황과 결과를 출력하는 역할을 한다. diff --git a/src/main/java/bridge/BridgeGameManager.java b/src/main/java/bridge/manager/BridgeGameManager.java similarity index 91% rename from src/main/java/bridge/BridgeGameManager.java rename to src/main/java/bridge/manager/BridgeGameManager.java index 15056dd5eb7..2f0a3335100 100644 --- a/src/main/java/bridge/BridgeGameManager.java +++ b/src/main/java/bridge/manager/BridgeGameManager.java @@ -1,4 +1,11 @@ -package bridge; +package bridge.manager; + +import bridge.constant.MoveResult; +import bridge.domain.BridgeGame; +import bridge.domain.TryCount; +import bridge.io.InputView; +import bridge.io.OutputView; +import bridge.factory.BridgeMaker; public class BridgeGameManager { private final InputView inputView; diff --git a/src/main/java/bridge/BridgeNumberGenerator.java b/src/main/java/bridge/utils/BridgeNumberGenerator.java similarity index 79% rename from src/main/java/bridge/BridgeNumberGenerator.java rename to src/main/java/bridge/utils/BridgeNumberGenerator.java index 56187b71d2d..94a44d6bfcf 100644 --- a/src/main/java/bridge/BridgeNumberGenerator.java +++ b/src/main/java/bridge/utils/BridgeNumberGenerator.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.utils; @FunctionalInterface public interface BridgeNumberGenerator { diff --git a/src/main/java/bridge/BridgeRandomNumberGenerator.java b/src/main/java/bridge/utils/BridgeRandomNumberGenerator.java similarity index 94% rename from src/main/java/bridge/BridgeRandomNumberGenerator.java rename to src/main/java/bridge/utils/BridgeRandomNumberGenerator.java index 4c9cb53e03a..f54f3073733 100644 --- a/src/main/java/bridge/BridgeRandomNumberGenerator.java +++ b/src/main/java/bridge/utils/BridgeRandomNumberGenerator.java @@ -1,4 +1,4 @@ -package bridge; +package bridge.utils; import camp.nextstep.edu.missionutils.Randoms; diff --git a/src/test/java/bridge/ApplicationTest.java b/src/test/java/bridge/ApplicationTest.java index 1a163ec0a2a..ca2cc40c4cb 100644 --- a/src/test/java/bridge/ApplicationTest.java +++ b/src/test/java/bridge/ApplicationTest.java @@ -5,6 +5,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Lists.newArrayList; +import bridge.factory.BridgeMaker; +import bridge.utils.BridgeNumberGenerator; import camp.nextstep.edu.missionutils.test.NsTest; import java.util.List; import org.junit.jupiter.api.Test; From 07131d6274ed14e0d1ea42a76861266aad881dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 11:06:16 +0900 Subject: [PATCH 31/35] =?UTF-8?q?refactor:=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94=EC=99=80=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=ED=95=A0=20=EB=B0=8F=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - enum 필드 추가를 통한 내부 분기문 제거 - 메서드 이름 변경 checkKeepGoing -> checkContinue - validate 메서드 분리 --- .../java/bridge/constant/GameResultStatus.java | 15 +++++++++------ src/main/java/bridge/factory/BridgeMaker.java | 10 +++++++--- .../java/bridge/factory/MoveResultMapper.java | 4 ++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/bridge/constant/GameResultStatus.java b/src/main/java/bridge/constant/GameResultStatus.java index a06fe00b8ec..92eaaebed63 100644 --- a/src/main/java/bridge/constant/GameResultStatus.java +++ b/src/main/java/bridge/constant/GameResultStatus.java @@ -1,15 +1,18 @@ package bridge.constant; public enum GameResultStatus { - O, X, NONE; + O("O"), + X("X"), + NONE(" "); - private static final String BLANK = " "; + private final String symbol; + + GameResultStatus(final String symbol) { + this.symbol = symbol; + } @Override public String toString() { - if (this == NONE) { - return BLANK; - } - return this.name(); + return this.symbol; } } diff --git a/src/main/java/bridge/factory/BridgeMaker.java b/src/main/java/bridge/factory/BridgeMaker.java index ec09abfb380..64a691e9b58 100644 --- a/src/main/java/bridge/factory/BridgeMaker.java +++ b/src/main/java/bridge/factory/BridgeMaker.java @@ -26,14 +26,18 @@ public BridgeMaker(final BridgeNumberGenerator bridgeNumberGenerator) { * @return 입력받은 길이에 해당하는 다리 모양. 위 칸이면 "U", 아래 칸이면 "D"로 표현해야 한다. */ public List makeBridge(final int size) { - if (size < MIN_BRIDGE_SIZE || MAX_BRIDGE_SIZE < size) { - throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_BRIDGE_SIZE.toString(), MIN_BRIDGE_SIZE, MAX_BRIDGE_SIZE)); - } + validateSize(size); return IntStream.range(START_INDEX, size) .mapToObj(i -> getBridgeDirection()) .collect(Collectors.toList()); } + private void validateSize(final int size) { + if (size < MIN_BRIDGE_SIZE || MAX_BRIDGE_SIZE < size) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_BRIDGE_SIZE.toString(), MIN_BRIDGE_SIZE, MAX_BRIDGE_SIZE)); + } + } + private String getBridgeDirection() { final int randomNumber = bridgeNumberGenerator.generate(); return BridgeType.getDirectionByClassifier(randomNumber); diff --git a/src/main/java/bridge/factory/MoveResultMapper.java b/src/main/java/bridge/factory/MoveResultMapper.java index c858418d021..a52b3953823 100644 --- a/src/main/java/bridge/factory/MoveResultMapper.java +++ b/src/main/java/bridge/factory/MoveResultMapper.java @@ -8,10 +8,10 @@ public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answe if (leftSize == 0) { return checkSuccess(input, answer); } - return checkKeepGoing(input, answer); + return checkContinue(input, answer); } - private MoveResult checkKeepGoing(final BridgeType input, final BridgeType answer) { + private MoveResult checkContinue(final BridgeType input, final BridgeType answer) { if (input == answer) { return MoveResult.CONTINUE; } From 5a67faef4dc693af28e86414fcdb21971fea45cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 11:13:52 +0900 Subject: [PATCH 32/35] =?UTF-8?q?refactor(MoveResultMapper):=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EC=83=81=EC=88=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - 숫자 상수 적용 NO_LEFT_ELEMENT --- src/main/java/bridge/factory/MoveResultMapper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/bridge/factory/MoveResultMapper.java b/src/main/java/bridge/factory/MoveResultMapper.java index a52b3953823..99c8855346b 100644 --- a/src/main/java/bridge/factory/MoveResultMapper.java +++ b/src/main/java/bridge/factory/MoveResultMapper.java @@ -4,8 +4,10 @@ import bridge.constant.MoveResult; public class MoveResultMapper { + private static final int NO_LEFT_ELEMENT = 0; + public MoveResult mapToMoveResult(final BridgeType input, final BridgeType answer, final int leftSize) { - if (leftSize == 0) { + if (leftSize == NO_LEFT_ELEMENT) { return checkSuccess(input, answer); } return checkContinue(input, answer); From 30a7d80bbb6f5aaf6231419fb8e183c578c7ebba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 11:32:22 +0900 Subject: [PATCH 33/35] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EB=B6=88=EB=B3=80=20=EA=B0=9D=EC=B2=B4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - TryCount 불변객체로 변환 - Bridge 불변객체로 변환 - BridgeGame 메서드 분리 --- src/main/java/bridge/domain/Bridge.java | 12 ++++++++---- src/main/java/bridge/domain/BridgeGame.java | 12 ++++++++---- src/main/java/bridge/domain/TryCount.java | 14 +++++++++----- .../java/bridge/manager/BridgeGameManager.java | 5 +++-- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main/java/bridge/domain/Bridge.java b/src/main/java/bridge/domain/Bridge.java index 2819987a645..723935ba5d1 100644 --- a/src/main/java/bridge/domain/Bridge.java +++ b/src/main/java/bridge/domain/Bridge.java @@ -3,14 +3,18 @@ import bridge.constant.BridgeType; import bridge.constant.ErrorMessage; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; -public class Bridge { +public final class Bridge { private final List directions; - public Bridge(final List directions) { - this.directions = new ArrayList<>(directions); + private Bridge(final List directions) { + this.directions = Collections.unmodifiableList(directions); + } + + public static Bridge create(final List directions) { + return new Bridge(directions); } public BridgeType getNextElement(final int currentIndex) { diff --git a/src/main/java/bridge/domain/BridgeGame.java b/src/main/java/bridge/domain/BridgeGame.java index ef3b2341301..da0f3ec5af2 100644 --- a/src/main/java/bridge/domain/BridgeGame.java +++ b/src/main/java/bridge/domain/BridgeGame.java @@ -21,7 +21,7 @@ public class BridgeGame { private Integer currentIndex; public BridgeGame(final List bridgeDirections) { - this.bridge = new Bridge(bridgeDirections); + this.bridge = Bridge.create(bridgeDirections); this.upperGameResult = new GameResult(); this.lowerGameResult = new GameResult(); this.moveResultMapper = new MoveResultMapper(); @@ -49,14 +49,18 @@ public MoveResult move(final String movingInput) { */ public boolean retry(final String retryInput) { if (retryInput.equals(RetryCommand.R.toString())) { - initCurrentIndex(); - upperGameResult.clearResult(); - lowerGameResult.clearResult(); + clearAll(); return true; } return false; } + private void clearAll() { + initCurrentIndex(); + upperGameResult.clearResult(); + lowerGameResult.clearResult(); + } + private void addGameResultStatus(final MoveResult moveResult, final BridgeType answerBridgeType) { if (moveResult == MoveResult.FAILED) { addToProperGameResult(answerBridgeType, GameResultStatus.X, false); diff --git a/src/main/java/bridge/domain/TryCount.java b/src/main/java/bridge/domain/TryCount.java index c1083d8f0b3..4a38a0d384b 100644 --- a/src/main/java/bridge/domain/TryCount.java +++ b/src/main/java/bridge/domain/TryCount.java @@ -1,11 +1,11 @@ package bridge.domain; -public class TryCount { +public final class TryCount { private static final int INITIAL_COUNT = 1; private int count; - public TryCount() { - this.count = INITIAL_COUNT; + private TryCount(final int count) { + this.count = count; } @Override @@ -13,7 +13,11 @@ public String toString() { return String.valueOf(this.count); } - public void increment() { - this.count++; + public static TryCount create() { + return new TryCount(INITIAL_COUNT); + } + + public TryCount next() { + return new TryCount(++this.count); } } diff --git a/src/main/java/bridge/manager/BridgeGameManager.java b/src/main/java/bridge/manager/BridgeGameManager.java index 2f0a3335100..74108a36eea 100644 --- a/src/main/java/bridge/manager/BridgeGameManager.java +++ b/src/main/java/bridge/manager/BridgeGameManager.java @@ -11,11 +11,13 @@ public class BridgeGameManager { private final InputView inputView; private final OutputView outputView; private final BridgeMaker bridgeMaker; + private TryCount tryCount; public BridgeGameManager(final InputView inputView, final OutputView outputView, final BridgeMaker bridgeMaker) { this.inputView = inputView; this.outputView = outputView; this.bridgeMaker = bridgeMaker; + this.tryCount = TryCount.create(); } public void playBridgeGame() { @@ -29,12 +31,11 @@ public void playBridgeGame() { private void playUntilGameEnd() { boolean isGameRunning = true; - final TryCount tryCount = new TryCount(); final BridgeGame bridgeGame = makeBridgeGameWithSize(); while (isGameRunning) { isGameRunning = moveAndGetRetryStatus(bridgeGame); if (isGameRunning) { - tryCount.increment(); + tryCount = tryCount.next(); } } outputView.printResult(tryCount, bridgeGame.getGameResultMap()); From 54d9c368185f3dd8207f5a3fcc9abc19cdfe758a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 11:42:09 +0900 Subject: [PATCH 34/35] =?UTF-8?q?refactor:=20validation=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - 검증 로직 위치 이동(InputValidator -> BridgeGame) --- .../java/bridge/constant/ErrorMessage.java | 3 ++- src/main/java/bridge/domain/BridgeGame.java | 19 +++++++++++++++---- src/main/java/bridge/io/InputValidator.java | 19 ++++++------------- src/main/java/bridge/io/InputView.java | 4 ++-- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/bridge/constant/ErrorMessage.java b/src/main/java/bridge/constant/ErrorMessage.java index 6c5353eaec4..3688a6e7fea 100644 --- a/src/main/java/bridge/constant/ErrorMessage.java +++ b/src/main/java/bridge/constant/ErrorMessage.java @@ -7,7 +7,8 @@ public enum ErrorMessage { INVALID_MOVE_DIRECTION("이동 방향 입력값은 %s 혹은 %s 입니다."), NO_ELEMENT_LEFT("리스트의 원소가 없습니다."), INVALID_RETRY_COMMAND("재시도 여부 입력값은 %s 혹은 %s 입니다."), - INVALID_BRIDGE_SIZE("다리의 길이는 %d 이상, %d 이하입니다."); + INVALID_BRIDGE_SIZE("다리의 길이는 %d 이상, %d 이하입니다."), + INVALID_COMMAND_LENGTH("커맨드의 길이는 %d 이여야 합니다."); private final String message; private static final String ERROR_PREFIX = "[ERROR] "; diff --git a/src/main/java/bridge/domain/BridgeGame.java b/src/main/java/bridge/domain/BridgeGame.java index da0f3ec5af2..4f6779aed67 100644 --- a/src/main/java/bridge/domain/BridgeGame.java +++ b/src/main/java/bridge/domain/BridgeGame.java @@ -1,9 +1,6 @@ package bridge.domain; -import bridge.constant.BridgeType; -import bridge.constant.GameResultStatus; -import bridge.constant.MoveResult; -import bridge.constant.RetryCommand; +import bridge.constant.*; import bridge.factory.MoveResultMapper; import java.util.List; @@ -34,6 +31,7 @@ public BridgeGame(final List bridgeDirections) { * 이동을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ public MoveResult move(final String movingInput) { + validateMovingInput(movingInput); final BridgeType inputBridgeType = BridgeType.valueOf(movingInput); final BridgeType answerBridgeType = bridge.getNextElement(currentIndex++); @@ -48,6 +46,7 @@ public MoveResult move(final String movingInput) { * 재시작을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다. */ public boolean retry(final String retryInput) { + validateRetryInput(retryInput); if (retryInput.equals(RetryCommand.R.toString())) { clearAll(); return true; @@ -94,4 +93,16 @@ public String getGameResultMap() { private void initCurrentIndex() { this.currentIndex = INITIAL_INDEX; } + + private void validateRetryInput(final String input) { + if (!input.equals(RetryCommand.R.toString()) && !input.equals(RetryCommand.Q.toString())) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_RETRY_COMMAND.toString(), RetryCommand.R, RetryCommand.Q)); + } + } + + private void validateMovingInput(final String input) { + if (!input.equals(BridgeType.U.toString()) && !input.equals(BridgeType.D.toString())) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_MOVE_DIRECTION.toString(), BridgeType.U, BridgeType.D)); + } + } } diff --git a/src/main/java/bridge/io/InputValidator.java b/src/main/java/bridge/io/InputValidator.java index 774f45da1fe..2efe4dde110 100644 --- a/src/main/java/bridge/io/InputValidator.java +++ b/src/main/java/bridge/io/InputValidator.java @@ -1,12 +1,11 @@ package bridge.io; -import bridge.constant.BridgeType; import bridge.constant.ErrorMessage; -import bridge.constant.RetryCommand; public class InputValidator { private static final Character START_NUMBER = '0'; private static final Character END_NUMBER = '9'; + private static final Integer COMMAND_LENGTH = 1; public void validateBridgeSizeInput(final String input) { validateNumeric(input); @@ -33,20 +32,14 @@ private void validateNotBlank(final String input) { } } - public void validateMovingInput(final String input) { + public void validateCommand(final String input) { validateNotBlank(input); - validateMoveDirection(input); + validateCommandLength(input); } - private void validateMoveDirection(final String input) { - if (!input.equals(BridgeType.U.toString()) && !input.equals(BridgeType.D.toString())) { - throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_MOVE_DIRECTION.toString(), BridgeType.U, BridgeType.D)); - } - } - - public void validateGameCommandInput(final String input) { - if (!input.equals(RetryCommand.R.toString()) && !input.equals(RetryCommand.Q.toString())) { - throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_RETRY_COMMAND.toString(), RetryCommand.R, RetryCommand.Q)); + private void validateCommandLength(final String input) { + if (input.length() != COMMAND_LENGTH) { + throw new IllegalArgumentException(String.format(ErrorMessage.INVALID_COMMAND_LENGTH.toString(), COMMAND_LENGTH)); } } } diff --git a/src/main/java/bridge/io/InputView.java b/src/main/java/bridge/io/InputView.java index 44e25c37d3a..732f99998eb 100644 --- a/src/main/java/bridge/io/InputView.java +++ b/src/main/java/bridge/io/InputView.java @@ -26,7 +26,7 @@ public int readBridgeSize() { */ public String readMoving() { final String input = Console.readLine(); - inputValidator.validateMovingInput(input); + inputValidator.validateCommand(input); return input; } @@ -35,7 +35,7 @@ public String readMoving() { */ public String readGameCommand() { final String input = Console.readLine(); - inputValidator.validateGameCommandInput(input); + inputValidator.validateCommand(input); return input; } } From 838f8ac6c572583c4b0736e958f13d52834b049e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 14 Aug 2023 11:47:05 +0900 Subject: [PATCH 35/35] =?UTF-8?q?refactor(TryCount):=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=ED=8C=A9=ED=86=A0=EB=A6=AC?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 리팩토링 - 상수 추가 - 팩토리 메서드 상수 활용 --- src/main/java/bridge/domain/TryCount.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/bridge/domain/TryCount.java b/src/main/java/bridge/domain/TryCount.java index 4a38a0d384b..20fe2116353 100644 --- a/src/main/java/bridge/domain/TryCount.java +++ b/src/main/java/bridge/domain/TryCount.java @@ -2,7 +2,8 @@ public final class TryCount { private static final int INITIAL_COUNT = 1; - private int count; + private static final int PLUS_UNIT = 1; + private final int count; private TryCount(final int count) { this.count = count; @@ -18,6 +19,6 @@ public static TryCount create() { } public TryCount next() { - return new TryCount(++this.count); + return new TryCount(this.count + PLUS_UNIT); } }