Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions src/main/java/BowlingMain.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
import domain.Frame;
import domain.NormalFrame;
import domain.BowlingGame;
import domain.Player;
import state.Ready;
import state.State;
import view.InputView;
import view.ResultView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class BowlingMain {
public static void main(String[] args) {
final int MAX_FRAME_NO = 10;

Scanner scanner = new Scanner(System.in);
Player player = new Player(InputView.getUserName(scanner));
List<Frame> frames = new ArrayList<>();
ResultView.printFrames(frames, player.getName());
BowlingGame bowlingGame = new BowlingGame();
List<Player> players = bowlingGame.createPlayer(Arrays.asList(InputView.getUserName(scanner)));
State currentState = new Ready();

Frame frame = new NormalFrame(1);
frames.add(frame);
for (int index = 1; index < MAX_FRAME_NO + 1; index++) {
do {
frame.throwing(InputView.getThrowing(scanner, index));
ResultView.printFrames(frames, player.getName());
} while (!frame.isEnd());
if (index != MAX_FRAME_NO) {
frame = frame.next();
frames.add(frame);
ResultView.printScoreBoard(players, currentState);
for (int index = 1; index < 11; index++) {
while (!bowlingGame.isEndFrame()) {
currentState = bowlingGame.bowl(InputView.getThrowing(scanner, index));
ResultView.printScoreBoard(players, currentState);
}
if (index < 10) {
bowlingGame.nextFrame();
}
}
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/domain/BowlingGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package domain;

import state.State;

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

public class BowlingGame {
private static final int FIRST = 1;
private List<Player> players;

public List<Player> createPlayer(List<String> names) {
players = new ArrayList<>();
for (String name : names) {
players.add(new Player(name));
}
return players;
}

public Pins createPins(int falledPins) {
return new Pins(falledPins);
}

public State bowl(int falledPins) {
return players.get(0).bowl(createPins(falledPins));
}

public boolean isEndFrame() {
// 다수 고려하지 않음, 우선 한 명만.
return players.get(0).isEnd();
}

public Frame nextFrame() {
return players.get(0).nextFrame();
}
}
17 changes: 6 additions & 11 deletions src/main/java/domain/Frame.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,24 @@

abstract public class Frame {
private static final int MAX_FRAME_NO = 10;
private final int no;

public Frame(int no) {
isValidNo(no);
this.no = no;
}

abstract public void throwing(int throwing);
abstract public State updateState(int throwing);
abstract public State bowl(Pins falledPins);
abstract public boolean isEnd();
abstract public String printState();
abstract public Score createScore(int beforeScore);
abstract public int getScore(int beforeScore);
abstract public Frame next();
abstract public boolean isLastFrame();
abstract public int calculateAdditionalScore(Score beforeScore);

public boolean isValidNo(int no) {
if ( no < 0 || no > 10 ) {
throw new RuntimeException("프레임의 번호는 0부터 10사이 입니다. 생성 시도한 프레임 번호는 " + no);
}
return true;
}

public Frame next() {
if (no == MAX_FRAME_NO - 1) {
return new LastFrame(no + 1);
}
return new NormalFrame(no + 1);
}
}
42 changes: 42 additions & 0 deletions src/main/java/domain/Frames.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package domain;

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

public class Frames {
private static final int FIRST = 1;
private static final int MAX_FRAME = 10;

private List<Frame> frames = new ArrayList<>();

public Frame createFirstFrame() {
return new NormalFrame(FIRST);
}

public boolean isEmpty() {
return frames.isEmpty();
}

public int getFinishedFrame() {
return frames.size();
}

public void add(Frame frame) {
if (frames.size() > MAX_FRAME) {
throw new RuntimeException("1경기당 최대 10프레임입니다.");
}
frames.add(frame);
}

public boolean equalsFrameCount(int frameCount) {
return frames.size() == frameCount;
}

public String printFramesState(int index) {
return frames.get(index).printState();
}

public int printFramesScore(int index, int beforeScore) {
return frames.get(index).getScore(beforeScore);
}
}
48 changes: 39 additions & 9 deletions src/main/java/domain/LastFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public LastFrame(int no) {
}

@Override
public void throwing(int throwing) {
state = updateState(throwing);
public State bowl(Pins falledPins) {
state = state.bowl(falledPins);
if (FirstBowl.isFirstBowl(state) || Strike.isStrike(state)) {
states.add(state);
return;
return state;
}
try {
states.set(index, state.clone());
Expand All @@ -33,19 +33,15 @@ public void throwing(int throwing) {
} catch (CloneNotSupportedException e) {
e.getMessage();
}
}

@Override
public State updateState(int throwing) {
return state.throwing(throwing);
return state;
}

@Override
public boolean isEnd() {
if (Open.isOpen(state) || states.size() == MAX) {
return true;
}
if (Spare.isSpare(states.get(FIRST_STATE)) && states.size() == 2) {
if (states.size() == 2 && Spare.isSpare(states.get(FIRST_STATE))) {
return true;
}
return false;
Expand All @@ -59,4 +55,38 @@ public String printState() {
}
return sb.toString();
}

@Override
public Score createScore(int beforeScore) {
return states.get(0).getScore().calculateScore(beforeScore);
}

@Override
public int getScore(int beforeScore) {
Score score = createScore(beforeScore);
if (score.canCalculateScore()) {
return score.getScore();
}
return calculateAdditionalScore(score);
}

public int calculateAdditionalScore(Score beforeScore) {
for (State state : states) {
beforeScore = state.updateScore(beforeScore);
if (beforeScore.canCalculateScore()) {
return beforeScore.getScore();
}
}
return 0;
}

@Override
public Frame next() {
throw new RuntimeException("마지막 프레임에서는 다음 프레임을 생성할 수 없습니다.");
}

@Override
public boolean isLastFrame() {
return true;
}
}
64 changes: 57 additions & 7 deletions src/main/java/domain/NormalFrame.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
package domain;

import state.*;
import state.Ready;
import state.State;

public class NormalFrame extends Frame {
private State state = new Ready();
private static final String EMPTY = "";
private static final int MAX_FRAME_NO = 10;

private final int no;
private Frame next;
private State state = new Ready(); // strike;

public NormalFrame(int no) {
super(no);
this.no = no;
}

public void throwing(int throwing) {
state = updateState(throwing);
@Override
public State bowl(Pins falledPins) {
return state = state.bowl(falledPins);
}

public State updateState(int throwing) {
return state.throwing(throwing);
@Override
public Frame next() {
if (no == MAX_FRAME_NO - 1) {
return next = new LastFrame(no + 1);
}
return next = new NormalFrame(no + 1);
}

@Override
public boolean isLastFrame() {
return false;
}

@Override
Expand All @@ -26,4 +43,37 @@ public boolean isEnd() {
public String printState() {
return state.printState();
}
}

@Override
public Score createScore(int beforeScore) {
return state.getScore().calculateScore(beforeScore);
}

@Override
public int getScore(int beforeScore) {
Score score = createScore(beforeScore);
if (score.canCalculateScore()) {
return score.getScore();
}
if (next != null) {
return next.calculateAdditionalScore(score);
}
return 0;
}

public int calculateAdditionalScore(Score beforeScore) {
beforeScore = state.updateScore(beforeScore);
if (beforeScore.canCalculateScore()) {
return beforeScore.getScore();
}
if (next != null) {
return next.calculateAdditionalScore(beforeScore);
}
return 0;
}

@Override
public String toString() {
return "no : " + no + ", next : " + next.toString() + ", state : " + state.printState();
}
}
62 changes: 62 additions & 0 deletions src/main/java/domain/Pins.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package domain;

public class Pins {
private static final int MAX_PINS = 10;
private static final int MIN_PINS = 0;

private final int falledPins;

public Pins(int falledPins) {
isValid(falledPins);
this.falledPins = falledPins;
}

public boolean isValid(int falledPins) {
if (falledPins > MAX_PINS) {
throw new IllegalArgumentException(
String.format("볼링 핀은 최대 10을 넘을 수 없습니다. 현재 쓰러진 핀 수는 %d", falledPins));
}

if (falledPins < MIN_PINS) {
throw new IllegalArgumentException(
String.format("볼링 핀은 최초 0 미만이 될 수 없습니다. 현재 쓰러진 핀 수는 %d", falledPins));
}
return true;
}

public boolean isStrike() {
return this.falledPins == MAX_PINS;
}

public boolean isSpare(Pins secondPins) {
return this.falledPins + secondPins.falledPins == MAX_PINS;
}

public boolean isOpen(Pins secondPins) {
return this.falledPins + secondPins.falledPins < MAX_PINS;
}

public boolean isGutter() {
return falledPins == MIN_PINS;
}

@Override
public String toString() {
return String.valueOf(falledPins);
}

public static int sumPins(Pins first, Pins second) {
if (first.falledPins + second.falledPins > 10 && first.falledPins + second.falledPins < 0) {
throw new RuntimeException("Pins.java : 쓰러진 핀의 합계는 0~10까지 입니다.");
}
return first.falledPins + second.falledPins;
}

public int sumScore(int score) {
return this.falledPins + score;
}

public Score createFirstBowlScore(int left) {
return new Score(falledPins, left);
}
}
Loading