diff --git a/docs/README.md b/docs/README.md
index e69de29bb2d..60915dd25bf 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -0,0 +1,166 @@
+# π» νλ‘κ·Έλ¨ λμ λ°©μ
+
+---
+
+#### 1. μ¬μ©μλ‘λΆν° `InputView`μμ κ°μ μ
λ ₯ λ°κ³ μ΄κΈ°ν ν, κ²μμ μ€ννλ€.
+#### 2. `InputView`μμ κ°μ μ
λ ₯ λ°λλ€.
+#### 3. `Validator`λ₯Ό ν΅ν΄ μ
λ ₯κ°μ κ²μ¦νλ€.
+#### 4. μμΈ λ°μμ μ¬μ
λ ₯λ°λλ€.
+#### 5. μμΈκ° λ°μνμ§ μμ κ²½μ°, `Application`μ κ°μ λ°ννλ€.
+#### 6. `BridgeGame`μ ν΄λΉ κ°μ λκ²¨μ£Όμ΄ updateνλ€.
+#### 7. updateλ `BridgeGame`μ `Application`μμ `OutputView`λ‘ λ겨μ€λ€.
+#### 8. ν΄λΉ κ°μ νμ©ν΄ μΆλ ₯νλ€.
+#### 9. κ²μμ΄ μ’
λ£λ λ κΉμ§ 2~8λ₯Ό λ°λ³΅νλ€.
+
+
+# π§° κΈ°λ₯ λͺ©λ‘
+
+---
+
+### 1. κ²μ μμ 문ꡬλ₯Ό μΆλ ₯νλ€. - `View`/`InputView`
+
+### 2. λ€λ¦¬μ κΈΈμ΄λ₯Ό μ«μλ₯Ό μ
λ ₯λ°κ³ μμ±νλ€.
+ - [x] μ
λ ₯λ°μ μ«μ(λ¬Έμμ΄)μ μ μλ‘ λ³ννλ€. - `Domain`/`InputConverter`
+ - [x] μ«μκ° μλ μ
λ ₯μΌ κ²½μ°(λ¬Έμ, λΉ λ¬Έμμ΄) μμΈλ₯Ό λμ§λ€. - `Domain`/`InputValidator`
+ - [x] μλͺ»λ μ
λ ₯μΌ κ²½μ°, μ¬λ°λ₯Έ μ
λ ₯μ΄ λ λ κΉμ§ μ
λ ₯λ°λλ€. - from `Application` call `View`/`InputView`
+ - [x] μ
λ ₯λ°μ μ«μκ° 3 μ΄μ 20 μ΄νμΈμ§ νμΈνκ³ μλλ©΄ μμΈλ₯Ό λμ§λ€. - `Domain`/`InputValidator`
+ - [x] 0κ³Ό 1μ λ€λ¦¬ κΈΈμ΄λ§νΌ 무μμλ‘ μμ±νλ€. - `BridgeMaker` from `BridgeRandomNumberGenerator`
+ - [x] 0μΈ κ²½μ° μλ« μΉΈμΈ `D`, 1μΈ κ²½μ° μ μΉΈμΈ `U`μΈ λ€λ¦¬ 리μ€νΈλ₯Ό λ§λ λ€. - from `Domain`/`Bridge` call `BridgeMaker`
+### 3.`U` λλ `D`λ₯Ό μ
λ ₯λ°μ μ΄λν μΉΈμ μ ννλ€. `View`/`InputView`
+ - [x] μ ν΄μ§ λ¬Έμκ° μλκ±°λ μ
λ ₯μ΄ μμΌλ©΄ μμΈλ₯Ό λμ§λ€. - `Domain`/`InputValidator`
+ - [x] μμΈκ° λ°μν κ²½μ°, λ€μ μ
λ ₯λ°λλ‘ νλ€. - from `Application` call `View`/`InputView`
+ - [x] μ΄λ ν μμ¬μ¬λΆλ₯Ό updateνλ€ - in `Domain`/`BridgeGame` update `Domain`/`Player`
+
+### 4. μ
λ ₯ κ²°κ³Όλ₯Ό μΆλ ₯νλ€.
+ - [X] 건λμ¨ μΉΈλ€μ μ λΆ Oλ‘ μΆλ ₯νκ³ μΉΈ μΌμΉμ¬λΆμ μμ¬μ¬λΆμ λ°λΌ O, Xλ₯Ό μΆλ ₯μ κ²°μ νλ€. - from `Application` call `View`/`OutputView`
+
+### 5. μμ¬μ¬λΆλ₯Ό νλ³ ν, λ€μ νλμ κ²°μ νλ€.
+ #### 5-1. μ£½μμ λ
+ - [x] 건λλ€ μ€ν¨νλ©΄ μ¬μμ `R`, μ’
λ£ `Q` ν μ μλ€. `View`/`InputView`
+ - [x] μ ν΄μ§ λ¬Έμκ° μλκ±°λ μ
λ ₯μ΄ μμΌλ©΄ μμΈλ₯Ό λμ§λ€ `Domain`/`InputValidator`
+ - [x] μμΈκ° λ°μν κ²½μ°, λ€μ μ
λ ₯λ°λλ‘ νλ€. from `Application` call `View`/`InputView`
+ - [x] μ¬μμμ μ²μλΆν° λ€μ μ§ννλ€. - `Application`
+
+ #### 5-2. μ΄μμ λ
+- [x] λμ λλ¬ν λ κΉμ§ κ³μ μ§ννλ€. - `Application`
+
+
+### 6. κ²μ μ’
λ£μ κ²°κ³Όλ₯Ό μΆλ ₯νλ€. `OutputView`/`printResult`
+ - [x] μ΅κ³ κΈ°λ‘μ μΆλ ₯νλ€.
+ - [x] κ²μ μ±κ³΅ μ¬λΆλ₯Ό μΆλ ₯νλ€.
+ - [x] μ΄ μλ νμλ₯Ό μΆλ ₯νλ€.
+
+
+
+
+
+# π οΈ ν΄λμ€ μ€κ³
+
+---
+
+## BridgeMaker
+```
+ - Bridgeλ₯Ό λλ€ν κΈΈμ΄λ‘ μμ±
+```
+
+## Constant
+
+---
+
+- ### InputValue
+```
+ - μ¬μ©μ μ
λ ₯κ°μΌλ‘ μ΄λ£¨μ΄μ§ μμ ν΄λμ€
+```
+
+- ### OutputValue
+```
+ - μΆλ ₯κ°μΌλ‘ μ΄λ£¨μ΄μ§ μμ ν΄λμ€
+```
+
+
+## Util
+
+---
+
+- ### InputConverter
+```
+ - μ¬μ©μκ° μ
λ ₯ν κ°(λ¬Έμμ΄)μ μ μλ‘ λ³νν΄ return
+ - λ³ν λΆκ°μ μμΈλ₯Ό λμ§
+```
+
+- ### InputValidator
+```
+ - μ
λ ₯κ°μ λν κ²μ¦
+ - μ¬λ°λ₯΄μ§ μμ μ
λ ₯μΌ μ μμΈλ₯Ό λμ§
+```
+
+
+## Model
+
+---
+
+- ### Bridge
+```
+ - κ²μμ μ¬μ©λλ λ€λ¦¬ μ 보
+```
+
+- ### BridgeBlock
+```
+ - μ¬μ©μ μ ν μ 보λ₯Ό μ΄κ±°ν μμλ‘ μ§μ ν enum ν΄λμ€
+```
+
+- ### Player
+```
+ - νμ¬ μμΉ
+ - μμ¬ μ¬λΆ
+```
+
+- ### BridgeGame
+```
+ - κ²μ μν λ° μ μ΄μ κ΄λ ¨λ ν΄λμ€
+ - μ£Όμ΄μ§ κ°μ λν κ²μ¦
+ - κ°μλ₯Ό μ
λ ₯λ°κ³ Bridge λͺ¨λΈ μ΄κΈ°ν
+ - μ
λ ₯κ°μ λ°λΌ μ μ μ μμ¬ μ¬λΆ λ° μμΉ κ²°μ
+ - μ΅κ³ κΈ°λ‘μ μ μ₯
+```
+
+
+## View
+
+---
+
+- ### InputView
+```
+ - κ²μ μμ 문ꡬ μΆλ ₯
+ - μ
λ ₯ 문ꡬ μΆλ ₯
+ - μ
λ ₯λ°μ κ°μ κ²μ¦ ν λ°ν
+```
+### OutputView
+```
+ - κ²°κ³Ό 문ꡬ μΆλ ₯
+ - updateλ μ 보λ₯Ό κ°κ³΅νμ¬ μΆλ ₯
+```
+
+
+
+# β μ£Όμμ¬ν μ²΄ν¬ λ¦¬μ€νΈ
+
+---
+
+- [x] `Exception`μ΄ μλ `IllegalArgumentException`κ³Ό κ°μ΄ λͺ
ννκ² μ νμ μ²λ¦¬νμλκ°?
+- [x] μ
μΆλ ₯ μꡬ μ¬νμ λͺ¨λ μ§μΌ°λκ°?
+ - [x] κ²μ μμ 문ꡬ
+ - [x] κΈΈμ΄ μ
λ ₯ 문ꡬ
+ - [x] μΉΈ μ
λ ₯ 문ꡬ
+ - [x] μΉΈ μ
λ ₯ ν λ€λ¦¬ μν
+ - [x] μ€ν¨νμ μ μ¬μλ, μ’
λ£ μ¬λΆ
+ - [x] κ²μ μ±κ³΅ μ¬λΆ λ° μλ νμ
+- [x] ν¨μ(λλ λ©μλ)μ κΈΈμ΄κ° 10λΌμΈ μ΄λ΄μΈκ°? (λΉμ€ ν¬ν¨)
+- [x] ν¨μ(λλ λ©μλ)μ νλΌλ―Έν°κ° 3κ° μ΄νμΈκ°?
+- [x] ν΄λμ€ μ μ½ μ¬νλ€μ λͺ¨λ μ§μΌ°λκ°?
+ - [x] `OutuptView`μ λ©μλ μ΄λ¦μ λ³κ²½νλ©΄ μλλ€. (printMap, printResult)
+ - [x] `BridgeMaker`μ λ©μλμ μκ·Έλμ²(μΈμ, μ΄λ¦)μ λ°ν νμ
μ λ³κ²½νλ©΄ μλλ€.
+ - [x] `BridgeGame`μ λ©μλ μ΄λ¦μ λ³κ²½νλ©΄ μλλ€. (move, retry)
+ - [x] `InputView` ν΄λμ€μμλ§ `readLine()`μ μ¬μ©νλ€.
+ - [x] `BridgeRandomNumberGenerator`, `BridgeNumberGenerator`μ λ₯Ό μμ νλ©΄ μλλ€.
+ - [x] `BridgeRandomNumberGenerator`, `BridgeNumberGenerator`μ ν¨ν€μ§λ₯Ό μμ νλ©΄ μλλ€.
diff --git a/src/main/java/bridge/Application.java b/src/main/java/bridge/Application.java
index 5cb72dfd3de..7efd6acfb2d 100644
--- a/src/main/java/bridge/Application.java
+++ b/src/main/java/bridge/Application.java
@@ -1,8 +1,73 @@
package bridge;
+import bridge.Model.BridgeGame;
+import bridge.View.InputView;
+import bridge.View.OutputView;
+
+
+
public class Application {
+ private static InputView inputView = new InputView();
+ private static OutputView outputView = new OutputView();
+
+
+ public static BridgeGame initiateBridgeGame() {
+ while (true) {
+ try {
+ int size = inputView.readBridgeSize();
+
+ return new BridgeGame(size);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ System.out.println(illegalArgumentException.getMessage());
+ }
+ }
+ }
+
+ public static void inputMoving(BridgeGame bridgeGame) {
+ while (true) {
+ try {
+ String selection = inputView.readMoving();
+ bridgeGame.move(selection);
+
+ return;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ System.out.println(illegalArgumentException.getMessage());
+ }
+ }
+ }
+
+ public static void inputCommand(BridgeGame bridgeGame) {
+ while (true) {
+ try {
+ String command = inputView.readGameCommand();
+ bridgeGame.retry(command);
+
+ return;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ System.out.println(illegalArgumentException.getMessage());
+ }
+ }
+ }
+
+ public static void run(BridgeGame bridgeGame) {
+ while (!bridgeGame.isGameOver()) {
+ inputMoving(bridgeGame);
+ outputView.printMap(bridgeGame, bridgeGame.getPassedCount());
+ bridgeGame.updatePlayer();
+
+ if (bridgeGame.isPlayerDead()) {
+ inputCommand(bridgeGame);
+ }
+ }
+ }
public static void main(String[] args) {
- // TODO: νλ‘κ·Έλ¨ κ΅¬ν
+ inputView.printStartMessage();
+
+ BridgeGame bridgeGame = initiateBridgeGame();
+
+ run(bridgeGame);
+
+ outputView.printResult(bridgeGame);
}
}
diff --git a/src/main/java/bridge/BridgeGame.java b/src/main/java/bridge/BridgeGame.java
deleted file mode 100644
index 834c1c8362b..00000000000
--- a/src/main/java/bridge/BridgeGame.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package bridge;
-
-/**
- * λ€λ¦¬ 건λκΈ° κ²μμ κ΄λ¦¬νλ ν΄λμ€
- */
-public class BridgeGame {
-
- /**
- * μ¬μ©μκ° μΉΈμ μ΄λν λ μ¬μ©νλ λ©μλ
- *
- * μ΄λμ μν΄ νμν λ©μλμ λ°ν νμ
(return type), μΈμ(parameter)λ μμ λ‘κ² μΆκ°νκ±°λ λ³κ²½ν μ μλ€.
- */
- public void move() {
- }
-
- /**
- * μ¬μ©μκ° κ²μμ λ€μ μλν λ μ¬μ©νλ λ©μλ
- *
- * μ¬μμμ μν΄ νμν λ©μλμ λ°ν νμ
(return type), μΈμ(parameter)λ μμ λ‘κ² μΆκ°νκ±°λ λ³κ²½ν μ μλ€.
- */
- public void retry() {
- }
-}
diff --git a/src/main/java/bridge/BridgeMaker.java b/src/main/java/bridge/BridgeMaker.java
index 27e9f2cfa7f..07341e08dce 100644
--- a/src/main/java/bridge/BridgeMaker.java
+++ b/src/main/java/bridge/BridgeMaker.java
@@ -1,10 +1,14 @@
package bridge;
+import bridge.Model.BridgeBlock;
+
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
+
+
-/**
- * λ€λ¦¬μ κΈΈμ΄λ₯Ό μ
λ ₯ λ°μμ λ€λ¦¬λ₯Ό μμ±ν΄μ£Όλ μν μ νλ€.
- */
public class BridgeMaker {
private final BridgeNumberGenerator bridgeNumberGenerator;
@@ -13,11 +17,24 @@ public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) {
this.bridgeNumberGenerator = bridgeNumberGenerator;
}
- /**
- * @param size λ€λ¦¬μ κΈΈμ΄
- * @return μ
λ ₯λ°μ κΈΈμ΄μ ν΄λΉνλ λ€λ¦¬ λͺ¨μ. μ μΉΈμ΄λ©΄ "U", μλ μΉΈμ΄λ©΄ "D"λ‘ ννν΄μΌ νλ€.
- */
+
public List makeBridge(int size) {
- return null;
+ List bridgeNumbers = generateBridgeNumbers(size);
+ List bridge = bridgeNumbers.stream()
+ .map(bridgeNumber -> BridgeBlock.getBlockIdentifier((bridgeNumber)))
+ .collect(Collectors.toList());
+
+ return Collections.unmodifiableList(bridge);
+ }
+
+ private List generateBridgeNumbers(int size) {
+ List bridgeNumbers = new ArrayList<>(size);
+
+ for (int i = 0; i < size; i++) {
+ int blockNumber = bridgeNumberGenerator.generate();
+ bridgeNumbers.add(blockNumber);
+ }
+
+ return bridgeNumbers;
}
}
diff --git a/src/main/java/bridge/BridgeNumberGenerator.java b/src/main/java/bridge/BridgeNumberGenerator.java
index 56187b71d2d..f201d1b1438 100644
--- a/src/main/java/bridge/BridgeNumberGenerator.java
+++ b/src/main/java/bridge/BridgeNumberGenerator.java
@@ -1,7 +1,8 @@
package bridge;
+
+
@FunctionalInterface
public interface BridgeNumberGenerator {
-
int generate();
}
diff --git a/src/main/java/bridge/BridgeRandomNumberGenerator.java b/src/main/java/bridge/BridgeRandomNumberGenerator.java
index 4c9cb53e03a..35915c4d98a 100644
--- a/src/main/java/bridge/BridgeRandomNumberGenerator.java
+++ b/src/main/java/bridge/BridgeRandomNumberGenerator.java
@@ -2,6 +2,8 @@
import camp.nextstep.edu.missionutils.Randoms;
+
+
public class BridgeRandomNumberGenerator implements BridgeNumberGenerator {
private static final int RANDOM_LOWER_INCLUSIVE = 0;
diff --git a/src/main/java/bridge/Constant/InputValue.java b/src/main/java/bridge/Constant/InputValue.java
new file mode 100644
index 00000000000..cc21fe617f7
--- /dev/null
+++ b/src/main/java/bridge/Constant/InputValue.java
@@ -0,0 +1,10 @@
+package bridge.Constant;
+
+
+
+public class InputValue {
+ public static final String SELECTION_UP = "U";
+ public static final String SELECTION_DOWN = "D";
+ public static final String COMMAND_RETRY = "R";
+ public static final String COMMAND_QUIT = "Q";
+}
diff --git a/src/main/java/bridge/Constant/OutputValue.java b/src/main/java/bridge/Constant/OutputValue.java
new file mode 100644
index 00000000000..cba86ea61d7
--- /dev/null
+++ b/src/main/java/bridge/Constant/OutputValue.java
@@ -0,0 +1,12 @@
+package bridge.Constant;
+
+
+
+public class OutputValue {
+ public static final String SEPARATOR = "|";
+ public static final String NOT_SELECTION = " ";
+ public static final String WRONG_SELECTION = " X ";
+ public static final String RIGHT_SELECTION = " O ";
+ public static final String SUCCESS = "μ±κ³΅";
+ public static final String FAIL = "μ€ν¨";
+}
diff --git a/src/main/java/bridge/InputView.java b/src/main/java/bridge/InputView.java
deleted file mode 100644
index c3911c8a8e7..00000000000
--- a/src/main/java/bridge/InputView.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package bridge;
-
-/**
- * μ¬μ©μλ‘λΆν° μ
λ ₯μ λ°λ μν μ νλ€.
- */
-public class InputView {
-
- /**
- * λ€λ¦¬μ κΈΈμ΄λ₯Ό μ
λ ₯λ°λλ€.
- */
- public int readBridgeSize() {
- return 0;
- }
-
- /**
- * μ¬μ©μκ° μ΄λν μΉΈμ μ
λ ₯λ°λλ€.
- */
- public String readMoving() {
- return null;
- }
-
- /**
- * μ¬μ©μκ° κ²μμ λ€μ μλν μ§ μ’
λ£ν μ§ μ¬λΆλ₯Ό μ
λ ₯λ°λλ€.
- */
- public String readGameCommand() {
- return null;
- }
-}
diff --git a/src/main/java/bridge/Model/Bridge.java b/src/main/java/bridge/Model/Bridge.java
new file mode 100644
index 00000000000..31a0b608980
--- /dev/null
+++ b/src/main/java/bridge/Model/Bridge.java
@@ -0,0 +1,49 @@
+package bridge.Model;
+
+import bridge.BridgeMaker;
+import bridge.BridgeNumberGenerator;
+import bridge.BridgeRandomNumberGenerator;
+
+import java.util.List;
+
+
+
+public class Bridge {
+ private final static int MIN_BRIDGE_SIZE = 3;
+ private final static int MAX_BRIDGE_SIZE = 20;
+ private final static String WRONG_RANGE_INPUT = "[ERROR] λ€λ¦¬ κΈΈμ΄λ %dλΆν° %d μ¬μ΄μ μ«μμ¬μΌ ν©λλ€." + System.lineSeparator();
+
+
+ private final List bridgeStates;
+
+
+ public Bridge(int bridgeSize) throws IllegalArgumentException {
+ try {
+ validate(bridgeSize);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+
+ BridgeNumberGenerator bridgeRandomNumberGenerator = new BridgeRandomNumberGenerator();
+ BridgeMaker bridgeMaker = new BridgeMaker(bridgeRandomNumberGenerator);
+
+ bridgeStates = bridgeMaker.makeBridge(bridgeSize);
+ }
+
+
+ public void validate(int bridgeSize) throws IllegalArgumentException {
+ if (bridgeSize < MIN_BRIDGE_SIZE || MAX_BRIDGE_SIZE < bridgeSize) {
+ String rangeError = String.format(WRONG_RANGE_INPUT, MIN_BRIDGE_SIZE, MAX_BRIDGE_SIZE);
+
+ throw new IllegalArgumentException(rangeError);
+ }
+ }
+
+ public List getBridgeStates() {
+ return bridgeStates;
+ }
+
+ public String getBridgeState(int bridgeLocation) {
+ return bridgeStates.get(bridgeLocation);
+ }
+}
diff --git a/src/main/java/bridge/Model/BridgeBlock.java b/src/main/java/bridge/Model/BridgeBlock.java
new file mode 100644
index 00000000000..a033bfc79c6
--- /dev/null
+++ b/src/main/java/bridge/Model/BridgeBlock.java
@@ -0,0 +1,29 @@
+package bridge.Model;
+
+import java.util.Arrays;
+
+
+
+public enum BridgeBlock {
+ UP("U", 1),
+ DOWN("D", 0);
+
+
+ private final String blockIdentifier;
+ private final int blockNumber;
+
+
+ BridgeBlock(String blockIdentifier, int blockNumber) {
+ this.blockIdentifier = blockIdentifier;
+ this.blockNumber = blockNumber;
+ }
+
+
+ public static String getBlockIdentifier(int blockNumber) {
+ return Arrays.stream(BridgeBlock.values())
+ .filter(block -> block.blockNumber == blockNumber)
+ .findAny()
+ .get()
+ .blockIdentifier;
+ }
+}
diff --git a/src/main/java/bridge/Model/BridgeGame.java b/src/main/java/bridge/Model/BridgeGame.java
new file mode 100644
index 00000000000..285246b5e59
--- /dev/null
+++ b/src/main/java/bridge/Model/BridgeGame.java
@@ -0,0 +1,105 @@
+package bridge.Model;
+
+import static bridge.Constant.InputValue.COMMAND_RETRY;
+
+import java.util.List;
+
+
+
+public class BridgeGame {
+ private final Bridge bridge;
+ private final Player player;
+ private int retryCount;
+ private int maxPassedCount;
+
+
+ public BridgeGame(int size) throws IllegalArgumentException {
+ try {
+ this.bridge = new Bridge(size);
+ this.player = new Player();
+ this.retryCount = 1;
+ this.maxPassedCount = 0;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+ }
+
+
+ public void move(String playerSelection) {
+ int nextPlayerLocation = player.getPassedCount();
+ String nextBridgeState = bridge.getBridgeState(nextPlayerLocation);
+
+ if (!playerSelection.equals(nextBridgeState)) {
+ player.die();
+ }
+ }
+
+ public void retry(String command) {
+ updateMaxPassedCount();
+
+ if (command.equals(COMMAND_RETRY)) {
+ player.revive();
+ retryCount++;
+ }
+ }
+
+ public void updateMaxPassedCount() {
+ int passedCount = player.getPassedCount();
+
+ if (maxPassedCount < passedCount) {
+ maxPassedCount = passedCount;
+ }
+ }
+
+ public boolean winGame() {
+ int playerNextLocation = player.getPassedCount();
+ List bridgeStates = bridge.getBridgeStates();
+
+ if (bridgeStates.size() <= playerNextLocation) { // λ€μμ μ΄λν κ³³μ΄ μΈλ±μ€λ₯Ό λ²μ΄λ κ²½μ° λμ λλ¬ν κ²
+ maxPassedCount = playerNextLocation - 1;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isGameOver() {
+ if (isPlayerDead() || winGame()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isPlayerDead() {
+ if (player.isAlive()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public void updatePlayer() {
+ if (player.isAlive()) {
+ player.success();
+ }
+ }
+
+ //getter
+ public List getBridgeStates() {
+ return bridge.getBridgeStates();
+ }
+
+ public int getRetryCount() {
+ return retryCount;
+ }
+
+ public int getMaxPassedCount() {
+ return maxPassedCount;
+ }
+
+ public int getPassedCount() {
+ return player.getPassedCount();
+ }
+}
diff --git a/src/main/java/bridge/Model/Player.java b/src/main/java/bridge/Model/Player.java
new file mode 100644
index 00000000000..c062b4753f7
--- /dev/null
+++ b/src/main/java/bridge/Model/Player.java
@@ -0,0 +1,37 @@
+package bridge.Model;
+
+
+
+public class Player {
+ private int passedCount;
+ private boolean alive;
+
+
+ public Player() {
+ this.passedCount = 0;
+ this.alive = true;
+ }
+
+
+ public void die() {
+ alive = false;
+ }
+
+ public void success() {
+ passedCount++;
+ }
+
+ public void revive() {
+ alive = true;
+ passedCount = 0;
+ }
+
+ // getter
+ public boolean isAlive() {
+ return alive;
+ }
+
+ public int getPassedCount() {
+ return passedCount;
+ }
+}
diff --git a/src/main/java/bridge/OutputView.java b/src/main/java/bridge/OutputView.java
deleted file mode 100644
index 69a433a6285..00000000000
--- a/src/main/java/bridge/OutputView.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package bridge;
-
-/**
- * μ¬μ©μμκ² κ²μ μ§ν μν©κ³Ό κ²°κ³Όλ₯Ό μΆλ ₯νλ μν μ νλ€.
- */
-public class OutputView {
-
- /**
- * νμ¬κΉμ§ μ΄λν λ€λ¦¬μ μνλ₯Ό μ ν΄μ§ νμμ λ§μΆ° μΆλ ₯νλ€.
- *
- * μΆλ ₯μ μν΄ νμν λ©μλμ μΈμ(parameter)λ μμ λ‘κ² μΆκ°νκ±°λ λ³κ²½ν μ μλ€.
- */
- public void printMap() {
- }
-
- /**
- * κ²μμ μ΅μ’
κ²°κ³Όλ₯Ό μ ν΄μ§ νμμ λ§μΆ° μΆλ ₯νλ€.
- *
- * μΆλ ₯μ μν΄ νμν λ©μλμ μΈμ(parameter)λ μμ λ‘κ² μΆκ°νκ±°λ λ³κ²½ν μ μλ€.
- */
- public void printResult() {
- }
-}
diff --git a/src/main/java/bridge/Util/InputConverter.java b/src/main/java/bridge/Util/InputConverter.java
new file mode 100644
index 00000000000..1fe2b7de4c9
--- /dev/null
+++ b/src/main/java/bridge/Util/InputConverter.java
@@ -0,0 +1,15 @@
+package bridge.Util;
+
+
+
+public class InputConverter {
+ public static int convertToInt(String input) throws IllegalArgumentException {
+ try {
+ InputValidator.validateNumberInput(input);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+
+ return Integer.parseInt(input);
+ }
+}
diff --git a/src/main/java/bridge/Util/InputValidator.java b/src/main/java/bridge/Util/InputValidator.java
new file mode 100644
index 00000000000..0f04945f114
--- /dev/null
+++ b/src/main/java/bridge/Util/InputValidator.java
@@ -0,0 +1,50 @@
+package bridge.Util;
+
+import static bridge.Constant.InputValue.COMMAND_QUIT;
+import static bridge.Constant.InputValue.COMMAND_RETRY;
+import static bridge.Constant.InputValue.SELECTION_DOWN;
+import static bridge.Constant.InputValue.SELECTION_UP;
+
+
+
+public class InputValidator {
+ private static final String ERROR_PREFIX = "[ERROR]";
+ private static final String EMPTY_INPUT = ERROR_PREFIX + "λΉ λ¬Έμμ
λλ€.";
+ private static final String WRONG_SIZE_INPUT = ERROR_PREFIX + "μ«μλ§ μ
λ ₯ κ°λ₯ν©λλ€.";
+ private static final String WRONG_SELECTION_INPUT = ERROR_PREFIX + "'U' λλ 'D'λ§ μ
λ ₯ κ°λ₯ν©λλ€.";
+ private static final String WRONG_COMMAND_INPUT = ERROR_PREFIX + "μ’
λ£λ₯Ό μν΄μλ 'Q', μ¬μμμ μν΄μλ 'Rμ μ
λ ₯ν΄μ£ΌμΈμ.";
+
+
+ public static void validateNumberInput(String input) throws IllegalArgumentException {
+ final String NUMBER_REGEX = "[0-9]+";
+
+ if (input.isBlank()) {
+ throw new IllegalArgumentException(EMPTY_INPUT);
+ }
+
+ if (!input.matches(NUMBER_REGEX)) {
+ throw new IllegalArgumentException(WRONG_SIZE_INPUT);
+ }
+ }
+
+ public static void validateSelectionInput(String input) throws IllegalArgumentException {
+ if (input.isBlank()) {
+ throw new IllegalArgumentException(EMPTY_INPUT);
+ }
+
+ if (!input.equals(SELECTION_UP) && !input.equals(SELECTION_DOWN)) {
+ throw new IllegalArgumentException(WRONG_SELECTION_INPUT);
+ }
+ }
+
+ public static void validateCommandInput(String input) throws IllegalArgumentException {
+ if (input.isBlank()) {
+ throw new IllegalArgumentException(EMPTY_INPUT);
+ }
+
+ if (!input.equals(COMMAND_RETRY) && !input.equals(COMMAND_QUIT)) {
+ throw new IllegalArgumentException(WRONG_COMMAND_INPUT);
+ }
+ }
+
+}
diff --git a/src/main/java/bridge/View/InputView.java b/src/main/java/bridge/View/InputView.java
new file mode 100644
index 00000000000..c53c894a0aa
--- /dev/null
+++ b/src/main/java/bridge/View/InputView.java
@@ -0,0 +1,60 @@
+package bridge.View;
+
+import static camp.nextstep.edu.missionutils.Console.readLine;
+
+import bridge.Util.InputConverter;
+import bridge.Util.InputValidator;
+
+
+
+public class InputView {
+ private static final String START_GAME = "λ€λ¦¬ 건λκΈ° κ²μμ μμν©λλ€.";
+ private static final String INPUT_BRIDGE_SIZE = "λ€λ¦¬μ κΈΈμ΄λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.";
+ private static final String INPUT_SELECTION = "μ΄λν μΉΈμ μ νν΄μ£ΌμΈμ. (μ: U, μλ: D)";
+ private static final String INPUT_COMMAND = "κ²μμ λ€μ μλν μ§ μ¬λΆλ₯Ό μ
λ ₯ν΄μ£ΌμΈμ. (μ¬μλ: R, μ’
λ£: Q)";
+
+
+ public void printStartMessage() {
+ System.out.println(START_GAME);
+ System.out.println();
+ }
+
+ public int readBridgeSize() throws IllegalArgumentException {
+ System.out.println(INPUT_BRIDGE_SIZE);
+ String input = readLine();
+
+ try {
+ int bridgeSize = InputConverter.convertToInt(input);
+
+ return bridgeSize;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+ }
+
+ public String readMoving() throws IllegalArgumentException {
+ System.out.println(INPUT_SELECTION);
+ String input = readLine();
+
+ try {
+ InputValidator.validateSelectionInput(input);
+
+ return input;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+ }
+
+ public String readGameCommand() throws IllegalArgumentException {
+ System.out.println(INPUT_COMMAND);
+ String input = readLine();
+
+ try {
+ InputValidator.validateCommandInput(input);
+
+ return input;
+ } catch (IllegalArgumentException illegalArgumentException) {
+ throw illegalArgumentException;
+ }
+ }
+}
diff --git a/src/main/java/bridge/View/OutputView.java b/src/main/java/bridge/View/OutputView.java
new file mode 100644
index 00000000000..5818db745c0
--- /dev/null
+++ b/src/main/java/bridge/View/OutputView.java
@@ -0,0 +1,89 @@
+package bridge.View;
+
+import static bridge.Constant.InputValue.SELECTION_DOWN;
+import static bridge.Constant.InputValue.SELECTION_UP;
+
+import static bridge.Constant.OutputValue.*;
+
+import bridge.Model.BridgeGame;
+
+import java.util.List;
+
+
+
+public class OutputView {
+ private static final String RESULT_MESSAGE = "μ΅μ’
κ²μ κ²°κ³Ό";
+ private static final String BRIDGE_MAP = "[%s]" + System.lineSeparator();
+ private static final String IS_SUCCESS = "κ²μ μ±κ³΅ μ¬λΆ: %s" + System.lineSeparator();
+ private static final String RETRY_COUNT = "μ΄ μλν νμ: %d" + System.lineSeparator();
+
+
+ private String getIsPassedStair(String bridgeState, String stair) {
+ if (bridgeState.equals(stair)) {
+ return RIGHT_SELECTION;
+ }
+
+ return NOT_SELECTION;
+ }
+
+ private String getPassedStair(List bridgeStates, int passedCount, String stair) {
+ String result = "";
+
+ for (int bridgeLocation = 0; bridgeLocation < passedCount; bridgeLocation++) {
+ String bridgeState = bridgeStates.get(bridgeLocation);
+
+ result += getIsPassedStair(bridgeState, stair);
+ result += SEPARATOR;
+ }
+
+ return result;
+ }
+
+ private void printStair(BridgeGame bridgeGame, int passedCount, String stair) {
+ List bridgeStates = bridgeGame.getBridgeStates();
+ String selectedBridgeState = bridgeStates.get(passedCount);
+ boolean playerDead = bridgeGame.isPlayerDead();
+
+ String result = getPassedStair(bridgeStates, passedCount, stair)
+ + getSelectResult(playerDead, selectedBridgeState, stair);
+
+ System.out.printf(BRIDGE_MAP, result);
+ }
+
+ private String getIsSuccess(boolean playerDead) {
+ if (playerDead) {
+ return FAIL;
+ }
+
+ return SUCCESS;
+ }
+
+ private String getSelectResult(boolean playerDead, String bridgeState, String stair) {
+ if (!playerDead && bridgeState.equals(stair)) {
+ return RIGHT_SELECTION;
+ }
+
+ if (playerDead && !bridgeState.equals(stair)) {
+ return WRONG_SELECTION;
+ }
+
+ return NOT_SELECTION;
+ }
+
+ public void printMap(BridgeGame bridgeGame, int passedCount) {
+ printStair(bridgeGame, passedCount, SELECTION_UP);
+ printStair(bridgeGame, passedCount, SELECTION_DOWN);
+ System.out.println();
+ }
+
+ public void printResult(BridgeGame bridgeGame) {
+ int maxPassedCount = bridgeGame.getMaxPassedCount();
+
+ System.out.println(RESULT_MESSAGE);
+
+ printMap(bridgeGame, maxPassedCount);
+
+ System.out.printf(IS_SUCCESS, getIsSuccess(bridgeGame.isPlayerDead()));
+ System.out.printf(RETRY_COUNT, bridgeGame.getRetryCount());
+ }
+}
diff --git a/src/test/java/bridge/ApplicationTest.java b/src/test/java/bridge/ApplicationTest.java
index 1a163ec0a2a..13ba1d376b3 100644
--- a/src/test/java/bridge/ApplicationTest.java
+++ b/src/test/java/bridge/ApplicationTest.java
@@ -7,6 +7,7 @@
import camp.nextstep.edu.missionutils.test.NsTest;
import java.util.List;
+import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class ApplicationTest extends NsTest {
@@ -39,6 +40,62 @@ class ApplicationTest extends NsTest {
}, 1, 0, 1);
}
+
+ @Test
+ void κΈ°λ₯_ν
μ€νΈ_μ€ν¨_ν_μ±κ³΅() {
+ assertRandomNumberInRangeTest(() -> {
+ run("3", "U", "U", "R", "D", "R", "U", "D", "U");
+ assertThat(output()).contains(
+ "[ O | X ]",
+ "[ | ]",
+ "[ ]",
+ "[ X ]",
+ "μ΅μ’
κ²μ κ²°κ³Ό",
+ "[ O | | O ]",
+ "[ | O | ]",
+ "κ²μ μ±κ³΅ μ¬λΆ: μ±κ³΅",
+ "μ΄ μλν νμ: 3"
+ );
+ }, 1, 0, 1);
+ }
+ @DisplayName("μ¬μμ μ νλ‘ μλ‘ λ€λ₯Έ κ°μΌ κ²½μ°")
+ @Test
+ void κΈ°λ₯_ν
μ€νΈ_μ€ν¨_ν_μ’
λ£_λ€λ₯Έκ°() {
+ assertRandomNumberInRangeTest(() -> {
+ run("3", "U", "U", "R", "D", "Q");
+ assertThat(output()).containsSubsequence(
+ "[ O | X ]",
+ "[ | ]",
+ "[ ]",
+ "[ X ]",
+ "μ΅μ’
κ²μ κ²°κ³Ό",
+ "[ O | X ]",
+ "[ | ]",
+ "κ²μ μ±κ³΅ μ¬λΆ: μ€ν¨",
+ "μ΄ μλν νμ: 2"
+ );
+ }, 1, 0, 1);
+ }
+
+ @DisplayName("μ¬μμ μ νλ‘ μλ‘ κ°μ κ°μΌ κ²½μ°")
+ @Test
+ void κΈ°λ₯_ν
μ€νΈ_μ€ν¨_ν_μ’
λ£_κ°μκ°() {
+ assertRandomNumberInRangeTest(() -> {
+ run("3", "U", "D", "R", "D", "Q");
+ assertThat(output()).containsSubsequence(
+ "[ O | ]",
+ "[ | X ]",
+ "[ ]",
+ "[ X ]",
+ "μ΅μ’
κ²μ κ²°κ³Ό",
+ "[ O | ]",
+ "[ | X ]",
+ "κ²μ μ±κ³΅ μ¬λΆ: μ€ν¨",
+ "μ΄ μλν νμ: 2"
+ );
+ }, 1, 1, 1);
+ }
+
@Test
void μμΈ_ν
μ€νΈ() {
assertSimpleTest(() -> {
diff --git a/src/test/java/bridge/Model/BridgeBlockTest.java b/src/test/java/bridge/Model/BridgeBlockTest.java
new file mode 100644
index 00000000000..e24340a0291
--- /dev/null
+++ b/src/test/java/bridge/Model/BridgeBlockTest.java
@@ -0,0 +1,30 @@
+package bridge.Model;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import static bridge.Constant.InputValue.SELECTION_DOWN;
+import static bridge.Constant.InputValue.SELECTION_UP;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+
+class BridgeBlockTest {
+ private static final int SELECTION_UP_NUMBER = 1;
+ private static final int SELECTION_DOWN_NUMBER = 0;
+
+ @DisplayName("μμ± λ²νΈμ λ°λ₯Έ μ¬λ°λ₯Έ λ¬Έμ λ°ννλμ§ ν
μ€νΈ")
+ @Nested
+ class StringReturnTest {
+ @Test
+ void λ°ν_μ¬λ°λ₯Έ_λ¬Έμ_UP() {
+ assertThat(BridgeBlock.getBlockIdentifier(SELECTION_UP_NUMBER)).isEqualTo(SELECTION_UP);
+ }
+ @Test
+ void λ°ν_μ¬λ°λ₯Έ_λ¬Έμ_DOWN() {
+ assertThat(BridgeBlock.getBlockIdentifier(SELECTION_DOWN_NUMBER)).isEqualTo(SELECTION_DOWN);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/bridge/Model/BridgeGameTest.java b/src/test/java/bridge/Model/BridgeGameTest.java
new file mode 100644
index 00000000000..1571dc6db61
--- /dev/null
+++ b/src/test/java/bridge/Model/BridgeGameTest.java
@@ -0,0 +1,28 @@
+package bridge.Model;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+
+class BridgeGameTest {
+ private static final String SELECTION_UP = "U";
+ private static final int SELECTION_UP_NUMBER = 1;
+ private static final String SELECTION_DOWN = "D";
+ private static final int SELECTION_DOWN_NUMBER = 0;
+ @DisplayName("μλͺ»λ λ°νμ λ°μμ λ μ£½λμ§ νμΈ")
+ @Test
+ void μλͺ»_μμ§μ¬_μ¬λ§() {
+ assertRandomNumberInRangeTest(() -> {
+ BridgeGame bridgeGame = new BridgeGame(3);
+ bridgeGame.move(SELECTION_DOWN);
+
+ assertThat(bridgeGame.isPlayerDead()).isTrue();
+ }, SELECTION_UP_NUMBER, SELECTION_DOWN_NUMBER, SELECTION_DOWN_NUMBER);
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/bridge/Model/BridgeTest.java b/src/test/java/bridge/Model/BridgeTest.java
new file mode 100644
index 00000000000..1010d33bc3b
--- /dev/null
+++ b/src/test/java/bridge/Model/BridgeTest.java
@@ -0,0 +1,43 @@
+package bridge.Model;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+
+
+class BridgeTest {
+ private static final String ERROR = "[ERROR]";
+ private static final int MIN_RANGE = 3;
+ private static final int MAX_RANGE = 20;
+
+
+ @DisplayName("λ²μ μΈμ μ«μ μ
λ ₯ μ μμΈ throw")
+ @ParameterizedTest
+ @ValueSource(ints = {1, 2, 55, 101})
+ void μμΈ_λ²μλ₯Ό_λ²μ΄λ_μ«μ(int size) {
+ assertThatThrownBy(() -> assertThat(new Bridge(size)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @DisplayName("λ²μ μΈμ μ«μ μ
λ ₯ μ μμΈ λ©μΈμ§ νμΈ")
+ @ParameterizedTest
+ @ValueSource(ints = {1, 2, 55, 101})
+ void μλ¬_λ²μλ₯Ό_λ²μ΄λ_μ«μ(int size) {
+ assertThatThrownBy(() -> assertThat(new Bridge(size)))
+ .hasMessageContaining(ERROR);
+ }
+
+ @DisplayName("λ²μ λ΄μ μ«μκ° μμΈλ₯Ό λ°μνμ§ μλμ§ νμΈ")
+ @ParameterizedTest
+ @ValueSource(ints = {MIN_RANGE, 5, MAX_RANGE})
+ void μ
λ ₯_λ²μ_λ΄μ_μ«μ(int size) {
+ assertDoesNotThrow(() -> new Bridge(size));
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/bridge/Util/InputConverterTest.java b/src/test/java/bridge/Util/InputConverterTest.java
new file mode 100644
index 00000000000..58b0fece9fe
--- /dev/null
+++ b/src/test/java/bridge/Util/InputConverterTest.java
@@ -0,0 +1,42 @@
+package bridge.Util;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+
+
+class InputConverterTest {
+ private static final String ERROR = "[ERROR]";
+
+ @DisplayName("μ μμ μΈ κ°μ λ¬Έμμ΄μ μ μλ‘ λ³ννλμ§ νμΈ")
+ @ParameterizedTest
+ @ValueSource(strings = {"12", "1", "5", "4", "10"})
+ void λ¬Έμμ΄μ_μ μλ‘_λ³ν(String input) {
+ int convertedNumber = InputConverter.convertToInt(input);
+ int expectedNumber = Integer.parseInt(input);
+
+ assertThat(convertedNumber).isEqualTo(expectedNumber);
+ }
+
+ @DisplayName("μλͺ»λ μ
λ ₯κ°μ΄ μμΈλ₯Ό λμ§λμ§ νμΈ")
+ @ParameterizedTest
+ @ValueSource(strings = {" ", "", "1a", "1,0"})
+ void μμΈ_μ μ_λ³ν(String input) {
+ assertThatThrownBy(() ->
+ InputConverter.convertToInt((input)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @DisplayName("μλͺ»λ μ
λ ₯κ°μ λν΄ [Error]λ₯Ό ν¬ν¨ν μμΈ λ©μΈμ§λ₯Ό λμ§λμ§ νμΈ")
+ @ParameterizedTest
+ @ValueSource(strings = {" ", "", "1a", "1,0"})
+ void μλ¬_μ μ_λ³ν(String input) {
+ assertThatThrownBy(() ->
+ InputConverter.convertToInt((input)))
+ .hasMessageContaining(ERROR);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/bridge/Util/InputValidatorTest.java b/src/test/java/bridge/Util/InputValidatorTest.java
new file mode 100644
index 00000000000..c6ce7ef7703
--- /dev/null
+++ b/src/test/java/bridge/Util/InputValidatorTest.java
@@ -0,0 +1,45 @@
+package bridge.Util;
+
+import bridge.Constant.InputValue;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+
+
+class InputValidatorTest {
+ @DisplayName("μλͺ»λ μ, μλ μ
λ ₯ μμΈ throw")
+ @ParameterizedTest
+ @ValueSource(strings = {"aaa", "bb", "d", "u", "", " "})
+ void validateSelectionInput(String input) {
+ assertThatThrownBy(() -> InputValidator.validateSelectionInput(input))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @DisplayName("μ¬λ°λ₯Έ μ, μλ μ
λ ₯ 체ν¬")
+ @ParameterizedTest
+ @ValueSource(strings = {InputValue.SELECTION_DOWN, InputValue.SELECTION_UP})
+ void assignSelectionInput(String input) {
+ assertDoesNotThrow(() -> InputValidator.validateSelectionInput(input));
+ }
+
+ @DisplayName("μλͺ»λ μ¬μμ/μ’
λ£ λͺ
λ Ήμ΄ μ
λ ₯ μμΈ throw")
+ @ParameterizedTest
+ @ValueSource(strings = {"aaa", "bb", "d1", "5", "", " ", "Q3", "3Q"})
+ void validateCommandInput(String input) {
+ assertThatThrownBy(() -> InputValidator.validateCommandInput(input))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @DisplayName("μ¬λ°λ₯Έ μ¬μμ/μ’
λ£ λͺ
λ Ήμ΄ μ²΄ν¬")
+ @ParameterizedTest
+ @ValueSource(strings = {InputValue.COMMAND_QUIT, InputValue.COMMAND_RETRY})
+ void assignCommandInput(String input) {
+ assertDoesNotThrow(() -> InputValidator.validateCommandInput(input));
+ }
+}
\ No newline at end of file