diff --git a/src/main/java/nextstep/ladder/LadderMain.java b/src/main/java/nextstep/ladder/LadderMain.java index 05553b6a29..4f628b75af 100644 --- a/src/main/java/nextstep/ladder/LadderMain.java +++ b/src/main/java/nextstep/ladder/LadderMain.java @@ -1,8 +1,6 @@ package nextstep.ladder; -import nextstep.ladder.domain.Ladder; import nextstep.ladder.domain.LadderGame; -import nextstep.ladder.domain.Players; import nextstep.ladder.factory.LineFactory; import nextstep.ladder.generator.RandomLineGenerator; import nextstep.ladder.view.InputView; @@ -12,20 +10,30 @@ public class LadderMain { public static void main(String[] args) { // 참가자 이름 입력 받기 String names = InputView.inputNames(); - + // 실행 결과 입력 받기 + String inputResults = InputView.inputResults(); // 높이 입력 받기 int height = InputView.inputHeight(); - // 참가자 생성 - Players players = new Players(names); - - // 사다리 생성 - Ladder ladder = new Ladder(height, players.getSize(), new LineFactory(new RandomLineGenerator())); - - // 사다리 게임 생성 - LadderGame ladderGame = new LadderGame(players, ladder); + LadderGame ladderGame = LadderGame.of( + names, + inputResults, + height, + new LineFactory(new RandomLineGenerator()) + ); OutputView.printPlayers(ladderGame.getPlayers()); - OutputView.printLadder(ladder.getLines()); + OutputView.printLadder(ladderGame.getLines()); + OutputView.printResults(ladderGame.getResults()); + + while (true) { + String playerName = InputView.inputResultName(); + if (playerName.equalsIgnoreCase("all")) { + OutputView.printAllResults(ladderGame); + break; + } else { + OutputView.printResult(ladderGame, playerName); + } + } } } diff --git a/src/main/java/nextstep/ladder/domain/Ladder.java b/src/main/java/nextstep/ladder/domain/Ladder.java index 1553e19daf..cdf8dd023e 100644 --- a/src/main/java/nextstep/ladder/domain/Ladder.java +++ b/src/main/java/nextstep/ladder/domain/Ladder.java @@ -21,4 +21,13 @@ public Ladder(List lines) { public List getLines() { return this.lines; } + + public int move(int startIndex){ + int index = startIndex; + for(Line line: lines) { + index = line.move(index); + } + return index; + } + } diff --git a/src/main/java/nextstep/ladder/domain/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java index 8c279926e5..a012a4fb0e 100644 --- a/src/main/java/nextstep/ladder/domain/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -1,21 +1,48 @@ package nextstep.ladder.domain; +import nextstep.ladder.factory.LineFactory; + import java.util.List; +import java.util.stream.Collectors; public class LadderGame { private final Players players; private final Ladder ladder; + private final Results results; - public LadderGame(String players, Ladder ladder) { - this(new Players(players), ladder); - } - - public LadderGame(Players players, Ladder ladder) { + private LadderGame(Players players, Ladder ladder, Results results) { this.players = players; this.ladder = ladder; + this.results = results; + } + + public static LadderGame of(String names, String results, int height, LineFactory factory) { + Players players = new Players(names); + Results result = new Results(results); + Ladder ladder = new Ladder(height, players.getSize(), factory); + + return new LadderGame(players, ladder, result); } public List getPlayers() { return this.players.getPlayers(); } + + public List getResults() { + return this.results.getResults(); + } + + public List getLines() { + return this.ladder.getLines(); + } + + public Result play(String playerName) { + return results.findResultByIndex(ladder.move(players.indexOf(playerName))); + } + + public List playAll() { + return players.getPlayers().stream() + .map(player -> play(player.getName())) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 46a1eef327..18ecdc2311 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -1,7 +1,6 @@ package nextstep.ladder.domain; import java.util.List; -import java.util.stream.IntStream; public class Line { private final List points; @@ -23,10 +22,25 @@ public boolean hasLine(int i) { return points.get(i); } + public int move(int index) { + if(canMoveRight(index)) return index + 1; + if (canMoveLeft(index)) return index - 1; + return index; + } + + private boolean canMoveLeft(int index) { + return index > 0 && this.hasLine(index - 1); + } + + private boolean canMoveRight(int index) { + return index < this.getPoints().size() && this.hasLine(index); + } + private void validate(List points) { - IntStream.range(0, points.size() - 1) - .filter(i -> points.get(i) && points.get(i + 1)).forEach(i -> { - throw new IllegalArgumentException("가로선이 연속될 수 없습니다."); - }); + for (int i = 0; i < points.size() - 1; i++) { + if (points.get(i) && points.get(i + 1)) { + throw new IllegalArgumentException("가로선이 연속될 수 없습니다."); + } + } } } diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index 3b13f8afa8..396da8d20b 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.stream.IntStream; public class Players { private final static String DELIMITER = ","; @@ -16,6 +17,22 @@ public Players(List players) { this.players = players; } + + public List getPlayers() { + return this.players; + } + + public int getSize() { + return this.players.size(); + } + + public int indexOf(String name) { + return IntStream.range(0, players.size()) + .filter(i -> players.get(i).getName().equals(name)) + .findFirst() + .orElseThrow(()->new IllegalArgumentException("해당 이름이 없습니다.")); + } + private static List convertList(String[] players) { return Arrays.stream(players) .map(String::trim) @@ -27,14 +44,6 @@ private static String[] split(String players) { return players.split(DELIMITER); } - public List getPlayers() { - return this.players; - } - - public int getSize() { - return this.players.size(); - } - @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; diff --git a/src/main/java/nextstep/ladder/domain/Result.java b/src/main/java/nextstep/ladder/domain/Result.java new file mode 100644 index 0000000000..bdc61d1535 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Result.java @@ -0,0 +1,13 @@ +package nextstep.ladder.domain; + +public class Result { + private final String value; + + public Result(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} diff --git a/src/main/java/nextstep/ladder/domain/Results.java b/src/main/java/nextstep/ladder/domain/Results.java new file mode 100644 index 0000000000..5bcc16fe25 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/Results.java @@ -0,0 +1,37 @@ +package nextstep.ladder.domain; + +import java.util.Arrays; +import java.util.List; + +public class Results { + private final static String DELIMITER = ","; + private final List results; + + public Results(String inputResults) { + this(convertList(split(inputResults))); + + } + + public Results(List results) { + this.results = results; + } + + private static List convertList(String[] results) { + return Arrays.stream(results) + .map(String::trim) + .map(Result::new) + .toList(); + } + + private static String[] split(String players) { + return players.split(DELIMITER); + } + + public List getResults() { + return this.results; + } + + public Result findResultByIndex(int index) { + return this.results.get(index); + } +} diff --git a/src/main/java/nextstep/ladder/generator/FixedLineGenerator.java b/src/main/java/nextstep/ladder/generator/FixedLineGenerator.java index 6932f39560..dd923beb0c 100644 --- a/src/main/java/nextstep/ladder/generator/FixedLineGenerator.java +++ b/src/main/java/nextstep/ladder/generator/FixedLineGenerator.java @@ -12,7 +12,6 @@ public FixedLineGenerator(Boolean... points) { @Override public boolean generate(boolean prev) { - if (prev) return false; return points.next(); } } diff --git a/src/main/java/nextstep/ladder/view/InputView.java b/src/main/java/nextstep/ladder/view/InputView.java index 81eaef7e12..9592b6ad99 100644 --- a/src/main/java/nextstep/ladder/view/InputView.java +++ b/src/main/java/nextstep/ladder/view/InputView.java @@ -6,12 +6,22 @@ public class InputView { private final static Scanner scanner = new Scanner(System.in); public static String inputNames() { - System.out.println("참여할 사람 이름을 입력하시오. (이름은 쉼표(,)로 구분하세요"); + System.out.println("참여할 사람 이름을 입력하시오. (이름은 쉼표(,)로 구분하세요)"); return scanner.nextLine(); } public static int inputHeight() { System.out.println("최대 사다리 높이는 몇 개인가요?"); - return scanner.nextInt(); + return Integer.parseInt(scanner.nextLine().trim()); + } + + public static String inputResults() { + System.out.println("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + return scanner.nextLine(); + } + + public static String inputResultName() { + System.out.println("결과를 보고 싶은 사람은?"); + return scanner.nextLine().trim(); } } diff --git a/src/main/java/nextstep/ladder/view/OutputView.java b/src/main/java/nextstep/ladder/view/OutputView.java index 62128470aa..5bd5c561fe 100644 --- a/src/main/java/nextstep/ladder/view/OutputView.java +++ b/src/main/java/nextstep/ladder/view/OutputView.java @@ -1,7 +1,9 @@ package nextstep.ladder.view; +import nextstep.ladder.domain.LadderGame; import nextstep.ladder.domain.Line; import nextstep.ladder.domain.Player; +import nextstep.ladder.domain.Result; import java.util.List; @@ -30,4 +32,25 @@ private static void printLine(Line line) { ); System.out.println(); } + + public static void printResults(List results) { + for (Result result : results) { + System.out.printf("%" + NAME_WIDTH + "." + NAME_WIDTH + "s", + result.getValue()); + } + System.out.println(); + } + + public static void printAllResults(LadderGame game) { + List players = game.getPlayers(); + List results = game.playAll(); + for (int i = 0; i < players.size(); i++) { + System.out.printf("%s : %s%n", players.get(i).getName(), results.get(i).getValue()); + } + } + + public static void printResult(LadderGame game, String playerName) { + Result result = game.play(playerName); + System.out.println("실행 결과\n" + result.getValue()); + } } diff --git a/src/test/java/nextstep/ladder/domain/LadderGameTest.java b/src/test/java/nextstep/ladder/domain/LadderGameTest.java index b4cf5fa77e..89eea9398f 100644 --- a/src/test/java/nextstep/ladder/domain/LadderGameTest.java +++ b/src/test/java/nextstep/ladder/domain/LadderGameTest.java @@ -2,22 +2,36 @@ import nextstep.ladder.factory.LineFactory; import nextstep.ladder.generator.FixedLineGenerator; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + public class LadderGameTest { + @Test void 생성() { - LineFactory lineFactory = new LineFactory(new FixedLineGenerator( + LineFactory factory = new LineFactory(new FixedLineGenerator( true, false, true, // 1번째 Line false, true, false, // 2번째 Line true, false, false // 3번째 Line )); - Ladder ladder = new Ladder(3, 4, lineFactory); + LadderGame game = LadderGame.of("pobi,honux,crong,jk", "꽝,5000,꽝,3000", 3, factory); + + assertThat(game.getPlayers()).hasSize(4); + } + + @Test + void 특정_플레이어의_결과를_반환한다() { + LineFactory factory = new LineFactory(new FixedLineGenerator( + true, false, true, + false, true, false, + true, false, false + )); - LadderGame ladderGame = new LadderGame("pobi,honux,crong,jk", ladder); + LadderGame game = LadderGame.of("pobi,honux,crong,jk", "꽝,5000,꽝,3000", 3, factory); - Assertions.assertThat(ladderGame.getPlayers()).hasSize(4); + assertThat(game.play("honux").getValue()).isEqualTo("5000"); + assertThat(game.play("jk").getValue()).isEqualTo("꽝"); } } diff --git a/src/test/java/nextstep/ladder/domain/LadderTest.java b/src/test/java/nextstep/ladder/domain/LadderTest.java index 282da468ab..fce4563b94 100644 --- a/src/test/java/nextstep/ladder/domain/LadderTest.java +++ b/src/test/java/nextstep/ladder/domain/LadderTest.java @@ -19,4 +19,19 @@ void create() { assertThat(ladder.getLines()).hasSize(3); } + + @Test + void 사다리를_타면_정해진_위치로_이동한다() { + LineFactory factory = new LineFactory(new FixedLineGenerator( + true, false, true, + false, true, false, + true, false, false + )); + Ladder ladder = new Ladder(3, 4, factory); + + assertThat(ladder.move(0)).isEqualTo(2); + assertThat(ladder.move(1)).isEqualTo(1); + assertThat(ladder.move(2)).isEqualTo(3); + assertThat(ladder.move(3)).isEqualTo(0); + } } diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index ab0a80437e..63b47d7d63 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -5,6 +5,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class LineTest { @@ -18,4 +19,22 @@ void create() { assertThat(line.getPoints()).hasSize(4); } + + @Test + void move() { + List points = List.of(true, false, true, false); + + Line line = new Line(points); + + assertThat(line.move(1)).isEqualTo(0); + } + + @Test + void 가로선이_연속이면_오류() { + List points = List.of(true, true, true, false); + + assertThatThrownBy(() -> new Line(points)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("가로선이 연속될 수 없습니다."); + } } diff --git a/src/test/java/nextstep/ladder/domain/ResultsTest.java b/src/test/java/nextstep/ladder/domain/ResultsTest.java new file mode 100644 index 0000000000..e7de7817e2 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/ResultsTest.java @@ -0,0 +1,13 @@ +package nextstep.ladder.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ResultsTest { + @Test + void 생성() { + Results results = new Results("꽝,3000,꽝,5000"); + + Assertions.assertThat(results.getResults()).hasSize(4); + } +}