From c12bbc0ea3f8790a2c6e29624bbf29bdf119f5a4 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 21:41:21 +0900 Subject: [PATCH 01/39] =?UTF-8?q?docs=20:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b4867cc0f..0fbb9e2666 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,31 @@ * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview) \ No newline at end of file +* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview) + +## 볼링 점수판 (그리기) + +* 플레이어의 이름 입력 받기 + +* 투구 점수 입력 받기 + +### 볼링 규칙 정리 +볼링게임은 최대 20번의 투구를 한다. +볼링게임은 1프레임당 최대 2번 투구할 수 있다. +* 스트라이크를 치면 1프레임에 1번 투구를 한다. + +1프레임은 10개의 볼링핀으로 구성된다. +1프레임 내 1번째 투구에 10개를 친다면 스트라이크이다. +1프레임 내 2번째 투구는 1번째 투구에서 남은 갯수로 수행한다. + +### 가장 작은 단위의 객체 찾기 +1. 볼링핀 +2. 볼링핀10개 +3. 투구 +4. 프레임 (첫번째 투구, 두번째 투구) +5. 볼링점수 + + + + + From 5adeec455564042732199b8878c6bef358288045 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:26:11 +0900 Subject: [PATCH 02/39] =?UTF-8?q?feat=20:=20BowlingPin=EA=B3=BC=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- src/main/java/bowling/BowlingPin.java | 39 +++++++++++++++++++++++ src/test/java/bowling/BowlingPinTest.java | 23 +++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/bowling/BowlingPin.java create mode 100644 src/test/java/bowling/BowlingPinTest.java diff --git a/src/main/java/bowling/BowlingPin.java b/src/main/java/bowling/BowlingPin.java new file mode 100644 index 0000000000..a182e4e991 --- /dev/null +++ b/src/main/java/bowling/BowlingPin.java @@ -0,0 +1,39 @@ +package bowling; + +import java.util.Objects; + +public class BowlingPin { + public static final int MAX_PIN_NUMBER = 10; + private static final int ZERO = 0; + + private final int count; + + public BowlingPin(int count) { + if (count < ZERO || count > MAX_PIN_NUMBER) { + throw new IllegalArgumentException("볼링핀의 갯수는 0~10사이여야만 합니다."); + } + this.count = count; + } + + public BowlingPin hitPins(BowlingPin bowlingPin) { + return new BowlingPin(this.count - bowlingPin.count); + } + + + public boolean isZero() { + return count == 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BowlingPin that = (BowlingPin) o; + return count == that.count; + } + + @Override + public int hashCode() { + return Objects.hash(count); + } +} diff --git a/src/test/java/bowling/BowlingPinTest.java b/src/test/java/bowling/BowlingPinTest.java new file mode 100644 index 0000000000..862655fff2 --- /dev/null +++ b/src/test/java/bowling/BowlingPinTest.java @@ -0,0 +1,23 @@ +package bowling; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class BowlingPinTest { + + @Test + void createFailed() { + assertThatThrownBy(() -> new BowlingPin(BowlingPin.MAX_PIN_NUMBER + 1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("볼링핀의 갯수는 0~10사이여야만 합니다."); + } + + @Test + void hitPins() { + BowlingPin bowlingPin = new BowlingPin(10); + assertThat(bowlingPin.hitPins(new BowlingPin(5))).isEqualTo(new BowlingPin(5)); + } +} \ No newline at end of file From 2a9955dc471c34da492a9d365bd2d3c4875e9db5 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:26:43 +0900 Subject: [PATCH 03/39] =?UTF-8?q?feat=20:=20=ED=95=9C=EB=9D=BC=EC=9A=B4?= =?UTF-8?q?=EB=93=9C=EC=9D=98=20Pin=EC=83=81=ED=83=9C=EB=A5=BC=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EA=B3=A0=20=EA=B8=B0=EB=A1=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20Frame=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 25 +++++++++++++++++++++++++ src/main/java/bowling/HitRecord.java | 13 +++++++++++++ src/test/java/bowling/FrameTest.java | 24 ++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/java/bowling/Frame.java create mode 100644 src/main/java/bowling/HitRecord.java create mode 100644 src/test/java/bowling/FrameTest.java diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java new file mode 100644 index 0000000000..1df32f672c --- /dev/null +++ b/src/main/java/bowling/Frame.java @@ -0,0 +1,25 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class Frame { + private BowlingPin bowlingPin; + private final List hitRecords; + + public Frame() { + this.bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); + hitRecords = new ArrayList<>(); + } + + public boolean hitBowlingPin(int count) { + bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); + hitRecords.add(new HitRecord(count)); + + return bowlingPin.isZero() || hitRecords.size() == 2; + } + + public List getHitRecords() { + return hitRecords; + } +} diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java new file mode 100644 index 0000000000..748e969de3 --- /dev/null +++ b/src/main/java/bowling/HitRecord.java @@ -0,0 +1,13 @@ +package bowling; + +public class HitRecord { + private final int count; + + public HitRecord(int count) { + this.count = count; + } + + public int getCount() { + return count; + } +} diff --git a/src/test/java/bowling/FrameTest.java b/src/test/java/bowling/FrameTest.java new file mode 100644 index 0000000000..917210a074 --- /dev/null +++ b/src/test/java/bowling/FrameTest.java @@ -0,0 +1,24 @@ +package bowling; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class FrameTest { + + @Test + void hitAllBowlingPins() { + Frame frame = new Frame(); + assertThat(frame.hitBowlingPin(3)).isFalse(); + assertThat(frame.hitBowlingPin(7)).isTrue(); + } + + @Test + void hitTwice() { + Frame frame = new Frame(); + assertThat(frame.hitBowlingPin(3)).isFalse(); + assertThat(frame.hitBowlingPin(3)).isTrue(); + } +} \ No newline at end of file From 891c0f9c893550fd5a65f5a07902e4b8259f16a8 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:27:03 +0900 Subject: [PATCH 04/39] =?UTF-8?q?feat=20:=20=EB=B3=BC=EB=A7=81=EC=A0=90?= =?UTF-8?q?=EC=88=98=ED=8C=90=20=EA=B4=80=EB=A6=AC=20=EA=B0=9D=EC=B2=B4=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 --- src/main/java/bowling/BowlingScoreRecord.java | 29 ++++++++++++++ .../java/bowling/BowlingScoreRecordTest.java | 39 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/bowling/BowlingScoreRecord.java create mode 100644 src/test/java/bowling/BowlingScoreRecordTest.java diff --git a/src/main/java/bowling/BowlingScoreRecord.java b/src/main/java/bowling/BowlingScoreRecord.java new file mode 100644 index 0000000000..b9da8422cd --- /dev/null +++ b/src/main/java/bowling/BowlingScoreRecord.java @@ -0,0 +1,29 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class BowlingScoreRecord { + private static final int BOWLING_ROUND_COUNT = 10; + private final List frames; + + public BowlingScoreRecord() { + this.frames = new ArrayList<>(); + for (int i = 0; i < BOWLING_ROUND_COUNT; i++) { + this.frames.add(new Frame()); + } + } + + public int hit(int frameNumber, int count) { + Frame frame = frames.get(frameNumber); + + if (frame.hitBowlingPin(count)) { + return frameNumber + 1; + } + return frameNumber; + } + + public List getFrames() { + return frames; + } +} diff --git a/src/test/java/bowling/BowlingScoreRecordTest.java b/src/test/java/bowling/BowlingScoreRecordTest.java new file mode 100644 index 0000000000..89e709b8cc --- /dev/null +++ b/src/test/java/bowling/BowlingScoreRecordTest.java @@ -0,0 +1,39 @@ +package bowling; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BowlingScoreRecordTest { + + @Test + void hitMiss() { + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 5); + Assertions.assertThat(frameNumber).isEqualTo(0); + } + + @Test + void hitStrike() { + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 10); + Assertions.assertThat(frameNumber).isEqualTo(1); + } + + @Test + void hitSpare() { + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 5); + frameNumber = bowlingScoreRecord.hit(frameNumber, 5); + Assertions.assertThat(frameNumber).isEqualTo(1); + } + + @Test + void hitGutterTwice() { + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 0); + frameNumber = bowlingScoreRecord.hit(frameNumber, 0); + Assertions.assertThat(frameNumber).isEqualTo(1); + } +} \ No newline at end of file From d2f3a0ad302baaee3b37ac4a2fa46acf9a0ee1be Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 10 Nov 2022 23:17:17 +0900 Subject: [PATCH 05/39] =?UTF-8?q?feat=20:=20=EB=B3=BC=EB=A7=81=EC=A0=90?= =?UTF-8?q?=EC=88=98=ED=8C=90=20=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 27 ++++++++++ src/main/java/bowling/BowilingTerm.java | 18 +++++++ src/main/java/bowling/BowlingPin.java | 2 +- src/main/java/bowling/Frame.java | 14 ++++- src/main/java/bowling/HitRecord.java | 16 ++++-- src/main/java/bowling/HitRecords.java | 11 ++++ src/main/java/bowling/Username.java | 16 ++++++ src/main/java/bowling/view/InputView.java | 23 ++++++++ src/main/java/bowling/view/OutputView.java | 63 ++++++++++++++++++++++ src/main/java/bowling/view/ScoreShape.java | 5 ++ 10 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 src/main/java/bowling/App.java create mode 100644 src/main/java/bowling/BowilingTerm.java create mode 100644 src/main/java/bowling/HitRecords.java create mode 100644 src/main/java/bowling/Username.java create mode 100644 src/main/java/bowling/view/InputView.java create mode 100644 src/main/java/bowling/view/OutputView.java create mode 100644 src/main/java/bowling/view/ScoreShape.java diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java new file mode 100644 index 0000000000..1691fb2c5f --- /dev/null +++ b/src/main/java/bowling/App.java @@ -0,0 +1,27 @@ +package bowling; + +import bowling.view.InputView; +import bowling.view.OutputView; +import org.hibernate.type.TrueFalseType; + +import java.util.List; +import java.util.Scanner; + +public class App { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + Username username = InputView.playerName(); + + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + + int frameNumber = 0; + while (frameNumber < 10) { + int count = InputView.hitCount(frameNumber + 1); + frameNumber = bowlingScoreRecord.hit(frameNumber, count); + List frames = bowlingScoreRecord.getFrames(); + OutputView.printScoreScreen(username, frames); + } + + } +} diff --git a/src/main/java/bowling/BowilingTerm.java b/src/main/java/bowling/BowilingTerm.java new file mode 100644 index 0000000000..42c606f734 --- /dev/null +++ b/src/main/java/bowling/BowilingTerm.java @@ -0,0 +1,18 @@ +package bowling; + +public enum BowilingTerm { + STRIKE("X"), + SPARE("/"), + GUTTER("-"), + MISS(""); + + private final String shape; + + BowilingTerm(String shape) { + this.shape = shape; + } + + public String shape() { + return this.shape; + } +} diff --git a/src/main/java/bowling/BowlingPin.java b/src/main/java/bowling/BowlingPin.java index a182e4e991..e4097357fa 100644 --- a/src/main/java/bowling/BowlingPin.java +++ b/src/main/java/bowling/BowlingPin.java @@ -4,7 +4,7 @@ public class BowlingPin { public static final int MAX_PIN_NUMBER = 10; - private static final int ZERO = 0; + public static final int ZERO = 0; private final int count; diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 1df32f672c..5471cd83ab 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,9 +1,13 @@ package bowling; +import bowling.view.ScoreShape; + import java.util.ArrayList; import java.util.List; public class Frame { + private static final int HIT_COUNT = 2; + private BowlingPin bowlingPin; private final List hitRecords; @@ -16,10 +20,18 @@ public boolean hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); - return bowlingPin.isZero() || hitRecords.size() == 2; + return clearAllFrame() || hitTwice(); } public List getHitRecords() { return hitRecords; } + + private boolean clearAllFrame() { + return bowlingPin.isZero(); + } + + private boolean hitTwice() { + return hitRecords.size() == HIT_COUNT; + } } diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 748e969de3..3ff0fc7e07 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -1,13 +1,21 @@ package bowling; public class HitRecord { - private final int count; + private final int hitCount; public HitRecord(int count) { - this.count = count; + this.hitCount = count; } - public int getCount() { - return count; + public int getHitCount() { + return hitCount; + } + + public boolean hitAll() { + return hitCount == BowlingPin.MAX_PIN_NUMBER; + } + + public boolean hitZero() { + return hitCount == BowlingPin.ZERO; } } diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java new file mode 100644 index 0000000000..2cc56a20f2 --- /dev/null +++ b/src/main/java/bowling/HitRecords.java @@ -0,0 +1,11 @@ +package bowling; + +import java.util.List; + +public class HitRecords { + private List hitRecords; + + public HitRecords(List hitRecords) { + this.hitRecords = hitRecords; + } +} diff --git a/src/main/java/bowling/Username.java b/src/main/java/bowling/Username.java new file mode 100644 index 0000000000..cd7adfbf11 --- /dev/null +++ b/src/main/java/bowling/Username.java @@ -0,0 +1,16 @@ +package bowling; + +public class Username { + private final String name; + + public Username(String name) { + if (name.length() > 3) { + throw new IllegalArgumentException("이름은 크기 3을 넘을 수 없습니다."); + } + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/bowling/view/InputView.java b/src/main/java/bowling/view/InputView.java new file mode 100644 index 0000000000..3b40950178 --- /dev/null +++ b/src/main/java/bowling/view/InputView.java @@ -0,0 +1,23 @@ +package bowling.view; + +import bowling.Username; + +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + + private InputView() { + } + + public static Username playerName() { + System.out.print("플레이어 이름은(3 english letters)?: "); + String name = scanner.nextLine(); + return new Username(name); + } + + public static int hitCount(int number) { + System.out.print(number + " 프레임투구 : "); + return scanner.nextInt(); + } +} diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java new file mode 100644 index 0000000000..c314976363 --- /dev/null +++ b/src/main/java/bowling/view/OutputView.java @@ -0,0 +1,63 @@ +package bowling.view; + +import bowling.BowilingTerm; +import bowling.Frame; +import bowling.HitRecord; +import bowling.Username; + +import java.util.List; + +public class OutputView { + private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String FORMAT_SHAPE = " %-4s|"; + private static final String SEPARATOR = "|"; + private static final int FIRST_ATTEMPT = 0; + private static final int LAST_ATTEMPT = 1; + private static final int ZERO_HIT_COUNT = 0; + private static final int MAX_HIT_COUNT = 10; + + private OutputView() { + } + + + public static void printScoreScreen(Username username, List frames) { + System.out.println(BASE_SCORE_SCREEN); + StringBuilder sb = new StringBuilder(); + sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); + for (Frame frame : frames) { + frameScore(sb, frame); + } + System.out.println(sb); + System.out.println(); + } + + private static void frameScore(StringBuilder sb, Frame frame) { + StringBuilder hitBuilder = new StringBuilder(); + List hitRecords = frame.getHitRecords(); + + int hitCount = 0; + for (int index = 0; index < hitRecords.size(); index++) { + HitRecord hitRecord = hitRecords.get(index); + hitCount += hitRecord.getHitCount(); + if (index == 1) { + hitBuilder.append(SEPARATOR); + if (hitCount == MAX_HIT_COUNT) { + hitBuilder.append(BowilingTerm.SPARE.shape()); + continue; + } + } + + if (index == 0 && hitRecord.hitAll()) { + hitBuilder.append(BowilingTerm.STRIKE.shape()); + continue; + } + + if (hitRecord.hitZero()) { + hitBuilder.append(BowilingTerm.GUTTER.shape()); + continue; + } + hitBuilder.append(hitRecord.getHitCount()); + } + sb.append(String.format(FORMAT_SHAPE, hitBuilder)); + } +} diff --git a/src/main/java/bowling/view/ScoreShape.java b/src/main/java/bowling/view/ScoreShape.java new file mode 100644 index 0000000000..929c1dae6d --- /dev/null +++ b/src/main/java/bowling/view/ScoreShape.java @@ -0,0 +1,5 @@ +package bowling.view; + +public class ScoreShape { + +} From 89511f0ecd2bb7438f20415ef199b33117e9dc21 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 00:56:28 +0900 Subject: [PATCH 06/39] =?UTF-8?q?refactor=20:=20FrameNumber=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=EC=A7=84=ED=96=89=EC=83=81=ED=83=9C=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 16 +++-- src/main/java/bowling/BowlingGame.java | 24 ++++++++ src/main/java/bowling/BowlingScoreRecord.java | 29 --------- src/main/java/bowling/Frame.java | 39 +++++++++--- src/main/java/bowling/FrameNumber.java | 60 +++++++++++++++++++ src/main/java/bowling/Frames.java | 50 ++++++++++++++++ src/main/java/bowling/view/OutputView.java | 31 +++++----- .../java/bowling/BowlingScoreRecordTest.java | 30 +++++----- src/test/java/bowling/FrameTest.java | 9 +-- 9 files changed, 208 insertions(+), 80 deletions(-) create mode 100644 src/main/java/bowling/BowlingGame.java delete mode 100644 src/main/java/bowling/BowlingScoreRecord.java create mode 100644 src/main/java/bowling/FrameNumber.java create mode 100644 src/main/java/bowling/Frames.java diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index 1691fb2c5f..0c3a12e854 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -2,9 +2,7 @@ import bowling.view.InputView; import bowling.view.OutputView; -import org.hibernate.type.TrueFalseType; -import java.util.List; import java.util.Scanner; public class App { @@ -13,15 +11,15 @@ public static void main(String[] args) { Username username = InputView.playerName(); - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + BowlingGame bowlingGame = new BowlingGame(); + FrameNumber frameNumber = FrameNumber.first(); + while (frameNumber.isBelow(BowlingGame.FRAME_SIZE)) { + int count = InputView.hitCount(frameNumber.getFrameNumber()); - int frameNumber = 0; - while (frameNumber < 10) { - int count = InputView.hitCount(frameNumber + 1); - frameNumber = bowlingScoreRecord.hit(frameNumber, count); - List frames = bowlingScoreRecord.getFrames(); + frameNumber = bowlingGame.pitchingBall(count); + + Frames frames = bowlingGame.getFrames(); OutputView.printScoreScreen(username, frames); } - } } diff --git a/src/main/java/bowling/BowlingGame.java b/src/main/java/bowling/BowlingGame.java new file mode 100644 index 0000000000..1e3818b8f2 --- /dev/null +++ b/src/main/java/bowling/BowlingGame.java @@ -0,0 +1,24 @@ +package bowling; + +public class BowlingGame { + public static final int FRAME_SIZE = 10; + private final Frames frames; + private FrameNumber frameNumber; + + public BowlingGame() { + this.frames = new Frames(FRAME_SIZE); + this.frameNumber = FrameNumber.first(); + } + + public FrameNumber pitchingBall(int hitCount) { + if (frameNumber.isSameNumber(FRAME_SIZE)) { + return frames.pitchingLast(frameNumber, hitCount); + } + this.frameNumber = frames.pitching(frameNumber, hitCount); + return this.frameNumber; + } + + public Frames getFrames() { + return frames; + } +} diff --git a/src/main/java/bowling/BowlingScoreRecord.java b/src/main/java/bowling/BowlingScoreRecord.java deleted file mode 100644 index b9da8422cd..0000000000 --- a/src/main/java/bowling/BowlingScoreRecord.java +++ /dev/null @@ -1,29 +0,0 @@ -package bowling; - -import java.util.ArrayList; -import java.util.List; - -public class BowlingScoreRecord { - private static final int BOWLING_ROUND_COUNT = 10; - private final List frames; - - public BowlingScoreRecord() { - this.frames = new ArrayList<>(); - for (int i = 0; i < BOWLING_ROUND_COUNT; i++) { - this.frames.add(new Frame()); - } - } - - public int hit(int frameNumber, int count) { - Frame frame = frames.get(frameNumber); - - if (frame.hitBowlingPin(count)) { - return frameNumber + 1; - } - return frameNumber; - } - - public List getFrames() { - return frames; - } -} diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 5471cd83ab..b753f96ccb 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,12 +1,11 @@ package bowling; -import bowling.view.ScoreShape; - import java.util.ArrayList; import java.util.List; public class Frame { - private static final int HIT_COUNT = 2; + private static final int HIT_TWICE = 2; + private static final int HIT_TRIPLE = 3; private BowlingPin bowlingPin; private final List hitRecords; @@ -16,22 +15,48 @@ public Frame() { hitRecords = new ArrayList<>(); } - public boolean hitBowlingPin(int count) { + public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); + } + public boolean finishFrame() { return clearAllFrame() || hitTwice(); } + public boolean hitDouble() { + if (hitRecords.size() != HIT_TWICE) { + return false; + } + for (HitRecord hitRecord : hitRecords) { + if (!hitRecord.hitAll()) { + return false; + } + } + return true; + } + + public boolean spare() { + return hitRecords.size() == HIT_TWICE && clearAllFrame(); + } + + public void chargeBowlingPin() { + bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); + } + public List getHitRecords() { return hitRecords; } - private boolean clearAllFrame() { + public boolean clearAllFrame() { return bowlingPin.isZero(); } - private boolean hitTwice() { - return hitRecords.size() == HIT_COUNT; + public boolean hitTriple() { + return hitRecords.size() == HIT_TRIPLE; + } + + public boolean hitTwice() { + return hitRecords.size() == HIT_TWICE; } } diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java new file mode 100644 index 0000000000..262bf52af8 --- /dev/null +++ b/src/main/java/bowling/FrameNumber.java @@ -0,0 +1,60 @@ +package bowling; + +import java.util.Objects; + +public class FrameNumber { + public static final int FIRST = 1; + private final int frameNumber; + + public static FrameNumber first() { + return new FrameNumber(); + } + + public static FrameNumber number(int number) { + return new FrameNumber(number); + } + + public static FrameNumber plus(FrameNumber frameNumber) { + return new FrameNumber(frameNumber.frameNumber + 1); + } + + private FrameNumber(int frameNumber) { + if (frameNumber < FIRST) { + throw new IllegalArgumentException(String.format("프레임의 숫자는 {}보다 작을 수 없습니다.", FIRST)); + } + this.frameNumber = frameNumber; + } + + private FrameNumber() { + this.frameNumber = FIRST; + } + + public int retrieveIndexNumber() { + return frameNumber - 1; + } + + public int getFrameNumber() { + return frameNumber; + } + + public boolean isBelow(int number) { + return frameNumber <= number; + } + + public boolean isSameNumber(int number) { + return this.frameNumber == number; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FrameNumber that = (FrameNumber) o; + return frameNumber == that.frameNumber; + } + + @Override + public int hashCode() { + return Objects.hash(frameNumber); + } +} diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java new file mode 100644 index 0000000000..6ae561694c --- /dev/null +++ b/src/main/java/bowling/Frames.java @@ -0,0 +1,50 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class Frames { + private final List frames; + + public Frames(int size) { + this.frames = new ArrayList<>(); + for (int i = 0; i < size; i++) { + this.frames.add(new Frame()); + } + } + + public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { + Frame frame = frames.get(frameNumber.retrieveIndexNumber()); + frame.hitBowlingPin(hitCount); + if (frame.finishFrame()) { + return FrameNumber.plus(frameNumber); + } + return frameNumber; + } + + public List getFrames() { + return frames; + } + + public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { + Frame frame = frames.get(frameNumber.retrieveIndexNumber()); + frame.hitBowlingPin(hitCount); + if (frame.hitTriple()) { + return FrameNumber.plus(frameNumber); + } + + if (frame.hitDouble()) { + return FrameNumber.plus(frameNumber); + } + + if (frame.hitTwice() && !frame.clearAllFrame()) { + return FrameNumber.plus(frameNumber); + } + + if (frame.clearAllFrame()) { + frame.chargeBowlingPin(); + return frameNumber; + } + return frameNumber; + } +} diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index c314976363..16c794bff8 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -1,37 +1,38 @@ package bowling.view; -import bowling.BowilingTerm; -import bowling.Frame; -import bowling.HitRecord; -import bowling.Username; +import bowling.*; import java.util.List; public class OutputView { - private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; private static final String FORMAT_SHAPE = " %-4s|"; + private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; - private static final int FIRST_ATTEMPT = 0; - private static final int LAST_ATTEMPT = 1; - private static final int ZERO_HIT_COUNT = 0; private static final int MAX_HIT_COUNT = 10; private OutputView() { } - public static void printScoreScreen(Username username, List frames) { + public static void printScoreScreen(Username username, Frames frames) { + List framesList = frames.getFrames(); System.out.println(BASE_SCORE_SCREEN); StringBuilder sb = new StringBuilder(); sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); - for (Frame frame : frames) { - frameScore(sb, frame); + for (int i = 0; i < framesList.size(); i++) { + String hitShape = frameScore(sb, framesList.get(i)); + if (i == framesList.size() - 1) { + sb.append(String.format(BONUS_SHAPE, hitShape)); + continue; + } + sb.append(String.format(FORMAT_SHAPE, hitShape)); } System.out.println(sb); System.out.println(); } - private static void frameScore(StringBuilder sb, Frame frame) { + private static String frameScore(StringBuilder sb, Frame frame) { StringBuilder hitBuilder = new StringBuilder(); List hitRecords = frame.getHitRecords(); @@ -39,7 +40,7 @@ private static void frameScore(StringBuilder sb, Frame frame) { for (int index = 0; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); hitCount += hitRecord.getHitCount(); - if (index == 1) { + if (index != 0) { hitBuilder.append(SEPARATOR); if (hitCount == MAX_HIT_COUNT) { hitBuilder.append(BowilingTerm.SPARE.shape()); @@ -47,7 +48,7 @@ private static void frameScore(StringBuilder sb, Frame frame) { } } - if (index == 0 && hitRecord.hitAll()) { + if (index != 1 && hitRecord.hitAll()) { hitBuilder.append(BowilingTerm.STRIKE.shape()); continue; } @@ -58,6 +59,6 @@ private static void frameScore(StringBuilder sb, Frame frame) { } hitBuilder.append(hitRecord.getHitCount()); } - sb.append(String.format(FORMAT_SHAPE, hitBuilder)); + return hitBuilder.toString(); } } diff --git a/src/test/java/bowling/BowlingScoreRecordTest.java b/src/test/java/bowling/BowlingScoreRecordTest.java index 89e709b8cc..ca12a198f6 100644 --- a/src/test/java/bowling/BowlingScoreRecordTest.java +++ b/src/test/java/bowling/BowlingScoreRecordTest.java @@ -3,37 +3,35 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class BowlingScoreRecordTest { @Test void hitMiss() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 5); - Assertions.assertThat(frameNumber).isEqualTo(0); + BowlingGame bowlingScoreRecord = new BowlingGame(); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.first()); } @Test void hitStrike() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 10); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall( 10); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } @Test void hitSpare() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 5); - frameNumber = bowlingScoreRecord.hit(frameNumber, 5); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + bowlingScoreRecord.pitchingBall(5); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } @Test void hitGutterTwice() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 0); - frameNumber = bowlingScoreRecord.hit(frameNumber, 0); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + bowlingScoreRecord.pitchingBall(0); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(0); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } } \ No newline at end of file diff --git a/src/test/java/bowling/FrameTest.java b/src/test/java/bowling/FrameTest.java index 917210a074..dc480e3519 100644 --- a/src/test/java/bowling/FrameTest.java +++ b/src/test/java/bowling/FrameTest.java @@ -11,14 +11,15 @@ class FrameTest { @Test void hitAllBowlingPins() { Frame frame = new Frame(); - assertThat(frame.hitBowlingPin(3)).isFalse(); - assertThat(frame.hitBowlingPin(7)).isTrue(); + frame.hitBowlingPin(3); + assertThat(frame.finishFrame()).isFalse(); } @Test void hitTwice() { Frame frame = new Frame(); - assertThat(frame.hitBowlingPin(3)).isFalse(); - assertThat(frame.hitBowlingPin(3)).isTrue(); + frame.hitBowlingPin(3); + frame.hitBowlingPin(5); + assertThat(frame.finishFrame()).isTrue(); } } \ No newline at end of file From 233f0ff6bd0d41f1e12d13a64e6243a4f58030d5 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:02:09 +0900 Subject: [PATCH 07/39] =?UTF-8?q?refactor=20:=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=20=EB=B3=B4=EB=84=88=EC=8A=A4=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20=EB=A1=9C=EC=A7=81=20frame=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 14 +++++++++----- src/main/java/bowling/Frames.java | 10 +--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index b753f96ccb..812f8fc401 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -15,6 +15,14 @@ public Frame() { hitRecords = new ArrayList<>(); } + public boolean finishLastFrame() { + return hitThreeTimes() || hitDouble() || failedBounsFrame(); + } + + private boolean failedBounsFrame() { + return hitTwice() && !clearAllFrame(); + } + public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); @@ -36,10 +44,6 @@ public boolean hitDouble() { return true; } - public boolean spare() { - return hitRecords.size() == HIT_TWICE && clearAllFrame(); - } - public void chargeBowlingPin() { bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); } @@ -52,7 +56,7 @@ public boolean clearAllFrame() { return bowlingPin.isZero(); } - public boolean hitTriple() { + public boolean hitThreeTimes() { return hitRecords.size() == HIT_TRIPLE; } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 6ae561694c..66241b4a28 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -29,15 +29,7 @@ public List getFrames() { public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); - if (frame.hitTriple()) { - return FrameNumber.plus(frameNumber); - } - - if (frame.hitDouble()) { - return FrameNumber.plus(frameNumber); - } - - if (frame.hitTwice() && !frame.clearAllFrame()) { + if (frame.finishLastFrame()) { return FrameNumber.plus(frameNumber); } From aa1242015375affa93efa7963bc954bf6236a82e Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:02:54 +0900 Subject: [PATCH 08/39] =?UTF-8?q?refactor=20:=20plus=20->=20next=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/FrameNumber.java | 2 +- src/main/java/bowling/Frames.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java index 262bf52af8..10aff795a2 100644 --- a/src/main/java/bowling/FrameNumber.java +++ b/src/main/java/bowling/FrameNumber.java @@ -14,7 +14,7 @@ public static FrameNumber number(int number) { return new FrameNumber(number); } - public static FrameNumber plus(FrameNumber frameNumber) { + public static FrameNumber next(FrameNumber frameNumber) { return new FrameNumber(frameNumber.frameNumber + 1); } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 66241b4a28..4fe651410e 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -17,7 +17,7 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishFrame()) { - return FrameNumber.plus(frameNumber); + return FrameNumber.next(frameNumber); } return frameNumber; } @@ -30,7 +30,7 @@ public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishLastFrame()) { - return FrameNumber.plus(frameNumber); + return FrameNumber.next(frameNumber); } if (frame.clearAllFrame()) { From 2c386dbb53bddeb5c8123593f99bb7baffc3dc30 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:22:33 +0900 Subject: [PATCH 09/39] =?UTF-8?q?feat=20:=20frames=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 현재 프레임의 위치와 Frame의 볼링을 친 갯수에 따라 다음 프레임 진행여부를 판단함 --- src/main/java/bowling/FrameNumber.java | 4 +- src/main/java/bowling/Frames.java | 11 ++-- src/test/java/bowling/FramesTest.java | 89 ++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 src/test/java/bowling/FramesTest.java diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java index 10aff795a2..30e2e4c8df 100644 --- a/src/main/java/bowling/FrameNumber.java +++ b/src/main/java/bowling/FrameNumber.java @@ -14,8 +14,8 @@ public static FrameNumber number(int number) { return new FrameNumber(number); } - public static FrameNumber next(FrameNumber frameNumber) { - return new FrameNumber(frameNumber.frameNumber + 1); + public FrameNumber next() { + return new FrameNumber(this.frameNumber + 1); } private FrameNumber(int frameNumber) { diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 4fe651410e..370f03eb0f 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -17,20 +17,17 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishFrame()) { - return FrameNumber.next(frameNumber); + return frameNumber.next(); } return frameNumber; } - public List getFrames() { - return frames; - } public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishLastFrame()) { - return FrameNumber.next(frameNumber); + return frameNumber.next(); } if (frame.clearAllFrame()) { @@ -39,4 +36,8 @@ public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { } return frameNumber; } + + public List getFrames() { + return frames; + } } diff --git a/src/test/java/bowling/FramesTest.java b/src/test/java/bowling/FramesTest.java new file mode 100644 index 0000000000..969f84ef71 --- /dev/null +++ b/src/test/java/bowling/FramesTest.java @@ -0,0 +1,89 @@ +package bowling; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class FramesTest { + + @Test + @DisplayName("Miss시에는 프레임번호가 변하지 않음") + void pitchingMiss() { + int number = 5; + Frames frames = new Frames(10); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(number), 5); + assertThat(frameNumber).isEqualTo(FrameNumber.number(number)); + } + + @Test + @DisplayName("Spare시에는 프레임번호가 변함") + void pitchingSpare() { + int number = 5; + Frames frames = new Frames(10); + frames.pitching(FrameNumber.number(number), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(number), 5); + assertThat(frameNumber).isEqualTo(FrameNumber.number(number + 1)); + } + + @Test + @DisplayName("Strike시에는 프레임번호가 변함") + void pitchingStrike() { + int number = 5; + Frames frames = new Frames(10); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(number), BowlingPin.MAX_PIN_NUMBER); + assertThat(frameNumber).isEqualTo(FrameNumber.number(number).next()); + } + + @Test + @DisplayName("마지막 프레임의 스트라이크의 첫번째 스트라이는 프레임이 변하지 않음") + void lastPitching() { + int lastNumber = 10; + Frames frames = new Frames(lastNumber); + FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); + assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); + } + + @Test + @DisplayName("마지막 프레임의 스트라이크의 두번째 스트라이크는 프레임이 변함") + void lastPitchingDouble() { + int lastNumber = 10; + Frames frames = new Frames(lastNumber); + frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); + FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); + assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); + } + + @Test + @DisplayName("마지막 프레임의 스페어는 프레임이 변하지 않음") + void lastPitchingSpare() { + int lastNumber = 10; + Frames frames = new Frames(lastNumber); + frames.pitchingLast(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 5); + assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); + } + + @Test + @DisplayName("마지막 프레임에서 두 번 다 미스한 경우는 프레임 증가(스페어아님)") + void lastFrameMiss() { + int lastNumber = 10; + Frames frames = new Frames(lastNumber); + frames.pitchingLast(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 4); + assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); + } + + @Test + @DisplayName("마지막 프레임에서 세 번 투구한 경우는 프레임 증가") + void lastFramePitchingThreeTimes() { + int lastNumber = 10; + Frames frames = new Frames(lastNumber); + frames.pitchingLast(FrameNumber.number(lastNumber), 5); + frames.pitchingLast(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 10); + assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); + } +} \ No newline at end of file From 682acf0fe917aad3fa286333302b41a36e9d7867 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:30:18 +0900 Subject: [PATCH 10/39] =?UTF-8?q?refactor=20:=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/view/OutputView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index 16c794bff8..a48a1627ff 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -21,7 +21,9 @@ public static void printScoreScreen(Username username, Frames frames) { StringBuilder sb = new StringBuilder(); sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); for (int i = 0; i < framesList.size(); i++) { - String hitShape = frameScore(sb, framesList.get(i)); + Frame frame = framesList.get(i); + String hitShape = frameScore(frame.getHitRecords()); + if (i == framesList.size() - 1) { sb.append(String.format(BONUS_SHAPE, hitShape)); continue; @@ -32,10 +34,8 @@ public static void printScoreScreen(Username username, Frames frames) { System.out.println(); } - private static String frameScore(StringBuilder sb, Frame frame) { + private static String frameScore(List hitRecords) { StringBuilder hitBuilder = new StringBuilder(); - List hitRecords = frame.getHitRecords(); - int hitCount = 0; for (int index = 0; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); From c2958f92816967644982049d3e03d56080b98b9d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 02:45:47 +0900 Subject: [PATCH 11/39] =?UTF-8?q?refactor=20:=20OutputView=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HitRecord에 각 투구 당시의 상황에 따른 볼링친 갯수와 그에따른 볼링용어를 기록하도록 함 --- src/main/java/bowling/Frame.java | 15 +++++- src/main/java/bowling/HitRecord.java | 8 ++- src/main/java/bowling/view/OutputView.java | 61 ++++++++++------------ src/main/java/bowling/view/ScoreShape.java | 5 -- 4 files changed, 50 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/bowling/view/ScoreShape.java diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 812f8fc401..08a25003ce 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -4,6 +4,7 @@ import java.util.List; public class Frame { + private static final int HIT_ONCE = 1; private static final int HIT_TWICE = 2; private static final int HIT_TRIPLE = 3; @@ -25,7 +26,19 @@ private boolean failedBounsFrame() { public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - hitRecords.add(new HitRecord(count)); + BowilingTerm bowilingTerm = BowilingTerm.MISS; + if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE) && bowlingPin.isZero()) { + bowilingTerm = BowilingTerm.STRIKE; + } + + if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { + bowilingTerm = BowilingTerm.SPARE; + } + + if (count == 0) { + bowilingTerm = BowilingTerm.GUTTER; + } + hitRecords.add(new HitRecord(count, bowilingTerm)); } public boolean finishFrame() { diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 3ff0fc7e07..7ad28a0828 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -2,15 +2,21 @@ public class HitRecord { private final int hitCount; + private final BowilingTerm bowilingTerm; - public HitRecord(int count) { + public HitRecord(int count, BowilingTerm bowilingTerm) { this.hitCount = count; + this.bowilingTerm = bowilingTerm; } public int getHitCount() { return hitCount; } + public BowilingTerm getBowilingTerm() { + return bowilingTerm; + } + public boolean hitAll() { return hitCount == BowlingPin.MAX_PIN_NUMBER; } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index a48a1627ff..f91d18e8e6 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -9,56 +9,53 @@ public class OutputView { private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; - private static final int MAX_HIT_COUNT = 10; private OutputView() { } public static void printScoreScreen(Username username, Frames frames) { - List framesList = frames.getFrames(); System.out.println(BASE_SCORE_SCREEN); + StringBuilder sb = new StringBuilder(); - sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); - for (int i = 0; i < framesList.size(); i++) { - Frame frame = framesList.get(i); - String hitShape = frameScore(frame.getHitRecords()); + sb.append(makeUserFormat(username)); - if (i == framesList.size() - 1) { - sb.append(String.format(BONUS_SHAPE, hitShape)); - continue; - } + List framesList = frames.getFrames(); + String hitShape = ""; + for (int i = 0; i < framesList.size() - 1; i++) { + Frame frame = framesList.get(i); + hitShape = makeFrameScoreShape(frame.getHitRecords()); sb.append(String.format(FORMAT_SHAPE, hitShape)); } + sb.append(String.format(BONUS_SHAPE, hitShape)); + + sb.append("\n"); System.out.println(sb); - System.out.println(); } - private static String frameScore(List hitRecords) { + private static String makeUserFormat(Username username) { + return String.format(SEPARATOR + FORMAT_SHAPE, username.getName()); + } + + private static String makeFrameScoreShape(List hitRecords) { StringBuilder hitBuilder = new StringBuilder(); - int hitCount = 0; - for (int index = 0; index < hitRecords.size(); index++) { + HitRecord hitRecordFirst = hitRecords.get(0); + hitBuilder.append(retrieveHitShape(hitRecordFirst)); + + for (int index = 1; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); - hitCount += hitRecord.getHitCount(); - if (index != 0) { - hitBuilder.append(SEPARATOR); - if (hitCount == MAX_HIT_COUNT) { - hitBuilder.append(BowilingTerm.SPARE.shape()); - continue; - } - } + hitBuilder.append(SEPARATOR); + hitBuilder.append(retrieveHitShape(hitRecord)); + } - if (index != 1 && hitRecord.hitAll()) { - hitBuilder.append(BowilingTerm.STRIKE.shape()); - continue; - } + return hitBuilder.toString(); + } - if (hitRecord.hitZero()) { - hitBuilder.append(BowilingTerm.GUTTER.shape()); - continue; - } - hitBuilder.append(hitRecord.getHitCount()); + private static String retrieveHitShape(HitRecord hitRecord) { + BowilingTerm bowilingTerm = hitRecord.getBowilingTerm(); + if (bowilingTerm.equals(BowilingTerm.MISS)) { + return String.valueOf(hitRecord.getHitCount()); } - return hitBuilder.toString(); + return bowilingTerm.shape(); } } diff --git a/src/main/java/bowling/view/ScoreShape.java b/src/main/java/bowling/view/ScoreShape.java deleted file mode 100644 index 929c1dae6d..0000000000 --- a/src/main/java/bowling/view/ScoreShape.java +++ /dev/null @@ -1,5 +0,0 @@ -package bowling.view; - -public class ScoreShape { - -} From 0e4cf29dca65b1f6c66ee63d9bb2732912f844f5 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 03:14:29 +0900 Subject: [PATCH 12/39] =?UTF-8?q?refactor=20:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20Scanner=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index 0c3a12e854..dfe4c49525 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -7,8 +7,6 @@ public class App { public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - Username username = InputView.playerName(); BowlingGame bowlingGame = new BowlingGame(); From c8b36eba3af8b9f6ea20835c9269a8584373cd0f Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 03:15:11 +0900 Subject: [PATCH 13/39] =?UTF-8?q?refactor=20:=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=A4=91=EB=B3=B5=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=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/bowling/Frame.java | 24 +++++++++++++++------- src/main/java/bowling/view/OutputView.java | 11 +++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 08a25003ce..170d15514f 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -27,20 +27,35 @@ private boolean failedBounsFrame() { public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); BowilingTerm bowilingTerm = BowilingTerm.MISS; - if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE) && bowlingPin.isZero()) { + if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE || hitStrike()) && bowlingPin.isZero()) { bowilingTerm = BowilingTerm.STRIKE; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { bowilingTerm = BowilingTerm.SPARE; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } if (count == 0) { bowilingTerm = BowilingTerm.GUTTER; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } hitRecords.add(new HitRecord(count, bowilingTerm)); } + private boolean hitStrike() { + for (HitRecord hitRecord : hitRecords) { + if (!hitRecord.hitAll()) { + return false; + } + } + return true; + } + public boolean finishFrame() { return clearAllFrame() || hitTwice(); } @@ -49,12 +64,7 @@ public boolean hitDouble() { if (hitRecords.size() != HIT_TWICE) { return false; } - for (HitRecord hitRecord : hitRecords) { - if (!hitRecord.hitAll()) { - return false; - } - } - return true; + return hitStrike(); } public void chargeBowlingPin() { diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index f91d18e8e6..3100d9511d 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -9,6 +9,7 @@ public class OutputView { private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; + private static final String BLANK = ""; private OutputView() { } @@ -21,13 +22,13 @@ public static void printScoreScreen(Username username, Frames frames) { sb.append(makeUserFormat(username)); List framesList = frames.getFrames(); - String hitShape = ""; for (int i = 0; i < framesList.size() - 1; i++) { Frame frame = framesList.get(i); - hitShape = makeFrameScoreShape(frame.getHitRecords()); + String hitShape = makeFrameScoreShape(frame.getHitRecords()); sb.append(String.format(FORMAT_SHAPE, hitShape)); } - sb.append(String.format(BONUS_SHAPE, hitShape)); + Frame lastFrame = framesList.get(framesList.size() - 1); + sb.append(String.format(BONUS_SHAPE, makeFrameScoreShape(lastFrame.getHitRecords()))); sb.append("\n"); System.out.println(sb); @@ -38,6 +39,10 @@ private static String makeUserFormat(Username username) { } private static String makeFrameScoreShape(List hitRecords) { + if (hitRecords.isEmpty()) { + return BLANK; + } + StringBuilder hitBuilder = new StringBuilder(); HitRecord hitRecordFirst = hitRecords.get(0); hitBuilder.append(retrieveHitShape(hitRecordFirst)); From 8f3d3beb0d3d78afe714c3198f9637c76358981a Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:36:07 +0900 Subject: [PATCH 14/39] =?UTF-8?q?refactor=20:=20FinalFrame=EC=9D=B4=20Fram?= =?UTF-8?q?e=EC=9D=84=20=EC=83=81=EC=86=8D=EB=B0=9B=EC=95=84=20=EC=83=81?= =?UTF-8?q?=EC=9D=B4=ED=95=9C=20=EC=A1=B0=EA=B1=B4=20=EB=B6=80=EB=B6=84?= =?UTF-8?q?=EC=9D=84=20=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/FinalFrame.java | 22 +++++++++ src/main/java/bowling/Frame.java | 68 +++++++-------------------- src/main/java/bowling/HitRecord.java | 4 ++ src/main/java/bowling/HitRecords.java | 45 +++++++++++++++++- 4 files changed, 86 insertions(+), 53 deletions(-) create mode 100644 src/main/java/bowling/FinalFrame.java diff --git a/src/main/java/bowling/FinalFrame.java b/src/main/java/bowling/FinalFrame.java new file mode 100644 index 0000000000..b610907bd6 --- /dev/null +++ b/src/main/java/bowling/FinalFrame.java @@ -0,0 +1,22 @@ +package bowling; + +public class FinalFrame extends Frame { + + @Override + public boolean strikeCondition() { + return (!hitRecords.hitTimes(HIT_TWICE) || hitRecords.isRecordAllStrike()) && bowlingPin.isZero(); + } + + @Override + public boolean finishFrame() { + boolean result = hitRecords.hitTimes(HIT_TRIPLE) || failedBounsFrame(); + if (clearAllFrame()) { + chargeBowlingPin(); + } + return result; + } + + private boolean failedBounsFrame() { + return hitRecords.hitTimes(HIT_TWICE) && !clearAllFrame(); + } +} diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 170d15514f..5084fa6414 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,70 +1,44 @@ package bowling; -import java.util.ArrayList; import java.util.List; public class Frame { - private static final int HIT_ONCE = 1; - private static final int HIT_TWICE = 2; - private static final int HIT_TRIPLE = 3; + protected static final int HIT_TWICE = 2; + protected static final int HIT_TRIPLE = 3; - private BowlingPin bowlingPin; - private final List hitRecords; + protected BowlingPin bowlingPin; + protected final HitRecords hitRecords; public Frame() { this.bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); - hitRecords = new ArrayList<>(); - } - - public boolean finishLastFrame() { - return hitThreeTimes() || hitDouble() || failedBounsFrame(); - } - - private boolean failedBounsFrame() { - return hitTwice() && !clearAllFrame(); + this.hitRecords = new HitRecords(); } public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - BowilingTerm bowilingTerm = BowilingTerm.MISS; - if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE || hitStrike()) && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.STRIKE; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (strikeCondition()) { + hitRecords.addStrike(); return ; } - if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.SPARE; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (hitRecords.hitOnce() && bowlingPin.isZero()) { + hitRecords.addSpare(); return ; } - if (count == 0) { - bowilingTerm = BowilingTerm.GUTTER; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (count == BowlingPin.ZERO) { + hitRecords.addGutter(); return ; } - hitRecords.add(new HitRecord(count, bowilingTerm)); - } - - private boolean hitStrike() { - for (HitRecord hitRecord : hitRecords) { - if (!hitRecord.hitAll()) { - return false; - } - } - return true; + hitRecords.addMiss(count); } - public boolean finishFrame() { - return clearAllFrame() || hitTwice(); + protected boolean strikeCondition() { + return bowlingPin.isZero(); } - public boolean hitDouble() { - if (hitRecords.size() != HIT_TWICE) { - return false; - } - return hitStrike(); + protected boolean finishFrame() { + return clearAllFrame() || hitRecords.hitTimes(HIT_TWICE); } public void chargeBowlingPin() { @@ -72,18 +46,10 @@ public void chargeBowlingPin() { } public List getHitRecords() { - return hitRecords; + return hitRecords.getHitRecords(); } public boolean clearAllFrame() { return bowlingPin.isZero(); } - - public boolean hitThreeTimes() { - return hitRecords.size() == HIT_TRIPLE; - } - - public boolean hitTwice() { - return hitRecords.size() == HIT_TWICE; - } } diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 7ad28a0828..45f8d77f2e 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -4,6 +4,10 @@ public class HitRecord { private final int hitCount; private final BowilingTerm bowilingTerm; + public static HitRecord of(int count, BowilingTerm bowilingTerm) { + return new HitRecord(count, bowilingTerm); + } + public HitRecord(int count, BowilingTerm bowilingTerm) { this.hitCount = count; this.bowilingTerm = bowilingTerm; diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index 2cc56a20f2..4e336c4031 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -1,11 +1,52 @@ package bowling; +import java.util.ArrayList; import java.util.List; public class HitRecords { + private static final int HIT_ONCE = 1; + private List hitRecords; - public HitRecords(List hitRecords) { - this.hitRecords = hitRecords; + public HitRecords() { + this.hitRecords = new ArrayList<>(); + } + + public boolean hitOnce() { + return hitRecords.size() == HIT_ONCE; + } + + + public void addRecord(HitRecord hitRecord) { + this.hitRecords.add(hitRecord); + } + + public void addStrike() { + this.hitRecords.add(HitRecord.of(10, BowilingTerm.STRIKE)); + } + + public void addSpare() { + this.hitRecords.add(HitRecord.of(10, BowilingTerm.SPARE)); + } + + public void addGutter() { + this.hitRecords.add(HitRecord.of(0, BowilingTerm.GUTTER)); + } + + public void addMiss(int count) { + this.hitRecords.add(HitRecord.of(count, BowilingTerm.MISS)); + } + + public boolean isRecordAllStrike() { + return hitRecords.stream() + .allMatch(HitRecord::hitAll); + } + + public boolean hitTimes(int hitTwice) { + return hitRecords.size() == hitTwice; + } + + public List getHitRecords() { + return hitRecords; } } From fb52c6acf6c565738ca418245401d41f90b4325f Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:38:28 +0900 Subject: [PATCH 15/39] =?UTF-8?q?refactor=20:=20=EB=8B=A4=ED=98=95?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20Frame?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A7=8C=EC=9C=BC=EB=A1=9C=20=EC=9D=BC?= =?UTF-8?q?=EB=B0=98=ED=94=84=EB=A0=88=EC=9E=84=EA=B3=BC=20=EB=A7=88?= =?UTF-8?q?=EC=A7=80=EB=A7=89=ED=94=84=EB=A0=88=EC=9E=84=20=EC=88=98?= =?UTF-8?q?=ED=96=89=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=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 BowlingGame과 Frames는 어떤 프레임인지 모르고 실행해도 실객체에 따라 알아서 스트라이크 조건과 프레임완료조건이 다르게 실행됨. --- src/main/java/bowling/BowlingGame.java | 3 --- src/main/java/bowling/Frames.java | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/bowling/BowlingGame.java b/src/main/java/bowling/BowlingGame.java index 1e3818b8f2..413cb5b68a 100644 --- a/src/main/java/bowling/BowlingGame.java +++ b/src/main/java/bowling/BowlingGame.java @@ -11,9 +11,6 @@ public BowlingGame() { } public FrameNumber pitchingBall(int hitCount) { - if (frameNumber.isSameNumber(FRAME_SIZE)) { - return frames.pitchingLast(frameNumber, hitCount); - } this.frameNumber = frames.pitching(frameNumber, hitCount); return this.frameNumber; } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 370f03eb0f..ad3a9a8eee 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -8,9 +8,10 @@ public class Frames { public Frames(int size) { this.frames = new ArrayList<>(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size - 1; i++) { this.frames.add(new Frame()); } + this.frames.add(new FinalFrame()); } public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { @@ -26,9 +27,6 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); - if (frame.finishLastFrame()) { - return frameNumber.next(); - } if (frame.clearAllFrame()) { frame.chargeBowlingPin(); From be3e10085946ce6c5b02be03094d4f0e8b689db5 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:44:25 +0900 Subject: [PATCH 16/39] =?UTF-8?q?refactor=20:=20=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=ED=95=84=EB=93=9C=EA=B0=92=EC=97=90=20final=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 --- src/main/java/bowling/HitRecords.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index 4e336c4031..a46f0d45d8 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -6,7 +6,7 @@ public class HitRecords { private static final int HIT_ONCE = 1; - private List hitRecords; + private final List hitRecords; public HitRecords() { this.hitRecords = new ArrayList<>(); From 0370f04a98f5edfec65cd70c89d96ed20ae60715 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:44:47 +0900 Subject: [PATCH 17/39] =?UTF-8?q?refactor=20:=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=ED=94=84=EB=A0=88=EC=9E=84=EC=9D=98=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=B8=20pitchingLast=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frames.java | 11 ----------- src/test/java/bowling/FramesTest.java | 28 ++++++++------------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index ad3a9a8eee..b81c5055ca 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -24,17 +24,6 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { } - public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { - Frame frame = frames.get(frameNumber.retrieveIndexNumber()); - frame.hitBowlingPin(hitCount); - - if (frame.clearAllFrame()) { - frame.chargeBowlingPin(); - return frameNumber; - } - return frameNumber; - } - public List getFrames() { return frames; } diff --git a/src/test/java/bowling/FramesTest.java b/src/test/java/bowling/FramesTest.java index 969f84ef71..eaca8713db 100644 --- a/src/test/java/bowling/FramesTest.java +++ b/src/test/java/bowling/FramesTest.java @@ -1,11 +1,9 @@ package bowling; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; class FramesTest { @@ -42,27 +40,17 @@ void pitchingStrike() { void lastPitching() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); } - @Test - @DisplayName("마지막 프레임의 스트라이크의 두번째 스트라이크는 프레임이 변함") - void lastPitchingDouble() { - int lastNumber = 10; - Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); - assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); - } - @Test @DisplayName("마지막 프레임의 스페어는 프레임이 변하지 않음") void lastPitchingSpare() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 5); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 5); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); } @@ -71,8 +59,8 @@ void lastPitchingSpare() { void lastFrameMiss() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 4); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 4); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); } @@ -81,9 +69,9 @@ void lastFrameMiss() { void lastFramePitchingThreeTimes() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 10); + frames.pitching(FrameNumber.number(lastNumber), 5); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 10); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); } } \ No newline at end of file From 7c0be803dd3be4dd012f92ca7c4baefd0f5db6b9 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:33:32 +0900 Subject: [PATCH 18/39] =?UTF-8?q?refactor=20:=20score=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Score.java | 47 +++++++++++++++++++++++++++++++ src/main/java/bowling/Scores.java | 12 ++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/bowling/Score.java create mode 100644 src/main/java/bowling/Scores.java diff --git a/src/main/java/bowling/Score.java b/src/main/java/bowling/Score.java new file mode 100644 index 0000000000..2a68ef73d4 --- /dev/null +++ b/src/main/java/bowling/Score.java @@ -0,0 +1,47 @@ +package bowling; + +public class Score { + private final int hitCount; + private final int bonusCount; + + public static Score ofZero() { + return new Score(0, -1); + } + + public static Score ofStrike() { + return new Score(10, 2); + } + + public static Score ofSpare() { + return new Score(10, 1); + } + + public static Score ofMiss(int hitCount) { + return new Score(hitCount, 0); + } + + private Score(int hitCount, int bonusCount) { + this.hitCount = hitCount; + this.bonusCount = bonusCount; + } + + public boolean remainBonus() { + return bonusCount != 0; + } + + public Score addBonusScore(int hitCount) { + return new Score(this.hitCount + hitCount, bonusCount - 1); + } + + public int getHitCount() { + return hitCount; + } + + public int getBonusCount() { + return bonusCount; + } + + public boolean isMiss() { + return hitCount != 10; + } +} diff --git a/src/main/java/bowling/Scores.java b/src/main/java/bowling/Scores.java new file mode 100644 index 0000000000..ac0d1b86e0 --- /dev/null +++ b/src/main/java/bowling/Scores.java @@ -0,0 +1,12 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class Scores { + private final List scores; + + public Scores() { + this.scores = new ArrayList<>(); + } +} From 4cffcd9fcf254e2bc98a40002892c9d074a7497e Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:33:57 +0900 Subject: [PATCH 19/39] =?UTF-8?q?refactor=20:=20score=EB=A5=BC=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EA=B3=A0=20miss=EA=B0=80=20=EB=82=AC?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=A0=90=EC=88=98=EB=A5=BC=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 25 +++++++++++++++++-------- src/main/java/bowling/Frames.java | 18 ++++++++++++++---- src/main/java/bowling/HitRecords.java | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 5084fa6414..bbb22ea62f 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -14,23 +14,24 @@ public Frame() { this.hitRecords = new HitRecords(); } - public void hitBowlingPin(int count) { + public BowilingTerm hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - if (strikeCondition()) { - hitRecords.addStrike(); - return ; - } - if (hitRecords.hitOnce() && bowlingPin.isZero()) { hitRecords.addSpare(); - return ; + return BowilingTerm.SPARE; + } + + if (strikeCondition()) { + hitRecords.addStrike(); + return BowilingTerm.STRIKE; } if (count == BowlingPin.ZERO) { hitRecords.addGutter(); - return ; + return BowilingTerm.GUTTER; } hitRecords.addMiss(count); + return BowilingTerm.MISS; } protected boolean strikeCondition() { @@ -52,4 +53,12 @@ public List getHitRecords() { public boolean clearAllFrame() { return bowlingPin.isZero(); } + + public void calculateBonus(int hitCount) { + hitRecords.calculateBonus(hitCount); + } + + public HitRecords hitRecords() { + return hitRecords; + } } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index b81c5055ca..9169ac1444 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -1,13 +1,15 @@ package bowling; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; public class Frames { - private final List frames; + private final LinkedList frames; public Frames(int size) { - this.frames = new ArrayList<>(); + this.frames = new LinkedList<>(); for (int i = 0; i < size - 1; i++) { this.frames.add(new Frame()); } @@ -16,14 +18,22 @@ public Frames(int size) { public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); - frame.hitBowlingPin(hitCount); + BowilingTerm bowilingTerm = frame.hitBowlingPin(hitCount); + + if (!bowilingTerm.equals(BowilingTerm.STRIKE)) { + ListIterator frameListIterator = frames.listIterator(frameNumber.retrieveIndexNumber()); + while (frameListIterator.hasPrevious()) { + Frame previous = frameListIterator.previous(); + previous.calculateBonus(hitCount); + } + } + if (frame.finishFrame()) { return frameNumber.next(); } return frameNumber; } - public List getFrames() { return frames; } diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index a46f0d45d8..7c1874ac15 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -7,9 +7,11 @@ public class HitRecords { private static final int HIT_ONCE = 1; private final List hitRecords; + private Score score; public HitRecords() { this.hitRecords = new ArrayList<>(); + this.score = Score.ofZero(); } public boolean hitOnce() { @@ -23,18 +25,22 @@ public void addRecord(HitRecord hitRecord) { public void addStrike() { this.hitRecords.add(HitRecord.of(10, BowilingTerm.STRIKE)); + score = Score.ofStrike(); } public void addSpare() { this.hitRecords.add(HitRecord.of(10, BowilingTerm.SPARE)); + score = Score.ofSpare(); } public void addGutter() { this.hitRecords.add(HitRecord.of(0, BowilingTerm.GUTTER)); + score = Score.ofMiss(hitSum()); } public void addMiss(int count) { this.hitRecords.add(HitRecord.of(count, BowilingTerm.MISS)); + score = Score.ofMiss(hitSum()); } public boolean isRecordAllStrike() { @@ -49,4 +55,18 @@ public boolean hitTimes(int hitTwice) { public List getHitRecords() { return hitRecords; } + + private int hitSum() { + return hitRecords.stream().mapToInt(HitRecord::getHitCount).sum(); + } + + public void calculateBonus(int hitCount) { + if (score.remainBonus()) { + score = score.addBonusScore(hitCount); + } + } + + public Score getScore() { + return score; + } } From 1aa45f6c2e28ee0b90dda5c48395a4de322d09b2 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:34:10 +0900 Subject: [PATCH 20/39] =?UTF-8?q?feat=20:=20=EC=A0=90=EC=88=98=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 2 +- src/main/java/bowling/BowlingGame.java | 4 +++ src/main/java/bowling/view/OutputView.java | 32 +++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index dfe4c49525..2783e33e19 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -17,7 +17,7 @@ public static void main(String[] args) { frameNumber = bowlingGame.pitchingBall(count); Frames frames = bowlingGame.getFrames(); - OutputView.printScoreScreen(username, frames); + OutputView.printScoreScreen(username, frames, bowlingGame); } } } diff --git a/src/main/java/bowling/BowlingGame.java b/src/main/java/bowling/BowlingGame.java index 413cb5b68a..83340205f9 100644 --- a/src/main/java/bowling/BowlingGame.java +++ b/src/main/java/bowling/BowlingGame.java @@ -18,4 +18,8 @@ public FrameNumber pitchingBall(int hitCount) { public Frames getFrames() { return frames; } + + public FrameNumber getFrameNumber() { + return frameNumber; + } } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index 3100d9511d..6c8ce7af8f 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -6,6 +6,7 @@ public class OutputView { private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String START_SHAPE = "| |"; private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; @@ -15,7 +16,7 @@ private OutputView() { } - public static void printScoreScreen(Username username, Frames frames) { + public static void printScoreScreen(Username username, Frames frames, BowlingGame bowlingGame) { System.out.println(BASE_SCORE_SCREEN); StringBuilder sb = new StringBuilder(); @@ -29,11 +30,40 @@ public static void printScoreScreen(Username username, Frames frames) { } Frame lastFrame = framesList.get(framesList.size() - 1); sb.append(String.format(BONUS_SHAPE, makeFrameScoreShape(lastFrame.getHitRecords()))); + sb.append("\n"); + int totalScore = 0; + sb.append(START_SHAPE); + for (int i = 0; i < framesList.size() - 1; i++) { + Frame frame = framesList.get(i); + FrameNumber frameNumber = bowlingGame.getFrameNumber(); + String score = makeFrameScore(i, frame.hitRecords(), frameNumber, totalScore); + if (!score.equals("")) { + totalScore += Integer.parseInt(score); + score = String.valueOf(totalScore); + } + sb.append(String.format(FORMAT_SHAPE, score)); + } + FrameNumber frameNumber = bowlingGame.getFrameNumber(); + lastFrame = framesList.get(framesList.size() - 1); + String score = makeFrameScore(framesList.size() - 1, lastFrame.hitRecords(), frameNumber, totalScore); + if (!score.equals("")) { + totalScore += Integer.parseInt(score); + score = String.valueOf(totalScore); + } + sb.append(String.format(BONUS_SHAPE, score)); sb.append("\n"); System.out.println(sb); } + private static String makeFrameScore(int index, HitRecords hitRecords, FrameNumber frameNumber, int totalScore) { + Score score = hitRecords.getScore(); + if (score.remainBonus() || index + 1 >= frameNumber.getFrameNumber()) { + return ""; + } + return String.valueOf(score.getHitCount()); + } + private static String makeUserFormat(Username username) { return String.format(SEPARATOR + FORMAT_SHAPE, username.getName()); } From 314932638f7f31c82071399ab1ee111576fb0873 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:26:11 +0900 Subject: [PATCH 21/39] =?UTF-8?q?feat=20:=20BowlingPin=EA=B3=BC=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- src/main/java/bowling/BowlingPin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bowling/BowlingPin.java b/src/main/java/bowling/BowlingPin.java index e4097357fa..a182e4e991 100644 --- a/src/main/java/bowling/BowlingPin.java +++ b/src/main/java/bowling/BowlingPin.java @@ -4,7 +4,7 @@ public class BowlingPin { public static final int MAX_PIN_NUMBER = 10; - public static final int ZERO = 0; + private static final int ZERO = 0; private final int count; From 5cf08a5e0d1981b20e9d567423789d0c6f3b34b2 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:26:43 +0900 Subject: [PATCH 22/39] =?UTF-8?q?feat=20:=20=ED=95=9C=EB=9D=BC=EC=9A=B4?= =?UTF-8?q?=EB=93=9C=EC=9D=98=20Pin=EC=83=81=ED=83=9C=EB=A5=BC=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EA=B3=A0=20=EA=B8=B0=EB=A1=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20Frame=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 70 ++-------------------------- src/main/java/bowling/HitRecord.java | 24 ++-------- src/test/java/bowling/FrameTest.java | 9 ++-- 3 files changed, 12 insertions(+), 91 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 170d15514f..1df32f672c 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -4,10 +4,6 @@ import java.util.List; public class Frame { - private static final int HIT_ONCE = 1; - private static final int HIT_TWICE = 2; - private static final int HIT_TRIPLE = 3; - private BowlingPin bowlingPin; private final List hitRecords; @@ -16,74 +12,14 @@ public Frame() { hitRecords = new ArrayList<>(); } - public boolean finishLastFrame() { - return hitThreeTimes() || hitDouble() || failedBounsFrame(); - } - - private boolean failedBounsFrame() { - return hitTwice() && !clearAllFrame(); - } - - public void hitBowlingPin(int count) { + public boolean hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - BowilingTerm bowilingTerm = BowilingTerm.MISS; - if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE || hitStrike()) && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.STRIKE; - hitRecords.add(new HitRecord(count, bowilingTerm)); - return ; - } - - if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.SPARE; - hitRecords.add(new HitRecord(count, bowilingTerm)); - return ; - } - - if (count == 0) { - bowilingTerm = BowilingTerm.GUTTER; - hitRecords.add(new HitRecord(count, bowilingTerm)); - return ; - } - hitRecords.add(new HitRecord(count, bowilingTerm)); - } - - private boolean hitStrike() { - for (HitRecord hitRecord : hitRecords) { - if (!hitRecord.hitAll()) { - return false; - } - } - return true; - } + hitRecords.add(new HitRecord(count)); - public boolean finishFrame() { - return clearAllFrame() || hitTwice(); - } - - public boolean hitDouble() { - if (hitRecords.size() != HIT_TWICE) { - return false; - } - return hitStrike(); - } - - public void chargeBowlingPin() { - bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); + return bowlingPin.isZero() || hitRecords.size() == 2; } public List getHitRecords() { return hitRecords; } - - public boolean clearAllFrame() { - return bowlingPin.isZero(); - } - - public boolean hitThreeTimes() { - return hitRecords.size() == HIT_TRIPLE; - } - - public boolean hitTwice() { - return hitRecords.size() == HIT_TWICE; - } } diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 7ad28a0828..748e969de3 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -1,27 +1,13 @@ package bowling; public class HitRecord { - private final int hitCount; - private final BowilingTerm bowilingTerm; + private final int count; - public HitRecord(int count, BowilingTerm bowilingTerm) { - this.hitCount = count; - this.bowilingTerm = bowilingTerm; + public HitRecord(int count) { + this.count = count; } - public int getHitCount() { - return hitCount; - } - - public BowilingTerm getBowilingTerm() { - return bowilingTerm; - } - - public boolean hitAll() { - return hitCount == BowlingPin.MAX_PIN_NUMBER; - } - - public boolean hitZero() { - return hitCount == BowlingPin.ZERO; + public int getCount() { + return count; } } diff --git a/src/test/java/bowling/FrameTest.java b/src/test/java/bowling/FrameTest.java index dc480e3519..917210a074 100644 --- a/src/test/java/bowling/FrameTest.java +++ b/src/test/java/bowling/FrameTest.java @@ -11,15 +11,14 @@ class FrameTest { @Test void hitAllBowlingPins() { Frame frame = new Frame(); - frame.hitBowlingPin(3); - assertThat(frame.finishFrame()).isFalse(); + assertThat(frame.hitBowlingPin(3)).isFalse(); + assertThat(frame.hitBowlingPin(7)).isTrue(); } @Test void hitTwice() { Frame frame = new Frame(); - frame.hitBowlingPin(3); - frame.hitBowlingPin(5); - assertThat(frame.finishFrame()).isTrue(); + assertThat(frame.hitBowlingPin(3)).isFalse(); + assertThat(frame.hitBowlingPin(3)).isTrue(); } } \ No newline at end of file From aee060abfa002ca9eda581b876f32ae9d2c04347 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Wed, 9 Nov 2022 23:27:03 +0900 Subject: [PATCH 23/39] =?UTF-8?q?feat=20:=20=EB=B3=BC=EB=A7=81=EC=A0=90?= =?UTF-8?q?=EC=88=98=ED=8C=90=20=EA=B4=80=EB=A6=AC=20=EA=B0=9D=EC=B2=B4=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 --- src/main/java/bowling/BowlingScoreRecord.java | 29 ++++++++++++++++++ .../java/bowling/BowlingScoreRecordTest.java | 30 ++++++++++--------- 2 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 src/main/java/bowling/BowlingScoreRecord.java diff --git a/src/main/java/bowling/BowlingScoreRecord.java b/src/main/java/bowling/BowlingScoreRecord.java new file mode 100644 index 0000000000..b9da8422cd --- /dev/null +++ b/src/main/java/bowling/BowlingScoreRecord.java @@ -0,0 +1,29 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class BowlingScoreRecord { + private static final int BOWLING_ROUND_COUNT = 10; + private final List frames; + + public BowlingScoreRecord() { + this.frames = new ArrayList<>(); + for (int i = 0; i < BOWLING_ROUND_COUNT; i++) { + this.frames.add(new Frame()); + } + } + + public int hit(int frameNumber, int count) { + Frame frame = frames.get(frameNumber); + + if (frame.hitBowlingPin(count)) { + return frameNumber + 1; + } + return frameNumber; + } + + public List getFrames() { + return frames; + } +} diff --git a/src/test/java/bowling/BowlingScoreRecordTest.java b/src/test/java/bowling/BowlingScoreRecordTest.java index ca12a198f6..89e709b8cc 100644 --- a/src/test/java/bowling/BowlingScoreRecordTest.java +++ b/src/test/java/bowling/BowlingScoreRecordTest.java @@ -3,35 +3,37 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + class BowlingScoreRecordTest { @Test void hitMiss() { - BowlingGame bowlingScoreRecord = new BowlingGame(); - FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); - Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.first()); + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 5); + Assertions.assertThat(frameNumber).isEqualTo(0); } @Test void hitStrike() { - BowlingGame bowlingScoreRecord = new BowlingGame(); - FrameNumber frameNumber = bowlingScoreRecord.pitchingBall( 10); - Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 10); + Assertions.assertThat(frameNumber).isEqualTo(1); } @Test void hitSpare() { - BowlingGame bowlingScoreRecord = new BowlingGame(); - bowlingScoreRecord.pitchingBall(5); - FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); - Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 5); + frameNumber = bowlingScoreRecord.hit(frameNumber, 5); + Assertions.assertThat(frameNumber).isEqualTo(1); } @Test void hitGutterTwice() { - BowlingGame bowlingScoreRecord = new BowlingGame(); - bowlingScoreRecord.pitchingBall(0); - FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(0); - Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + int frameNumber = bowlingScoreRecord.hit(0, 0); + frameNumber = bowlingScoreRecord.hit(frameNumber, 0); + Assertions.assertThat(frameNumber).isEqualTo(1); } } \ No newline at end of file From 02b2620a23b66cc7d87315d5db258629b91b3e9d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 10 Nov 2022 23:17:17 +0900 Subject: [PATCH 24/39] =?UTF-8?q?feat=20:=20=EB=B3=BC=EB=A7=81=EC=A0=90?= =?UTF-8?q?=EC=88=98=ED=8C=90=20=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 18 +++-- src/main/java/bowling/BowlingPin.java | 2 +- src/main/java/bowling/Frame.java | 14 +++- src/main/java/bowling/HitRecord.java | 16 +++-- src/main/java/bowling/view/OutputView.java | 79 +++++++++++----------- src/main/java/bowling/view/ScoreShape.java | 5 ++ 6 files changed, 80 insertions(+), 54 deletions(-) create mode 100644 src/main/java/bowling/view/ScoreShape.java diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index dfe4c49525..1691fb2c5f 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -2,22 +2,26 @@ import bowling.view.InputView; import bowling.view.OutputView; +import org.hibernate.type.TrueFalseType; +import java.util.List; import java.util.Scanner; public class App { public static void main(String[] args) { - Username username = InputView.playerName(); + Scanner scanner = new Scanner(System.in); - BowlingGame bowlingGame = new BowlingGame(); - FrameNumber frameNumber = FrameNumber.first(); - while (frameNumber.isBelow(BowlingGame.FRAME_SIZE)) { - int count = InputView.hitCount(frameNumber.getFrameNumber()); + Username username = InputView.playerName(); - frameNumber = bowlingGame.pitchingBall(count); + BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - Frames frames = bowlingGame.getFrames(); + int frameNumber = 0; + while (frameNumber < 10) { + int count = InputView.hitCount(frameNumber + 1); + frameNumber = bowlingScoreRecord.hit(frameNumber, count); + List frames = bowlingScoreRecord.getFrames(); OutputView.printScoreScreen(username, frames); } + } } diff --git a/src/main/java/bowling/BowlingPin.java b/src/main/java/bowling/BowlingPin.java index a182e4e991..e4097357fa 100644 --- a/src/main/java/bowling/BowlingPin.java +++ b/src/main/java/bowling/BowlingPin.java @@ -4,7 +4,7 @@ public class BowlingPin { public static final int MAX_PIN_NUMBER = 10; - private static final int ZERO = 0; + public static final int ZERO = 0; private final int count; diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 1df32f672c..5471cd83ab 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,9 +1,13 @@ package bowling; +import bowling.view.ScoreShape; + import java.util.ArrayList; import java.util.List; public class Frame { + private static final int HIT_COUNT = 2; + private BowlingPin bowlingPin; private final List hitRecords; @@ -16,10 +20,18 @@ public boolean hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); - return bowlingPin.isZero() || hitRecords.size() == 2; + return clearAllFrame() || hitTwice(); } public List getHitRecords() { return hitRecords; } + + private boolean clearAllFrame() { + return bowlingPin.isZero(); + } + + private boolean hitTwice() { + return hitRecords.size() == HIT_COUNT; + } } diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 748e969de3..3ff0fc7e07 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -1,13 +1,21 @@ package bowling; public class HitRecord { - private final int count; + private final int hitCount; public HitRecord(int count) { - this.count = count; + this.hitCount = count; } - public int getCount() { - return count; + public int getHitCount() { + return hitCount; + } + + public boolean hitAll() { + return hitCount == BowlingPin.MAX_PIN_NUMBER; + } + + public boolean hitZero() { + return hitCount == BowlingPin.ZERO; } } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index 3100d9511d..c314976363 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -1,66 +1,63 @@ package bowling.view; -import bowling.*; +import bowling.BowilingTerm; +import bowling.Frame; +import bowling.HitRecord; +import bowling.Username; import java.util.List; public class OutputView { - private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; private static final String FORMAT_SHAPE = " %-4s|"; - private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; - private static final String BLANK = ""; + private static final int FIRST_ATTEMPT = 0; + private static final int LAST_ATTEMPT = 1; + private static final int ZERO_HIT_COUNT = 0; + private static final int MAX_HIT_COUNT = 10; private OutputView() { } - public static void printScoreScreen(Username username, Frames frames) { + public static void printScoreScreen(Username username, List frames) { System.out.println(BASE_SCORE_SCREEN); - StringBuilder sb = new StringBuilder(); - sb.append(makeUserFormat(username)); - - List framesList = frames.getFrames(); - for (int i = 0; i < framesList.size() - 1; i++) { - Frame frame = framesList.get(i); - String hitShape = makeFrameScoreShape(frame.getHitRecords()); - sb.append(String.format(FORMAT_SHAPE, hitShape)); + sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); + for (Frame frame : frames) { + frameScore(sb, frame); } - Frame lastFrame = framesList.get(framesList.size() - 1); - sb.append(String.format(BONUS_SHAPE, makeFrameScoreShape(lastFrame.getHitRecords()))); - - sb.append("\n"); System.out.println(sb); + System.out.println(); } - private static String makeUserFormat(Username username) { - return String.format(SEPARATOR + FORMAT_SHAPE, username.getName()); - } - - private static String makeFrameScoreShape(List hitRecords) { - if (hitRecords.isEmpty()) { - return BLANK; - } - + private static void frameScore(StringBuilder sb, Frame frame) { StringBuilder hitBuilder = new StringBuilder(); - HitRecord hitRecordFirst = hitRecords.get(0); - hitBuilder.append(retrieveHitShape(hitRecordFirst)); + List hitRecords = frame.getHitRecords(); - for (int index = 1; index < hitRecords.size(); index++) { + int hitCount = 0; + for (int index = 0; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); - hitBuilder.append(SEPARATOR); - hitBuilder.append(retrieveHitShape(hitRecord)); - } - - return hitBuilder.toString(); - } - - private static String retrieveHitShape(HitRecord hitRecord) { - BowilingTerm bowilingTerm = hitRecord.getBowilingTerm(); - if (bowilingTerm.equals(BowilingTerm.MISS)) { - return String.valueOf(hitRecord.getHitCount()); + hitCount += hitRecord.getHitCount(); + if (index == 1) { + hitBuilder.append(SEPARATOR); + if (hitCount == MAX_HIT_COUNT) { + hitBuilder.append(BowilingTerm.SPARE.shape()); + continue; + } + } + + if (index == 0 && hitRecord.hitAll()) { + hitBuilder.append(BowilingTerm.STRIKE.shape()); + continue; + } + + if (hitRecord.hitZero()) { + hitBuilder.append(BowilingTerm.GUTTER.shape()); + continue; + } + hitBuilder.append(hitRecord.getHitCount()); } - return bowilingTerm.shape(); + sb.append(String.format(FORMAT_SHAPE, hitBuilder)); } } diff --git a/src/main/java/bowling/view/ScoreShape.java b/src/main/java/bowling/view/ScoreShape.java new file mode 100644 index 0000000000..929c1dae6d --- /dev/null +++ b/src/main/java/bowling/view/ScoreShape.java @@ -0,0 +1,5 @@ +package bowling.view; + +public class ScoreShape { + +} From 62404883fc3019113bff47ca50ede000225f1b48 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 00:56:28 +0900 Subject: [PATCH 25/39] =?UTF-8?q?refactor=20:=20FrameNumber=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=EC=A7=84=ED=96=89=EC=83=81=ED=83=9C=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 16 ++++---- src/main/java/bowling/BowlingScoreRecord.java | 29 -------------- src/main/java/bowling/Frame.java | 39 +++++++++++++++---- src/main/java/bowling/FrameNumber.java | 4 +- src/main/java/bowling/Frames.java | 21 ++++++---- src/main/java/bowling/view/OutputView.java | 31 ++++++++------- .../java/bowling/BowlingScoreRecordTest.java | 30 +++++++------- src/test/java/bowling/FrameTest.java | 9 +++-- 8 files changed, 90 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/bowling/BowlingScoreRecord.java diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index 1691fb2c5f..0c3a12e854 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -2,9 +2,7 @@ import bowling.view.InputView; import bowling.view.OutputView; -import org.hibernate.type.TrueFalseType; -import java.util.List; import java.util.Scanner; public class App { @@ -13,15 +11,15 @@ public static void main(String[] args) { Username username = InputView.playerName(); - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); + BowlingGame bowlingGame = new BowlingGame(); + FrameNumber frameNumber = FrameNumber.first(); + while (frameNumber.isBelow(BowlingGame.FRAME_SIZE)) { + int count = InputView.hitCount(frameNumber.getFrameNumber()); - int frameNumber = 0; - while (frameNumber < 10) { - int count = InputView.hitCount(frameNumber + 1); - frameNumber = bowlingScoreRecord.hit(frameNumber, count); - List frames = bowlingScoreRecord.getFrames(); + frameNumber = bowlingGame.pitchingBall(count); + + Frames frames = bowlingGame.getFrames(); OutputView.printScoreScreen(username, frames); } - } } diff --git a/src/main/java/bowling/BowlingScoreRecord.java b/src/main/java/bowling/BowlingScoreRecord.java deleted file mode 100644 index b9da8422cd..0000000000 --- a/src/main/java/bowling/BowlingScoreRecord.java +++ /dev/null @@ -1,29 +0,0 @@ -package bowling; - -import java.util.ArrayList; -import java.util.List; - -public class BowlingScoreRecord { - private static final int BOWLING_ROUND_COUNT = 10; - private final List frames; - - public BowlingScoreRecord() { - this.frames = new ArrayList<>(); - for (int i = 0; i < BOWLING_ROUND_COUNT; i++) { - this.frames.add(new Frame()); - } - } - - public int hit(int frameNumber, int count) { - Frame frame = frames.get(frameNumber); - - if (frame.hitBowlingPin(count)) { - return frameNumber + 1; - } - return frameNumber; - } - - public List getFrames() { - return frames; - } -} diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 5471cd83ab..b753f96ccb 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,12 +1,11 @@ package bowling; -import bowling.view.ScoreShape; - import java.util.ArrayList; import java.util.List; public class Frame { - private static final int HIT_COUNT = 2; + private static final int HIT_TWICE = 2; + private static final int HIT_TRIPLE = 3; private BowlingPin bowlingPin; private final List hitRecords; @@ -16,22 +15,48 @@ public Frame() { hitRecords = new ArrayList<>(); } - public boolean hitBowlingPin(int count) { + public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); + } + public boolean finishFrame() { return clearAllFrame() || hitTwice(); } + public boolean hitDouble() { + if (hitRecords.size() != HIT_TWICE) { + return false; + } + for (HitRecord hitRecord : hitRecords) { + if (!hitRecord.hitAll()) { + return false; + } + } + return true; + } + + public boolean spare() { + return hitRecords.size() == HIT_TWICE && clearAllFrame(); + } + + public void chargeBowlingPin() { + bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); + } + public List getHitRecords() { return hitRecords; } - private boolean clearAllFrame() { + public boolean clearAllFrame() { return bowlingPin.isZero(); } - private boolean hitTwice() { - return hitRecords.size() == HIT_COUNT; + public boolean hitTriple() { + return hitRecords.size() == HIT_TRIPLE; + } + + public boolean hitTwice() { + return hitRecords.size() == HIT_TWICE; } } diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java index 30e2e4c8df..262bf52af8 100644 --- a/src/main/java/bowling/FrameNumber.java +++ b/src/main/java/bowling/FrameNumber.java @@ -14,8 +14,8 @@ public static FrameNumber number(int number) { return new FrameNumber(number); } - public FrameNumber next() { - return new FrameNumber(this.frameNumber + 1); + public static FrameNumber plus(FrameNumber frameNumber) { + return new FrameNumber(frameNumber.frameNumber + 1); } private FrameNumber(int frameNumber) { diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 370f03eb0f..6ae561694c 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -17,17 +17,28 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishFrame()) { - return frameNumber.next(); + return FrameNumber.plus(frameNumber); } return frameNumber; } + public List getFrames() { + return frames; + } public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); - if (frame.finishLastFrame()) { - return frameNumber.next(); + if (frame.hitTriple()) { + return FrameNumber.plus(frameNumber); + } + + if (frame.hitDouble()) { + return FrameNumber.plus(frameNumber); + } + + if (frame.hitTwice() && !frame.clearAllFrame()) { + return FrameNumber.plus(frameNumber); } if (frame.clearAllFrame()) { @@ -36,8 +47,4 @@ public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { } return frameNumber; } - - public List getFrames() { - return frames; - } } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index c314976363..16c794bff8 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -1,37 +1,38 @@ package bowling.view; -import bowling.BowilingTerm; -import bowling.Frame; -import bowling.HitRecord; -import bowling.Username; +import bowling.*; import java.util.List; public class OutputView { - private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; private static final String FORMAT_SHAPE = " %-4s|"; + private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; - private static final int FIRST_ATTEMPT = 0; - private static final int LAST_ATTEMPT = 1; - private static final int ZERO_HIT_COUNT = 0; private static final int MAX_HIT_COUNT = 10; private OutputView() { } - public static void printScoreScreen(Username username, List frames) { + public static void printScoreScreen(Username username, Frames frames) { + List framesList = frames.getFrames(); System.out.println(BASE_SCORE_SCREEN); StringBuilder sb = new StringBuilder(); sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); - for (Frame frame : frames) { - frameScore(sb, frame); + for (int i = 0; i < framesList.size(); i++) { + String hitShape = frameScore(sb, framesList.get(i)); + if (i == framesList.size() - 1) { + sb.append(String.format(BONUS_SHAPE, hitShape)); + continue; + } + sb.append(String.format(FORMAT_SHAPE, hitShape)); } System.out.println(sb); System.out.println(); } - private static void frameScore(StringBuilder sb, Frame frame) { + private static String frameScore(StringBuilder sb, Frame frame) { StringBuilder hitBuilder = new StringBuilder(); List hitRecords = frame.getHitRecords(); @@ -39,7 +40,7 @@ private static void frameScore(StringBuilder sb, Frame frame) { for (int index = 0; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); hitCount += hitRecord.getHitCount(); - if (index == 1) { + if (index != 0) { hitBuilder.append(SEPARATOR); if (hitCount == MAX_HIT_COUNT) { hitBuilder.append(BowilingTerm.SPARE.shape()); @@ -47,7 +48,7 @@ private static void frameScore(StringBuilder sb, Frame frame) { } } - if (index == 0 && hitRecord.hitAll()) { + if (index != 1 && hitRecord.hitAll()) { hitBuilder.append(BowilingTerm.STRIKE.shape()); continue; } @@ -58,6 +59,6 @@ private static void frameScore(StringBuilder sb, Frame frame) { } hitBuilder.append(hitRecord.getHitCount()); } - sb.append(String.format(FORMAT_SHAPE, hitBuilder)); + return hitBuilder.toString(); } } diff --git a/src/test/java/bowling/BowlingScoreRecordTest.java b/src/test/java/bowling/BowlingScoreRecordTest.java index 89e709b8cc..ca12a198f6 100644 --- a/src/test/java/bowling/BowlingScoreRecordTest.java +++ b/src/test/java/bowling/BowlingScoreRecordTest.java @@ -3,37 +3,35 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class BowlingScoreRecordTest { @Test void hitMiss() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 5); - Assertions.assertThat(frameNumber).isEqualTo(0); + BowlingGame bowlingScoreRecord = new BowlingGame(); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.first()); } @Test void hitStrike() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 10); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall( 10); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } @Test void hitSpare() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 5); - frameNumber = bowlingScoreRecord.hit(frameNumber, 5); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + bowlingScoreRecord.pitchingBall(5); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(5); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } @Test void hitGutterTwice() { - BowlingScoreRecord bowlingScoreRecord = new BowlingScoreRecord(); - int frameNumber = bowlingScoreRecord.hit(0, 0); - frameNumber = bowlingScoreRecord.hit(frameNumber, 0); - Assertions.assertThat(frameNumber).isEqualTo(1); + BowlingGame bowlingScoreRecord = new BowlingGame(); + bowlingScoreRecord.pitchingBall(0); + FrameNumber frameNumber = bowlingScoreRecord.pitchingBall(0); + Assertions.assertThat(frameNumber).isEqualTo(FrameNumber.number(2)); } } \ No newline at end of file diff --git a/src/test/java/bowling/FrameTest.java b/src/test/java/bowling/FrameTest.java index 917210a074..dc480e3519 100644 --- a/src/test/java/bowling/FrameTest.java +++ b/src/test/java/bowling/FrameTest.java @@ -11,14 +11,15 @@ class FrameTest { @Test void hitAllBowlingPins() { Frame frame = new Frame(); - assertThat(frame.hitBowlingPin(3)).isFalse(); - assertThat(frame.hitBowlingPin(7)).isTrue(); + frame.hitBowlingPin(3); + assertThat(frame.finishFrame()).isFalse(); } @Test void hitTwice() { Frame frame = new Frame(); - assertThat(frame.hitBowlingPin(3)).isFalse(); - assertThat(frame.hitBowlingPin(3)).isTrue(); + frame.hitBowlingPin(3); + frame.hitBowlingPin(5); + assertThat(frame.finishFrame()).isTrue(); } } \ No newline at end of file From 0fa9b912babe205c2b838a6b4d925d0fdf913448 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:02:09 +0900 Subject: [PATCH 26/39] =?UTF-8?q?refactor=20:=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=20=EB=B3=B4=EB=84=88=EC=8A=A4=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20=EB=A1=9C=EC=A7=81=20frame=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 14 +++++++++----- src/main/java/bowling/Frames.java | 10 +--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index b753f96ccb..812f8fc401 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -15,6 +15,14 @@ public Frame() { hitRecords = new ArrayList<>(); } + public boolean finishLastFrame() { + return hitThreeTimes() || hitDouble() || failedBounsFrame(); + } + + private boolean failedBounsFrame() { + return hitTwice() && !clearAllFrame(); + } + public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); hitRecords.add(new HitRecord(count)); @@ -36,10 +44,6 @@ public boolean hitDouble() { return true; } - public boolean spare() { - return hitRecords.size() == HIT_TWICE && clearAllFrame(); - } - public void chargeBowlingPin() { bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); } @@ -52,7 +56,7 @@ public boolean clearAllFrame() { return bowlingPin.isZero(); } - public boolean hitTriple() { + public boolean hitThreeTimes() { return hitRecords.size() == HIT_TRIPLE; } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 6ae561694c..66241b4a28 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -29,15 +29,7 @@ public List getFrames() { public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); - if (frame.hitTriple()) { - return FrameNumber.plus(frameNumber); - } - - if (frame.hitDouble()) { - return FrameNumber.plus(frameNumber); - } - - if (frame.hitTwice() && !frame.clearAllFrame()) { + if (frame.finishLastFrame()) { return FrameNumber.plus(frameNumber); } From 1b7adc391037ffab59fd9ca85ec356b97036dfc4 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:02:54 +0900 Subject: [PATCH 27/39] =?UTF-8?q?refactor=20:=20plus=20->=20next=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/FrameNumber.java | 2 +- src/main/java/bowling/Frames.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java index 262bf52af8..10aff795a2 100644 --- a/src/main/java/bowling/FrameNumber.java +++ b/src/main/java/bowling/FrameNumber.java @@ -14,7 +14,7 @@ public static FrameNumber number(int number) { return new FrameNumber(number); } - public static FrameNumber plus(FrameNumber frameNumber) { + public static FrameNumber next(FrameNumber frameNumber) { return new FrameNumber(frameNumber.frameNumber + 1); } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 66241b4a28..4fe651410e 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -17,7 +17,7 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishFrame()) { - return FrameNumber.plus(frameNumber); + return FrameNumber.next(frameNumber); } return frameNumber; } @@ -30,7 +30,7 @@ public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishLastFrame()) { - return FrameNumber.plus(frameNumber); + return FrameNumber.next(frameNumber); } if (frame.clearAllFrame()) { From 93a9a5d99a1e4d7dc2fd120d490c9fa302b7ea88 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:22:33 +0900 Subject: [PATCH 28/39] =?UTF-8?q?feat=20:=20frames=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 현재 프레임의 위치와 Frame의 볼링을 친 갯수에 따라 다음 프레임 진행여부를 판단함 --- src/main/java/bowling/FrameNumber.java | 4 ++-- src/main/java/bowling/Frames.java | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/bowling/FrameNumber.java b/src/main/java/bowling/FrameNumber.java index 10aff795a2..30e2e4c8df 100644 --- a/src/main/java/bowling/FrameNumber.java +++ b/src/main/java/bowling/FrameNumber.java @@ -14,8 +14,8 @@ public static FrameNumber number(int number) { return new FrameNumber(number); } - public static FrameNumber next(FrameNumber frameNumber) { - return new FrameNumber(frameNumber.frameNumber + 1); + public FrameNumber next() { + return new FrameNumber(this.frameNumber + 1); } private FrameNumber(int frameNumber) { diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 4fe651410e..370f03eb0f 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -17,20 +17,17 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishFrame()) { - return FrameNumber.next(frameNumber); + return frameNumber.next(); } return frameNumber; } - public List getFrames() { - return frames; - } public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); if (frame.finishLastFrame()) { - return FrameNumber.next(frameNumber); + return frameNumber.next(); } if (frame.clearAllFrame()) { @@ -39,4 +36,8 @@ public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { } return frameNumber; } + + public List getFrames() { + return frames; + } } From 2ef1e8fe89fa46495fa84a8885c4c1848ecd935b Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 01:30:18 +0900 Subject: [PATCH 29/39] =?UTF-8?q?refactor=20:=20=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/view/OutputView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index 16c794bff8..a48a1627ff 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -21,7 +21,9 @@ public static void printScoreScreen(Username username, Frames frames) { StringBuilder sb = new StringBuilder(); sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); for (int i = 0; i < framesList.size(); i++) { - String hitShape = frameScore(sb, framesList.get(i)); + Frame frame = framesList.get(i); + String hitShape = frameScore(frame.getHitRecords()); + if (i == framesList.size() - 1) { sb.append(String.format(BONUS_SHAPE, hitShape)); continue; @@ -32,10 +34,8 @@ public static void printScoreScreen(Username username, Frames frames) { System.out.println(); } - private static String frameScore(StringBuilder sb, Frame frame) { + private static String frameScore(List hitRecords) { StringBuilder hitBuilder = new StringBuilder(); - List hitRecords = frame.getHitRecords(); - int hitCount = 0; for (int index = 0; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); From 793292bc1544dee19474f22dc0e137e3732201ea Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 02:45:47 +0900 Subject: [PATCH 30/39] =?UTF-8?q?refactor=20:=20OutputView=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HitRecord에 각 투구 당시의 상황에 따른 볼링친 갯수와 그에따른 볼링용어를 기록하도록 함 --- src/main/java/bowling/Frame.java | 15 +++++- src/main/java/bowling/HitRecord.java | 8 ++- src/main/java/bowling/view/OutputView.java | 61 ++++++++++------------ src/main/java/bowling/view/ScoreShape.java | 5 -- 4 files changed, 50 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/bowling/view/ScoreShape.java diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 812f8fc401..08a25003ce 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -4,6 +4,7 @@ import java.util.List; public class Frame { + private static final int HIT_ONCE = 1; private static final int HIT_TWICE = 2; private static final int HIT_TRIPLE = 3; @@ -25,7 +26,19 @@ private boolean failedBounsFrame() { public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - hitRecords.add(new HitRecord(count)); + BowilingTerm bowilingTerm = BowilingTerm.MISS; + if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE) && bowlingPin.isZero()) { + bowilingTerm = BowilingTerm.STRIKE; + } + + if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { + bowilingTerm = BowilingTerm.SPARE; + } + + if (count == 0) { + bowilingTerm = BowilingTerm.GUTTER; + } + hitRecords.add(new HitRecord(count, bowilingTerm)); } public boolean finishFrame() { diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 3ff0fc7e07..7ad28a0828 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -2,15 +2,21 @@ public class HitRecord { private final int hitCount; + private final BowilingTerm bowilingTerm; - public HitRecord(int count) { + public HitRecord(int count, BowilingTerm bowilingTerm) { this.hitCount = count; + this.bowilingTerm = bowilingTerm; } public int getHitCount() { return hitCount; } + public BowilingTerm getBowilingTerm() { + return bowilingTerm; + } + public boolean hitAll() { return hitCount == BowlingPin.MAX_PIN_NUMBER; } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index a48a1627ff..f91d18e8e6 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -9,56 +9,53 @@ public class OutputView { private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; - private static final int MAX_HIT_COUNT = 10; private OutputView() { } public static void printScoreScreen(Username username, Frames frames) { - List framesList = frames.getFrames(); System.out.println(BASE_SCORE_SCREEN); + StringBuilder sb = new StringBuilder(); - sb.append(String.format("|" + FORMAT_SHAPE, username.getName())); - for (int i = 0; i < framesList.size(); i++) { - Frame frame = framesList.get(i); - String hitShape = frameScore(frame.getHitRecords()); + sb.append(makeUserFormat(username)); - if (i == framesList.size() - 1) { - sb.append(String.format(BONUS_SHAPE, hitShape)); - continue; - } + List framesList = frames.getFrames(); + String hitShape = ""; + for (int i = 0; i < framesList.size() - 1; i++) { + Frame frame = framesList.get(i); + hitShape = makeFrameScoreShape(frame.getHitRecords()); sb.append(String.format(FORMAT_SHAPE, hitShape)); } + sb.append(String.format(BONUS_SHAPE, hitShape)); + + sb.append("\n"); System.out.println(sb); - System.out.println(); } - private static String frameScore(List hitRecords) { + private static String makeUserFormat(Username username) { + return String.format(SEPARATOR + FORMAT_SHAPE, username.getName()); + } + + private static String makeFrameScoreShape(List hitRecords) { StringBuilder hitBuilder = new StringBuilder(); - int hitCount = 0; - for (int index = 0; index < hitRecords.size(); index++) { + HitRecord hitRecordFirst = hitRecords.get(0); + hitBuilder.append(retrieveHitShape(hitRecordFirst)); + + for (int index = 1; index < hitRecords.size(); index++) { HitRecord hitRecord = hitRecords.get(index); - hitCount += hitRecord.getHitCount(); - if (index != 0) { - hitBuilder.append(SEPARATOR); - if (hitCount == MAX_HIT_COUNT) { - hitBuilder.append(BowilingTerm.SPARE.shape()); - continue; - } - } + hitBuilder.append(SEPARATOR); + hitBuilder.append(retrieveHitShape(hitRecord)); + } - if (index != 1 && hitRecord.hitAll()) { - hitBuilder.append(BowilingTerm.STRIKE.shape()); - continue; - } + return hitBuilder.toString(); + } - if (hitRecord.hitZero()) { - hitBuilder.append(BowilingTerm.GUTTER.shape()); - continue; - } - hitBuilder.append(hitRecord.getHitCount()); + private static String retrieveHitShape(HitRecord hitRecord) { + BowilingTerm bowilingTerm = hitRecord.getBowilingTerm(); + if (bowilingTerm.equals(BowilingTerm.MISS)) { + return String.valueOf(hitRecord.getHitCount()); } - return hitBuilder.toString(); + return bowilingTerm.shape(); } } diff --git a/src/main/java/bowling/view/ScoreShape.java b/src/main/java/bowling/view/ScoreShape.java deleted file mode 100644 index 929c1dae6d..0000000000 --- a/src/main/java/bowling/view/ScoreShape.java +++ /dev/null @@ -1,5 +0,0 @@ -package bowling.view; - -public class ScoreShape { - -} From 94be0c5cacf249f098880c08ab698505179a713d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 03:14:29 +0900 Subject: [PATCH 31/39] =?UTF-8?q?refactor=20:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20Scanner=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index 0c3a12e854..dfe4c49525 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -7,8 +7,6 @@ public class App { public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - Username username = InputView.playerName(); BowlingGame bowlingGame = new BowlingGame(); From 5e8d2e32f188e8f78a9edfa085ba09af5a424bff Mon Sep 17 00:00:00 2001 From: yunhwan Date: Sun, 13 Nov 2022 03:15:11 +0900 Subject: [PATCH 32/39] =?UTF-8?q?refactor=20:=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=A4=91=EB=B3=B5=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=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/bowling/Frame.java | 24 +++++++++++++++------- src/main/java/bowling/view/OutputView.java | 11 +++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 08a25003ce..170d15514f 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -27,20 +27,35 @@ private boolean failedBounsFrame() { public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); BowilingTerm bowilingTerm = BowilingTerm.MISS; - if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE) && bowlingPin.isZero()) { + if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE || hitStrike()) && bowlingPin.isZero()) { bowilingTerm = BowilingTerm.STRIKE; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { bowilingTerm = BowilingTerm.SPARE; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } if (count == 0) { bowilingTerm = BowilingTerm.GUTTER; + hitRecords.add(new HitRecord(count, bowilingTerm)); + return ; } hitRecords.add(new HitRecord(count, bowilingTerm)); } + private boolean hitStrike() { + for (HitRecord hitRecord : hitRecords) { + if (!hitRecord.hitAll()) { + return false; + } + } + return true; + } + public boolean finishFrame() { return clearAllFrame() || hitTwice(); } @@ -49,12 +64,7 @@ public boolean hitDouble() { if (hitRecords.size() != HIT_TWICE) { return false; } - for (HitRecord hitRecord : hitRecords) { - if (!hitRecord.hitAll()) { - return false; - } - } - return true; + return hitStrike(); } public void chargeBowlingPin() { diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index f91d18e8e6..3100d9511d 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -9,6 +9,7 @@ public class OutputView { private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; + private static final String BLANK = ""; private OutputView() { } @@ -21,13 +22,13 @@ public static void printScoreScreen(Username username, Frames frames) { sb.append(makeUserFormat(username)); List framesList = frames.getFrames(); - String hitShape = ""; for (int i = 0; i < framesList.size() - 1; i++) { Frame frame = framesList.get(i); - hitShape = makeFrameScoreShape(frame.getHitRecords()); + String hitShape = makeFrameScoreShape(frame.getHitRecords()); sb.append(String.format(FORMAT_SHAPE, hitShape)); } - sb.append(String.format(BONUS_SHAPE, hitShape)); + Frame lastFrame = framesList.get(framesList.size() - 1); + sb.append(String.format(BONUS_SHAPE, makeFrameScoreShape(lastFrame.getHitRecords()))); sb.append("\n"); System.out.println(sb); @@ -38,6 +39,10 @@ private static String makeUserFormat(Username username) { } private static String makeFrameScoreShape(List hitRecords) { + if (hitRecords.isEmpty()) { + return BLANK; + } + StringBuilder hitBuilder = new StringBuilder(); HitRecord hitRecordFirst = hitRecords.get(0); hitBuilder.append(retrieveHitShape(hitRecordFirst)); From 6812ccb3ed1ee50087759f1c936daf3d4b9a2402 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:36:07 +0900 Subject: [PATCH 33/39] =?UTF-8?q?refactor=20:=20FinalFrame=EC=9D=B4=20Fram?= =?UTF-8?q?e=EC=9D=84=20=EC=83=81=EC=86=8D=EB=B0=9B=EC=95=84=20=EC=83=81?= =?UTF-8?q?=EC=9D=B4=ED=95=9C=20=EC=A1=B0=EA=B1=B4=20=EB=B6=80=EB=B6=84?= =?UTF-8?q?=EC=9D=84=20=EC=98=A4=EB=B2=84=EB=9D=BC=EC=9D=B4=EB=94=A9=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/FinalFrame.java | 22 +++++++++ src/main/java/bowling/Frame.java | 68 +++++++-------------------- src/main/java/bowling/HitRecord.java | 4 ++ src/main/java/bowling/HitRecords.java | 45 +++++++++++++++++- 4 files changed, 86 insertions(+), 53 deletions(-) create mode 100644 src/main/java/bowling/FinalFrame.java diff --git a/src/main/java/bowling/FinalFrame.java b/src/main/java/bowling/FinalFrame.java new file mode 100644 index 0000000000..b610907bd6 --- /dev/null +++ b/src/main/java/bowling/FinalFrame.java @@ -0,0 +1,22 @@ +package bowling; + +public class FinalFrame extends Frame { + + @Override + public boolean strikeCondition() { + return (!hitRecords.hitTimes(HIT_TWICE) || hitRecords.isRecordAllStrike()) && bowlingPin.isZero(); + } + + @Override + public boolean finishFrame() { + boolean result = hitRecords.hitTimes(HIT_TRIPLE) || failedBounsFrame(); + if (clearAllFrame()) { + chargeBowlingPin(); + } + return result; + } + + private boolean failedBounsFrame() { + return hitRecords.hitTimes(HIT_TWICE) && !clearAllFrame(); + } +} diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 170d15514f..5084fa6414 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -1,70 +1,44 @@ package bowling; -import java.util.ArrayList; import java.util.List; public class Frame { - private static final int HIT_ONCE = 1; - private static final int HIT_TWICE = 2; - private static final int HIT_TRIPLE = 3; + protected static final int HIT_TWICE = 2; + protected static final int HIT_TRIPLE = 3; - private BowlingPin bowlingPin; - private final List hitRecords; + protected BowlingPin bowlingPin; + protected final HitRecords hitRecords; public Frame() { this.bowlingPin = new BowlingPin(BowlingPin.MAX_PIN_NUMBER); - hitRecords = new ArrayList<>(); - } - - public boolean finishLastFrame() { - return hitThreeTimes() || hitDouble() || failedBounsFrame(); - } - - private boolean failedBounsFrame() { - return hitTwice() && !clearAllFrame(); + this.hitRecords = new HitRecords(); } public void hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - BowilingTerm bowilingTerm = BowilingTerm.MISS; - if ((hitRecords.isEmpty() || hitRecords.size() == HIT_TRIPLE || hitStrike()) && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.STRIKE; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (strikeCondition()) { + hitRecords.addStrike(); return ; } - if (hitRecords.size() == HIT_ONCE && bowlingPin.isZero()) { - bowilingTerm = BowilingTerm.SPARE; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (hitRecords.hitOnce() && bowlingPin.isZero()) { + hitRecords.addSpare(); return ; } - if (count == 0) { - bowilingTerm = BowilingTerm.GUTTER; - hitRecords.add(new HitRecord(count, bowilingTerm)); + if (count == BowlingPin.ZERO) { + hitRecords.addGutter(); return ; } - hitRecords.add(new HitRecord(count, bowilingTerm)); - } - - private boolean hitStrike() { - for (HitRecord hitRecord : hitRecords) { - if (!hitRecord.hitAll()) { - return false; - } - } - return true; + hitRecords.addMiss(count); } - public boolean finishFrame() { - return clearAllFrame() || hitTwice(); + protected boolean strikeCondition() { + return bowlingPin.isZero(); } - public boolean hitDouble() { - if (hitRecords.size() != HIT_TWICE) { - return false; - } - return hitStrike(); + protected boolean finishFrame() { + return clearAllFrame() || hitRecords.hitTimes(HIT_TWICE); } public void chargeBowlingPin() { @@ -72,18 +46,10 @@ public void chargeBowlingPin() { } public List getHitRecords() { - return hitRecords; + return hitRecords.getHitRecords(); } public boolean clearAllFrame() { return bowlingPin.isZero(); } - - public boolean hitThreeTimes() { - return hitRecords.size() == HIT_TRIPLE; - } - - public boolean hitTwice() { - return hitRecords.size() == HIT_TWICE; - } } diff --git a/src/main/java/bowling/HitRecord.java b/src/main/java/bowling/HitRecord.java index 7ad28a0828..45f8d77f2e 100644 --- a/src/main/java/bowling/HitRecord.java +++ b/src/main/java/bowling/HitRecord.java @@ -4,6 +4,10 @@ public class HitRecord { private final int hitCount; private final BowilingTerm bowilingTerm; + public static HitRecord of(int count, BowilingTerm bowilingTerm) { + return new HitRecord(count, bowilingTerm); + } + public HitRecord(int count, BowilingTerm bowilingTerm) { this.hitCount = count; this.bowilingTerm = bowilingTerm; diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index 2cc56a20f2..4e336c4031 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -1,11 +1,52 @@ package bowling; +import java.util.ArrayList; import java.util.List; public class HitRecords { + private static final int HIT_ONCE = 1; + private List hitRecords; - public HitRecords(List hitRecords) { - this.hitRecords = hitRecords; + public HitRecords() { + this.hitRecords = new ArrayList<>(); + } + + public boolean hitOnce() { + return hitRecords.size() == HIT_ONCE; + } + + + public void addRecord(HitRecord hitRecord) { + this.hitRecords.add(hitRecord); + } + + public void addStrike() { + this.hitRecords.add(HitRecord.of(10, BowilingTerm.STRIKE)); + } + + public void addSpare() { + this.hitRecords.add(HitRecord.of(10, BowilingTerm.SPARE)); + } + + public void addGutter() { + this.hitRecords.add(HitRecord.of(0, BowilingTerm.GUTTER)); + } + + public void addMiss(int count) { + this.hitRecords.add(HitRecord.of(count, BowilingTerm.MISS)); + } + + public boolean isRecordAllStrike() { + return hitRecords.stream() + .allMatch(HitRecord::hitAll); + } + + public boolean hitTimes(int hitTwice) { + return hitRecords.size() == hitTwice; + } + + public List getHitRecords() { + return hitRecords; } } From 1e39ba18dc4161d5f6dd440b5fa7a353a8255527 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:38:28 +0900 Subject: [PATCH 34/39] =?UTF-8?q?refactor=20:=20=EB=8B=A4=ED=98=95?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20Frame?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A7=8C=EC=9C=BC=EB=A1=9C=20=EC=9D=BC?= =?UTF-8?q?=EB=B0=98=ED=94=84=EB=A0=88=EC=9E=84=EA=B3=BC=20=EB=A7=88?= =?UTF-8?q?=EC=A7=80=EB=A7=89=ED=94=84=EB=A0=88=EC=9E=84=20=EC=88=98?= =?UTF-8?q?=ED=96=89=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=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 BowlingGame과 Frames는 어떤 프레임인지 모르고 실행해도 실객체에 따라 알아서 스트라이크 조건과 프레임완료조건이 다르게 실행됨. --- src/main/java/bowling/BowlingGame.java | 3 --- src/main/java/bowling/Frames.java | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/bowling/BowlingGame.java b/src/main/java/bowling/BowlingGame.java index 1e3818b8f2..413cb5b68a 100644 --- a/src/main/java/bowling/BowlingGame.java +++ b/src/main/java/bowling/BowlingGame.java @@ -11,9 +11,6 @@ public BowlingGame() { } public FrameNumber pitchingBall(int hitCount) { - if (frameNumber.isSameNumber(FRAME_SIZE)) { - return frames.pitchingLast(frameNumber, hitCount); - } this.frameNumber = frames.pitching(frameNumber, hitCount); return this.frameNumber; } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index 370f03eb0f..ad3a9a8eee 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -8,9 +8,10 @@ public class Frames { public Frames(int size) { this.frames = new ArrayList<>(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < size - 1; i++) { this.frames.add(new Frame()); } + this.frames.add(new FinalFrame()); } public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { @@ -26,9 +27,6 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); frame.hitBowlingPin(hitCount); - if (frame.finishLastFrame()) { - return frameNumber.next(); - } if (frame.clearAllFrame()) { frame.chargeBowlingPin(); From 6f4a592327c55278f7e6dbb13842215ec8272c8d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:44:25 +0900 Subject: [PATCH 35/39] =?UTF-8?q?refactor=20:=20=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=ED=95=84=EB=93=9C=EA=B0=92=EC=97=90=20final=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 --- src/main/java/bowling/HitRecords.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index 4e336c4031..a46f0d45d8 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -6,7 +6,7 @@ public class HitRecords { private static final int HIT_ONCE = 1; - private List hitRecords; + private final List hitRecords; public HitRecords() { this.hitRecords = new ArrayList<>(); From 011e1a09dc5586a1196b1e47fc7fb4c60e1f3d22 Mon Sep 17 00:00:00 2001 From: yunhwan Date: Tue, 15 Nov 2022 23:44:47 +0900 Subject: [PATCH 36/39] =?UTF-8?q?refactor=20:=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=ED=94=84=EB=A0=88=EC=9E=84=EC=9D=98=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=B8=20pitchingLast=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frames.java | 11 ----------- src/test/java/bowling/FramesTest.java | 28 ++++++++------------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index ad3a9a8eee..b81c5055ca 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -24,17 +24,6 @@ public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { } - public FrameNumber pitchingLast(FrameNumber frameNumber, int hitCount) { - Frame frame = frames.get(frameNumber.retrieveIndexNumber()); - frame.hitBowlingPin(hitCount); - - if (frame.clearAllFrame()) { - frame.chargeBowlingPin(); - return frameNumber; - } - return frameNumber; - } - public List getFrames() { return frames; } diff --git a/src/test/java/bowling/FramesTest.java b/src/test/java/bowling/FramesTest.java index 969f84ef71..eaca8713db 100644 --- a/src/test/java/bowling/FramesTest.java +++ b/src/test/java/bowling/FramesTest.java @@ -1,11 +1,9 @@ package bowling; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; class FramesTest { @@ -42,27 +40,17 @@ void pitchingStrike() { void lastPitching() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); } - @Test - @DisplayName("마지막 프레임의 스트라이크의 두번째 스트라이크는 프레임이 변함") - void lastPitchingDouble() { - int lastNumber = 10; - Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), BowlingPin.MAX_PIN_NUMBER); - assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); - } - @Test @DisplayName("마지막 프레임의 스페어는 프레임이 변하지 않음") void lastPitchingSpare() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 5); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 5); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber)); } @@ -71,8 +59,8 @@ void lastPitchingSpare() { void lastFrameMiss() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 4); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 4); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); } @@ -81,9 +69,9 @@ void lastFrameMiss() { void lastFramePitchingThreeTimes() { int lastNumber = 10; Frames frames = new Frames(lastNumber); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - frames.pitchingLast(FrameNumber.number(lastNumber), 5); - FrameNumber frameNumber = frames.pitchingLast(FrameNumber.number(lastNumber), 10); + frames.pitching(FrameNumber.number(lastNumber), 5); + frames.pitching(FrameNumber.number(lastNumber), 5); + FrameNumber frameNumber = frames.pitching(FrameNumber.number(lastNumber), 10); assertThat(frameNumber).isEqualTo(FrameNumber.number(lastNumber).next()); } } \ No newline at end of file From 0f996a81f81152d40ef288175106ecdf48a7301d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:33:32 +0900 Subject: [PATCH 37/39] =?UTF-8?q?refactor=20:=20score=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Score.java | 47 +++++++++++++++++++++++++++++++ src/main/java/bowling/Scores.java | 12 ++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/bowling/Score.java create mode 100644 src/main/java/bowling/Scores.java diff --git a/src/main/java/bowling/Score.java b/src/main/java/bowling/Score.java new file mode 100644 index 0000000000..2a68ef73d4 --- /dev/null +++ b/src/main/java/bowling/Score.java @@ -0,0 +1,47 @@ +package bowling; + +public class Score { + private final int hitCount; + private final int bonusCount; + + public static Score ofZero() { + return new Score(0, -1); + } + + public static Score ofStrike() { + return new Score(10, 2); + } + + public static Score ofSpare() { + return new Score(10, 1); + } + + public static Score ofMiss(int hitCount) { + return new Score(hitCount, 0); + } + + private Score(int hitCount, int bonusCount) { + this.hitCount = hitCount; + this.bonusCount = bonusCount; + } + + public boolean remainBonus() { + return bonusCount != 0; + } + + public Score addBonusScore(int hitCount) { + return new Score(this.hitCount + hitCount, bonusCount - 1); + } + + public int getHitCount() { + return hitCount; + } + + public int getBonusCount() { + return bonusCount; + } + + public boolean isMiss() { + return hitCount != 10; + } +} diff --git a/src/main/java/bowling/Scores.java b/src/main/java/bowling/Scores.java new file mode 100644 index 0000000000..ac0d1b86e0 --- /dev/null +++ b/src/main/java/bowling/Scores.java @@ -0,0 +1,12 @@ +package bowling; + +import java.util.ArrayList; +import java.util.List; + +public class Scores { + private final List scores; + + public Scores() { + this.scores = new ArrayList<>(); + } +} From 7ef92d9300e1030f9d9783cb019cd1a2fc90096d Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:33:57 +0900 Subject: [PATCH 38/39] =?UTF-8?q?refactor=20:=20score=EB=A5=BC=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EA=B3=A0=20miss=EA=B0=80=20=EB=82=AC?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=A0=90=EC=88=98=EB=A5=BC=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/Frame.java | 25 +++++++++++++++++-------- src/main/java/bowling/Frames.java | 18 ++++++++++++++---- src/main/java/bowling/HitRecords.java | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/bowling/Frame.java b/src/main/java/bowling/Frame.java index 5084fa6414..bbb22ea62f 100644 --- a/src/main/java/bowling/Frame.java +++ b/src/main/java/bowling/Frame.java @@ -14,23 +14,24 @@ public Frame() { this.hitRecords = new HitRecords(); } - public void hitBowlingPin(int count) { + public BowilingTerm hitBowlingPin(int count) { bowlingPin = bowlingPin.hitPins(new BowlingPin(count)); - if (strikeCondition()) { - hitRecords.addStrike(); - return ; - } - if (hitRecords.hitOnce() && bowlingPin.isZero()) { hitRecords.addSpare(); - return ; + return BowilingTerm.SPARE; + } + + if (strikeCondition()) { + hitRecords.addStrike(); + return BowilingTerm.STRIKE; } if (count == BowlingPin.ZERO) { hitRecords.addGutter(); - return ; + return BowilingTerm.GUTTER; } hitRecords.addMiss(count); + return BowilingTerm.MISS; } protected boolean strikeCondition() { @@ -52,4 +53,12 @@ public List getHitRecords() { public boolean clearAllFrame() { return bowlingPin.isZero(); } + + public void calculateBonus(int hitCount) { + hitRecords.calculateBonus(hitCount); + } + + public HitRecords hitRecords() { + return hitRecords; + } } diff --git a/src/main/java/bowling/Frames.java b/src/main/java/bowling/Frames.java index b81c5055ca..9169ac1444 100644 --- a/src/main/java/bowling/Frames.java +++ b/src/main/java/bowling/Frames.java @@ -1,13 +1,15 @@ package bowling; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; public class Frames { - private final List frames; + private final LinkedList frames; public Frames(int size) { - this.frames = new ArrayList<>(); + this.frames = new LinkedList<>(); for (int i = 0; i < size - 1; i++) { this.frames.add(new Frame()); } @@ -16,14 +18,22 @@ public Frames(int size) { public FrameNumber pitching(FrameNumber frameNumber, int hitCount) { Frame frame = frames.get(frameNumber.retrieveIndexNumber()); - frame.hitBowlingPin(hitCount); + BowilingTerm bowilingTerm = frame.hitBowlingPin(hitCount); + + if (!bowilingTerm.equals(BowilingTerm.STRIKE)) { + ListIterator frameListIterator = frames.listIterator(frameNumber.retrieveIndexNumber()); + while (frameListIterator.hasPrevious()) { + Frame previous = frameListIterator.previous(); + previous.calculateBonus(hitCount); + } + } + if (frame.finishFrame()) { return frameNumber.next(); } return frameNumber; } - public List getFrames() { return frames; } diff --git a/src/main/java/bowling/HitRecords.java b/src/main/java/bowling/HitRecords.java index a46f0d45d8..7c1874ac15 100644 --- a/src/main/java/bowling/HitRecords.java +++ b/src/main/java/bowling/HitRecords.java @@ -7,9 +7,11 @@ public class HitRecords { private static final int HIT_ONCE = 1; private final List hitRecords; + private Score score; public HitRecords() { this.hitRecords = new ArrayList<>(); + this.score = Score.ofZero(); } public boolean hitOnce() { @@ -23,18 +25,22 @@ public void addRecord(HitRecord hitRecord) { public void addStrike() { this.hitRecords.add(HitRecord.of(10, BowilingTerm.STRIKE)); + score = Score.ofStrike(); } public void addSpare() { this.hitRecords.add(HitRecord.of(10, BowilingTerm.SPARE)); + score = Score.ofSpare(); } public void addGutter() { this.hitRecords.add(HitRecord.of(0, BowilingTerm.GUTTER)); + score = Score.ofMiss(hitSum()); } public void addMiss(int count) { this.hitRecords.add(HitRecord.of(count, BowilingTerm.MISS)); + score = Score.ofMiss(hitSum()); } public boolean isRecordAllStrike() { @@ -49,4 +55,18 @@ public boolean hitTimes(int hitTwice) { public List getHitRecords() { return hitRecords; } + + private int hitSum() { + return hitRecords.stream().mapToInt(HitRecord::getHitCount).sum(); + } + + public void calculateBonus(int hitCount) { + if (score.remainBonus()) { + score = score.addBonusScore(hitCount); + } + } + + public Score getScore() { + return score; + } } From 443d2f31a148ae8d1db850510f5bf0642520b71a Mon Sep 17 00:00:00 2001 From: yunhwan Date: Thu, 17 Nov 2022 02:34:10 +0900 Subject: [PATCH 39/39] =?UTF-8?q?feat=20:=20=EC=A0=90=EC=88=98=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/bowling/App.java | 2 +- src/main/java/bowling/BowlingGame.java | 4 +++ src/main/java/bowling/view/OutputView.java | 32 +++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main/java/bowling/App.java b/src/main/java/bowling/App.java index dfe4c49525..2783e33e19 100644 --- a/src/main/java/bowling/App.java +++ b/src/main/java/bowling/App.java @@ -17,7 +17,7 @@ public static void main(String[] args) { frameNumber = bowlingGame.pitchingBall(count); Frames frames = bowlingGame.getFrames(); - OutputView.printScoreScreen(username, frames); + OutputView.printScoreScreen(username, frames, bowlingGame); } } } diff --git a/src/main/java/bowling/BowlingGame.java b/src/main/java/bowling/BowlingGame.java index 413cb5b68a..83340205f9 100644 --- a/src/main/java/bowling/BowlingGame.java +++ b/src/main/java/bowling/BowlingGame.java @@ -18,4 +18,8 @@ public FrameNumber pitchingBall(int hitCount) { public Frames getFrames() { return frames; } + + public FrameNumber getFrameNumber() { + return frameNumber; + } } diff --git a/src/main/java/bowling/view/OutputView.java b/src/main/java/bowling/view/OutputView.java index 3100d9511d..6c8ce7af8f 100644 --- a/src/main/java/bowling/view/OutputView.java +++ b/src/main/java/bowling/view/OutputView.java @@ -6,6 +6,7 @@ public class OutputView { private static final String BASE_SCORE_SCREEN = "| NAME | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |"; + private static final String START_SHAPE = "| |"; private static final String FORMAT_SHAPE = " %-4s|"; private static final String BONUS_SHAPE = " %-6s|"; private static final String SEPARATOR = "|"; @@ -15,7 +16,7 @@ private OutputView() { } - public static void printScoreScreen(Username username, Frames frames) { + public static void printScoreScreen(Username username, Frames frames, BowlingGame bowlingGame) { System.out.println(BASE_SCORE_SCREEN); StringBuilder sb = new StringBuilder(); @@ -29,11 +30,40 @@ public static void printScoreScreen(Username username, Frames frames) { } Frame lastFrame = framesList.get(framesList.size() - 1); sb.append(String.format(BONUS_SHAPE, makeFrameScoreShape(lastFrame.getHitRecords()))); + sb.append("\n"); + int totalScore = 0; + sb.append(START_SHAPE); + for (int i = 0; i < framesList.size() - 1; i++) { + Frame frame = framesList.get(i); + FrameNumber frameNumber = bowlingGame.getFrameNumber(); + String score = makeFrameScore(i, frame.hitRecords(), frameNumber, totalScore); + if (!score.equals("")) { + totalScore += Integer.parseInt(score); + score = String.valueOf(totalScore); + } + sb.append(String.format(FORMAT_SHAPE, score)); + } + FrameNumber frameNumber = bowlingGame.getFrameNumber(); + lastFrame = framesList.get(framesList.size() - 1); + String score = makeFrameScore(framesList.size() - 1, lastFrame.hitRecords(), frameNumber, totalScore); + if (!score.equals("")) { + totalScore += Integer.parseInt(score); + score = String.valueOf(totalScore); + } + sb.append(String.format(BONUS_SHAPE, score)); sb.append("\n"); System.out.println(sb); } + private static String makeFrameScore(int index, HitRecords hitRecords, FrameNumber frameNumber, int totalScore) { + Score score = hitRecords.getScore(); + if (score.remainBonus() || index + 1 >= frameNumber.getFrameNumber()) { + return ""; + } + return String.valueOf(score.getHitCount()); + } + private static String makeUserFormat(Username username) { return String.format(SEPARATOR + FORMAT_SHAPE, username.getName()); }