Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,24 @@

## 과제 제출 과정
* [과제 제출 방법](https://github.com/next-step/nextstep-docs/tree/master/ent-precourse)

## 구현할 기능
- 상대방이 무작위 3개의 숫자 선택
- 선택한 3개의 숫자는 서로 달라야한다.
- 플레이어로부터 입력을 받는다.
- 입력과 정답은 같은 갯수의 숫자로 이루어져야한다.
- 입력 받은 숫자들은 서로 달라야한다.
- 플레이어의 입력과 정답으로부터 스코어를 계산한다.
- 스코어 계산은 입력의 각 자리수마다 따로 계산한다.
- 입력 받은 수가 정답과 같은 자리에 있으면 스트라이크(STRIKE)로 계산한다.
- 입력 받은 수가 정답에 존재하지만 다른 자리에 있으면 볼(BALL)로 계산한다.
- 입력 받은 수가 정답에 존재하지 않으면 낫싱(NOTHING)으로 계산한다.
- 플레이어가 입력한 숫자에 대한 결과를 출력한다. 스트라이크가 `s`개, 볼이 `b`개인 경우 출력은 다음과 같다.
- `s >= 1, b >= 1`
- `{s} 스트라이크 {b} 볼` 출력
- `s >= 1, b == 0`
- `{s} 스트라이크` 출력
- `s == 0, b >= 1`
- `{b} 볼` 출력
- `s == 0, b == 0`
- `낫싱` 출력
9 changes: 9 additions & 0 deletions src/main/java/MainApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import player.Player;

public class MainApplication {

public static void main(String[] args) {
Player player = new Player();
player.start();
}
}
10 changes: 10 additions & 0 deletions src/main/java/exception/GameCommandNoutFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package exception;

public class GameCommandNoutFoundException extends RuntimeException {

public static final String GAME_COMMAND_NOT_FOUND_EXCEPTION = "잘못된 커멘드 입력입니다.";

public GameCommandNoutFoundException() {
super(GAME_COMMAND_NOT_FOUND_EXCEPTION);
}
}
10 changes: 10 additions & 0 deletions src/main/java/exception/InputLengthValidationException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package exception;

public class InputLengthValidationException extends RuntimeException {

public static final String INPUT_LENGTH_VALIDATION_EXCEPTION_MESSAGE = "잘못된 길이의 입력입니다.";

public InputLengthValidationException() {
super(INPUT_LENGTH_VALIDATION_EXCEPTION_MESSAGE);
}
}
10 changes: 10 additions & 0 deletions src/main/java/exception/InputNumberDuplicationException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package exception;

public class InputNumberDuplicationException extends RuntimeException {

public static final String INPUT_NUMBER_DUPLICATION_EXCEPTION_MESSAGE = "입력에는 중복된 숫자가 존재할 수 없습니다.";

public InputNumberDuplicationException() {
super(INPUT_NUMBER_DUPLICATION_EXCEPTION_MESSAGE);
}
}
43 changes: 43 additions & 0 deletions src/main/java/game/BaseBallGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package game;

import opponent.Opponent;
import score.Score;
import settings.GameSetting;
import ui.InputManager;
import ui.OutputManager;

import java.util.List;

public class BaseBallGame {

private final Opponent opponent;

public BaseBallGame(Opponent opponent) {
this.opponent = opponent;
}

public void start() {
Score score;
do {
score = nextStage();
} while (!isGameOver(score));
GameSetting.getInstance().getOutputManager().printGameOverMessage();
}

private boolean isGameOver(Score score) {
return score.getStrikeCount() == 3;
}

private Score nextStage() {
Score score = new Score(0, 0);
OutputManager outputManager = GameSetting.getInstance().getOutputManager();
InputManager inputManager = GameSetting.getInstance().getInputManager();
outputManager.printInputMessage();
List<Integer> inputNumbers = inputManager.getInputNumbers();
for (int i = 0; i < inputNumbers.size(); i++) {
score.updateScore(opponent.getAnswer(), inputNumbers.get(i), i);
}
outputManager.printResult(score);
return score;
}
}
41 changes: 41 additions & 0 deletions src/main/java/game/GameCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package game;

import exception.GameCommandNoutFoundException;

import java.util.HashMap;
import java.util.Map;

public enum GameCommand {

RESTART(1),
END(2);

private static final Map<Integer, GameCommand> gameCommandMapping = new HashMap<>();

static {
for (GameCommand gameCommand : GameCommand.values()) {
gameCommandMapping.put(
gameCommand.getCommandNumber(),
gameCommand
);
}
}

private final int commandNumber;

GameCommand(int commandNumber) {
this.commandNumber = commandNumber;
}

public static GameCommand getCommand(int commandNumber) {
if (!gameCommandMapping.containsKey(commandNumber)) {
throw new GameCommandNoutFoundException();
}

return gameCommandMapping.get(commandNumber);
}

public int getCommandNumber() {
return commandNumber;
}
}
15 changes: 15 additions & 0 deletions src/main/java/input/InputParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package input;

import java.util.ArrayList;
import java.util.List;

public class InputParser {

public List<Integer> toIntegerList(String input) throws NumberFormatException {
ArrayList<Integer> result = new ArrayList<>();
for (String element : input.split("")) {
result.add(Integer.parseInt(element));
}
return result;
}
}
27 changes: 27 additions & 0 deletions src/main/java/input/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package input;

import exception.InputLengthValidationException;
import exception.InputNumberDuplicationException;

import java.util.HashSet;
import java.util.List;

public class InputValidator {

public void validateInput(List<Integer> input) {
if (!isValidSize(input)) {
throw new InputLengthValidationException();
}
if (hasDuplicatedNumbers(input)) {
throw new InputNumberDuplicationException();
}
}

private boolean isValidSize(List<Integer> input) {
return input.size() == 3;
}

private boolean hasDuplicatedNumbers(List<Integer> input) {
return new HashSet<>(input).size() != input.size();
}
}
27 changes: 27 additions & 0 deletions src/main/java/opponent/Opponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package opponent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Opponent {
private final List<Integer> answer;

public Opponent() {
answer = Collections.unmodifiableList(chooseAnswer());
}

public List<Integer> getAnswer() {
return answer;
}

protected List<Integer> chooseAnswer() {
ArrayList<Integer> possibleNumbers = new ArrayList<>();
for (int i = 1; i < 10; i++) {
possibleNumbers.add(i);
}
Collections.shuffle(possibleNumbers);
return possibleNumbers.subList(0, 3);
}

}
25 changes: 25 additions & 0 deletions src/main/java/player/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package player;

import game.BaseBallGame;
import game.GameCommand;
import opponent.Opponent;
import settings.GameSetting;
import ui.InputManager;

public class Player {

public void start() {
InputManager inputManager = GameSetting.getInstance().getInputManager();
do {
playRound();
} while (inputManager.getInputGameCommand() == GameCommand.RESTART);
}

protected void playRound() {
Opponent opponent = new Opponent();
BaseBallGame baseBallGame = new BaseBallGame(opponent);
baseBallGame.start();
}


}
9 changes: 9 additions & 0 deletions src/main/java/score/BaseBallCriterion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package score;

import java.util.List;

@FunctionalInterface
public interface BaseBallCriterion {

boolean judge(List<Integer> answer, Integer userNumber, Integer pos);
}
25 changes: 25 additions & 0 deletions src/main/java/score/BaseBallJudgement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package score;

import java.util.List;

public enum BaseBallJudgement {

STRIKE((answer, userNumber, pos) -> answer.get(pos).equals(userNumber)),
BALL((answer, userNumber, pos) -> {
if (STRIKE.hit(answer, userNumber, pos)) {
return false;
}
return answer.contains(userNumber);
}),
NOTHING((answer, userNumber, pos) -> !answer.contains(userNumber));

private final BaseBallCriterion criterion;

BaseBallJudgement(BaseBallCriterion criterion) {
this.criterion = criterion;
}

public boolean hit(List<Integer> answer, Integer userNumber, Integer pos) {
return criterion.judge(answer, userNumber, pos);
}
}
51 changes: 51 additions & 0 deletions src/main/java/score/Score.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package score;

import java.util.List;
import java.util.Objects;

import static score.BaseBallJudgement.BALL;
import static score.BaseBallJudgement.STRIKE;

public class Score {

private Integer strikeCount;

private Integer ballCount;

public Score(Integer strikeCount, Integer ballCount) {
this.strikeCount = strikeCount;
this.ballCount = ballCount;
}

public Integer getStrikeCount() {
return strikeCount;
}

public Integer getBallCount() {
return ballCount;
}

public void updateScore(List<Integer> answer, Integer userNumber, Integer pos) {
if (STRIKE.hit(answer, userNumber, pos)) {
strikeCount += 1;
return;
}
if (BALL.hit(answer, userNumber, pos)) {
ballCount += 1;
return;
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Score score = (Score) o;
return Objects.equals(strikeCount, score.strikeCount) && Objects.equals(ballCount, score.ballCount);
}

@Override
public int hashCode() {
return Objects.hash(strikeCount, ballCount);
}
}
32 changes: 32 additions & 0 deletions src/main/java/settings/GameSetting.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package settings;

import ui.InputManager;
import ui.OutputManager;

public class GameSetting {

private final InputManager inputManager;

private final OutputManager outputManager;

private GameSetting() {
inputManager = new InputManager(System.in);
outputManager = new OutputManager(System.out);
}

public static GameSetting getInstance() {
return GameSettingHolder.GAME_SETTING;
}

public InputManager getInputManager() {
return inputManager;
}

public OutputManager getOutputManager() {
return outputManager;
}

private static class GameSettingHolder {
private static final GameSetting GAME_SETTING = new GameSetting();
}
}
Loading