Repository navigation
Step1 #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Step1 #67
Changes from all commits
9a77ce7
de4659a
4469e3c
e7d2fab
561e821
cd22c46
a9d7c8e
fa222d2
8e10bc6
7be0d73
d554c19
e2d2456
e5dd49c
e79587d
e977d42
e5423f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import domain.Player; | ||
| import view.InputView; | ||
| import view.OutputView; | ||
|
|
||
| import static view.InputView.getScore; | ||
|
|
||
| public class BowlingMain { | ||
|
|
||
| public static void main(String[] args) { | ||
| Player player = InputView.getPlayer(); | ||
| while (!player.isFinish()) { | ||
| doGame(player); | ||
| } | ||
| } | ||
|
|
||
| private static void doGame(Player player) { | ||
| try { | ||
| player.recordScore(getScore(player.getCurrentFrameNum())); | ||
| OutputView.printResult(player); | ||
| } catch (IllegalArgumentException e) { | ||
| InputView.printMessage(e.getMessage()); | ||
| doGame(player); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package domain; | ||
|
|
||
| import domain.frame.Frames; | ||
| import domain.frame.result.FrameResults; | ||
|
|
||
| public class Player { | ||
| private PlayerName name; | ||
| private Frames frames; | ||
| private FrameResults results; | ||
|
|
||
| public Player(String name) throws IllegalArgumentException { | ||
| this.name = new PlayerName(name); | ||
| frames = new Frames(); | ||
| results = new FrameResults(); | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name.getName(); | ||
| } | ||
|
|
||
| public boolean isFinish() { | ||
| return frames.isFinish(); | ||
| } | ||
|
|
||
| public FrameResults recordScore(int score) { | ||
| results.addResult(frames.getCurrentFrameIdx(), frames.recordScore(score)); | ||
| return results; | ||
| } | ||
|
|
||
| public int getCurrentFrameNum() { | ||
| return frames.getCurrentFrameNum(); | ||
| } | ||
|
|
||
| public FrameResults getResults() { | ||
| return results; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package domain; | ||
|
|
||
| public class PlayerName { | ||
| public static final int LENGTH = 3; | ||
| private String name; | ||
|
|
||
| public PlayerName(String name) { | ||
| if (!isValidNameLength(name)) { | ||
| throw new IllegalArgumentException("이름은 " + LENGTH + "자로 해야함"); | ||
| } | ||
|
|
||
| if (!isValidEnglishName(name)) { | ||
| throw new IllegalArgumentException("영어만 입력 해야함"); | ||
| } | ||
| this.name = name; | ||
| } | ||
|
|
||
| public static boolean isValidNameLength(String name) { | ||
| return name.length() == LENGTH; | ||
| } | ||
|
|
||
| public static boolean isValidEnglishName(String name) { | ||
| char[] convertName = name.toCharArray(); | ||
| for (char ch : convertName) { | ||
| if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 확실하지는 않은데 String에 이를 위해 제공해 주는 메소드가 있지 않나? |
||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package domain; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Score { | ||
| public static final int MIN = 0; | ||
| public static final int MAX = 10; | ||
| private int score; | ||
|
|
||
| public Score(int score) { | ||
| if (!isValidRange(score)) { | ||
| throw new IllegalArgumentException("유효하지않은 범위의 점수입니다"); | ||
| } | ||
| this.score = score; | ||
| } | ||
|
|
||
| public static boolean isValidRange(int score) { | ||
| return score >= MIN && score <= MAX; | ||
| } | ||
|
|
||
| public static boolean isScoreLimit(List<Score> scores) { | ||
| return scores.stream().mapToInt(scoreInstance -> scoreInstance.score).sum() == MAX; | ||
| } | ||
|
|
||
| public boolean isOverRecord(List<Score> scores) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isScoreLimit(), isOverRecord() 메소드를 분리한 이유는?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isOverRecord는 Scores에 총 2번 기록이 되는데 이전에 저장되어있는 Score에 지금 몇점의 점수를 추가하려고 하는데 최대 10점(정규 투구)을 넘었을 경우 입력 예외처리를 하기위해서 만들어진 것입니다. 메소드를 사용할 때 이전에 저장되어있다는 조건을 달아주지않아서 의도가 명확하지않았던 것 같습니다. isScoreLimit은 프레임의 상태를 설정하기 전에 Scores에 점수가 10점인지 아닌지를 물어볼 때 사용하려고 구현했습니다. 두 메소드의 차이는 10점이냐 10점을 넘어가냐의 의미적인 차이와 평가를 할 때 주어지는 조건값이 달라 각각 만들어놓았습니다. |
||
| int existingSum = scores.stream().mapToInt(scoreInstance -> scoreInstance.score).sum(); | ||
| return existingSum + this.score > MAX; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class Scores { | ||
| private static final int LIMIT_NUM = 2; | ||
| private List<Score> scores = new ArrayList<>(); | ||
|
|
||
| public Score addScore(int number) throws IllegalArgumentException { | ||
| Score newScore = new Score(number); | ||
| if (scores.size() != 0 && newScore.isOverRecord(scores)) { | ||
| throw new IllegalArgumentException("합산 : " + Score.MAX + "점을 넘을 수 없습니다"); | ||
| } | ||
| scores.add(newScore); | ||
| return newScore; | ||
| } | ||
|
|
||
| public boolean isFinish() { | ||
| return isLimitSize() || isScoreLimit(); | ||
| } | ||
|
|
||
| public boolean isScoreLimit() { | ||
| return Score.isScoreLimit(scores); | ||
| } | ||
|
|
||
| public boolean isLimitSize() { | ||
| return scores.size() == LIMIT_NUM; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package domain.frame; | ||
|
|
||
| public interface Frame { | ||
|
|
||
| String addScore(int score) throws IllegalArgumentException; | ||
|
|
||
| boolean isFinish(); | ||
|
|
||
| String convertScore(int score); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package domain.frame; | ||
|
|
||
| import utils.FrameFactory; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class Frames { | ||
| public static final int LIMIT_NUM = 10; | ||
| private List<Frame> frames; | ||
| private int nextFrameIdx; | ||
|
|
||
| public Frames() { | ||
| frames = new ArrayList<>(); | ||
| nextFrameIdx = 0; | ||
| } | ||
|
|
||
| public String recordScore(int score) { | ||
| Frame currentFrame = getCurrentFrame(); | ||
| String convertedScore = currentFrame.addScore(score); | ||
| if (currentFrame.isFinish()) { | ||
| nextFrameIdx++; | ||
| } | ||
| return convertedScore; | ||
| } | ||
|
|
||
| public Frame getCurrentFrame() { | ||
| try { | ||
| return frames.get(nextFrameIdx); | ||
| } catch (IndexOutOfBoundsException e) { | ||
| int frameNum = nextFrameIdx + 1; | ||
| frames.add(FrameFactory.of(frameNum)); | ||
| return frames.get(nextFrameIdx); | ||
| } | ||
| } | ||
|
|
||
| public int getCurrentFrameIdx() { | ||
| return nextFrameIdx; | ||
| } | ||
|
|
||
| public int getCurrentFrameNum() { | ||
| return nextFrameIdx + 1; | ||
| } | ||
|
|
||
| public boolean isFinish() { | ||
| return frames.size() == LIMIT_NUM && frames.stream().allMatch(Frame::isFinish); | ||
| } | ||
|
|
||
| public static boolean isLast(int frameNum) { | ||
| return frameNum == LIMIT_NUM; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package domain.frame; | ||
|
|
||
| import domain.Score; | ||
| import domain.Scores; | ||
| import domain.frame.result.ScoreMessage; | ||
| import domain.frame.status.FrameStatus; | ||
|
|
||
| public class LastFrame implements Frame { | ||
| private FrameStatus status; | ||
| private Scores scores; | ||
| private Score bonusScore; | ||
|
|
||
| public LastFrame() { | ||
| scores = new Scores(); | ||
| status = FrameStatus.getInitStatus(); | ||
| } | ||
|
|
||
| @Override | ||
| public String addScore(int score) throws IllegalArgumentException { | ||
| if (status.isBonus()) { | ||
| bonusScore = new Score(score); | ||
| return convertScore(score); | ||
| } | ||
| scores.addScore(score); | ||
| status = status.changeStatus(scores); | ||
| return convertScore(score); | ||
| } | ||
|
|
||
| @Override | ||
| public String convertScore(int score) { | ||
| if (scores.isFinish()) { | ||
| return ScoreMessage.convertMessage(score); | ||
| } | ||
| return status.convertScore(score); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isFinish() { | ||
| if (!status.isFinish()) { | ||
| return false; | ||
| } | ||
|
|
||
| if (!status.isBonus()) { | ||
| return true; | ||
| } | ||
| return bonusScore != null; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package domain.frame; | ||
|
|
||
| import domain.Scores; | ||
| import domain.frame.status.FrameStatus; | ||
|
|
||
| public class NormalFrame implements Frame { | ||
| private FrameStatus status; | ||
| private Scores scores; | ||
|
|
||
| public NormalFrame() { | ||
| scores = new Scores(); | ||
| status = FrameStatus.getInitStatus(); | ||
| } | ||
|
|
||
| @Override | ||
| public String addScore(int score) throws IllegalArgumentException { | ||
| scores.addScore(score); | ||
| status = status.changeStatus(scores); | ||
| return convertScore(score); | ||
| } | ||
|
|
||
| @Override | ||
| public String convertScore(int score) { | ||
| return status.convertScore(score); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isFinish() { | ||
| return status.isFinish(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package domain.frame.result; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static java.util.stream.Collectors.joining; | ||
|
|
||
| public class FrameResult { | ||
| private List<String> results = new ArrayList<>(); | ||
|
|
||
| public void add(String resultMessage) { | ||
| results.add(resultMessage); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return results.stream().collect(joining("|")); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package domain.frame.result; | ||
|
|
||
| import domain.frame.Frames; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class FrameResults { | ||
| private List<FrameResult> results = new ArrayList<>(); | ||
|
|
||
| public void addResult(int frameIdx, String convertedScore) { | ||
| if (!isExistFrameResult(frameIdx)) { | ||
| results.add(new FrameResult()); | ||
| } | ||
| FrameResult result = results.get(frameIdx); | ||
| result.add(convertedScore); | ||
| } | ||
|
|
||
| public boolean isExistFrameResult(int frameIdx) { | ||
| try { | ||
| results.get(frameIdx); | ||
| return true; | ||
| } catch (IndexOutOfBoundsException e) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| public int getSavedSize() { | ||
| return results.size(); | ||
| } | ||
|
|
||
| public int getMaxSaveSize() { | ||
| return Frames.LIMIT_NUM; | ||
| } | ||
|
|
||
| public String getFrameResultMessage(int frameIdx) { | ||
| try { | ||
| FrameResult frameResult = results.get(frameIdx); | ||
| return frameResult.toString(); | ||
| } catch (IndexOutOfBoundsException e) { | ||
| return null; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Player와 Frames간의 객체 관계는 어떻게 될까?
현재와 같이 분리해서 구현하는 경우와 Player가 Frames와 의존 관계를 가지도록 구현하는 경우 중 어느 것이 더 나은 설계일까?