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
23 changes: 23 additions & 0 deletions src/main/java/bowling/Console.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package bowling;

import bowling.view.InputView;


/**
* @author sangsik.kim
*/
public class Console {

public static void main(String[] args) {
GameResult gameResult = new GameResult(InputView.getName());

for (int i = 1; i < 10; i++) {
Frame normalFrame = new NormalFrame(i);
while (!normalFrame.isFinish()) {
normalFrame.bowl(InputView.getPins(i));
gameResult.addScore(normalFrame.getScore());
InputView.displayFrameResult(gameResult);
}
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/bowling/Frame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package bowling;

/**
* @author sangsik.kim
*/
public interface Frame {
Frame bowl(int pin);

boolean isFinish();

String status();

Score getScore();
}
34 changes: 34 additions & 0 deletions src/main/java/bowling/GameResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bowling;

import org.apache.commons.lang3.StringUtils;

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

/**
* @author sangsik.kim
*/
public class GameResult {
private String playerName;
private Map<Integer, Score> scores = new HashMap<>();

public GameResult(String playerName) {
this.playerName = playerName;
}

public GameResult addScore(Score score) {
this.scores.put(score.getFrameNumber(), score);
return this;
}

public String getPlayerName() {
return this.playerName;
}

public String getScore(int frameNumber) {
return Optional.ofNullable(scores.get(frameNumber))
.map(Score::toText)
.orElse(StringUtils.EMPTY);
}
}
41 changes: 41 additions & 0 deletions src/main/java/bowling/NormalFrame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package bowling;

import bowling.status.Ready;
import bowling.status.Status;

/**
* @author sangsik.kim
*/
public class NormalFrame implements Frame {
private int frameNumber;
private Status status = new Ready();

public NormalFrame() {
this(1);
}

public NormalFrame(int frameNumber) {
this.frameNumber = frameNumber;
}

@Override
public String status() {
return this.status.getClass().getSimpleName();
}

@Override
public Score getScore() {
return new Score(this.frameNumber, this.status.getScore());
}

@Override
public Frame bowl(int pin) {
this.status = this.status.bowl(pin);
return this;
}

@Override
public boolean isFinish() {
return this.status.isFinish();
}
}
22 changes: 22 additions & 0 deletions src/main/java/bowling/Score.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package bowling;

/**
* @author sangsik.kim
*/
public class Score {
private int frameNumber;
private String scoreText;

public Score(int frameNumber, String scoreText) {
this.frameNumber = frameNumber;
this.scoreText = scoreText;
}

public int getFrameNumber() {
return this.frameNumber;
}

public String toText() {
return this.scoreText;
}
}
10 changes: 10 additions & 0 deletions src/main/java/bowling/status/FinishedStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class FinishedStatus {
public boolean isFinish() {
return true;
}
}
19 changes: 19 additions & 0 deletions src/main/java/bowling/status/Gutter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Gutter extends RunningStatus implements Status {
@Override
public Status bowl(int pin) {
if (pin == 10) {
return new Spare(0, 10);
}
return new Miss(0, pin);
}

@Override
public String getScore() {
return "-";
}
}
31 changes: 31 additions & 0 deletions src/main/java/bowling/status/Miss.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Miss extends FinishedStatus implements Status {
private int first;
private int second;

public Miss(int first, int second) {
if (first + second > 10) {
throw new IllegalArgumentException("쓰러진 핀의 갯수가 올바르지 않습니다.");
}
this.first = first;
this.second = second;
}

@Override
public Status bowl(int pin) {
throw new IllegalArgumentException("이미 투구를 완료하였습니다.");
}

@Override
public String getScore() {
return convertGutter(this.first) + "|" + convertGutter(this.second);
}

private String convertGutter(int pin) {
return pin == 0 ? "-" : String.valueOf(pin);
}
}
22 changes: 22 additions & 0 deletions src/main/java/bowling/status/Ready.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Ready extends RunningStatus implements Status {
@Override
public Status bowl(int pin) {
if (pin == 10) {
return new Strike();
}
if (pin == 0) {
return new Gutter();
}
return new Running(pin);
}

@Override
public String getScore() {
return "Ready";
}
}
28 changes: 28 additions & 0 deletions src/main/java/bowling/status/Running.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Running extends RunningStatus implements Status {
private int first;

public Running(int pin) {
this.first = pin;
}

@Override
public Status bowl(int pin) {
if (this.first + pin > 10) {
throw new IllegalArgumentException("쓰러진 핀의 갯수가 올바르지 않습니다.");
}
if (this.first + pin == 10) {
return new Spare(this.first, pin);
}
return new Miss(this.first, pin);
}

@Override
public String getScore() {
return String.valueOf(first);
}
}
10 changes: 10 additions & 0 deletions src/main/java/bowling/status/RunningStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class RunningStatus {
public boolean isFinish() {
return false;
}
}
25 changes: 25 additions & 0 deletions src/main/java/bowling/status/Spare.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Spare extends FinishedStatus implements Status {
private int first;

public Spare(int first, int second) {
if (first + second > 10) {
throw new IllegalArgumentException("쓰러진 핀의 갯수가 올바르지 않습니다.");
}
this.first = first;
}

@Override
public Status bowl(int pin) {
throw new IllegalArgumentException("이미 투구를 완료하였습니다.");
}

@Override
public String getScore() {
return this.first == 0 ? "-|/" : this.first + "|/";
}
}
12 changes: 12 additions & 0 deletions src/main/java/bowling/status/Status.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public interface Status {
Status bowl(int pin);

String getScore();

boolean isFinish();
}
17 changes: 17 additions & 0 deletions src/main/java/bowling/status/Strike.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package bowling.status;

/**
* @author sangsik.kim
*/
public class Strike extends FinishedStatus implements Status {

@Override
public Status bowl(int pin) {
throw new IllegalArgumentException("이미 투구를 완료하였습니다.");
}

@Override
public String getScore() {
return "X";
}
}
59 changes: 59 additions & 0 deletions src/main/java/bowling/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package bowling.view;

import bowling.GameResult;
import org.apache.commons.lang3.StringUtils;

import java.util.Scanner;

/**
* @author sangsik.kim
*/
public class InputView {
private static final String SCORE_FORMAT = "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|\n";
private static final String INPUT_PLAYER_NAME_TEXT = "플레이어 이름은(3 english letters)? : ";
private static final String INPUT_KNOCK_DOWN_PIN_TEXT = "%d프레임 투구 : ";
private static final Scanner scanner = new Scanner(System.in);

public static String getName() {
System.out.print(INPUT_PLAYER_NAME_TEXT);
return scanner.next();
}

public static int getPins(int frameNumber) {
System.out.print(String.format(INPUT_KNOCK_DOWN_PIN_TEXT, frameNumber));
return scanner.nextInt();
}

public static void displayFrameResult(GameResult gameResult) {
System.out.println(getScoreHeader());
System.out.println(getScore(gameResult));
}

private static String getScoreHeader() {
return String.format(SCORE_FORMAT,
StringUtils.center("NAME", 8),
StringUtils.center("01", 9),
StringUtils.center("02", 9),
StringUtils.center("03", 9),
StringUtils.center("04", 9),
StringUtils.center("05", 9),
StringUtils.center("06", 9),
StringUtils.center("07", 9),
StringUtils.center("08", 9),
StringUtils.center("09", 9),
StringUtils.center("10", 9));
}

private static String getScore(GameResult gameResult) {
return String.format(SCORE_FORMAT, makeScoreFormat(gameResult));
}

private static Object[] makeScoreFormat(GameResult gameResult) {
String[] result = new String[11];
result[0] = StringUtils.center(gameResult.getPlayerName(), 8);
for (int i = 1; i <= 10; i++) {
result[i] = StringUtils.center(gameResult.getScore(i), 9);
}
return result;
}
}
Loading