Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public class BridgeMaker {

### BridgeRandomNumberGenerator 클래스

- Random 값 추출은 제공된 `bridge.BridgeRandomNumberGenerator`의 `generate()`를 활용한다.
- Random 값 추출은 제공된 `BridgeRandomNumberGenerator`의 `generate()`를 활용한다.
- `BridgeRandomNumberGenerator`, `BridgeNumberGenerator` 클래스의 코드는 변경할 수 없다.

#### 사용 예시
Expand Down
54 changes: 54 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 요구사항 명세서
## [카테고리]
1. 사용자
2. 다리 생성기
3. 이동 검사
4. 시스템

## [카테고리 별 요구사항 내용]
### 1. 사용자
- 다리의 길이를 입력한다.
- 이동할 칸을 입력한다.
- 게임 재시작 여부를 입력한다.


### 2. 다리 생성기
- 입력한 길이의 다리를 생성한다.
- 다리는 각 칸은 위, 아래 두 칸으로 둘 중 하나의 칸만 건널 수 있도록 해야한다.


### 3. 이동 검사
- 사용자가 이동할 칸을 검사한다.


### 4. 시스템
- 게임을 시작한다.
- 게임 재시작 여부를 체크한다.
- 최종 게임 결과를 출력하고 게임을 종료한다.


# 기능 목록
### 1. 입력 기능
- 사용자가 입력하는 다리의 길이를 입력 받는 기능
- 사용자가 입력하는 이동할 칸을 입력 받는 기능
- 사용자가 입력하는 게임 재시작 여부를 입력 받는 기능


### 2. 출력 기능
- 사용자가 선택한 칸 출력 기능
- 최종 게임 결과 출력 기능


### 3. 게임 로직 기능
- 입력 받은 길이의 다리 생성 기능
- 이동할 수 있는 칸인지 검사하는 기능
- 게임 시작/ 재시작 기능
- 시도한 횟수를 세는 기능


### 4. 검증 기능
- 입력 검증
- 사용자가 입력한 다리의 길이가 3 이상 20 이하 정수인지 검증
- 사용자가 입력한 다리의 길이가 숫자 1개인지 검증
- 사용자가 입력한 이동할 칸이 U와 D 중 하나의 문자인지 검증
- 사용자가 입력한 재시작 코드가 R와 Q 중 하나의 문자인지 검증
3 changes: 3 additions & 0 deletions src/main/java/bridge/Application.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package bridge;

import bridge.controller.BridgeGame;

public class Application {

public static void main(String[] args) {
// TODO: 프로그램 구현
new BridgeGame().run();
Comment on lines 7 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO 제거

}
}
23 changes: 0 additions & 23 deletions src/main/java/bridge/BridgeGame.java

This file was deleted.

23 changes: 0 additions & 23 deletions src/main/java/bridge/BridgeMaker.java

This file was deleted.

28 changes: 0 additions & 28 deletions src/main/java/bridge/InputView.java

This file was deleted.

23 changes: 0 additions & 23 deletions src/main/java/bridge/OutputView.java

This file was deleted.

121 changes: 121 additions & 0 deletions src/main/java/bridge/controller/BridgeGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package bridge.controller;

import bridge.model.RestartStatus;
import bridge.model.bridge.BridgeMaker;
import bridge.model.bridge.BridgeRandomNumberGenerator;
import bridge.model.result.CompareResult;
import bridge.model.result.FinalResult;
import bridge.model.result.MoveResult;
import bridge.model.user.UserSquare;
import bridge.service.BridgeService;

import java.util.List;

/**
* 다리 건너기 게임을 관리하는 클래스
*/
public class BridgeGame {
private static BridgeService bridgeService;

private static BridgeMaker bridgeMaker;

private static int count;

private static CompareResult compare;

private static RestartStatus restartStatus;

private static FinalResult finalResult;

public BridgeGame() {
bridgeMaker = new BridgeMaker(new BridgeRandomNumberGenerator());
bridgeService = new BridgeService();
count = 0;
}

public void run() {
final List<String> bridge = createBridge();
playGame(bridge);
endGame();
}

private List<String> createBridge() {
return bridgeService.createBridge(bridgeMaker);
}

private void playGame(final List<String> bridge) {
do {
List<Boolean> moveResult = createResultHolder();
count += 1;
for (final String bridgeSquare : bridge) {
move(bridgeSquare, moveResult, bridge);

if (isDifferent()) {
break;
}
}
gameOver();
} while (!isQuit());
}

private void endGame() {
bridgeService.end(count, finalResult);
}

private static List<Boolean> createResultHolder() {
MoveResult.initResultHolder();
return MoveResult.getMoveResult();
}

/**
* 사용자가 칸을 이동할 때 사용하는 메서드
* <p>
* 이동을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다.
*/
public void move(final String bridgeSquare, List<Boolean> moveResult, final List<String> bridge) {
final UserSquare userSquare = new UserSquare();
final boolean eachResult = bridgeService.checkMove(userSquare.getSquare(), bridgeSquare);

compare = CompareResult.getCompareBy(eachResult);
bridgeService.move(moveResult, eachResult, bridge);
retry(eachResult);
}

private static void gameOver() {
if (isSuccess()) {
restartStatus = RestartStatus.QUIT;
finalResult = FinalResult.SUCCESS;
}

if (isFail()) {
finalResult = FinalResult.FAIL;
}
}

/**
* 사용자가 게임을 다시 시도할 때 사용하는 메서드
* <p>
* 재시작을 위해 필요한 메서드의 반환 타입(return type), 인자(parameter)는 자유롭게 추가하거나 변경할 수 있다.
*/
public void retry(final boolean eachResult) {
if (eachResult == false) {
restartStatus = bridgeService.retry();
}
}
Comment on lines +100 to +104
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void retry(final boolean eachResult) {
if (eachResult == false) {
restartStatus = bridgeService.retry();
}
}
public void retry(final boolean eachResult) {
if (!eachResult) {
restartStatus = bridgeService.retry();
}
}


private boolean isDifferent() {
return compare == CompareResult.DIFF;
}

private boolean isQuit() {
return restartStatus == RestartStatus.QUIT;
}

private static boolean isSuccess() {
return compare == CompareResult.SAME;
}

private static boolean isFail() {
return compare == CompareResult.DIFF && restartStatus == RestartStatus.QUIT;
}
}
7 changes: 7 additions & 0 deletions src/main/java/bridge/exception/HasWhiteSpaceException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package bridge.exception;

public class HasWhiteSpaceException extends IllegalArgumentException{
Comment on lines +1 to +3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exception 패키지에 있는 Exception들은 안쓰는거 같은데 만드신 이유가 있나요

public HasWhiteSpaceException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package bridge.exception;

public class InvalidInputRestartStatusException extends IllegalArgumentException{
public InvalidInputRestartStatusException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package bridge.exception;

public class InvalidInputSquareException extends IllegalArgumentException{
public InvalidInputSquareException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package bridge.exception;

public class NotInRangeBridgeSizeException extends IllegalArgumentException{
public NotInRangeBridgeSizeException(final String message) {
super(message);
}
}
7 changes: 7 additions & 0 deletions src/main/java/bridge/exception/NotNumericException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package bridge.exception;

public class NotNumericException extends IllegalArgumentException{
public NotNumericException(final String message) {
super(message);
}
}
37 changes: 37 additions & 0 deletions src/main/java/bridge/model/RestartStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package bridge.model;

import java.util.Arrays;

import static bridge.utils.ExceptionMessage.Input_Exception.INVALID_INPUT_RESTART_STATUS_EXCEPTION;

public enum RestartStatus {
RESTART("R"),
QUIT("Q");

private static final String QUIT_SIGN = "Q";
private static final String RESTART_SIGN = "R";
Comment on lines +11 to +12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 RESTART.signal, QUIT.signal로 쓰면 되지 않나요?
별도의 private static final 상수를 둔 이유는 뭘까요

private final String signal;

RestartStatus(String signal) {
this.signal = signal;
}

public static RestartStatus getRestartStatusBy(final String signal) {
validateCharacter(signal);

return Arrays.stream(values())
.filter(RestartStatus -> RestartStatus.signal.equals(signal))
.findFirst()
.orElseGet(() -> null);
}
Comment on lines +19 to +26
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검증하는게 R, Q 중 하나로 제대로 들어온거 같은데 애초에 이 두 문자가 아닌 다른 문자가 들어오면 Exception을 발생시켜야 하지 않을까요?

밑에서 orElseGet으로 null을 반환하는 이유는 뭐죠? 잘못된 값을 Application 로직에서 null로 다루는건가요?

  • orElseGet -> orElseThrow


private static void validateCharacter(final String signal) {
if (isInvalidCharacter(signal)) {
throw new IllegalArgumentException(INVALID_INPUT_RESTART_STATUS_EXCEPTION.getMessage());
}
}

private static boolean isInvalidCharacter(final String signal) {
return !signal.equals(RESTART_SIGN) && !signal.equals(QUIT_SIGN);
}
}
Loading