From ec68a0e766c9a67e77607a68bd0b670558853fa4 Mon Sep 17 00:00:00 2001 From: taewoo Date: Thu, 30 Oct 2025 17:19:31 +0900 Subject: [PATCH 01/46] =?UTF-8?q?=EB=A1=9C=EB=98=90=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 22 +++++ .../java/controller/LadderController.java | 64 ++++++++++++++ src/main/java/domain/Ladder.java | 21 +++++ src/main/java/domain/LadderGame.java | 55 ++++++++++++ src/main/java/domain/Line.java | 47 +++++++++++ src/main/java/domain/Names.java | 32 +++++++ src/main/java/domain/Players.java | 30 +++++++ src/main/java/domain/Results.java | 17 ++++ src/main/java/view/InputView.java | 18 ++++ src/main/java/view/OutputView.java | 84 +++++++++++++++++++ 10 files changed, 390 insertions(+) create mode 100644 src/main/java/Main.java create mode 100644 src/main/java/controller/LadderController.java create mode 100644 src/main/java/domain/Ladder.java create mode 100644 src/main/java/domain/LadderGame.java create mode 100644 src/main/java/domain/Line.java create mode 100644 src/main/java/domain/Names.java create mode 100644 src/main/java/domain/Players.java create mode 100644 src/main/java/domain/Results.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 00000000..2c365b61 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,22 @@ +import controller.LadderController; +import domain.LadderGame; +import domain.Players; +import domain.Results; +import view.InputView; +import view.OutputView; + +public class Main { + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + LadderController controller = new LadderController(inputView, outputView); + + Players players = controller.inputPlayers(); + Results results = controller.inputResults(); + int height = controller.inputHeight(); + + LadderGame game = controller.startLadderGame(height, players, results); + controller.showResult(game, players); + + } +} diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java new file mode 100644 index 00000000..4bc3ef0f --- /dev/null +++ b/src/main/java/controller/LadderController.java @@ -0,0 +1,64 @@ +package controller; + +import domain.Ladder; +import domain.LadderGame; +import domain.Players; +import domain.Results; +import view.InputView; +import view.OutputView; + +import java.util.Random; + +public class LadderController { + private final InputView inputView; + private final OutputView outputView; + + public LadderController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public Players inputPlayers() { + outputView.printAskPlayers(); + return new Players(inputView.readString()); + } + + public Results inputResults() { + outputView.printAskResults(); + return new Results(inputView.readString()); + } + + public int inputHeight() { + outputView.printAskHeight(); + return inputView.readInt(); + } + + public LadderGame startLadderGame(int height, Players players, Results results) { + Ladder ladder = new Ladder(height, players.size(), new Random()); + LadderGame game = new LadderGame(ladder, players, results); + outputView.printLadderResultTitle(); + outputView.printLadder(ladder + , players.getPlayers().getValues() + , results.getResults().getValues()); + return game; + } + + public void showResult(LadderGame game, Players players) { + boolean run = true; + while (run) { + outputView.printAskResultByPlayer(); + String name = inputView.readString(); + run = validateRun(game, players, name); + } + } + + private boolean validateRun(LadderGame game, Players players, String name) { + if (name.equals("all")) { + outputView.printAllResults(game.findAll(), players); + return false; + } + String result = game.findResultByPlayer(name); + outputView.printSingleResult(name, result); + return true; + } +} diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java new file mode 100644 index 00000000..84ff7872 --- /dev/null +++ b/src/main/java/domain/Ladder.java @@ -0,0 +1,21 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Ladder { + private final List lines; + + public Ladder(int height, int playerCount, Random random) { + List temp = new ArrayList<>(); + for (int i = 0; i < height; i++) { + temp.add(Line.create(playerCount, random)); + } + this.lines = List.copyOf(temp); + } + + public List getLines() { + return lines; + } +} diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java new file mode 100644 index 00000000..15a8793c --- /dev/null +++ b/src/main/java/domain/LadderGame.java @@ -0,0 +1,55 @@ +package domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LadderGame { + private final Ladder ladder; + private final Players players; + private final Results results; + + public LadderGame(Ladder ladder, Players players, Results results) { + validatePlayerAndResultCount(players, results); + this.ladder = ladder; + this.players = players; + this.results = results; + } + + private void validatePlayerAndResultCount(Players players, Results results) { + if (players.size() != results.size()) { + throw new IllegalArgumentException("참가자와 결과 수는 같아야 합니다."); + } + } + + private int move(int position) { + for (Line line : ladder.getLines()) { + position += calculateNextPosition(line, position); + } + return position; + } + + private int calculateNextPosition(Line line, int position) { + if ((line.validateMoveRight(position))) return 1; + if ((line.validateMoveLeft(position))) return -1; + return 0; + } + + public String findResultByPlayer(String name) { + List player = players.getPlayers().getValues(); + List result = results.getResults().getValues(); + + int index = player.indexOf(name); + index = move(index); + return result.get(index); + } + + public Map findAll() { + Map map = new HashMap<>(); + List player = players.getPlayers().getValues(); + for (String name : player) { + map.put(name, findResultByPlayer(name)); + } + return map; + } +} diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java new file mode 100644 index 00000000..f4174d09 --- /dev/null +++ b/src/main/java/domain/Line.java @@ -0,0 +1,47 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Line { + private final List points; + + private Line(List points) { + this.points = List.copyOf(points); + } + + public static Line create(int playerCount, Random random) { + List points = new ArrayList<>(); + boolean prev = false; + + for (int i = 0; i < playerCount - 1; i++) { + boolean next = random.nextBoolean(); + next = checkPrev(prev, next); + points.add(next); + prev = next; + } + return new Line(points); + } + + private static boolean checkPrev(boolean prev, boolean next) { + if (prev) { + next = false; + } + return next; + } + + public boolean validateMoveRight(int index) { + if (index >= points.size()) return false; + return points.get(index); + } + + public boolean validateMoveLeft(int index) { + if (index == 0) return false; + return points.get(index - 1); + } + + public List getPoints() { + return points; + } +} diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java new file mode 100644 index 00000000..edf8e39f --- /dev/null +++ b/src/main/java/domain/Names.java @@ -0,0 +1,32 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Names { + private final List values; + + public Names(String input) { + String[] tokens = input.split(","); + List temp = new ArrayList<>(); + for (String token : tokens) { + addIfValid(temp, token); + } + this.values = List.copyOf(temp); + } + + private void addIfValid(List temp, String token) { + String trimmed = token.trim(); + if (!trimmed.isEmpty()) { + temp.add(trimmed); + } + } + + public int size() { + return values.size(); + } + + public List getValues() { + return values; + } +} diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java new file mode 100644 index 00000000..83d889c4 --- /dev/null +++ b/src/main/java/domain/Players.java @@ -0,0 +1,30 @@ +package domain; + +public class Players { + private final Names players; + + public Players(String input) { + this.players = new Names(input); + validatePlayerNames(); + } + + private void validatePlayerNames() { + for (String name : players.getValues()) { + validateNameLength(name); + } + } + + private void validateNameLength(String name) { + if (name.length() > 5) { + throw new IllegalArgumentException("이름은 5글자를 넘기면 안됩니다."); + } + } + + public int size() { + return players.size(); + } + + public Names getPlayers() { + return players; + } +} diff --git a/src/main/java/domain/Results.java b/src/main/java/domain/Results.java new file mode 100644 index 00000000..1613f4e5 --- /dev/null +++ b/src/main/java/domain/Results.java @@ -0,0 +1,17 @@ +package domain; + +public class Results { + private final Names results; + + public Results(String input) { + this.results = new Names(input); + } + + public int size() { + return results.size(); + } + + public Names getResults() { + return results; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..de860c3a --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,18 @@ +package view; + +import java.util.Scanner; + +public class InputView { + Scanner input = new Scanner(System.in); + + public String readString() { + return input.nextLine(); + } + + public int readInt() { + int number = input.nextInt(); + input.nextLine(); + return number; + } +} + diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..1d6c3463 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,84 @@ +package view; + +import domain.Ladder; +import domain.Line; +import domain.Players; + +import java.util.List; +import java.util.Map; + +public class OutputView { + public void printAskPlayers() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼포(,)로 구분하세요)"); + } + + public void printAskResults() { + System.out.println("\n실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + } + + public void printAskHeight() { + System.out.println("\n최대 사다리 높이는 몇 개인가요?"); + } + + public void printLadderResultTitle() { + System.out.println("\n사다리 결과\n"); + } + + public void printAskResultByPlayer() { + System.out.println("\n결과를 보고 싶은 사람은?"); + } + + private void printPlayers(List players) { + for (String name : players) { + System.out.printf("%6s", name); + } + System.out.println(); + } + + private void printLines(List lines) { + for (Line line : lines) { + System.out.print(" |"); + printLine(line); + System.out.println(); + } + } + + private void printLine(Line line) { + for (boolean point : line.getPoints()) { + printPoint(point); + } + } + + private void printPoint(Boolean point) { + if (point) { + System.out.print("-----|"); + return; + } + System.out.print(" |"); + } + + public void printLadder(Ladder ladder, List players, List results) { + printPlayers(players); + printLines(ladder.getLines()); + printResults(results); + } + + private void printResults(List results) { + for (String result : results) { + System.out.printf("%6s", result); + } + System.out.println(); + } + + public void printSingleResult(String name, String result) { + System.out.println("\n실행 결과"); + System.out.println(result); + } + + public void printAllResults(Map results, Players players) { + System.out.println("\n실행 결과"); + for (String name : players.getPlayers().getValues()) { + System.out.println(name + " : " + results.get(name)); + } + } +} From ab34af1395bd5f3a0e07095cfb07e705a60d30a5 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 12:52:46 +0900 Subject: [PATCH 02/46] =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=84=20=EC=9B=90?= =?UTF-8?q?=EC=8B=9C=EA=B0=92=EC=9C=BC=EB=A1=9C=20=ED=8F=AC=EC=9E=A5?= =?UTF-8?q?=ED=95=9C=20Name=20=ED=81=B4=EB=9E=98=EC=8A=A4=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/domain/Name.java | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/domain/Name.java diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java new file mode 100644 index 00000000..dadc1ce7 --- /dev/null +++ b/src/main/java/domain/Name.java @@ -0,0 +1,35 @@ +package domain; + +import java.util.Objects; + +public class Name { + private final String value; + public Name(String value){ + if (value == null || value.trim().isEmpty()){ + throw new IllegalArgumentException("비어 있을 수 없습니다."); + } + this.value = value.trim(); + } + + public String value(){ + return value; + } + + @Override + public String toString(){ + return value; + } + + @Override + public boolean equals(Object obj){ + if (this == obj) return true; + if (!(obj instanceof Name)) return false; + Name name = (Name)obj; + return value.equals(name.value); + } + + @Override + public int hashCode(){ + return value.hashCode(); + } +} From b5d6346eb93c7d108d0ac114e309331594b1e9a0 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 14:13:08 +0900 Subject: [PATCH 03/46] =?UTF-8?q?=20Names=EB=A5=BC=20Name=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Names.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java index edf8e39f..07110349 100644 --- a/src/main/java/domain/Names.java +++ b/src/main/java/domain/Names.java @@ -4,21 +4,25 @@ import java.util.List; public class Names { - private final List values; + private final List values; public Names(String input) { String[] tokens = input.split(","); - List temp = new ArrayList<>(); + List temp = new ArrayList<>(); for (String token : tokens) { addIfValid(temp, token); } this.values = List.copyOf(temp); } - private void addIfValid(List temp, String token) { + public Names(List names) { + this.values = List.copyOf(names); + } + + private void addIfValid(List temp, String token) { String trimmed = token.trim(); if (!trimmed.isEmpty()) { - temp.add(trimmed); + temp.add(new Name(trimmed)); } } @@ -26,7 +30,7 @@ public int size() { return values.size(); } - public List getValues() { + public List getValues() { return values; } } From 64252616600ab1510ada61763619ce47b68dd71a Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 14:14:56 +0900 Subject: [PATCH 04/46] =?UTF-8?q?Players=20=EC=9D=B4=EB=A6=84=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=A0=9C=EA=B1=B0=20=EB=A1=9C=EC=A7=81=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/domain/Players.java | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index 83d889c4..a96bffaf 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -1,21 +1,40 @@ package domain; +import java.util.ArrayList; +import java.util.List; + public class Players { private final Names players; public Players(String input) { - this.players = new Names(input); + this.players = removeDuplicate(input); validatePlayerNames(); } + private Names removeDuplicate(String input) { + String[] tokens = input.split(","); + List newInput = new ArrayList<>(); + + for (String token : tokens) { + String trimmed = token.trim(); + if (!trimmed.isEmpty()) { + Name name = new Name(trimmed); + if (!newInput.contains(name)) { + newInput.add(name); + } + } + } + return new Names(newInput); + } + private void validatePlayerNames() { - for (String name : players.getValues()) { + for (Name name : players.getValues()) { validateNameLength(name); } } - private void validateNameLength(String name) { - if (name.length() > 5) { + private void validateNameLength(Name name) { + if (name.value().length() > 5) { throw new IllegalArgumentException("이름은 5글자를 넘기면 안됩니다."); } } From b3e4558d8eda089ed3a0f688929d6aec949e0060 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 15:02:40 +0900 Subject: [PATCH 05/46] =?UTF-8?q?=EB=B0=B0=EC=97=B4=20=EC=A7=81=EC=A0=91?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=20X?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Names.java | 2 +- src/main/java/domain/Players.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java index 07110349..2391a4ca 100644 --- a/src/main/java/domain/Names.java +++ b/src/main/java/domain/Names.java @@ -7,7 +7,7 @@ public class Names { private final List values; public Names(String input) { - String[] tokens = input.split(","); + List tokens = List.of(input.split(",")); List temp = new ArrayList<>(); for (String token : tokens) { addIfValid(temp, token); diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index a96bffaf..8ef75fbe 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -4,6 +4,7 @@ import java.util.List; public class Players { + private static final int PLAYERS_NAME_MAX_LENGTH = 5; private final Names players; public Players(String input) { @@ -12,7 +13,7 @@ public Players(String input) { } private Names removeDuplicate(String input) { - String[] tokens = input.split(","); + List tokens = List.of(input.split(",")); List newInput = new ArrayList<>(); for (String token : tokens) { @@ -34,7 +35,7 @@ private void validatePlayerNames() { } private void validateNameLength(Name name) { - if (name.value().length() > 5) { + if (name.value().length() > PLAYERS_NAME_MAX_LENGTH) { throw new IllegalArgumentException("이름은 5글자를 넘기면 안됩니다."); } } From e0819f488c618e398952e01615c4e4bc7acebb56 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:28:36 +0900 Subject: [PATCH 06/46] =?UTF-8?q?=EB=86=92=EC=9D=B4=EB=A5=BC=20int=20?= =?UTF-8?q?=EB=8C=80=EC=8B=A0=20Height=20=EA=B0=9D=EC=B2=B4=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EA=B3=A0,=20Results=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20Players=20=EC=A0=84=EB=8B=AC=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=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/Main.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 2c365b61..282f55df 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,4 +1,5 @@ import controller.LadderController; +import domain.Height; import domain.LadderGame; import domain.Players; import domain.Results; @@ -12,8 +13,8 @@ public static void main(String[] args) { LadderController controller = new LadderController(inputView, outputView); Players players = controller.inputPlayers(); - Results results = controller.inputResults(); - int height = controller.inputHeight(); + Results results = controller.inputResults(players); + Height height = controller.inputHeight(); LadderGame game = controller.startLadderGame(height, players, results); controller.showResult(game, players); From 8421f7455b0801fed873ab2e68ed3a424c83ea38 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:31:10 +0900 Subject: [PATCH 07/46] =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=8B=9C=20=EC=9E=AC=EC=9E=85=EB=A0=A5=20=EB=A3=A8?= =?UTF-8?q?=ED=94=84=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=9B=90=EC=8B=9C?= =?UTF-8?q?=EA=B0=92=20=ED=8F=AC=EC=9E=A5=C2=B7=EC=9D=BC=EA=B8=89=20?= =?UTF-8?q?=EC=BB=AC=EB=A0=89=EC=85=98=20=EC=A0=81=EC=9A=A9=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/LadderController.java | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java index 4bc3ef0f..ccc98d42 100644 --- a/src/main/java/controller/LadderController.java +++ b/src/main/java/controller/LadderController.java @@ -1,5 +1,6 @@ package controller; +import domain.Height; import domain.Ladder; import domain.LadderGame; import domain.Players; @@ -7,6 +8,7 @@ import view.InputView; import view.OutputView; +import java.util.InputMismatchException; import java.util.Random; public class LadderController { @@ -20,20 +22,43 @@ public LadderController(InputView inputView, OutputView outputView) { public Players inputPlayers() { outputView.printAskPlayers(); - return new Players(inputView.readString()); + while (true) { + try { + return new Players(inputView.readString()); + } catch (IllegalArgumentException e) { + outputView.printException(e); + outputView.printRetryInputMessage(); + } + } } - public Results inputResults() { + public Results inputResults(Players players) { outputView.printAskResults(); - return new Results(inputView.readString()); + while (true) { + try { + Results results = new Results(inputView.readString()); + LadderGame.validatePlayerAndResultCount(players, results); + return results; + } catch (IllegalArgumentException e) { + outputView.printException(e); + outputView.printRetryInputMessage(); + } + } } - public int inputHeight() { + public Height inputHeight() { outputView.printAskHeight(); - return inputView.readInt(); + while (true) { + try { + return new Height(inputView.readInt()); + } catch (InputMismatchException | IllegalArgumentException e) { + outputView.printException(e); + outputView.printRetryInputMessage(); + } + } } - public LadderGame startLadderGame(int height, Players players, Results results) { + public LadderGame startLadderGame(Height height, Players players, Results results) { Ladder ladder = new Ladder(height, players.size(), new Random()); LadderGame game = new LadderGame(ladder, players, results); outputView.printLadderResultTitle(); @@ -58,7 +83,7 @@ private boolean validateRun(LadderGame game, Players players, String name) { return false; } String result = game.findResultByPlayer(name); - outputView.printSingleResult(name, result); + outputView.printSingleResult(result); return true; } } From 7bd2af2c94dae837b1782585654107e2c7abeb93 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:32:03 +0900 Subject: [PATCH 08/46] =?UTF-8?q?=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EC=83=81=ED=83=9C=20=ED=91=9C=ED=98=84=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20Connect=20enum=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/domain/Connect.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/domain/Connect.java diff --git a/src/main/java/domain/Connect.java b/src/main/java/domain/Connect.java new file mode 100644 index 00000000..e160a28d --- /dev/null +++ b/src/main/java/domain/Connect.java @@ -0,0 +1,20 @@ +package domain; + +public enum Connect { + CONNECTED(true), + DISCONNECTED(false); + + private final boolean value; + + Connect(boolean value){ + this.value = value; + } + + public boolean isConnected(){ + return value; + } + + public static Connect from(boolean value){ + return value ? CONNECTED : DISCONNECTED; + } +} From 94e6bdeda09cc6422d0309689c9e1ca4df5bec76 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:32:52 +0900 Subject: [PATCH 09/46] =?UTF-8?q?=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EB=86=92?= =?UTF-8?q?=EC=9D=B4=20=EA=B2=80=EC=A6=9D=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?Height=20=EC=9B=90=EC=8B=9C=EA=B0=92=20=ED=8F=AC=EC=9E=A5=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=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/domain/Height.java | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/domain/Height.java diff --git a/src/main/java/domain/Height.java b/src/main/java/domain/Height.java new file mode 100644 index 00000000..e04b2856 --- /dev/null +++ b/src/main/java/domain/Height.java @@ -0,0 +1,36 @@ +package domain; + +public class Height { + private static final int HEIGHT_MIN = 0; + private final int height; + + public Height(int height) { + if (height < HEIGHT_MIN) { + throw new IllegalArgumentException("사다리 높이는 양수여야 합니다."); + } + + this.height = height; + } + + public int getHeight() { + return height; + } + + @Override + public String toString() { + return String.valueOf(height); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Height)) return false; + Height other = (Height) obj; + return height == other.getHeight(); + } + + @Override + public int hashCode() { + return Integer.hashCode(height); + } +} From af22352470e4838705524da49daa37d4317f8e73 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:34:08 +0900 Subject: [PATCH 10/46] =?UTF-8?q?=EB=86=92=EC=9D=B4=EA=B0=80=200=EC=9D=B8?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=EC=97=90=EB=8F=84=20=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=ED=95=9C=20=EC=A4=84=EC=9D=B4=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Ladder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 84ff7872..b31738ab 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -7,9 +7,13 @@ public class Ladder { private final List lines; - public Ladder(int height, int playerCount, Random random) { + public Ladder(Height height, int playerCount, Random random) { List temp = new ArrayList<>(); - for (int i = 0; i < height; i++) { + + for (int i = 0; i < height.getHeight(); i++) { + temp.add(Line.create(playerCount, random)); + } + if (height.getHeight() == 0) { temp.add(Line.create(playerCount, random)); } this.lines = List.copyOf(temp); From ecac217fe7919c4d8ed19ec94d794659b604b762 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:35:19 +0900 Subject: [PATCH 11/46] =?UTF-8?q?=EC=9B=90=EC=8B=9C=EA=B0=92=20=ED=8F=AC?= =?UTF-8?q?=EC=9E=A5=20=EB=B0=8F=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EC=A0=81=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20LadderGame=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index 15a8793c..ea6790a2 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -10,13 +10,12 @@ public class LadderGame { private final Results results; public LadderGame(Ladder ladder, Players players, Results results) { - validatePlayerAndResultCount(players, results); this.ladder = ladder; this.players = players; this.results = results; } - private void validatePlayerAndResultCount(Players players, Results results) { + public static void validatePlayerAndResultCount(Players players, Results results) { if (players.size() != results.size()) { throw new IllegalArgumentException("참가자와 결과 수는 같아야 합니다."); } @@ -30,25 +29,25 @@ private int move(int position) { } private int calculateNextPosition(Line line, int position) { - if ((line.validateMoveRight(position))) return 1; - if ((line.validateMoveLeft(position))) return -1; + if (line.validateMoveRight(position).isConnected()) return 1; + if (line.validateMoveLeft(position).isConnected()) return -1; return 0; } public String findResultByPlayer(String name) { - List player = players.getPlayers().getValues(); - List result = results.getResults().getValues(); + List player = players.getPlayers().getValues(); + List result = results.getResults().getValues(); - int index = player.indexOf(name); + int index = player.indexOf(new Name(name)); index = move(index); - return result.get(index); + return result.get(index).value(); } public Map findAll() { Map map = new HashMap<>(); - List player = players.getPlayers().getValues(); - for (String name : player) { - map.put(name, findResultByPlayer(name)); + List player = players.getPlayers().getValues(); + for (Name name : player) { + map.put(name.value(), findResultByPlayer(name.value())); } return map; } From 1514d48ebb839aa96336e259cfc1f446d7a7d64e Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:36:26 +0900 Subject: [PATCH 12/46] =?UTF-8?q?Line=EC=97=90=20=EC=9D=BC=EA=B8=89=20?= =?UTF-8?q?=EC=BB=AC=EB=A0=89=EC=85=98(Point)=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20Connect=20enum=EC=9C=BC=EB=A1=9C=20=EC=9D=98?= =?UTF-8?q?=EB=AF=B8=20=EC=A0=84=EB=8B=AC=20=EB=AA=85=ED=99=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index f4174d09..1f106a59 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -5,43 +5,43 @@ import java.util.Random; public class Line { - private final List points; + private final List points; - private Line(List points) { + private Line(List points) { this.points = List.copyOf(points); } public static Line create(int playerCount, Random random) { - List points = new ArrayList<>(); - boolean prev = false; + List points = new ArrayList<>(); + Connect prev = Connect.DISCONNECTED; for (int i = 0; i < playerCount - 1; i++) { - boolean next = random.nextBoolean(); + Connect next = Connect.from(random.nextBoolean()); next = checkPrev(prev, next); - points.add(next); + points.add(new Point(next)); prev = next; } return new Line(points); } - private static boolean checkPrev(boolean prev, boolean next) { - if (prev) { - next = false; + private static Connect checkPrev(Connect prev, Connect next) { + if (prev.isConnected()) { + return Connect.DISCONNECTED; } return next; } - public boolean validateMoveRight(int index) { - if (index >= points.size()) return false; - return points.get(index); + public Connect validateMoveRight(int index) { + if (index >= points.size()) return Connect.DISCONNECTED; + return points.get(index).point(); } - public boolean validateMoveLeft(int index) { - if (index == 0) return false; - return points.get(index - 1); + public Connect validateMoveLeft(int index) { + if (index == 0) return Connect.DISCONNECTED; + return points.get(index - 1).point(); } - public List getPoints() { + public List getPoints() { return points; } } From 54ddd4d10a92b1cd742a70d988d6792fc334f01f Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:37:19 +0900 Subject: [PATCH 13/46] =?UTF-8?q?=EC=9E=85=EB=A0=A5=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=EC=9B=90=EC=8B=9C=EA=B0=92=EC=9C=BC=EB=A1=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=9E=A5=ED=95=98=EB=8A=94=20Name=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=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/domain/Name.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java index dadc1ce7..c8325fcd 100644 --- a/src/main/java/domain/Name.java +++ b/src/main/java/domain/Name.java @@ -1,35 +1,34 @@ package domain; -import java.util.Objects; - public class Name { private final String value; - public Name(String value){ - if (value == null || value.trim().isEmpty()){ + + public Name(String value) { + if (value == null || value.trim().isEmpty()) { throw new IllegalArgumentException("비어 있을 수 없습니다."); } this.value = value.trim(); } - public String value(){ + public String value() { return value; } @Override - public String toString(){ + public String toString() { return value; } @Override - public boolean equals(Object obj){ + public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Name)) return false; - Name name = (Name)obj; + Name name = (Name) obj; return value.equals(name.value); } @Override - public int hashCode(){ + public int hashCode() { return value.hashCode(); } } From 99aa5337e1bd7f8c67688edd55976dea437c67de Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:38:32 +0900 Subject: [PATCH 14/46] =?UTF-8?q?Names=EB=A5=BC=20=EC=9D=BC=EA=B8=89=20?= =?UTF-8?q?=EC=BB=AC=EB=A0=89=EC=85=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=98=EA=B3=A0=20=EB=B0=B0=EC=97=B4=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Names.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java index 2391a4ca..b78aa404 100644 --- a/src/main/java/domain/Names.java +++ b/src/main/java/domain/Names.java @@ -21,9 +21,7 @@ public Names(List names) { private void addIfValid(List temp, String token) { String trimmed = token.trim(); - if (!trimmed.isEmpty()) { - temp.add(new Name(trimmed)); - } + temp.add(new Name(trimmed)); } public int size() { From d8ce27fdd38dec392f53e30e89e81a8c64dd6ecf Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:43:15 +0900 Subject: [PATCH 15/46] =?UTF-8?q?Players=EC=97=90=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Players.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index 8ef75fbe..7dc35686 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -18,16 +18,18 @@ private Names removeDuplicate(String input) { for (String token : tokens) { String trimmed = token.trim(); - if (!trimmed.isEmpty()) { - Name name = new Name(trimmed); - if (!newInput.contains(name)) { - newInput.add(name); - } - } + Name name = new Name(trimmed); + addIfAbsent(newInput, name); } return new Names(newInput); } + private void addIfAbsent(List newInput, Name name) { + if (!newInput.contains(name)) { + newInput.add(name); + } + } + private void validatePlayerNames() { for (Name name : players.getValues()) { validateNameLength(name); From cbd131e76a99b1528bfa5efde8d6793e48e33125 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:44:49 +0900 Subject: [PATCH 16/46] =?UTF-8?q?=EC=9B=90=EC=8B=9C=EA=B0=92=20=ED=8F=AC?= =?UTF-8?q?=EC=9E=A5=20=EB=B0=8F=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EC=A0=81=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=88=98=EC=A0=95,=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=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/view/OutputView.java | 50 ++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1d6c3463..1b8e23c9 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,15 +1,18 @@ package view; +import domain.Connect; import domain.Ladder; import domain.Line; +import domain.Name; import domain.Players; +import domain.Point; import java.util.List; import java.util.Map; public class OutputView { public void printAskPlayers() { - System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼포(,)로 구분하세요)"); + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); } public void printAskResults() { @@ -28,13 +31,32 @@ public void printAskResultByPlayer() { System.out.println("\n결과를 보고 싶은 사람은?"); } - private void printPlayers(List players) { - for (String name : players) { + public void printRetryInputMessage() { + System.out.println("다시 입력해주세요."); + } + + public void printException(Exception e) { + if (e.getMessage() == null) { + System.out.println("숫자를 입력해주세요."); + return; + } + System.out.println(e.getMessage()); + } + + private void printPlayers(List players) { + for (Name name : players) { System.out.printf("%6s", name); } System.out.println(); } + private void printResults(List results) { + for (Name result : results) { + System.out.printf("%6s", result); + } + System.out.println(); + } + private void printLines(List lines) { for (Line line : lines) { System.out.print(" |"); @@ -44,41 +66,35 @@ private void printLines(List lines) { } private void printLine(Line line) { - for (boolean point : line.getPoints()) { - printPoint(point); + for (Point point : line.getPoints()) { + printPoint(point.point()); } } - private void printPoint(Boolean point) { - if (point) { + private void printPoint(Connect point) { + if (point.isConnected()) { System.out.print("-----|"); return; } System.out.print(" |"); } - public void printLadder(Ladder ladder, List players, List results) { + public void printLadder(Ladder ladder, List players, List results) { printPlayers(players); printLines(ladder.getLines()); printResults(results); } - private void printResults(List results) { - for (String result : results) { - System.out.printf("%6s", result); - } - System.out.println(); - } - public void printSingleResult(String name, String result) { + public void printSingleResult(String result) { System.out.println("\n실행 결과"); System.out.println(result); } public void printAllResults(Map results, Players players) { System.out.println("\n실행 결과"); - for (String name : players.getPlayers().getValues()) { - System.out.println(name + " : " + results.get(name)); + for (Name name : players.getPlayers().getValues()) { + System.out.println(name.value() + " : " + results.get(name.value())); } } } From 5d6dfca71bb78640f9b91aa862d927ae2c9d4740 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:45:20 +0900 Subject: [PATCH 17/46] =?UTF-8?q?Connect.from()=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=8F=99=EC=9E=91=20=EA=B2=80=EC=A6=9D=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=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 --- src/test/java/domain/ConnectTest.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/test/java/domain/ConnectTest.java diff --git a/src/test/java/domain/ConnectTest.java b/src/test/java/domain/ConnectTest.java new file mode 100644 index 00000000..ee9359aa --- /dev/null +++ b/src/test/java/domain/ConnectTest.java @@ -0,0 +1,25 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ConnectTest { + @Test + void from메서드_true면_CONNECTED_반환() { + //when + Connect value = Connect.from(true); + + //then + assertThat(value).isEqualTo(Connect.CONNECTED); + } + + @Test + void from메서드_true면_DISCONNECTED_반환() { + //when + Connect value = Connect.from(false); + + //then + assertThat(value).isEqualTo(Connect.DISCONNECTED); + } +} From fb63a02ebc8ab67f140599bc0e049d8574e9f111 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:45:57 +0900 Subject: [PATCH 18/46] =?UTF-8?q?LadderGame=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91=20=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/test/java/domain/LadderGameTest.java | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/java/domain/LadderGameTest.java diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java new file mode 100644 index 00000000..8b0b83d5 --- /dev/null +++ b/src/test/java/domain/LadderGameTest.java @@ -0,0 +1,60 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LadderGameTest { + + @Test + void 참가자와_결과_수_불일치() { + //given + Players players = new Players("태우,태우,태우1"); + Results results = new Results("꽝"); + + //when & then + assertThatThrownBy(() -> LadderGame.validatePlayerAndResultCount(players, results)) + .isInstanceOf(IllegalArgumentException.class); + + } + + @Test + void 참가자_이름으로_결과를_조회할_수_있다() { + //given + Players players = new Players("태우,태우1"); + Results results = new Results("꽝,5000"); + Height height = new Height(2); + Ladder ladder = new Ladder(height, players.size(), new Random(1)); + LadderGame game = new LadderGame(ladder, players, results); + + //when + String result1 = game.findResultByPlayer("태우"); + String result2 = game.findResultByPlayer("태우1"); + + //then + assertThat(result1).isIn("꽝", "5000"); + assertThat(result2).isIn("꽝", "5000"); + } + + @Test + void all_입력시_모든_참가자와_그_결과가_나온다() { + //given + Players players = new Players("태우,태우1"); + Results results = new Results("꽝,5000"); + Height height = new Height(2); + Ladder ladder = new Ladder(height, players.size(), new Random(1)); + LadderGame game = new LadderGame(ladder, players, results); + + //when + Map map = game.findAll(); + + //then + assertThat(map.keySet()).containsExactlyInAnyOrder("태우", "태우1"); + assertThat(map.values()).containsExactlyInAnyOrder("꽝", "5000"); + } + +} From a7b8c8174675935dd1c7047b3ccb0ffe6e50261b Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:46:35 +0900 Subject: [PATCH 19/46] =?UTF-8?q?Ladder=20=EB=86=92=EC=9D=B4=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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/test/java/domain/LadderTest.java | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/java/domain/LadderTest.java diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java new file mode 100644 index 00000000..f14782d5 --- /dev/null +++ b/src/test/java/domain/LadderTest.java @@ -0,0 +1,35 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +class LadderTest { + @Test + void 높이가_0인_사다리_생성() { + //given + Height height = new Height(0); + int playerCount = 3; + + //when + Ladder ladder = new Ladder(height, playerCount, new Random(1)); + + //then + assertThat(ladder.getLines()).hasSize(1); + } + + @Test + void 높이가_3인_사다리_생성() { + //given + Height height = new Height(3); + int playerCount = 3; + + //when + Ladder ladder = new Ladder(height, playerCount, new Random(1)); + + //then + assertThat(ladder.getLines()).hasSize(3); + } +} From ffe782d77452f1be5bd90e99fa81ffdf4146e406 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:47:10 +0900 Subject: [PATCH 20/46] =?UTF-8?q?Line=20=EC=83=9D=EC=84=B1=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99=20=EB=B0=8F=20=EC=9D=B4=EB=8F=99=20=EA=B2=BD=EA=B3=84?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=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/test/java/domain/LineTest.java | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/domain/LineTest.java diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java new file mode 100644 index 00000000..c2d52a4c --- /dev/null +++ b/src/test/java/domain/LineTest.java @@ -0,0 +1,52 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +class LineTest { + @Test + void 하나의_라인에_인접한_두_point가_CONNECTED이면_안된다() { + //givn + Random random = new Random(1); + int playerCount = 3; + + //when + Line line = Line.create(playerCount, random); + + //then + for (int i = 0; i < line.getPoints().size() - 1; i++) { + boolean prev = line.getPoints().get(i).point().isConnected(); + boolean next = line.getPoints().get(i + 1).point().isConnected(); + assertThat(prev && next).isFalse(); + } + } + + @Test + void 사다리가_맨끝인_경우_DISCONNECTED이다() { + //given + int index = 3; + Line line = Line.create(4, new Random(1)); + + //when + Connect result = line.validateMoveRight(index); + + //then + assertThat(result).isEqualTo(Connect.DISCONNECTED); + } + + @Test + void 사다리가_처음인_경우_DISCONNECTED이다() { + //given + int index = 0; + Line line = Line.create(4, new Random(1)); + + //when + Connect result = line.validateMoveLeft(index); + + //then + assertThat(result).isEqualTo(Connect.DISCONNECTED); + } +} From fb624ea6945e5091ea2e15263924758c3b786103 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:47:41 +0900 Subject: [PATCH 21/46] =?UTF-8?q?Name=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=85=8C=EC=8A=A4=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 --- src/test/java/domain/NamesTest.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/java/domain/NamesTest.java diff --git a/src/test/java/domain/NamesTest.java b/src/test/java/domain/NamesTest.java new file mode 100644 index 00000000..9f9f202b --- /dev/null +++ b/src/test/java/domain/NamesTest.java @@ -0,0 +1,22 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class NamesTest { + @Test + void 쉼표로_구분된_문자열_생성() { + //given + String input = "태우1,태우2"; + + //when + Names names = new Names(input); + + //then + assertThat(names.size()).isEqualTo(2); + assertThat(names.getValues()) + .extracting(Name::value) + .containsExactly("태우1", "태우2"); + } +} From 851055c3f8f66f12e9d785fe0b14b16a07f0fcb0 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:48:15 +0900 Subject: [PATCH 22/46] =?UTF-8?q?Name=20=EA=B0=92=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EC=9D=98=20=EC=9E=85=EB=A0=A5=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F?= =?UTF-8?q?=20=EB=8F=99=EB=93=B1=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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/test/java/domain/NameTest.java | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/test/java/domain/NameTest.java diff --git a/src/test/java/domain/NameTest.java b/src/test/java/domain/NameTest.java new file mode 100644 index 00000000..5010cd6d --- /dev/null +++ b/src/test/java/domain/NameTest.java @@ -0,0 +1,41 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class NameTest { + @Test + void 이름_공백제거_확인() { + //given + String input = " 태우"; + + //when + Name name = new Name(input); + + //then + assertThat(name.value()).isEqualTo("태우"); + } + + @Test + void 빈문자열_예외확인() { + //given + String input = " "; + + //when & then + assertThatThrownBy(() -> new Name(input)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 동일한_이름일시_True_반환() { + //given + Name n1 = new Name("태우"); + Name n2 = new Name("태우"); + + //when & then + assertThat(n1).isEqualTo(n2); + assertThat(n1.hashCode()).isEqualTo(n2.hashCode()); + } +} From 6a287b1add50201e836cd61272b2910949f2aab8 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:48:47 +0900 Subject: [PATCH 23/46] =?UTF-8?q?Players=20=EC=9D=B4=EB=A6=84=20=ED=8C=8C?= =?UTF-8?q?=EC=8B=B1,=20=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=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 --- src/test/java/domain/PlayersTest.java | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/java/domain/PlayersTest.java diff --git a/src/test/java/domain/PlayersTest.java b/src/test/java/domain/PlayersTest.java new file mode 100644 index 00000000..6e0b231a --- /dev/null +++ b/src/test/java/domain/PlayersTest.java @@ -0,0 +1,49 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayersTest { + @Test + void 쉼표로_구분된_문자열_생성() { + //given + String input = "태우1,태우2"; + + //when + Players players = new Players(input); + + //then + assertThat(players.size()).isEqualTo(2); + assertThat(players.getPlayers().getValues()) + .extracting(Name::value) + .containsExactly("태우1", "태우2"); + } + + @Test + void 이름_5글자_초과시_예외발생() { + //given + String input = "태우태우태우"; + + //when & then + assertThatThrownBy(() -> new Players(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름은 5글자를 넘기면 안됩니다."); + } + + @Test + void 중복된_이름은_저장하지_않는다() { + //given + String input = "태우,태우,태우1"; + + //when + Players players = new Players(input); + + //then + assertThat(players.size()).isEqualTo(2); + assertThat(players.getPlayers().getValues()) + .extracting(Name::value) + .containsExactly("태우", "태우1"); + } +} From 5d7fbc9af42a0efefd55ef0e6393b5c60121bc08 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:49:12 +0900 Subject: [PATCH 24/46] =?UTF-8?q?Point=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20?= =?UTF-8?q?Connect=20=EA=B0=92=20=EC=A0=95=EC=83=81=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=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/domain/Point.java | 14 ++++++++++++++ src/test/java/domain/PointTest.java | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/main/java/domain/Point.java create mode 100644 src/test/java/domain/PointTest.java diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java new file mode 100644 index 00000000..3e989721 --- /dev/null +++ b/src/main/java/domain/Point.java @@ -0,0 +1,14 @@ +package domain; + +public class Point { + private final Connect point; + + public Point(Connect connect) { + this.point = connect; + } + + public Connect point(){ + return point; + } + +} diff --git a/src/test/java/domain/PointTest.java b/src/test/java/domain/PointTest.java new file mode 100644 index 00000000..5c4228ed --- /dev/null +++ b/src/test/java/domain/PointTest.java @@ -0,0 +1,19 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class PointTest { + @Test + void 생성한_point가_Connect와_같은지_확인() { + //given + Connect connect = Connect.CONNECTED; + + //when + Point point = new Point(connect); + + //then + assertThat(point.point()).isEqualTo(connect); + } +} From 2ff5f2161fa3277fbdd2835f81ed36d87deb568a Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:50:37 +0900 Subject: [PATCH 25/46] =?UTF-8?q?Results=20=EB=AC=B8=EC=9E=90=EC=97=B4=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=20=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/test/java/domain/ResultsTest.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/java/domain/ResultsTest.java diff --git a/src/test/java/domain/ResultsTest.java b/src/test/java/domain/ResultsTest.java new file mode 100644 index 00000000..8509fd08 --- /dev/null +++ b/src/test/java/domain/ResultsTest.java @@ -0,0 +1,22 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ResultsTest { + @Test + void 쉼표로_구분된_문자열_생성() { + //given + String input = "꽝,5000,꽝"; + + //when + Results results = new Results(input); + + //then + assertThat(results.size()).isEqualTo(3); + assertThat(results.getResults().getValues()) + .extracting(Name::value) + .containsExactly("꽝", "5000", "꽝"); + } +} From 6fa0b0d04bbc0f2eb9643cbf13c59d7c34cd90a3 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:51:50 +0900 Subject: [PATCH 26/46] =?UTF-8?q?=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EB=AA=85=EC=84=B8=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/README.md diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..d4e6c0bd --- /dev/null +++ b/src/README.md @@ -0,0 +1,54 @@ +# 사다리 게임 + +## 💡 기능 요구사항 + +1. 사다리 게임에 참여하는 사람에 이름을 최대 5글자까지 부여할 수 있다. +2. 사다리를 출력할 때 사람 이름도 같이 출력한다. +3. 사람 이름은 쉼표(,)를 기준으로 구분한다. +4. 개인별 이름을 입력하면 개인별 결과를 출력한다. +5. `"all"`을 입력하면 전체 참여자의 실행 결과를 출력한다. + +--- + +## 클래스 소개 + +| 클래스 | 역할 | +|----------------------------|--------------------------------------| +| `Name` | 이름 단위를 표현 | +| `Names` | 이름들의 일급 컬렉션 | +| `Players` | 참가자 이름 목록 관리 및 중복 제거 | +| `Results` | 실행 결과 목록 관리 | +| `Height` | 사다리 높이 검증 및 저장 | +| `Connect` | `CONNECTED` / `DISCONNECTED` 상태 Enum | +| `Point` | 연결 여부(`Connect`) 표현 | +| `Line` | 한 줄의 연결 상태(`Point`) 관리 | +| `Ladder` | 사다리 전체를 구성 (여러 Line의 집합) | +| `LadderGame` | 이동 로직 및 결과 매핑 수행 | +| `LadderController` | 전체 게임 실행 흐름 제어 | +| `InputView` / `OutputView` | 입출력 담당 | +| `Main` | 프로그램 실행의 진입점 담당 | + +--- + +## 프로그램 실행 흐름 + +1. **입력 단계** + - 참여자 이름, 실행 결과, 사다리 높이를 순서대로 입력받는다. + - 이름과 결과의 개수가 다르면 예외를 발생시킨다. + - 이름이 5글자를 초과하면 예외를 발생한다. + - 사다리 높이가 양수가 아니거나 숫자가 아닌 입력이 들어오면 예외를 발생시킨다. + +--- + +2. **사다리 생성 단계** + - 입력받은 높이와 인원 수를 기반으로 `Ladder` 객체를 생성한다. + - 내부적으로 `Line.create()`를 호출하여 각 Line의 연결 상태를 무작위로 생성한다. + - 높이가 0인 경우에도 1줄의 사다리가 생성된다. + +--- + +3. **결과 조회 단계** + - 사용자가 이름을 입력하면 해당 참가자의 결과를 출력한다. + - `"all"`을 입력하면 전체 참가자의 결과를 한 번에 출력한다. + +--- From bf10258a1dcd92776201313905c81f4585774279 Mon Sep 17 00:00:00 2001 From: taewoo Date: Fri, 31 Oct 2025 22:55:55 +0900 Subject: [PATCH 27/46] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/README.md b/src/README.md index d4e6c0bd..640ddc5f 100644 --- a/src/README.md +++ b/src/README.md @@ -12,21 +12,21 @@ ## 클래스 소개 -| 클래스 | 역할 | -|----------------------------|--------------------------------------| -| `Name` | 이름 단위를 표현 | -| `Names` | 이름들의 일급 컬렉션 | -| `Players` | 참가자 이름 목록 관리 및 중복 제거 | -| `Results` | 실행 결과 목록 관리 | -| `Height` | 사다리 높이 검증 및 저장 | +| 클래스 | 역할| +|----------------------------|---| +| `Name` | 이름 단위를 표현 | +| `Names` | 이름들의 일급 컬렉션 | +| `Players` | 참가자 이름 목록 관리 및 중복 제거 | +| `Results` | 실행 결과 목록 관리 | +| `Height` | 사다리 높이 검증 및 저장 | | `Connect` | `CONNECTED` / `DISCONNECTED` 상태 Enum | -| `Point` | 연결 여부(`Connect`) 표현 | -| `Line` | 한 줄의 연결 상태(`Point`) 관리 | -| `Ladder` | 사다리 전체를 구성 (여러 Line의 집합) | -| `LadderGame` | 이동 로직 및 결과 매핑 수행 | -| `LadderController` | 전체 게임 실행 흐름 제어 | -| `InputView` / `OutputView` | 입출력 담당 | -| `Main` | 프로그램 실행의 진입점 담당 | +| `Point` | 연결 여부(`Connect`) 표현 | +| `Line` | 한 줄의 연결 상태(`Point`) 관리 | +| `Ladder` | 사다리 전체를 구성 (여러 Line의 집합) | +| `LadderGame` | 이동 로직 및 결과 매핑 수행 | +| `LadderController` | 전체 게임 실행 흐름 제어 | +| `InputView` / `OutputView` | 입출력 담당 | +| `Main` | 프로그램 실행의 진입점 담당 | --- From 5326b931a70fbf45fd720d94a0480a2cbc688ab6 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:52:54 +0900 Subject: [PATCH 28/46] =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EA=B7=9C=EC=B9=99=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EA=B2=8C=20Controller=20=EB=B0=8F=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=A1=9C=EC=A7=81=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 --- .../java/controller/LadderController.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java index ccc98d42..4b073d33 100644 --- a/src/main/java/controller/LadderController.java +++ b/src/main/java/controller/LadderController.java @@ -1,14 +1,17 @@ package controller; -import domain.Height; import domain.Ladder; import domain.LadderGame; +import domain.PlayerName; import domain.Players; +import domain.ResultName; import domain.Results; import view.InputView; import view.OutputView; +import java.util.Arrays; import java.util.InputMismatchException; +import java.util.List; import java.util.Random; public class LadderController { @@ -24,7 +27,12 @@ public Players inputPlayers() { outputView.printAskPlayers(); while (true) { try { - return new Players(inputView.readString()); + String input = inputView.readString(); + List players = Arrays.stream(input.split(",")) + .map(String::trim) + .map(PlayerName::new) + .toList(); + return new Players(players); } catch (IllegalArgumentException e) { outputView.printException(e); outputView.printRetryInputMessage(); @@ -36,7 +44,12 @@ public Results inputResults(Players players) { outputView.printAskResults(); while (true) { try { - Results results = new Results(inputView.readString()); + String input = inputView.readString(); + List result = Arrays.stream(input.split(",")) + .map(String::trim) + .map(ResultName::new) + .toList(); + Results results = new Results(result); LadderGame.validatePlayerAndResultCount(players, results); return results; } catch (IllegalArgumentException e) { @@ -46,11 +59,15 @@ public Results inputResults(Players players) { } } - public Height inputHeight() { + public int inputHeight() { outputView.printAskHeight(); while (true) { try { - return new Height(inputView.readInt()); + int height = inputView.readInt(); + if (height < 0) { + throw new IllegalArgumentException("높이는 양수여야 합니다."); + } + return height; } catch (InputMismatchException | IllegalArgumentException e) { outputView.printException(e); outputView.printRetryInputMessage(); @@ -58,13 +75,11 @@ public Height inputHeight() { } } - public LadderGame startLadderGame(Height height, Players players, Results results) { + public LadderGame startLadderGame(int height, Players players, Results results) { Ladder ladder = new Ladder(height, players.size(), new Random()); LadderGame game = new LadderGame(ladder, players, results); outputView.printLadderResultTitle(); - outputView.printLadder(ladder - , players.getPlayers().getValues() - , results.getResults().getValues()); + outputView.printLadder(ladder, players.getPlayers(), results.getResults()); return game; } From 931719247c2ed593043e96bbae9159bf83412b2e Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:53:47 +0900 Subject: [PATCH 29/46] =?UTF-8?q?Connect=20enum=EC=97=90=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=B1=85=EC=9E=84=EC=9D=84=20=EB=B6=80=EC=97=AC?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9D=91?= =?UTF-8?q?=EC=A7=91=EB=8F=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Connect.java | 34 ++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/Connect.java b/src/main/java/domain/Connect.java index e160a28d..b087e5ce 100644 --- a/src/main/java/domain/Connect.java +++ b/src/main/java/domain/Connect.java @@ -1,20 +1,44 @@ package domain; public enum Connect { - CONNECTED(true), - DISCONNECTED(false); + CONNECTED(true) { + @Override + public int moveRight(int index) { + return index + 1; + } + + @Override + public int moveLeft(int index) { + return index - 1; + } + }, + DISCONNECTED(false) { + @Override + public int moveRight(int index) { + return index; + } + + @Override + public int moveLeft(int index) { + return index; + } + }; private final boolean value; - Connect(boolean value){ + Connect(boolean value) { this.value = value; } - public boolean isConnected(){ + public abstract int moveRight(int index); + + public abstract int moveLeft(int index); + + public boolean isConnected() { return value; } - public static Connect from(boolean value){ + public static Connect from(boolean value) { return value ? CONNECTED : DISCONNECTED; } } From 339963b237a78a8f2429e8b2f18b3c955fd352c7 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:55:19 +0900 Subject: [PATCH 30/46] =?UTF-8?q?Height=20=EA=B0=9D=EC=B2=B4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=EC=97=90=20=EB=94=B0=EB=A5=B8=20Ladder=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=B6=80=20=EB=B0=8F=20=EC=97=B0=EA=B4=80=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=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/domain/Ladder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index b31738ab..f60bb7d5 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -7,13 +7,13 @@ public class Ladder { private final List lines; - public Ladder(Height height, int playerCount, Random random) { + public Ladder(int height, int playerCount, Random random) { List temp = new ArrayList<>(); - for (int i = 0; i < height.getHeight(); i++) { + for (int i = 0; i < height; i++) { temp.add(Line.create(playerCount, random)); } - if (height.getHeight() == 0) { + if (height == 0) { temp.add(Line.create(playerCount, random)); } this.lines = List.copyOf(temp); From 5570d3e11f021637038e49160734fd58e828fae5 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:56:41 +0900 Subject: [PATCH 31/46] =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=ED=8C=90=EB=8B=A8?= =?UTF-8?q?=EC=9D=84=20Line=EC=9C=BC=EB=A1=9C,=20=EC=8B=A4=EC=A0=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EA=B3=84=EC=82=B0=EC=9D=84=20Connect?= =?UTF-8?q?=EB=A1=9C=20=EC=9C=84=EC=9E=84=ED=95=98=EC=97=AC=20LadderGame?= =?UTF-8?q?=20=EC=B1=85=EC=9E=84=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/LadderGame.java | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java index ea6790a2..5655098f 100644 --- a/src/main/java/domain/LadderGame.java +++ b/src/main/java/domain/LadderGame.java @@ -23,30 +23,28 @@ public static void validatePlayerAndResultCount(Players players, Results results private int move(int position) { for (Line line : ladder.getLines()) { - position += calculateNextPosition(line, position); + position = line.moveOf(position); } return position; } - private int calculateNextPosition(Line line, int position) { - if (line.validateMoveRight(position).isConnected()) return 1; - if (line.validateMoveLeft(position).isConnected()) return -1; - return 0; - } public String findResultByPlayer(String name) { - List player = players.getPlayers().getValues(); - List result = results.getResults().getValues(); + List player = players.getPlayers(); + List result = results.getResults(); - int index = player.indexOf(new Name(name)); + int index = player.indexOf(new PlayerName(name)); + if (index < 0) { + throw new IllegalArgumentException("존재하지 않는 플레이어입니다."); + } index = move(index); return result.get(index).value(); } public Map findAll() { Map map = new HashMap<>(); - List player = players.getPlayers().getValues(); - for (Name name : player) { + List player = players.getPlayers(); + for (PlayerName name : player) { map.put(name.value(), findResultByPlayer(name.value())); } return map; From 9507b6bf37a46f2b15accaddfd4d1019b97ba7b2 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:57:08 +0900 Subject: [PATCH 32/46] =?UTF-8?q?=20Line=EC=9D=80=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=8C=90=EB=8B=A8=EB=A7=8C=20=EB=8B=B4?= =?UTF-8?q?=EB=8B=B9=ED=95=98=EA=B3=A0=20=EC=9D=B4=EB=8F=99=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EC=9D=80=20Connect=EB=A1=9C=20=EC=9C=84=EC=9E=84?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=B1=85=EC=9E=84=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Line.java | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 1f106a59..751c5423 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -5,20 +5,24 @@ import java.util.Random; public class Line { - private final List points; + private final List points; - private Line(List points) { + private Line(List points) { this.points = List.copyOf(points); } + static Line of(List points) { + return new Line(points); + } + public static Line create(int playerCount, Random random) { - List points = new ArrayList<>(); + List points = new ArrayList<>(); Connect prev = Connect.DISCONNECTED; for (int i = 0; i < playerCount - 1; i++) { Connect next = Connect.from(random.nextBoolean()); next = checkPrev(prev, next); - points.add(new Point(next)); + points.add(next); prev = next; } return new Line(points); @@ -31,17 +35,27 @@ private static Connect checkPrev(Connect prev, Connect next) { return next; } - public Connect validateMoveRight(int index) { + private Connect rightOf(int index) { if (index >= points.size()) return Connect.DISCONNECTED; - return points.get(index).point(); + return points.get(index); } - public Connect validateMoveLeft(int index) { - if (index == 0) return Connect.DISCONNECTED; - return points.get(index - 1).point(); + private Connect leftOf(int index) { + if (index <= 0) return Connect.DISCONNECTED; + return points.get(index - 1); + } + + public int moveOf(int index) { + Connect right = rightOf(index); + if (right.isConnected()) return right.moveRight(index); + + Connect left = leftOf(index); + if (left.isConnected()) return left.moveLeft(index); + + return index; } - public List getPoints() { + public List getPoints() { return points; } } From f5e4d9def14b35ddda31cc1d0956451bc074b22d Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:58:09 +0900 Subject: [PATCH 33/46] =?UTF-8?q?Players=EA=B0=80=20PlayerName=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=A7=81=EC=A0=91=20=EA=B0=80?= =?UTF-8?q?=EC=A7=80=EB=8F=84=EB=A1=9D=20=EA=B5=AC=EC=A1=B0=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Players.java | 45 ++++++++----------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java index 7dc35686..56a5b24d 100644 --- a/src/main/java/domain/Players.java +++ b/src/main/java/domain/Players.java @@ -1,44 +1,21 @@ package domain; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Players { - private static final int PLAYERS_NAME_MAX_LENGTH = 5; - private final Names players; + private final List players; - public Players(String input) { - this.players = removeDuplicate(input); - validatePlayerNames(); + public Players(List players) { + validateDuplicate(players); + this.players = List.copyOf(players); } - private Names removeDuplicate(String input) { - List tokens = List.of(input.split(",")); - List newInput = new ArrayList<>(); - - for (String token : tokens) { - String trimmed = token.trim(); - Name name = new Name(trimmed); - addIfAbsent(newInput, name); - } - return new Names(newInput); - } - - private void addIfAbsent(List newInput, Name name) { - if (!newInput.contains(name)) { - newInput.add(name); - } - } - - private void validatePlayerNames() { - for (Name name : players.getValues()) { - validateNameLength(name); - } - } - - private void validateNameLength(Name name) { - if (name.value().length() > PLAYERS_NAME_MAX_LENGTH) { - throw new IllegalArgumentException("이름은 5글자를 넘기면 안됩니다."); + private void validateDuplicate(List players) { + Set set = new HashSet<>(players); + if (set.size() != players.size()) { + throw new IllegalArgumentException("플레이어 이름은 중복될 수 없습니다."); } } @@ -46,7 +23,7 @@ public int size() { return players.size(); } - public Names getPlayers() { + public List getPlayers() { return players; } } From 370c1c8141fe79d08940c71d64933d3e689fdc85 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:58:39 +0900 Subject: [PATCH 34/46] =?UTF-8?q?=EC=B6=94=EC=83=81=20Name/Names=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=ED=9B=84=20PlayerName=20VO=EB=A1=9C=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9D=98=EB=AF=B8=20=EB=AA=85?= =?UTF-8?q?=ED=99=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/PlayerName.java | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/domain/PlayerName.java diff --git a/src/main/java/domain/PlayerName.java b/src/main/java/domain/PlayerName.java new file mode 100644 index 00000000..1852fe4d --- /dev/null +++ b/src/main/java/domain/PlayerName.java @@ -0,0 +1,43 @@ +package domain; + +public class PlayerName { + private static final int PLAYER_NAME_MAX_LENGTH = 5; + private final String value; + + public PlayerName(String value) { + if (value == null) { + throw new IllegalArgumentException("플레이어 이름은 null일 수 없습니다."); + } + String trimmed = value.trim(); + if (trimmed.isEmpty()) { + throw new IllegalArgumentException("플레이어 이름은 비어있을 수 없습니다."); + } + + if (trimmed.length() > PLAYER_NAME_MAX_LENGTH) { + throw new IllegalArgumentException("플에이어 이름은 5글자를 넘으면 안됩니다."); + } + this.value = trimmed; + } + + public String value() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof PlayerName)) return false; + PlayerName other = (PlayerName) obj; + return value.equals(other.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value; + } +} From b4a8608931abc9144644b6a21ffeaf8100ebe89f Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:59:18 +0900 Subject: [PATCH 35/46] =?UTF-8?q?=20=EC=B6=94=EC=83=81=20Name/Names=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=ED=9B=84=20ResultName=20VO=EB=A1=9C=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9D=98?= =?UTF-8?q?=EB=AF=B8=20=EB=AA=85=ED=99=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/ResultName.java | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/domain/ResultName.java diff --git a/src/main/java/domain/ResultName.java b/src/main/java/domain/ResultName.java new file mode 100644 index 00000000..55938b32 --- /dev/null +++ b/src/main/java/domain/ResultName.java @@ -0,0 +1,39 @@ +package domain; + +public class ResultName { + private final String value; + + public ResultName(String value) { + if (value == null) { + throw new IllegalArgumentException("결과 이름은 null일 수 없습니다."); + } + String trimmed = value.trim(); + if (trimmed.isEmpty()) { + throw new IllegalArgumentException("결과 이름은 비어있을 수 없습니다."); + } + + this.value = trimmed; + } + + public String value() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof ResultName)) return false; + ResultName other = (ResultName) obj; + return value.equals(other.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value; + } +} From ab293fe44304865d139b1b8fab891c3624718f78 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 17:59:57 +0900 Subject: [PATCH 36/46] =?UTF-8?q?=20Results=EA=B0=80=20ResultName=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EA=B0=80=EC=A7=80=EB=8F=84=EB=A1=9D=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Results.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/Results.java b/src/main/java/domain/Results.java index 1613f4e5..fbf27ad0 100644 --- a/src/main/java/domain/Results.java +++ b/src/main/java/domain/Results.java @@ -1,17 +1,19 @@ package domain; +import java.util.List; + public class Results { - private final Names results; + private final List results; - public Results(String input) { - this.results = new Names(input); + public Results(List results) { + this.results = List.copyOf(results); } public int size() { return results.size(); } - public Names getResults() { + public List getResults() { return results; } } From fdb8c207b7276d2ee95aa889c7c50c2aeac5e1dc Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:00:12 +0900 Subject: [PATCH 37/46] =?UTF-8?q?=EC=82=AD=EC=A0=9C=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Height.java | 36 ------------------------- src/main/java/domain/Name.java | 34 ------------------------ src/main/java/domain/Names.java | 34 ------------------------ src/main/java/domain/Point.java | 14 ---------- src/test/java/domain/NameTest.java | 41 ----------------------------- src/test/java/domain/NamesTest.java | 22 ---------------- src/test/java/domain/PointTest.java | 19 ------------- 7 files changed, 200 deletions(-) delete mode 100644 src/main/java/domain/Height.java delete mode 100644 src/main/java/domain/Name.java delete mode 100644 src/main/java/domain/Names.java delete mode 100644 src/main/java/domain/Point.java delete mode 100644 src/test/java/domain/NameTest.java delete mode 100644 src/test/java/domain/NamesTest.java delete mode 100644 src/test/java/domain/PointTest.java diff --git a/src/main/java/domain/Height.java b/src/main/java/domain/Height.java deleted file mode 100644 index e04b2856..00000000 --- a/src/main/java/domain/Height.java +++ /dev/null @@ -1,36 +0,0 @@ -package domain; - -public class Height { - private static final int HEIGHT_MIN = 0; - private final int height; - - public Height(int height) { - if (height < HEIGHT_MIN) { - throw new IllegalArgumentException("사다리 높이는 양수여야 합니다."); - } - - this.height = height; - } - - public int getHeight() { - return height; - } - - @Override - public String toString() { - return String.valueOf(height); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof Height)) return false; - Height other = (Height) obj; - return height == other.getHeight(); - } - - @Override - public int hashCode() { - return Integer.hashCode(height); - } -} diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java deleted file mode 100644 index c8325fcd..00000000 --- a/src/main/java/domain/Name.java +++ /dev/null @@ -1,34 +0,0 @@ -package domain; - -public class Name { - private final String value; - - public Name(String value) { - if (value == null || value.trim().isEmpty()) { - throw new IllegalArgumentException("비어 있을 수 없습니다."); - } - this.value = value.trim(); - } - - public String value() { - return value; - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof Name)) return false; - Name name = (Name) obj; - return value.equals(name.value); - } - - @Override - public int hashCode() { - return value.hashCode(); - } -} diff --git a/src/main/java/domain/Names.java b/src/main/java/domain/Names.java deleted file mode 100644 index b78aa404..00000000 --- a/src/main/java/domain/Names.java +++ /dev/null @@ -1,34 +0,0 @@ -package domain; - -import java.util.ArrayList; -import java.util.List; - -public class Names { - private final List values; - - public Names(String input) { - List tokens = List.of(input.split(",")); - List temp = new ArrayList<>(); - for (String token : tokens) { - addIfValid(temp, token); - } - this.values = List.copyOf(temp); - } - - public Names(List names) { - this.values = List.copyOf(names); - } - - private void addIfValid(List temp, String token) { - String trimmed = token.trim(); - temp.add(new Name(trimmed)); - } - - public int size() { - return values.size(); - } - - public List getValues() { - return values; - } -} diff --git a/src/main/java/domain/Point.java b/src/main/java/domain/Point.java deleted file mode 100644 index 3e989721..00000000 --- a/src/main/java/domain/Point.java +++ /dev/null @@ -1,14 +0,0 @@ -package domain; - -public class Point { - private final Connect point; - - public Point(Connect connect) { - this.point = connect; - } - - public Connect point(){ - return point; - } - -} diff --git a/src/test/java/domain/NameTest.java b/src/test/java/domain/NameTest.java deleted file mode 100644 index 5010cd6d..00000000 --- a/src/test/java/domain/NameTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package domain; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -class NameTest { - @Test - void 이름_공백제거_확인() { - //given - String input = " 태우"; - - //when - Name name = new Name(input); - - //then - assertThat(name.value()).isEqualTo("태우"); - } - - @Test - void 빈문자열_예외확인() { - //given - String input = " "; - - //when & then - assertThatThrownBy(() -> new Name(input)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void 동일한_이름일시_True_반환() { - //given - Name n1 = new Name("태우"); - Name n2 = new Name("태우"); - - //when & then - assertThat(n1).isEqualTo(n2); - assertThat(n1.hashCode()).isEqualTo(n2.hashCode()); - } -} diff --git a/src/test/java/domain/NamesTest.java b/src/test/java/domain/NamesTest.java deleted file mode 100644 index 9f9f202b..00000000 --- a/src/test/java/domain/NamesTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package domain; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class NamesTest { - @Test - void 쉼표로_구분된_문자열_생성() { - //given - String input = "태우1,태우2"; - - //when - Names names = new Names(input); - - //then - assertThat(names.size()).isEqualTo(2); - assertThat(names.getValues()) - .extracting(Name::value) - .containsExactly("태우1", "태우2"); - } -} diff --git a/src/test/java/domain/PointTest.java b/src/test/java/domain/PointTest.java deleted file mode 100644 index 5c4228ed..00000000 --- a/src/test/java/domain/PointTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package domain; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class PointTest { - @Test - void 생성한_point가_Connect와_같은지_확인() { - //given - Connect connect = Connect.CONNECTED; - - //when - Point point = new Point(connect); - - //then - assertThat(point.point()).isEqualTo(connect); - } -} From 4f5bc72a2fbb3ca59396c1abd5e24b29213bfb9b Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:01:20 +0900 Subject: [PATCH 38/46] =?UTF-8?q?Name/Names=20=EC=82=AD=EC=A0=9C=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=A5=B8=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/Main.java | 3 +-- src/main/java/view/OutputView.java | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 282f55df..0b99e6e8 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,5 +1,4 @@ import controller.LadderController; -import domain.Height; import domain.LadderGame; import domain.Players; import domain.Results; @@ -14,7 +13,7 @@ public static void main(String[] args) { Players players = controller.inputPlayers(); Results results = controller.inputResults(players); - Height height = controller.inputHeight(); + int height = controller.inputHeight(); LadderGame game = controller.startLadderGame(height, players, results); controller.showResult(game, players); diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1b8e23c9..0d2611e4 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -3,9 +3,9 @@ import domain.Connect; import domain.Ladder; import domain.Line; -import domain.Name; +import domain.PlayerName; import domain.Players; -import domain.Point; +import domain.ResultName; import java.util.List; import java.util.Map; @@ -43,15 +43,15 @@ public void printException(Exception e) { System.out.println(e.getMessage()); } - private void printPlayers(List players) { - for (Name name : players) { + private void printPlayers(List players) { + for (PlayerName name : players) { System.out.printf("%6s", name); } System.out.println(); } - private void printResults(List results) { - for (Name result : results) { + private void printResults(List results) { + for (ResultName result : results) { System.out.printf("%6s", result); } System.out.println(); @@ -66,8 +66,8 @@ private void printLines(List lines) { } private void printLine(Line line) { - for (Point point : line.getPoints()) { - printPoint(point.point()); + for (Connect point : line.getPoints()) { + printPoint(point); } } @@ -79,7 +79,7 @@ private void printPoint(Connect point) { System.out.print(" |"); } - public void printLadder(Ladder ladder, List players, List results) { + public void printLadder(Ladder ladder, List players, List results) { printPlayers(players); printLines(ladder.getLines()); printResults(results); @@ -93,7 +93,7 @@ public void printSingleResult(String result) { public void printAllResults(Map results, Players players) { System.out.println("\n실행 결과"); - for (Name name : players.getPlayers().getValues()) { + for (PlayerName name : players.getPlayers()) { System.out.println(name.value() + " : " + results.get(name.value())); } } From 4db9002091d727c31fa8e6b6fbf01d7fe604f38b Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:02:40 +0900 Subject: [PATCH 39/46] =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=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 --- src/test/java/domain/ConnectTest.java | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/test/java/domain/ConnectTest.java b/src/test/java/domain/ConnectTest.java index ee9359aa..09e4ace5 100644 --- a/src/test/java/domain/ConnectTest.java +++ b/src/test/java/domain/ConnectTest.java @@ -22,4 +22,42 @@ class ConnectTest { //then assertThat(value).isEqualTo(Connect.DISCONNECTED); } + + @Test + void CONNECTED_왼쪽으로_이동한다() { + //give + int index = 3; + + //when + int result = Connect.CONNECTED.moveLeft(index); + + //then + assertThat(result).isEqualTo(2); + } + + @Test + void CONNECTED_오른쪽으로_이동한다() { + //give + int index = 3; + + //when + int result = Connect.CONNECTED.moveRight(index); + + //then + assertThat(result).isEqualTo(4); + } + + @Test + void DISCONNECTED_제자리이다() { + //give + int index = 3; + + //when + int result1 = Connect.DISCONNECTED.moveRight(index); + int result2 = Connect.DISCONNECTED.moveLeft(index); + + //then + assertThat(result1).isEqualTo(3); + assertThat(result2).isEqualTo(3); + } } From e23bafd533e8d95d92630566b9c3593ac8f55793 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:03:22 +0900 Subject: [PATCH 40/46] =?UTF-8?q?=20PlayerName/ResultName=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=EC=9C=BC=EB=A1=9C=20LadderGame=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LadderGameTest.java | 31 ++++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/test/java/domain/LadderGameTest.java b/src/test/java/domain/LadderGameTest.java index 8b0b83d5..202932b2 100644 --- a/src/test/java/domain/LadderGameTest.java +++ b/src/test/java/domain/LadderGameTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Map; import java.util.Random; @@ -13,8 +14,8 @@ class LadderGameTest { @Test void 참가자와_결과_수_불일치() { //given - Players players = new Players("태우,태우,태우1"); - Results results = new Results("꽝"); + Players players = new Players(List.of(new PlayerName("태우"), new PlayerName("태우1"))); + Results results = new Results(List.of(new ResultName("꽝"))); //when & then assertThatThrownBy(() -> LadderGame.validatePlayerAndResultCount(players, results)) @@ -25,9 +26,9 @@ class LadderGameTest { @Test void 참가자_이름으로_결과를_조회할_수_있다() { //given - Players players = new Players("태우,태우1"); - Results results = new Results("꽝,5000"); - Height height = new Height(2); + Players players = new Players(List.of(new PlayerName("태우"), new PlayerName("태우1"))); + Results results = new Results(List.of(new ResultName("꽝"), new ResultName("5000"))); + int height = 2; Ladder ladder = new Ladder(height, players.size(), new Random(1)); LadderGame game = new LadderGame(ladder, players, results); @@ -43,9 +44,9 @@ class LadderGameTest { @Test void all_입력시_모든_참가자와_그_결과가_나온다() { //given - Players players = new Players("태우,태우1"); - Results results = new Results("꽝,5000"); - Height height = new Height(2); + Players players = new Players(List.of(new PlayerName("태우"), new PlayerName("태우1"))); + Results results = new Results(List.of(new ResultName("꽝"), new ResultName("5000"))); + int height = 2; Ladder ladder = new Ladder(height, players.size(), new Random(1)); LadderGame game = new LadderGame(ladder, players, results); @@ -57,4 +58,18 @@ class LadderGameTest { assertThat(map.values()).containsExactlyInAnyOrder("꽝", "5000"); } + @Test + void 존재하지_않는_플레이어_조회시_예외() { + //given + Players players = new Players(List.of(new PlayerName("태우"), new PlayerName("태우1"))); + Results results = new Results(List.of(new ResultName("꽝"), new ResultName("5000"))); + int height = 2; + Ladder ladder = new Ladder(height, players.size(), new Random(1)); + LadderGame game = new LadderGame(ladder, players, results); + + // when & then + assertThatThrownBy(() -> game.findResultByPlayer("철수")) + .isInstanceOf(IllegalArgumentException.class); + + } } From 7e4d3668fb82d92b0539ddbb3670f5cc46eb0c21 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:04:04 +0900 Subject: [PATCH 41/46] =?UTF-8?q?Height=20=EC=A0=9C=EA=B1=B0=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=9D=BC=20LadderTest=EB=A5=BC=20int=20height=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LadderTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/domain/LadderTest.java b/src/test/java/domain/LadderTest.java index f14782d5..1f0cec5b 100644 --- a/src/test/java/domain/LadderTest.java +++ b/src/test/java/domain/LadderTest.java @@ -10,7 +10,7 @@ class LadderTest { @Test void 높이가_0인_사다리_생성() { //given - Height height = new Height(0); + int height = 0; int playerCount = 3; //when @@ -23,7 +23,7 @@ class LadderTest { @Test void 높이가_3인_사다리_생성() { //given - Height height = new Height(3); + int height = 3; int playerCount = 3; //when @@ -32,4 +32,5 @@ class LadderTest { //then assertThat(ladder.getLines()).hasSize(3); } + } From ff4df5e4b113920fc1e4a740fd22f058fe11e4d0 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:04:50 +0900 Subject: [PATCH 42/46] =?UTF-8?q?Line=20=EC=9D=B4=EB=8F=99=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99=EC=9D=84=20moveOf=20=EA=B8=B0=EC=A4=80=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9E=AC=EA=B5=AC=EC=84=B1=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=B3=B4?= =?UTF-8?q?=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/LineTest.java | 77 +++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java index c2d52a4c..e02c7f15 100644 --- a/src/test/java/domain/LineTest.java +++ b/src/test/java/domain/LineTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Random; import static org.assertj.core.api.Assertions.assertThat; @@ -18,35 +19,89 @@ class LineTest { //then for (int i = 0; i < line.getPoints().size() - 1; i++) { - boolean prev = line.getPoints().get(i).point().isConnected(); - boolean next = line.getPoints().get(i + 1).point().isConnected(); + boolean prev = line.getPoints().get(i).isConnected(); + boolean next = line.getPoints().get(i + 1).isConnected(); assertThat(prev && next).isFalse(); } } @Test - void 사다리가_맨끝인_경우_DISCONNECTED이다() { + void 라인_마지막_인덱스면_오른쪽이동불가() { //given - int index = 3; - Line line = Line.create(4, new Random(1)); + int index = 2; + Line line = Line.of(List.of( + Connect.CONNECTED, + Connect.DISCONNECTED + )); //when - Connect result = line.validateMoveRight(index); + int result = line.moveOf(index); //then - assertThat(result).isEqualTo(Connect.DISCONNECTED); + assertThat(result).isEqualTo(index); } @Test - void 사다리가_처음인_경우_DISCONNECTED이다() { + void 라인_처음_인덱스면_왼쪽이동불가() { //given + Line line = Line.of(List.of( + Connect.DISCONNECTED, + Connect.CONNECTED + )); int index = 0; - Line line = Line.create(4, new Random(1)); //when - Connect result = line.validateMoveLeft(index); + int result = line.moveOf(index); //then - assertThat(result).isEqualTo(Connect.DISCONNECTED); + assertThat(result).isEqualTo(index); + } + + @Test + void 오른쪽은_DISCONNECTED_왼쪽은_CONNECTED면_왼쪽_으로_이동한다() { + // given + Line line = Line.of(List.of( + Connect.DISCONNECTED, + Connect.CONNECTED + )); + int index = 2; + + // when + int result = line.moveOf(index); + + // then + assertThat(result).isEqualTo(1); + } + + @Test + void 오른쪽은_CONNECTED_왼쪽은_DISCONNECTED면_오른쪽_으로_이동한다() { + // given + Line line = Line.of(List.of( + Connect.DISCONNECTED, + Connect.CONNECTED + )); + int index = 1; + + // when + int result = line.moveOf(index); + + // then + assertThat(result).isEqualTo(2); + } + + @Test + void 양쪽모두_DISCONNECTED면_제자리() { + //give + Line line = Line.of(List.of( + Connect.DISCONNECTED, + Connect.DISCONNECTED + )); + int index = 1; + + //when + int result = line.moveOf(index); + + //then + assertThat(result).isEqualTo(index); } } From 33e9c62c0bfc598f2fa9972ad3bebc589a4fde12 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:05:15 +0900 Subject: [PATCH 43/46] =?UTF-8?q?=20PlayerName=20VO=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=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 --- src/test/java/domain/PlayerNameTest.java | 42 ++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/java/domain/PlayerNameTest.java diff --git a/src/test/java/domain/PlayerNameTest.java b/src/test/java/domain/PlayerNameTest.java new file mode 100644 index 00000000..3247778b --- /dev/null +++ b/src/test/java/domain/PlayerNameTest.java @@ -0,0 +1,42 @@ +package domain; + + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayerNameTest { + @Test + void null은_허용되지_않는다() { + // when & then + assertThatThrownBy(() -> new PlayerName(null)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 빈문자열은_허용되지_않는다() { + // when & then + assertThatThrownBy(() -> new PlayerName(" ")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 이름은_5글자를_초과할_수_없다() { + // when & then + assertThatThrownBy(() -> new PlayerName("태우태우태우")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 정상_이름이면_생성된다() { + // given + String name = "태우"; + + // when + PlayerName playerName = new PlayerName(name); + + // then + assertThat(playerName.value()).isEqualTo(name); + } +} From e023d6de36fdc9c409bcf5141ebcd2b08bf2ee38 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:05:52 +0900 Subject: [PATCH 44/46] =?UTF-8?q?PlayerName=20=EA=B8=B0=EB=B0=98=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20PlayersTest=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/PlayersTest.java | 46 +++++++++------------------ 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/src/test/java/domain/PlayersTest.java b/src/test/java/domain/PlayersTest.java index 6e0b231a..6cb596e0 100644 --- a/src/test/java/domain/PlayersTest.java +++ b/src/test/java/domain/PlayersTest.java @@ -2,48 +2,32 @@ import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class PlayersTest { + @Test - void 쉼표로_구분된_문자열_생성() { - //given - String input = "태우1,태우2"; + void 플레이어_리스트를_생성할_수_있다() { + // given + List list = List.of(new PlayerName("태우1"), new PlayerName("태우2")); - //when - Players players = new Players(input); + // when + Players players = new Players(list); - //then + // then assertThat(players.size()).isEqualTo(2); - assertThat(players.getPlayers().getValues()) - .extracting(Name::value) - .containsExactly("태우1", "태우2"); } @Test - void 이름_5글자_초과시_예외발생() { - //given - String input = "태우태우태우"; - - //when & then - assertThatThrownBy(() -> new Players(input)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("이름은 5글자를 넘기면 안됩니다."); - } + void 중복된_이름이_있으면_예외() { + // given + List list = List.of(new PlayerName("태우"), new PlayerName("태우")); - @Test - void 중복된_이름은_저장하지_않는다() { - //given - String input = "태우,태우,태우1"; - - //when - Players players = new Players(input); - - //then - assertThat(players.size()).isEqualTo(2); - assertThat(players.getPlayers().getValues()) - .extracting(Name::value) - .containsExactly("태우", "태우1"); + // when & then + assertThatThrownBy(() -> new Players(list)) + .isInstanceOf(IllegalArgumentException.class); } } From ff8a8db128beba4060b410e21e860d0a348255e5 Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:06:13 +0900 Subject: [PATCH 45/46] =?UTF-8?q?ResultName=20VO=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=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 --- src/test/java/domain/ResultNameTest.java | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/java/domain/ResultNameTest.java diff --git a/src/test/java/domain/ResultNameTest.java b/src/test/java/domain/ResultNameTest.java new file mode 100644 index 00000000..edd16a84 --- /dev/null +++ b/src/test/java/domain/ResultNameTest.java @@ -0,0 +1,35 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class ResultNameTest { + @Test + void null은_허용되지_않는다() { + // when & then + assertThatThrownBy(() -> new ResultName(null)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 빈문자열은_허용되지_않는다() { + // when & then + assertThatThrownBy(() -> new ResultName(" ")) + .isInstanceOf(IllegalArgumentException.class); + } + + + @Test + void 정상_이름이면_생성된다() { + // given + String name = "태우"; + + // when + ResultName resultName = new ResultName(name); + + // then + assertThat(resultName.value()).isEqualTo(name); + } +} From bf23911eb5a6c5b5b104c99bff70e44be9158c7e Mon Sep 17 00:00:00 2001 From: taewoo Date: Mon, 3 Nov 2025 18:06:38 +0900 Subject: [PATCH 46/46] =?UTF-8?q?ResultName=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20ResultsTest=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 --- src/test/java/domain/ResultsTest.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/test/java/domain/ResultsTest.java b/src/test/java/domain/ResultsTest.java index 8509fd08..d81b82db 100644 --- a/src/test/java/domain/ResultsTest.java +++ b/src/test/java/domain/ResultsTest.java @@ -2,21 +2,20 @@ import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; class ResultsTest { @Test - void 쉼표로_구분된_문자열_생성() { - //given - String input = "꽝,5000,꽝"; + void 결과_리스트를_생성할_수_있다() { + // given + List list = List.of(new ResultName("태우1"), new ResultName("태우2")); - //when - Results results = new Results(input); + // when + Results results = new Results(list); - //then - assertThat(results.size()).isEqualTo(3); - assertThat(results.getResults().getValues()) - .extracting(Name::value) - .containsExactly("꽝", "5000", "꽝"); + // then + assertThat(results.size()).isEqualTo(2); } }