Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step2 #3

Open
wants to merge 8 commits into
base: delf
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.project/
.gradle/
.idea/
bin/
build/
.settings
.classpath
out/
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ repositories {
dependencies {
testCompile('org.junit.jupiter:junit-jupiter:5.4.2')
testCompile('org.assertj:assertj-core:3.11.1')
implementation 'junit:junit:4.12'
}

test {
useJUnitPlatform()
}
5 changes: 3 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Thu Feb 20 23:25:10 KST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
30 changes: 30 additions & 0 deletions src/main/java/BowlingApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import domain.BowlingGame;
import domain.FallingPin;
import domain.Player;
import domain.Players;
import input.BowlingGameInputtable;
import input.ConsoleBowlingGameInputInterface;
import output.ConsoleBowlingScorePresenter;

import java.util.Collections;

public class BowlingApplication {
private static final int DEFAULT_BOWLING_MAX_FRAME = 10;
private static BowlingGameInputtable inputManager = new ConsoleBowlingGameInputInterface();

public static void main(String[] args) throws IllegalAccessException {
String playerName = inputManager.getPlayerName();
Player player = new Player(playerName);
Players playerList = new Players(Collections.singletonList(player));
BowlingGame bowlingGame = new BowlingGame(DEFAULT_BOWLING_MAX_FRAME, playerList);

while (bowlingGame.hasNext()) {
Player thisTurnPlayer = bowlingGame.nextPlayer();
FallingPin fallingPinCount = inputManager.getFallingPint();
thisTurnPlayer.bowl(fallingPinCount);
ConsoleBowlingScorePresenter.print(bowlingGame);
}

System.out.println("--볼링 게임 끝--");
}
}
37 changes: 37 additions & 0 deletions src/main/java/domain/BowlingGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package domain;

public class BowlingGame {
public final int MAX_FRAME;
private final Players players;
private int nowFrameNumber;

public BowlingGame(int maxFrame, Players players) {
this.MAX_FRAME = maxFrame;
this.players = players;
}

public boolean hasNext() {
return MAX_FRAME > nowFrameNumber;
}

public Player nextPlayer() {
if (players.isLastPlayer()) {
nowFrameNumber++;
}

return players.getCurrentPlayer();
}

@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("| NAME |");
for (int i = 0; i < MAX_FRAME; i++) {
stringBuilder.append(String.format(" %2d |", i + 1));
}

stringBuilder.append("\n").append(players);

return stringBuilder.toString() + "\n";
}
}
49 changes: 49 additions & 0 deletions src/main/java/domain/FallingPin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package domain;

public class FallingPin {
public final static FallingPin MISS = new FallingPin(0);
public final static FallingPin NONE = new FallingPin(-1);
private int fallingPinCount;

public FallingPin(int fallingPinCount) {
if (fallingPinCount > Frame.DEFAULT_BOWLING_PIN) {
throw new IllegalArgumentException("10개 이하");
}
this.fallingPinCount = fallingPinCount;
}

public int value() {
if(this.equals(NONE)) {
return 0;
}
return fallingPinCount;
}

public String getSymbol() {
if (this.equals(MISS)) {
return Frame.FrameStatus.MISS.symbol;
}

if (this.equals(NONE)) {
return Frame.FrameStatus.NONE.symbol;
}

return String.valueOf(fallingPinCount);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

FallingPin that = (FallingPin) o;

return fallingPinCount == that.fallingPinCount;

}

@Override
public int hashCode() {
return fallingPinCount;
}
}
123 changes: 123 additions & 0 deletions src/main/java/domain/Frame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package domain;

import java.util.Objects;

import static domain.Frame.FrameStatus.*;

public class Frame implements Scorable {
public final static int DEFAULT_BOWLING_PIN = 10;
public final static Frame NONE_FRAME = new Frame();

private FallingPin first = FallingPin.NONE;
private FallingPin second = FallingPin.NONE;

private Frame nextFrame = NONE_FRAME;

public void fall(FallingPin pins) throws IllegalAccessException {
if (first.equals(FallingPin.NONE)) {
this.first = pins;
return;
}
this.second = pins;

if (pinCount() > DEFAULT_BOWLING_PIN) {
throw new IllegalAccessException();
}
}

private int pinCount() {
return first.value() + second.value();
}

public void setNextFrame(Frame nextFrame) {
this.nextFrame = nextFrame;
}

public boolean isEnd() {
if (FrameStatus.of(this).equals(STRIKE)) {
return true;
}
return !second.equals(FallingPin.NONE);
}

@Override
public Score getScore() { // 다듬을 여지 있음
if (Objects.isNull(nextFrame) || !isEnd()) {
return Score.NOT_DETERMINED;
}

Score nextFrameScore = Score.of(0);

if (FrameStatus.of(this).equals(STRIKE)) {
if (!nextFrame.isEnd()) {
return Score.NOT_DETERMINED;
}
nextFrameScore = nextFrame.getFallingPinCount();
}

if (FrameStatus.of(this).equals(SPARE)) {
if (nextFrame.isEndFirstTry()) {
return Score.NOT_DETERMINED;
}
nextFrameScore = nextFrame.getFallingPinCountAtFirstTry();
}

return getFallingPinCount().add(nextFrameScore);
}

private boolean isEndFirstTry() {
return first.equals(FallingPin.NONE);
}

private Score getFallingPinCountAtFirstTry() {
return Score.of(first.value());
}

private Score getFallingPinCount() {
return Score.of(first.value() + second.value());
}

@Override
public String toString() {
switch (FrameStatus.of(this)) {
case STRIKE:
return " " + STRIKE.symbol + " ";

case SPARE:
return " " + first.getSymbol() + "|" + SPARE.symbol + " ";

default:
return " " + first.getSymbol() + "|" + second.getSymbol() + " ";
}
}

public enum FrameStatus {
STRIKE("X"), SPARE("/"), MISS("-"), HIT(""), NONE(" ");

String symbol;

FrameStatus(String symbol) {
this.symbol = symbol;
}

public static FrameStatus of(Frame frame) {
FallingPin first = frame.first;

if (first.equals(FallingPin.NONE)) {
return NONE;
}

if (first.value() == DEFAULT_BOWLING_PIN) {
return STRIKE;
}

FallingPin second = frame.second;

if (first.value() + second.value() == DEFAULT_BOWLING_PIN) {
return SPARE;
}

return HIT;
}
}
}
52 changes: 52 additions & 0 deletions src/main/java/domain/FrameCollection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package domain;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

public class FrameCollection {
private LinkedList<Frame> frameList = new LinkedList<>();

// 현재 유효한 Frame 반환
public Frame getCurrent() {
Frame currentFrame;
if (frameList.isEmpty()) { // 비어있으면 List에 새 Frame 추가 후 반환
currentFrame = new Frame();
frameList.add(currentFrame);
return currentFrame;
}

// 비어있지 않지만
currentFrame = frameList.getLast();
if (currentFrame.isEnd()) { // 마지막 Frame이 끝났으면 새 Frame 추가 후 반환
Frame nextFrame = new Frame();
currentFrame.setNextFrame(nextFrame);
frameList.add(nextFrame);
return nextFrame;
}

return currentFrame; // 안끝났으면 해당 Frame 반환
}

@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
frameList.stream()
.map(Frame::toString)
.forEach(s -> stringBuilder.append(s).append("|"));
for (int i = 0; i < Frame.DEFAULT_BOWLING_PIN - frameList.size(); i++) {
stringBuilder.append(" |");
}

return stringBuilder.toString();
}

public String getScore() {
StringBuilder stringBuilder = new StringBuilder();
frameList.stream()
.map(Frame::getScore)
.forEach(s -> stringBuilder.append(s).append(" | "));
return stringBuilder.toString();
}
}
29 changes: 29 additions & 0 deletions src/main/java/domain/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package domain;

public class Player {
private String name;
private FrameCollection frames = new FrameCollection();

public Player(String playerName) {
this.name = playerName;
}

public void bowl(FallingPin pins) throws IllegalAccessException {
Frame currentFrame = frames.getCurrent();
currentFrame.fall(pins);
}

public boolean hasChance() {
Frame currentFrame = frames.getCurrent();
return !currentFrame.isEnd();
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("| ").append(name).append(" |").append(frames).append("\n");
sb.append(" | ").append(frames.getScore());

return sb.toString();
}
}
41 changes: 41 additions & 0 deletions src/main/java/domain/Players.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package domain;

import java.util.List;

public class Players {
private List<Player> players;
private int currentPlayerIndex;

public Players(List<Player> players) {
this.players = players;
}

public Player getCurrentPlayer() {
Player currentPlayer = currentPlayer();
if (currentPlayer.hasChance()) {
return currentPlayer;
}

return nextPlayer();
}

private Player nextPlayer() {
currentPlayerIndex = currentPlayerIndex % players.size();
return players.get(currentPlayerIndex++);
}

public boolean isLastPlayer() {
return currentPlayerIndex == players.size();
}

private Player currentPlayer() {
return players.get(currentPlayerIndex);
}

@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
players.stream().map(Player::toString).forEach(stringBuilder::append);
return stringBuilder.toString();
}
}
Loading