From c907d1c03eb4f863627b66632725a049cc7700de Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 01:58:21 +0900 Subject: [PATCH 01/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC?= =?UTF-8?q?=EC=9D=98=20=EA=B0=80=EB=A1=9C,=20=EC=84=B8=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=92=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9B=90=EC=8B=9C?= =?UTF-8?q?=EA=B0=92=20=ED=8F=AC=EC=9E=A5=20-=20=EA=B0=81=20=EA=B0=92?= =?UTF-8?q?=EB=93=A4=EC=9D=80=20=EC=83=9D=EC=84=B1=EC=9E=90=EB=A5=BC=20pri?= =?UTF-8?q?vate=EB=A1=9C=20=ED=95=98=EA=B3=A0=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=86=B5=ED=95=B4=20=EA=B2=80=EC=A6=9D=20=ED=9B=84?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20-=20=EA=B0=80=EB=A1=9C=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D:=20=EC=B5=9C=EC=86=8C=20=EB=91=90=20=EB=AA=85?= =?UTF-8?q?=EC=9D=98=20=EC=B0=B8=EA=B0=80=EC=9E=90=EA=B0=80=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20value=20<=202=20-=20=EC=84=B8=EB=A1=9C=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D:=201=20=EC=9D=B4=EC=83=81=EC=9D=98=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EC=9E=85=EB=A0=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20value=20<=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/LadderHeight.java | 25 +++++++++++++++++ src/main/java/ladder/domain/LadderWidth.java | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/main/java/ladder/domain/LadderHeight.java create mode 100644 src/main/java/ladder/domain/LadderWidth.java diff --git a/src/main/java/ladder/domain/LadderHeight.java b/src/main/java/ladder/domain/LadderHeight.java new file mode 100644 index 00000000..e75c2ad6 --- /dev/null +++ b/src/main/java/ladder/domain/LadderHeight.java @@ -0,0 +1,25 @@ +package ladder.domain; + +public class LadderHeight { + private final int value; + + private LadderHeight(int value) { + this.value = value; + } + + public static LadderHeight from(int value) { + validate(value); + return new LadderHeight(value); + } + + public int getValue() { + return value; + } + + private static void validate(int value) { + if (value < 1) { + throw new IllegalArgumentException("참여할 사람은 최소 2명 이상이어야 합니다."); + } + } + +} diff --git a/src/main/java/ladder/domain/LadderWidth.java b/src/main/java/ladder/domain/LadderWidth.java new file mode 100644 index 00000000..fa4a4317 --- /dev/null +++ b/src/main/java/ladder/domain/LadderWidth.java @@ -0,0 +1,28 @@ +package ladder.domain; + +public class LadderWidth { + private final int value; + + private LadderWidth(int value) { + this.value = value; + } + + public static LadderWidth from(int value) { + validate(value); + return new LadderWidth(value); + } + + public int getPointCount() { // 다리 수 = 참여자 수 -1 + return value - 1; + } + + public int getValue() { + return value; + } + + private static void validate(int value) { + if (value < 2) { + throw new IllegalArgumentException("참여할 사람은 최소 2명 이상이어야 합니다."); + } + } +} From 3df589347a7440ea76a2abffe093e3ac80a91783 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:01:27 +0900 Subject: [PATCH 02/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A7=80=EC=A0=90=20=EC=83=81=ED=83=9C=EB=A5=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20Point=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EA=B5=AC=ED=98=84=20-=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EB=B0=A9=EC=A7=80=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=A0=95=EC=A0=81=20=ED=8C=A9=ED=84=B0?= =?UTF-8?q?=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B0=8F=20=EC=BA=90?= =?UTF-8?q?=EC=8B=B1=20=EC=A0=81=EC=9A=A9=20-=20boolean=20=EC=9B=90?= =?UTF-8?q?=EC=8B=9C=20=EA=B0=92=20=ED=8F=AC=EC=9E=A5=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BA=A1=EC=8A=90=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Point.java | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/ladder/domain/Point.java diff --git a/src/main/java/ladder/domain/Point.java b/src/main/java/ladder/domain/Point.java new file mode 100644 index 00000000..a613c2a2 --- /dev/null +++ b/src/main/java/ladder/domain/Point.java @@ -0,0 +1,24 @@ +package ladder.domain; + +public class Point { + + private static final Point BRIDGE = new Point(true); + private static final Point EMPTY = new Point(false); + + private final boolean hasBridge; + + private Point(boolean hasBridge) { + this.hasBridge = hasBridge; + } + + public static Point from(boolean hasBridge) { + if (hasBridge) { + return BRIDGE; + } + return EMPTY; + } + + public boolean hasBridge() { + return hasBridge; + } +} From 8d031318a12a09b4ec8f2990624899e147253725 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:02:22 +0900 Subject: [PATCH 03/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC?= =?UTF-8?q?=EC=9D=98=20=EA=B0=80=EB=A1=9C=20=ED=95=9C=20=EC=A4=84=EC=9D=84?= =?UTF-8?q?=20=EB=8B=B4=EB=8B=B9=ED=95=98=EB=8A=94=20Line=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EA=B5=AC=ED=98=84=20-=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=ED=86=B5=ED=95=B4=20Point=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=A1=B0=EB=A6=BD=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20=EA=B0=80=EB=A1=9C=20=EB=9D=BC=EC=9D=B8?= =?UTF-8?q?=EC=9D=B4=20=EA=B2=B9=EC=B9=98=EC=A7=80=20=EC=95=8A=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=97=B0=EC=86=8D=20=EC=83=9D=EC=84=B1=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80=20=EB=A1=9C=EC=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Line.java | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/ladder/domain/Line.java diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java new file mode 100644 index 00000000..dd3f9dee --- /dev/null +++ b/src/main/java/ladder/domain/Line.java @@ -0,0 +1,44 @@ +package ladder.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 = points; + } + + public static Line from(int size) { + return new Line(generatePoints(size)); + } + + public List getPoints() { + return points; + } + + private static List generatePoints(int size) { + List points = new ArrayList<>(); + boolean lastBridge = false; + for (int i = 0; i < size; i++) { + lastBridge = addPoint(points, lastBridge); + } + return points; + } + + private static boolean addPoint(List points, boolean lastBridge) { + boolean currentBridge = canDraw(lastBridge); + points.add(Point.from(currentBridge)); + return currentBridge; + } + + private static boolean canDraw(boolean lastBridge) { + if (lastBridge) { + return false; + } + return new Random().nextBoolean(); + } +} From 9b6cb0c4d4602076d273c62f9bd336e54d2f41c8 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:03:16 +0900 Subject: [PATCH 04/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=84=EC=B2=B4=20=EA=B5=AC=EC=A1=B0=EB=A5=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20Ladder=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EA=B5=AC=ED=98=84=20-=20LadderWidth?= =?UTF-8?q?=EC=99=80=20LadderHeight=EB=A5=BC=20=EA=B8=B0=EB=B0=98=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EC=A1=B0=EB=A6=BD=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20-=20List?= =?UTF-8?q?=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20=EC=9D=BC?= =?UTF-8?q?=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Ladder.java | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/ladder/domain/Ladder.java diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java new file mode 100644 index 00000000..6415c851 --- /dev/null +++ b/src/main/java/ladder/domain/Ladder.java @@ -0,0 +1,35 @@ +package ladder.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Ladder { + + private final List lines; + private final LadderWidth width; + private final LadderHeight height; + + private Ladder(List lines, LadderWidth width, LadderHeight height) { + this.lines = lines; + this.width = width; + this.height = height; + } + + public static Ladder of(LadderWidth width, LadderHeight height) { + List lines = generateLines(width, height); + + return new Ladder(lines, width, height); + } + + private static List generateLines(LadderWidth width, LadderHeight height) { + List lines = new ArrayList<>(); + for (int i = 0; i < height.getValue(); i++) { + lines.add(Line.from(width.getPointCount())); + } + return lines; + } + + public List getLines() { + return lines; + } +} From 0342e8f30cae2179c544dbc4f16edb9f85e39360 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:05:06 +0900 Subject: [PATCH 05/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC?= =?UTF-8?q?=EC=9D=98=20=EC=8B=9C=EA=B0=81=ED=99=94=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20OutputView=20=EA=B5=AC=ED=98=84\=20-=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EC=8B=9C=EA=B0=81?= =?UTF-8?q?=ED=99=94=20=EB=AC=B8=EC=9E=90=EC=97=B4=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EB=A7=A4=EC=A7=81=EB=84=98=EB=B2=84=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20-=20printLadder=EB=A5=BC=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EA=B0=81=20Line=EB=93=A4=EC=9D=84=20=EA=B5=AC=ED=98=84=20-=20?= =?UTF-8?q?=EA=B0=81=20Line=EC=9D=80=20=EC=84=B8=EB=A1=9C=EC=A4=84=20?= =?UTF-8?q?=EB=B0=8F=20Point=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=EC=A4=84=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/view/OutputView.java | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/ladder/view/OutputView.java diff --git a/src/main/java/ladder/view/OutputView.java b/src/main/java/ladder/view/OutputView.java new file mode 100644 index 00000000..28a8dea8 --- /dev/null +++ b/src/main/java/ladder/view/OutputView.java @@ -0,0 +1,32 @@ +package ladder.view; + +import ladder.domain.Ladder; +import ladder.domain.Line; +import ladder.domain.Point; + +public class OutputView { + + private static final String VERTICAL_BAR = "|"; + private static final String BRIDGE = "-----"; + private static final String EMPTY = " "; + + public static void printLadder(Ladder ladder) { + System.out.println("\n실행 결과\n"); + ladder.getLines().forEach(OutputView::printLine); + } + + private static void printLine(Line line) { + System.out.print(VERTICAL_BAR); + line.getPoints().forEach(OutputView::printPoint); + System.out.println(); + } + + private static void printPoint(Point point) { + if (point.hasBridge()) { + System.out.print(BRIDGE + VERTICAL_BAR); + return; + } + System.out.print(EMPTY + VERTICAL_BAR); + } + +} From 301cd44caca21b7164bc69f152ec44ed63189693 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:07:03 +0900 Subject: [PATCH 06/34] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=9D=84=20=EB=8B=B4=EB=8B=B9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20InputView=20=EA=B5=AC=ED=98=84=20-=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=EC=9E=AC=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20=EC=9C=A0=EB=8F=84=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=9E=85=EB=A0=A5=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=EB=A6=AC=ED=8B=B0=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(Supplier=20=ED=99=9C=EC=9A=A9)=20-=20=EC=82=AC?= =?UTF-8?q?=EB=8B=A4=EB=A6=AC=20=EB=84=88=EB=B9=84=20=EB=B0=8F=20=EB=86=92?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20=EC=A0=95=EC=88=98=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EA=B0=92=EC=97=90=20=EB=8C=80=ED=95=9C=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EA=B2=80=EC=A6=9D=20=EB=B0=8F=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/view/InputView.java | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/ladder/view/InputView.java diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java new file mode 100644 index 00000000..8c24b990 --- /dev/null +++ b/src/main/java/ladder/view/InputView.java @@ -0,0 +1,47 @@ +package ladder.view; + +import java.util.Scanner; +import java.util.function.Supplier; +import ladder.domain.LadderHeight; +import ladder.domain.LadderWidth; + +public class InputView { + + private static final Scanner sc = new Scanner(System.in); + + private InputView() {} + + private static T input(String message, Supplier supplier) { + while (true) { + try { + System.out.println(message); + return supplier.get(); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } + } + + public static LadderWidth inputWidth() { + return input("사다리의 넓이는 몇 개인가요?", () -> { + String input = sc.nextLine(); + return LadderWidth.from(parseToInt(input)); + }); + } + + public static LadderHeight inputHeight() { + return input("사다리의 높이는 몇 개인가요?", () -> { + String input = sc.nextLine(); + return LadderHeight.from(parseToInt(input)); + }); + } + + private static int parseToInt(String input) { + try { + return Integer.parseInt(input.trim()); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자만 입력 가능합니다."); + } + } + +} From 5ca9ff3a5af932a1e2ed91d1b1c89f7c69c98117 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:08:16 +0900 Subject: [PATCH 07/34] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=A8=20=EC=8B=A4=ED=96=89=EC=9D=84=20=EB=8B=B4=EB=8B=B9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20Application=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20-=20InputView,=20Ladd?= =?UTF-8?q?er,=20OutputView=EB=A5=BC=20=EC=97=B0=EA=B2=B0=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=A0=84=EC=B2=B4=20=EA=B2=8C=EC=9E=84=20=ED=9D=90?= =?UTF-8?q?=EB=A6=84=20=EC=A0=9C=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/Application.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/ladder/Application.java diff --git a/src/main/java/ladder/Application.java b/src/main/java/ladder/Application.java new file mode 100644 index 00000000..bff28f00 --- /dev/null +++ b/src/main/java/ladder/Application.java @@ -0,0 +1,20 @@ +package ladder; + +import ladder.domain.Ladder; +import ladder.domain.LadderHeight; +import ladder.domain.LadderWidth; +import ladder.view.InputView; +import ladder.view.OutputView; + +public class Application { + + public static void main(String[] args) { + LadderWidth width = InputView.inputWidth(); + LadderHeight height = InputView.inputHeight(); + + Ladder ladder = Ladder.of(width, height); + + OutputView.printLadder(ladder); + } + +} From c5552c9e16d69094f0857416fd5cb535f653ce82 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:27:53 +0900 Subject: [PATCH 08/34] =?UTF-8?q?feat:=20Line=EC=9D=98=20=EC=9C=A0?= =?UTF-8?q?=EB=AC=B4=EB=A5=BC=20=ED=8C=90=EB=8B=A8=ED=95=98=EB=8A=94=20Poi?= =?UTF-8?q?nt=EC=9D=98=20boolean=EC=97=90=20=EB=8C=80=ED=95=B4=20BooleanSu?= =?UTF-8?q?pplier=20=EC=A0=81=EC=9A=A9=20-=20=EC=99=B8=EB=B6=80=EC=97=90?= =?UTF-8?q?=EC=84=9C=20boolean=EC=9D=84=20=EC=A3=BC=EC=9E=85=ED=95=98?= =?UTF-8?q?=EB=8A=94=20strategy=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20-=20?= =?UTF-8?q?=EC=B0=A8=ED=9B=84=20=EC=9A=A9=EC=9D=B4=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/Application.java | 5 ++++- src/main/java/ladder/domain/Ladder.java | 9 +++++---- src/main/java/ladder/domain/Line.java | 13 +++++++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/ladder/Application.java b/src/main/java/ladder/Application.java index bff28f00..374ce0e0 100644 --- a/src/main/java/ladder/Application.java +++ b/src/main/java/ladder/Application.java @@ -1,5 +1,6 @@ package ladder; +import java.util.Random; import ladder.domain.Ladder; import ladder.domain.LadderHeight; import ladder.domain.LadderWidth; @@ -8,11 +9,13 @@ public class Application { + private static final Random RANDOM = new Random(); + public static void main(String[] args) { LadderWidth width = InputView.inputWidth(); LadderHeight height = InputView.inputHeight(); - Ladder ladder = Ladder.of(width, height); + Ladder ladder = Ladder.of(width, height, RANDOM::nextBoolean); OutputView.printLadder(ladder); } diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java index 6415c851..14d6999b 100644 --- a/src/main/java/ladder/domain/Ladder.java +++ b/src/main/java/ladder/domain/Ladder.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.BooleanSupplier; public class Ladder { @@ -15,16 +16,16 @@ private Ladder(List lines, LadderWidth width, LadderHeight height) { this.height = height; } - public static Ladder of(LadderWidth width, LadderHeight height) { - List lines = generateLines(width, height); + public static Ladder of(LadderWidth width, LadderHeight height, BooleanSupplier strategy) { + List lines = generateLines(width, height, strategy); return new Ladder(lines, width, height); } - private static List generateLines(LadderWidth width, LadderHeight height) { + private static List generateLines(LadderWidth width, LadderHeight height, BooleanSupplier strategy) { List lines = new ArrayList<>(); for (int i = 0; i < height.getValue(); i++) { - lines.add(Line.from(width.getPointCount())); + lines.add(Line.from(width.getPointCount(), strategy)); } return lines; } diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index dd3f9dee..18b74dc5 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.function.BooleanSupplier; public class Line { @@ -12,25 +13,25 @@ private Line(List points) { this.points = points; } - public static Line from(int size) { - return new Line(generatePoints(size)); + public static Line from(int size, BooleanSupplier strategy) { + return new Line(generatePoints(size, strategy)); } public List getPoints() { return points; } - private static List generatePoints(int size) { + private static List generatePoints(int size, BooleanSupplier strategy) { List points = new ArrayList<>(); boolean lastBridge = false; for (int i = 0; i < size; i++) { - lastBridge = addPoint(points, lastBridge); + lastBridge = addPoint(points, lastBridge, strategy); } return points; } - private static boolean addPoint(List points, boolean lastBridge) { - boolean currentBridge = canDraw(lastBridge); + private static boolean addPoint(List points, boolean lastBridge, BooleanSupplier strategy) { + boolean currentBridge = !lastBridge && strategy.getAsBoolean(); points.add(Point.from(currentBridge)); return currentBridge; } From ae958f069caa39ad570f687b4ef65c96eede6be4 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:29:37 +0900 Subject: [PATCH 09/34] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EA=B8=B0=EC=A1=B4=20canDraw?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Line.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index 18b74dc5..a7e0a8d6 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -35,11 +35,4 @@ private static boolean addPoint(List points, boolean lastBridge, BooleanS points.add(Point.from(currentBridge)); return currentBridge; } - - private static boolean canDraw(boolean lastBridge) { - if (lastBridge) { - return false; - } - return new Random().nextBoolean(); - } } From a6ea6450b5f387ddc637529b9247313196212c3d Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:33:59 +0900 Subject: [PATCH 10/34] =?UTF-8?q?test:=20=EA=B0=92=20=EA=B0=9D=EC=B2=B4(Po?= =?UTF-8?q?int,=20Width,=20Height)=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=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/ladder/domain/LadderTest.java | 60 +++++++++++++++++++ .../java/ladder/domain/LadderWidthTest.java | 29 +++++++++ src/test/java/ladder/domain/PointTest.java | 31 ++++++++++ 3 files changed, 120 insertions(+) create mode 100644 src/test/java/ladder/domain/LadderTest.java create mode 100644 src/test/java/ladder/domain/LadderWidthTest.java create mode 100644 src/test/java/ladder/domain/PointTest.java diff --git a/src/test/java/ladder/domain/LadderTest.java b/src/test/java/ladder/domain/LadderTest.java new file mode 100644 index 00000000..5eaa012b --- /dev/null +++ b/src/test/java/ladder/domain/LadderTest.java @@ -0,0 +1,60 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LadderTest { + + @DisplayName("설정한 높이만큼 사다리의 가로 줄(Line)이 생성된다.") + @Test + void createLadder_HeightCheck() { + // given + LadderWidth width = LadderWidth.from(3); + LadderHeight height = LadderHeight.from(5); + + // when + Ladder ladder = Ladder.of(width, height, () -> true); + + // then + assertThat(ladder.getLines()).hasSize(5); + } + + @DisplayName("각 가로 줄(Line)은 사람 수보다 1개 적은 포인트(Point)를 가진다.") + @Test + void createLadder_WidthCheck() { + // given + int personCount = 4; + LadderWidth width = LadderWidth.from(personCount); + LadderHeight height = LadderHeight.from(3); + + // when + Ladder ladder = Ladder.of(width, height, () -> true); + + // then + assertThat(ladder.getLines()).allSatisfy(line -> { + assertThat(line.getPoints()).hasSize(3); + }); + } + + @DisplayName("주입된 전략에 따라 사다리 내부의 다리들이 규칙적으로 생성된다.") + @Test + void createLadder_StrategyCheck() { + // given + LadderWidth width = LadderWidth.from(3); // 포인트 2개 + LadderHeight height = LadderHeight.from(1); + + // when + Ladder ladder = Ladder.of(width, height, () -> true); + Line firstLine = ladder.getLines().get(0); + + // then + assertAll( + () -> assertThat(firstLine.getPoints().get(0).hasBridge()).isTrue(), + () -> assertThat(firstLine.getPoints().get(1).hasBridge()).isFalse() + ); + } + +} diff --git a/src/test/java/ladder/domain/LadderWidthTest.java b/src/test/java/ladder/domain/LadderWidthTest.java new file mode 100644 index 00000000..9aa2012d --- /dev/null +++ b/src/test/java/ladder/domain/LadderWidthTest.java @@ -0,0 +1,29 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class LadderWidthTest { + + @DisplayName("유효한 사다리 너비(2명 이상)로 객체를 생성할 수 있다.") + @ParameterizedTest + @ValueSource(ints = {2, 5, 100}) + void createWidth(int value) { + LadderWidth width = LadderWidth.from(value); + assertThat(width.getValue()).isEqualTo(value); + } + + @DisplayName("사다리 너비가 2 미만일 경우 예외가 발생한다.") + @ParameterizedTest + @ValueSource(ints = {0, 1, -5}) + void invalidWidth(int value) { + assertThatThrownBy(() -> LadderWidth.from(value)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("참여할 사람은 최소 2명 이상이어야 합니다."); + } +} diff --git a/src/test/java/ladder/domain/PointTest.java b/src/test/java/ladder/domain/PointTest.java new file mode 100644 index 00000000..6b93da23 --- /dev/null +++ b/src/test/java/ladder/domain/PointTest.java @@ -0,0 +1,31 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class PointTest { + + @DisplayName("Point 생성 시 상태 값이 올바르게 저장된다.") + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void createPoint(boolean hasBridge) { + Point point = Point.from(hasBridge); + assertThat(point.hasBridge()).isEqualTo(hasBridge); + } + + @DisplayName("동일한 상태 값으로 생성 시 같은 인스턴스를 반환한다. (캐싱 확인)") + @Test + void pointCaching() { + + Point first = Point.from(true); + Point second = Point.from(true); + + assertThat(first).isSameAs(second); + } + +} From 605275bfaa5043fdd9075dd7ba0e853bc36929ac Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:34:07 +0900 Subject: [PATCH 11/34] =?UTF-8?q?test:=20Line=EC=9D=98=20=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EA=B0=80=EB=A1=9C?= =?UTF-8?q?=20=EC=A4=91=EB=B3=B5=20=EA=B8=88=EC=A7=80=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=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/ladder/domain/LineTest.java | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/java/ladder/domain/LineTest.java diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java new file mode 100644 index 00000000..18c8d6df --- /dev/null +++ b/src/test/java/ladder/domain/LineTest.java @@ -0,0 +1,51 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LineTest { + + @DisplayName("전략이 항상 true여도 다리는 연속해서 생성되지 않고 건너서 생성된다.") + @Test + void createLine_AlwaysTrueStrategy() { + // given + int size = 3; + // when + Line line = Line.from(size, () -> true); + List points = line.getPoints(); + + // then + assertAll( + () -> assertThat(points.get(0).hasBridge()).isTrue(), + () -> assertThat(points.get(1).hasBridge()).isFalse(), + () -> assertThat(points.get(2).hasBridge()).isTrue() + ); + } + + @DisplayName("전략이 항상 false이면 모든 지점에 다리가 없어야 한다.") + @Test + void createLine_AlwaysFalseStrategy() { + // given + int size = 5; + // when + Line line = Line.from(size, () -> false); + + // then + assertThat(line.getPoints()) + .extracting(Point::hasBridge) + .containsOnly(false); + } + + @DisplayName("요청한 사이즈만큼 Point가 생성된다.") + @Test + void createLine_SizeCheck() { + int size = 10; + Line line = Line.from(size, () -> true); + assertThat(line.getPoints()).hasSize(size); + } + +} From a9ff74beb5a9a5461c3e68907bd68480c96231e4 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:34:13 +0900 Subject: [PATCH 12/34] =?UTF-8?q?test:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EA=B5=AC=EC=A1=B0=20=EB=B0=8F=20=EC=A1=B0?= =?UTF-8?q?=EB=A6=BD=20=EB=A1=9C=EC=A7=81=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 --- .../java/ladder/domain/LadderHeightTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/ladder/domain/LadderHeightTest.java diff --git a/src/test/java/ladder/domain/LadderHeightTest.java b/src/test/java/ladder/domain/LadderHeightTest.java new file mode 100644 index 00000000..ba7d6ab4 --- /dev/null +++ b/src/test/java/ladder/domain/LadderHeightTest.java @@ -0,0 +1,29 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class LadderHeightTest { + + @DisplayName("유효한 사다리 높이로 객체를 생성할 수 있다.") + @ParameterizedTest + @ValueSource(ints = {1, 10, 100}) + void createHeight(int value) { + LadderHeight height = LadderHeight.from(value); + assertThat(height.getValue()).isEqualTo(value); + } + + @DisplayName("사다리 높이가 1 미만일 경우 예외가 발생한다.") + @ParameterizedTest + @ValueSource(ints = {0, -1}) + void invalidHeight(int value) { + assertThatThrownBy(() -> LadderHeight.from(value)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("참여할 사람은 최소 2명 이상이어야 합니다."); + } + +} From a5ed58a559cd6737f54aa261beb011a7402a846e Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:31:17 +0900 Subject: [PATCH 13/34] =?UTF-8?q?feat:=20=ED=95=98=EB=82=98=EC=9D=98=20Lin?= =?UTF-8?q?e=20=EB=82=B4=EC=97=90=EC=84=9C=EC=9D=98=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EB=A9=94=EC=84=9C=EB=93=9C=20move=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=20=EC=9A=B0=EC=B8=A1=EC=97=90=20?= =?UTF-8?q?=EC=97=AC=EC=9C=A0=20=EA=B3=B5=EA=B0=84=EC=9D=B4=20=EC=9E=88?= =?UTF-8?q?=EA=B3=A0=20=ED=8F=AC=EC=9D=B8=ED=8A=B8=EA=B0=80=20=EC=9E=88?= =?UTF-8?q?=EC=9C=BC=EB=A9=B4=20=EC=9A=B0=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?-=20=EC=A2=8C=EC=B8=A1=EC=97=90=20=EC=97=AC=EC=9C=A0=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=84=EC=9D=B4=20=EC=9E=88=EA=B3=A0,=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=EA=B0=80=20=EC=9E=88=EC=9C=BC=EB=A9=B4=20?= =?UTF-8?q?=EC=A2=8C=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20-=20=EA=B7=B8?= =?UTF-8?q?=EB=A0=87=EC=A7=80=20=EC=95=8A=EC=9C=BC=EB=A9=B4=20=20=EA=B7=B8?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EB=82=B4=EB=A0=A4=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Line.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java index a7e0a8d6..3923a493 100644 --- a/src/main/java/ladder/domain/Line.java +++ b/src/main/java/ladder/domain/Line.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Random; import java.util.function.BooleanSupplier; public class Line { @@ -21,6 +20,16 @@ public List getPoints() { return points; } + public int move(int index) { + if (index < points.size() && points.get(index).hasBridge()) { + return index + 1; + } + if (index > 0 && points.get(index - 1).hasBridge()) { + return index - 1; + } + return index; + } + private static List generatePoints(int size, BooleanSupplier strategy) { List points = new ArrayList<>(); boolean lastBridge = false; From 2071d3ecade8903a9a178f2339c854fa29ce1765 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:33:08 +0900 Subject: [PATCH 14/34] =?UTF-8?q?feat:=20Ladder=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EB=8B=A4=EB=A6=AC=20=EA=B2=8C=EC=9E=84=20=EC=88=98?= =?UTF-8?q?=ED=96=89=20=EB=B0=8F=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=20climb:=20=EA=B0=81=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=EC=97=90=EC=84=9C=20=EC=8B=9C=EC=9E=91?= =?UTF-8?q?=ED=95=98=EC=97=AC=20Line=EC=9D=84=20=EB=AA=A8=EB=91=90=20?= =?UTF-8?q?=EA=B1=B0=EC=B3=90=20=EB=8F=84=EC=B0=A9=EC=A7=80=EC=9D=98=20?= =?UTF-8?q?=EC=9D=B8=EB=8D=B1=EC=8A=A4=EB=A5=BC=20=EB=B0=98=ED=99=98=20-?= =?UTF-8?q?=20generateResults:=20=EB=AA=A8=EB=93=A0=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EC=97=90=20=EB=8C=80=ED=95=B4=20climb=EB=A5=BC=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=ED=95=98=EC=97=AC=20=EA=B7=B8=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EB=A5=BC=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Ladder.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java index 14d6999b..7a80d57e 100644 --- a/src/main/java/ladder/domain/Ladder.java +++ b/src/main/java/ladder/domain/Ladder.java @@ -1,7 +1,9 @@ package ladder.domain; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.BooleanSupplier; public class Ladder { @@ -22,6 +24,22 @@ public static Ladder of(LadderWidth width, LadderHeight height, BooleanSupplier return new Ladder(lines, width, height); } + public int climb(int startIndex) { + int currentIndex = startIndex; + for (Line line : lines) { + currentIndex = line.move(currentIndex); + } + return currentIndex; + } + + public Map generateResults() { + Map results = new LinkedHashMap<>(); + for (int i = 0; i < width.getValue(); i++) { + results.put(i, climb(i)); + } + return results; + } + private static List generateLines(LadderWidth width, LadderHeight height, BooleanSupplier strategy) { List lines = new ArrayList<>(); for (int i = 0; i < height.getValue(); i++) { From 28fe4d9b39d7c69b8fc3e7e1fdf1a0d5f5b05651 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:33:59 +0900 Subject: [PATCH 15/34] =?UTF-8?q?feat:=20OutputView=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EB=8B=A4=EB=A6=AC=EA=B2=8C=EC=9E=84=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/view/OutputView.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/ladder/view/OutputView.java b/src/main/java/ladder/view/OutputView.java index 28a8dea8..1c3175b2 100644 --- a/src/main/java/ladder/view/OutputView.java +++ b/src/main/java/ladder/view/OutputView.java @@ -1,5 +1,6 @@ package ladder.view; +import java.util.Map; import ladder.domain.Ladder; import ladder.domain.Line; import ladder.domain.Point; @@ -29,4 +30,10 @@ private static void printPoint(Point point) { System.out.print(EMPTY + VERTICAL_BAR); } + public static void printResults(Map results) { + System.out.println(); + results.forEach((start, end) -> + System.out.println(start + " -> " + end) + ); + } } From d101e0030f95f9883631bf47dedc076c9de28095 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:57:32 +0900 Subject: [PATCH 16/34] =?UTF-8?q?test:=20move=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20-=20Point=EB=A5=BC=203=EA=B0=9C=EB=A1=9C?= =?UTF-8?q?=20=EC=A7=80=EC=A0=95=ED=95=98=EA=B3=A0=20=EC=A0=84=EB=9E=B5?= =?UTF-8?q?=EC=9D=84=20true=EB=A1=9C=20=ED=95=98=EC=97=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=91=A5=EC=9D=B4=20true,=20false,=20true=EB=A1=9C=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=90=98=EA=B2=8C=20=ED=95=A8=20-=20=EA=B0=81=20?= =?UTF-8?q?=EA=B8=B0=EB=91=A5=EC=97=90=EC=84=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=8F=84=EC=B0=A9=ED=95=9C=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=EB=A5=BC=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ladder/domain/LineTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/ladder/domain/LineTest.java b/src/test/java/ladder/domain/LineTest.java index 18c8d6df..410e9d4e 100644 --- a/src/test/java/ladder/domain/LineTest.java +++ b/src/test/java/ladder/domain/LineTest.java @@ -48,4 +48,23 @@ void createLine_SizeCheck() { assertThat(line.getPoints()).hasSize(size); } + @DisplayName("다리 유무에 따라 인덱스가 좌, 우로 이동하거나 그대로 유지된다.") + @Test + void move() { + Line line = Line.from(3, () -> true); + + assertAll( + // 0번 기둥: 0번 포인트가 T이므로 오른쪽(1)으로 이동 + () -> assertThat(line.move(0)).isEqualTo(1), + + // 1번 기둥: 0번 포인트가 T이므로 왼쪽(0)으로 이동 + () -> assertThat(line.move(1)).isEqualTo(0), + + // 2번 기둥: 2번 포인트가 T이므로 오른쪽(3)으로 이동 (1번 포인트는 F) + () -> assertThat(line.move(2)).isEqualTo(3), + + // 3번 기둥: 2번 포인트가 T이므로 왼쪽(2)으로 이동 + () -> assertThat(line.move(3)).isEqualTo(2) + ); + } } From 614c62d9c0a9a8f97379158ee18bfd0b59164faf Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Sun, 8 Feb 2026 23:00:47 +0900 Subject: [PATCH 17/34] =?UTF-8?q?test:=20climb=EA=B3=BC=20generateResults?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20-=20climb:=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=EC=9E=90=EB=A5=BC=202,=20=EB=86=92=EC=9D=B4?= =?UTF-8?q?=EB=A5=BC=201,=20=EC=A0=84=EB=9E=B5=EC=9D=84=20true=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=ED=95=98=EC=97=AC=20=EA=B5=90=EC=B0=A8?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=EB=82=B4=EB=A0=A4=EA=B0=90=EC=9D=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20-=20generateResults:=20=EC=B0=B8=EC=97=AC?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=203,=20=EB=86=92=EC=9D=B4=EB=A5=BC=201,=20?= =?UTF-8?q?=EC=A0=84=EB=9E=B5=EC=9D=84=20true=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=95=98=EC=97=AC=20=EA=B2=B0=EA=B3=BC=EC=9D=98=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=EC=99=80=20=EA=B7=B8=20=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ladder/domain/LadderTest.java | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/java/ladder/domain/LadderTest.java b/src/test/java/ladder/domain/LadderTest.java index 5eaa012b..2fc2e0ea 100644 --- a/src/test/java/ladder/domain/LadderTest.java +++ b/src/test/java/ladder/domain/LadderTest.java @@ -57,4 +57,34 @@ void createLadder_StrategyCheck() { ); } + @DisplayName("사다리를 타고 내려가 최종 도착 지점의 인덱스를 반환한다.") + @Test + void climb() { + // given + Ladder ladder = Ladder.of(LadderWidth.from(2), LadderHeight.from(1), () -> true); + + // then + assertAll( + () -> assertThat(ladder.climb(0)).isEqualTo(1), + () -> assertThat(ladder.climb(1)).isEqualTo(0) + ); + } + + @DisplayName("사다리 전체 실행 결과를 Map 형태로 반환한다.") + @Test + void generateResults() { + // given: 3명(포인트 2개), 높이 1, 전략은 항상 true + Ladder ladder = Ladder.of(LadderWidth.from(3), LadderHeight.from(1), () -> true); + + // when + java.util.Map results = ladder.generateResults(); + + // then: 0->1, 1->0, 2->2 결과 확인 + assertAll( + () -> assertThat(results).hasSize(3), + () -> assertThat(results.get(0)).isEqualTo(1), + () -> assertThat(results.get(1)).isEqualTo(0), + () -> assertThat(results.get(2)).isEqualTo(2) + ); + } } From 49d73b30cf8cb40ee5c5b5481007ee4bd0178401 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:03:32 +0900 Subject: [PATCH 18/34] =?UTF-8?q?refactor:=20LadderTest=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=B0=98=EB=B3=B5=EB=90=98=EB=8A=94=20Participants=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=97=90=20=EB=8C=80=ED=95=B4=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EB=B0=8F=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ladder/domain/LadderTest.java | 55 +++++++++------------ 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/test/java/ladder/domain/LadderTest.java b/src/test/java/ladder/domain/LadderTest.java index 2fc2e0ea..ecc2f149 100644 --- a/src/test/java/ladder/domain/LadderTest.java +++ b/src/test/java/ladder/domain/LadderTest.java @@ -3,54 +3,42 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import java.util.List; +import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class LadderTest { + private static final List NAMES_3 = List.of("p1", "p2", "p3"); + private static final List NAMES_4 = List.of("p1", "p2", "p3", "p4"); + @DisplayName("설정한 높이만큼 사다리의 가로 줄(Line)이 생성된다.") @Test void createLadder_HeightCheck() { - // given - LadderWidth width = LadderWidth.from(3); - LadderHeight height = LadderHeight.from(5); - - // when - Ladder ladder = Ladder.of(width, height, () -> true); + int heightValue = 5; + Ladder ladder = createLadder(NAMES_3, heightValue); // then - assertThat(ladder.getLines()).hasSize(5); + assertThat(ladder.getLines()).hasSize(heightValue); } @DisplayName("각 가로 줄(Line)은 사람 수보다 1개 적은 포인트(Point)를 가진다.") @Test void createLadder_WidthCheck() { - // given - int personCount = 4; - LadderWidth width = LadderWidth.from(personCount); - LadderHeight height = LadderHeight.from(3); - - // when - Ladder ladder = Ladder.of(width, height, () -> true); + Ladder ladder = createLadder(NAMES_4, 3); - // then assertThat(ladder.getLines()).allSatisfy(line -> { - assertThat(line.getPoints()).hasSize(3); + assertThat(line.getPoints()).hasSize(NAMES_4.size() - 1); }); } @DisplayName("주입된 전략에 따라 사다리 내부의 다리들이 규칙적으로 생성된다.") @Test void createLadder_StrategyCheck() { - // given - LadderWidth width = LadderWidth.from(3); // 포인트 2개 - LadderHeight height = LadderHeight.from(1); - - // when - Ladder ladder = Ladder.of(width, height, () -> true); + Ladder ladder = createLadder(NAMES_3, 1); Line firstLine = ladder.getLines().get(0); - // then assertAll( () -> assertThat(firstLine.getPoints().get(0).hasBridge()).isTrue(), () -> assertThat(firstLine.getPoints().get(1).hasBridge()).isFalse() @@ -60,10 +48,8 @@ void createLadder_StrategyCheck() { @DisplayName("사다리를 타고 내려가 최종 도착 지점의 인덱스를 반환한다.") @Test void climb() { - // given - Ladder ladder = Ladder.of(LadderWidth.from(2), LadderHeight.from(1), () -> true); + Ladder ladder = createLadder(List.of("p1", "p2"), 1); - // then assertAll( () -> assertThat(ladder.climb(0)).isEqualTo(1), () -> assertThat(ladder.climb(1)).isEqualTo(0) @@ -73,18 +59,23 @@ void climb() { @DisplayName("사다리 전체 실행 결과를 Map 형태로 반환한다.") @Test void generateResults() { - // given: 3명(포인트 2개), 높이 1, 전략은 항상 true - Ladder ladder = Ladder.of(LadderWidth.from(3), LadderHeight.from(1), () -> true); + Ladder ladder = createLadder(NAMES_3, 1); - // when - java.util.Map results = ladder.generateResults(); + Map results = ladder.generateResults(); - // then: 0->1, 1->0, 2->2 결과 확인 assertAll( - () -> assertThat(results).hasSize(3), + () -> assertThat(results).hasSize(NAMES_3.size()), () -> assertThat(results.get(0)).isEqualTo(1), () -> assertThat(results.get(1)).isEqualTo(0), () -> assertThat(results.get(2)).isEqualTo(2) ); } + + private Ladder createLadder(List names, int height) { + return Ladder.of( + Participants.from(names), + LadderHeight.from(height), + () -> true + ); + } } From b3ac3e1f4d5e1ad73d806d7c47858a0eae24b827 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:04:28 +0900 Subject: [PATCH 19/34] =?UTF-8?q?feat:=20Ladder=EC=9D=98=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8C=A9=ED=84=B0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20-=20=EA=B8=B0=EC=A1=B4=20LadderWidth=EB=8A=94=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20X=20-=20Participants=EB=A5=BC=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=20=EA=B7=B8=20=ED=81=AC=EA=B8=B0=EB=A1=9C=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Ladder.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java index 7a80d57e..74f98717 100644 --- a/src/main/java/ladder/domain/Ladder.java +++ b/src/main/java/ladder/domain/Ladder.java @@ -9,19 +9,18 @@ public class Ladder { private final List lines; - private final LadderWidth width; - private final LadderHeight height; + private final int width; - private Ladder(List lines, LadderWidth width, LadderHeight height) { + private Ladder(List lines, int width) { this.lines = lines; this.width = width; - this.height = height; } - public static Ladder of(LadderWidth width, LadderHeight height, BooleanSupplier strategy) { - List lines = generateLines(width, height, strategy); + public static Ladder of(Participants participants, LadderHeight height, BooleanSupplier strategy) { + int participantCount = participants.size(); + List lines = generateLines(participantCount, height, strategy); - return new Ladder(lines, width, height); + return new Ladder(lines, participantCount); } public int climb(int startIndex) { @@ -34,16 +33,17 @@ public int climb(int startIndex) { public Map generateResults() { Map results = new LinkedHashMap<>(); - for (int i = 0; i < width.getValue(); i++) { + for (int i = 0; i < width; i++) { results.put(i, climb(i)); } return results; } - private static List generateLines(LadderWidth width, LadderHeight height, BooleanSupplier strategy) { + private static List generateLines(int participantCount, LadderHeight height, BooleanSupplier strategy) { List lines = new ArrayList<>(); + int pointCount = participantCount - 1; for (int i = 0; i < height.getValue(); i++) { - lines.add(Line.from(width.getPointCount(), strategy)); + lines.add(Line.from(pointCount, strategy)); } return lines; } From 349cf9f1cef3ff6903d28e98e2eafa9b422d3598 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:08:46 +0900 Subject: [PATCH 20/34] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20LadderWidth=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/LadderWidth.java | 28 ------------------ .../java/ladder/domain/LadderWidthTest.java | 29 ------------------- 2 files changed, 57 deletions(-) delete mode 100644 src/main/java/ladder/domain/LadderWidth.java delete mode 100644 src/test/java/ladder/domain/LadderWidthTest.java diff --git a/src/main/java/ladder/domain/LadderWidth.java b/src/main/java/ladder/domain/LadderWidth.java deleted file mode 100644 index fa4a4317..00000000 --- a/src/main/java/ladder/domain/LadderWidth.java +++ /dev/null @@ -1,28 +0,0 @@ -package ladder.domain; - -public class LadderWidth { - private final int value; - - private LadderWidth(int value) { - this.value = value; - } - - public static LadderWidth from(int value) { - validate(value); - return new LadderWidth(value); - } - - public int getPointCount() { // 다리 수 = 참여자 수 -1 - return value - 1; - } - - public int getValue() { - return value; - } - - private static void validate(int value) { - if (value < 2) { - throw new IllegalArgumentException("참여할 사람은 최소 2명 이상이어야 합니다."); - } - } -} diff --git a/src/test/java/ladder/domain/LadderWidthTest.java b/src/test/java/ladder/domain/LadderWidthTest.java deleted file mode 100644 index 9aa2012d..00000000 --- a/src/test/java/ladder/domain/LadderWidthTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package ladder.domain; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -public class LadderWidthTest { - - @DisplayName("유효한 사다리 너비(2명 이상)로 객체를 생성할 수 있다.") - @ParameterizedTest - @ValueSource(ints = {2, 5, 100}) - void createWidth(int value) { - LadderWidth width = LadderWidth.from(value); - assertThat(width.getValue()).isEqualTo(value); - } - - @DisplayName("사다리 너비가 2 미만일 경우 예외가 발생한다.") - @ParameterizedTest - @ValueSource(ints = {0, 1, -5}) - void invalidWidth(int value) { - assertThatThrownBy(() -> LadderWidth.from(value)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("참여할 사람은 최소 2명 이상이어야 합니다."); - } -} From ff2eb5e47e667b5b88540a04e8fa58e33c13a6e1 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:09:06 +0900 Subject: [PATCH 21/34] =?UTF-8?q?feat:=20=EC=8B=A4=ED=96=89=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EC=99=80=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=8B=B4?= =?UTF-8?q?=EB=8A=94=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/LadderResult.java | 23 +++++++++++++++++++ .../java/ladder/domain/LadderResults.java | 22 ++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/main/java/ladder/domain/LadderResult.java create mode 100644 src/main/java/ladder/domain/LadderResults.java diff --git a/src/main/java/ladder/domain/LadderResult.java b/src/main/java/ladder/domain/LadderResult.java new file mode 100644 index 00000000..e1b3888f --- /dev/null +++ b/src/main/java/ladder/domain/LadderResult.java @@ -0,0 +1,23 @@ +package ladder.domain; + +public class LadderResult { + private final String value; + + private LadderResult(String value) { + validate(value); + this.value = value; + } + + public static LadderResult from(String value) { + return new LadderResult(value.trim()); + } + + private void validate(String value) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("실행 결과는 빈 값일 수 없습니다."); + } + if (value.length() > 5) { + throw new IllegalArgumentException("실행 결과는 최대 5글자입니다."); + } + } +} diff --git a/src/main/java/ladder/domain/LadderResults.java b/src/main/java/ladder/domain/LadderResults.java new file mode 100644 index 00000000..03ac275e --- /dev/null +++ b/src/main/java/ladder/domain/LadderResults.java @@ -0,0 +1,22 @@ +package ladder.domain; + +import java.util.List; + +public class LadderResults { + private final List results; + + private LadderResults(List results) { + this.results = results; + } + + public static LadderResults of(List rawResults, int participantCount) { + if (rawResults.size() != participantCount) { + throw new IllegalArgumentException("참가자 수와 결과의 개수가 일치해야 합니다."); + } + + List results = rawResults.stream() + .map(LadderResult::from) + .toList(); + return new LadderResults(results); + } +} From 10df688beb49989896082bf02e554ef5374fc0c9 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:09:55 +0900 Subject: [PATCH 22/34] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=9E=90=20?= =?UTF-8?q?=EB=AA=85=EA=B3=BC=20=EC=B0=B8=EC=97=AC=EC=9E=90=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20=EC=9D=BC?= =?UTF-8?q?=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?-=20Name:=20=EB=B9=88=20=EA=B0=92=EC=9D=B4=EA=B1=B0=EB=82=98=20?= =?UTF-8?q?5=EA=B8=80=EC=9E=90=EB=A5=BC=20=EB=84=98=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=97=86=EC=9D=8C=20-=20Participants:=20=EC=B5=9C=EC=86=8C?= =?UTF-8?q?=202=EB=AA=85=EC=9D=B4=EB=A9=B0,=20=EC=9D=B4=EB=A6=84=EC=9D=80?= =?UTF-8?q?=20=EC=A4=91=EB=B3=B5=EB=90=A0=20=EC=88=98=20=EC=97=86=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/Name.java | 25 +++++++++++ src/main/java/ladder/domain/Participants.java | 43 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/ladder/domain/Name.java create mode 100644 src/main/java/ladder/domain/Participants.java diff --git a/src/main/java/ladder/domain/Name.java b/src/main/java/ladder/domain/Name.java new file mode 100644 index 00000000..9c6f754a --- /dev/null +++ b/src/main/java/ladder/domain/Name.java @@ -0,0 +1,25 @@ +package ladder.domain; + +public class Name { + + private final String name; + + private Name(String name) { + this.name = name; + } + + public static Name from(String name) { + String trimmedName = name.trim(); + validate(trimmedName); + return new Name(trimmedName); + } + + private static void validate(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("이름은 빈 값일 수 없습니다."); + } + if (name.length() > 5) { + throw new IllegalArgumentException("이름은 최대 5글자입니다."); + } + } +} diff --git a/src/main/java/ladder/domain/Participants.java b/src/main/java/ladder/domain/Participants.java new file mode 100644 index 00000000..e40fa9e1 --- /dev/null +++ b/src/main/java/ladder/domain/Participants.java @@ -0,0 +1,43 @@ +package ladder.domain; + +import java.util.List; +import java.util.stream.Collectors; + +public class Participants { + + private final List participants; + + private Participants(List participants) { + validate(participants); + this.participants = participants; + } + + public static Participants from(List names) { + List nameList = names.stream() + .map(Name::from) + .collect(Collectors.toList()); + return new Participants(nameList); + } + + private void validate(List participants) { + if (participants.size() < 2) { + throw new IllegalArgumentException("참여할 사람은 최소 2명 이상이어야 합니다."); + } + long distinctCount = participants.stream() + .map(Name::toString) + .distinct() + .count(); + if (distinctCount != participants.size()) { + throw new IllegalArgumentException("이름은 중복될 수 없습니다."); + } + } + + public int size() { + return participants.size(); + } + + public List getValues() { + return participants; + } + +} From 076b917b991a01583548c2056bdea97464a547a5 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:10:20 +0900 Subject: [PATCH 23/34] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=9E=90?= =?UTF-8?q?=EC=99=80=20=EC=8B=A4=ED=96=89=20=EA=B2=B0=EA=B3=BC=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=9E=85=EB=A0=A5=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/view/InputView.java | 30 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java index 8c24b990..0a201f91 100644 --- a/src/main/java/ladder/view/InputView.java +++ b/src/main/java/ladder/view/InputView.java @@ -1,9 +1,12 @@ package ladder.view; +import java.util.Arrays; +import java.util.List; import java.util.Scanner; import java.util.function.Supplier; import ladder.domain.LadderHeight; -import ladder.domain.LadderWidth; +import ladder.domain.LadderResults; +import ladder.domain.Participants; public class InputView { @@ -22,10 +25,29 @@ private static T input(String message, Supplier supplier) { } } - public static LadderWidth inputWidth() { - return input("사다리의 넓이는 몇 개인가요?", () -> { + public static Participants inputNames() { + return input("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)", () -> { String input = sc.nextLine(); - return LadderWidth.from(parseToInt(input)); + if (input == null || input.isBlank()) { + throw new IllegalArgumentException("참가자 이름을 입력해야 합니다."); + } + List names = Arrays.asList(input.split(",")); + return Participants.from(names); + }); + } + + public static LadderResults inputLadderResults(int participantCount) { + return input("\n실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)", () -> { + String input = sc.nextLine(); + if (input == null || input.isBlank()) { + throw new IllegalArgumentException("실행 결과는 빈 값일 수 없습니다."); + } + + List rawResults = Arrays.stream(input.split(",")) + .map(String::trim) + .toList(); + + return LadderResults.of(rawResults, participantCount); }); } From b21eb78f41331d9ba0e7cb9c736bc444c065dba2 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:28:37 +0900 Subject: [PATCH 24/34] =?UTF-8?q?feat:=20=EB=8B=A8=EC=9D=BC=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=98=EC=97=AC=20toString()=20=EC=97=86=EC=9D=B4=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=EB=A1=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/LadderResult.java | 4 ++++ src/main/java/ladder/domain/Name.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/ladder/domain/LadderResult.java b/src/main/java/ladder/domain/LadderResult.java index e1b3888f..7d6c2b2d 100644 --- a/src/main/java/ladder/domain/LadderResult.java +++ b/src/main/java/ladder/domain/LadderResult.java @@ -12,6 +12,10 @@ public static LadderResult from(String value) { return new LadderResult(value.trim()); } + public String getValue() { + return value; + } + private void validate(String value) { if (value == null || value.isBlank()) { throw new IllegalArgumentException("실행 결과는 빈 값일 수 없습니다."); diff --git a/src/main/java/ladder/domain/Name.java b/src/main/java/ladder/domain/Name.java index 9c6f754a..0146b3b4 100644 --- a/src/main/java/ladder/domain/Name.java +++ b/src/main/java/ladder/domain/Name.java @@ -14,6 +14,10 @@ public static Name from(String name) { return new Name(trimmedName); } + public String getName() { + return name; + } + private static void validate(String name) { if (name == null || name.isBlank()) { throw new IllegalArgumentException("이름은 빈 값일 수 없습니다."); From 11048f64f8b824d64c634507f7fe4400427dbeec Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:28:45 +0900 Subject: [PATCH 25/34] =?UTF-8?q?feat:=20=EB=8B=A8=EC=9D=BC=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=98=EC=97=AC=20toString()=20=EC=97=86=EC=9D=B4=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=EB=A1=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/domain/LadderResults.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/ladder/domain/LadderResults.java b/src/main/java/ladder/domain/LadderResults.java index 03ac275e..94c44ec7 100644 --- a/src/main/java/ladder/domain/LadderResults.java +++ b/src/main/java/ladder/domain/LadderResults.java @@ -19,4 +19,8 @@ public static LadderResults of(List rawResults, int participantCount) { .toList(); return new LadderResults(results); } + + public List getValues() { + return results; + } } From bbd4b73bc1fb49b7d1ca73f8865d33c35e2c82c9 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:58:29 +0900 Subject: [PATCH 26/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EA=B2=B0=EA=B3=BC=20=EB=A7=A4=ED=95=91?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20LadderGameResult=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80=20-=20Participants?= =?UTF-8?q?=EC=99=80=20LadderResults=EB=A5=BC=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=20=EA=B2=BD=EB=A1=9C(Map)=EB=A5=BC=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=A7=A4=ED=95=91=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20-=20?= =?UTF-8?q?=ED=8A=B9=EC=A0=95=20=EC=B0=B8=EC=97=AC=EC=9E=90=EC=9D=98=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=84=20=EA=B2=80=EC=83=89=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=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 --- .../java/ladder/domain/LadderGameResult.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/ladder/domain/LadderGameResult.java diff --git a/src/main/java/ladder/domain/LadderGameResult.java b/src/main/java/ladder/domain/LadderGameResult.java new file mode 100644 index 00000000..2cca86f1 --- /dev/null +++ b/src/main/java/ladder/domain/LadderGameResult.java @@ -0,0 +1,41 @@ +package ladder.domain; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +public class LadderGameResult { + + private final Map gameResults; + + private LadderGameResult(Map gameResults) { + this.gameResults = gameResults; + } + + public static LadderGameResult of(Participants participants, LadderResults results, Map ladderPath) { + Map mappedResult = new LinkedHashMap<>(); + + for (int i = 0; i < participants.size(); i++) { + Name participant = participants.getValues().get(i); + int arrivalIndex = ladderPath.get(i); + LadderResult result = results.getValues().get(arrivalIndex); + + mappedResult.put(participant, result); + } + + return new LadderGameResult(mappedResult); + } + + public String getResultByName(String name) { + return gameResults.entrySet().stream() + .filter(entry -> entry.getKey().getName().equals(name)) + .map(entry -> entry.getValue().getValue()) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("해당 이름의 참가자가 없습니다.")); + } + + public Map getAllResults() { + return Collections.unmodifiableMap(gameResults); + } + +} From 591482aaf08f31977555dbeb3f5fcc233f8ac2a2 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:58:42 +0900 Subject: [PATCH 27/34] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=A1=B0=ED=9A=8C=20=ED=9D=90=EB=A6=84=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EC=96=B4=ED=95=98=EB=8A=94=20LadderGameController=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20'all'=20=EC=9E=85=EB=A0=A5=20=EC=A0=84?= =?UTF-8?q?=EA=B9=8C=EC=A7=80=20=EB=B0=98=EB=B3=B5=ED=95=B4=EC=84=9C=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EC=A1=B0=ED=9A=8C=ED=95=98?= =?UTF-8?q?=EB=8A=94=20runInquiry=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EA=B0=92=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=8B=A8?= =?UTF-8?q?=EC=9D=BC=20=EA=B2=B0=EA=B3=BC=20=EB=98=90=EB=8A=94=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=97=B0=EA=B2=B0=EB=A5=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=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 --- .../controller/LadderGameController.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/ladder/controller/LadderGameController.java diff --git a/src/main/java/ladder/controller/LadderGameController.java b/src/main/java/ladder/controller/LadderGameController.java new file mode 100644 index 00000000..346cac8e --- /dev/null +++ b/src/main/java/ladder/controller/LadderGameController.java @@ -0,0 +1,28 @@ +package ladder.controller; + +import ladder.domain.LadderGameResult; +import ladder.view.InputView; +import ladder.view.OutputView; + +public class LadderGameController { + + public static void runInquiry(LadderGameResult gameResult) { + String nameQuery; + do { + nameQuery = InputView.inputNameQuery(); + printResult(gameResult, nameQuery); + } while (!"all".equals(nameQuery)); + } + + private static void printResult(LadderGameResult gameResult, String nameQuery) { + if ("all".equals(nameQuery)) { + OutputView.printAllResults(gameResult.getAllResults()); + return; + } + try { + OutputView.printSingleResult(gameResult.getResultByName(nameQuery)); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] " + e.getMessage()); + } + } +} From 3c81f1937b788003b79dc3c069c7cf449a73e96c Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:59:15 +0900 Subject: [PATCH 28/34] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=EC=9E=90=EC=9D=98=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=ED=95=98=EB=8A=94=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/view/InputView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java index 0a201f91..1ffdedfd 100644 --- a/src/main/java/ladder/view/InputView.java +++ b/src/main/java/ladder/view/InputView.java @@ -66,4 +66,9 @@ private static int parseToInt(String input) { } } + public static String inputNameQuery() { + System.out.println("\n결과를 보고 싶은 사람은?"); + return sc.nextLine(); + } + } From 8dbf07eb8dc79f4911c379f8eb9af983609145f7 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:00:05 +0900 Subject: [PATCH 29/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=81=ED=99=94=20=EC=A0=95=EB=A0=AC=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20-=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EA=B3=BC=20=EC=8B=A4=ED=96=89=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=EC=9D=98=20=EA=B0=80=EB=A1=9C=20=EC=A0=95=EB=A0=AC=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=206=EC=B9=B8=20=ED=8F=AC=EB=A7=A4=ED=8C=85(%?= =?UTF-8?q?6s)=20=EC=A0=81=EC=9A=A9=20-=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=91=A5=EA=B3=BC=20=EC=9D=B4=EB=A6=84=EC=9D=98=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EB=A5=BC=20=EB=A7=9E=EC=B6=94=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=9D=BC=EC=9D=B8=20=EC=8B=9C=EC=9E=91=20?= =?UTF-8?q?=EC=97=AC=EB=B0=B1=20=EC=B2=98=EB=A6=AC=20-=20=EA=B0=9C?= =?UTF-8?q?=EB=B3=84=20=EA=B2=B0=EA=B3=BC=20=EB=B0=8F=20=EC=A0=84=EC=B2=B4?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=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/ladder/view/OutputView.java | 46 +++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/ladder/view/OutputView.java b/src/main/java/ladder/view/OutputView.java index 1c3175b2..69471842 100644 --- a/src/main/java/ladder/view/OutputView.java +++ b/src/main/java/ladder/view/OutputView.java @@ -2,7 +2,11 @@ import java.util.Map; import ladder.domain.Ladder; +import ladder.domain.LadderResult; +import ladder.domain.LadderResults; import ladder.domain.Line; +import ladder.domain.Name; +import ladder.domain.Participants; import ladder.domain.Point; public class OutputView { @@ -11,13 +15,36 @@ public class OutputView { private static final String BRIDGE = "-----"; private static final String EMPTY = " "; - public static void printLadder(Ladder ladder) { - System.out.println("\n실행 결과\n"); + public static void printLadder(Participants participants, Ladder ladder, LadderResults results) { + System.out.println("\n사다리 결과\n\n"); + + printParticipants(participants); + ladder.getLines().forEach(OutputView::printLine); + + printLadderResults(results); + } + + private static void printParticipants(Participants participants) { + participants.getValues().forEach(name -> + System.out.print(format(name.getName())) + ); + System.out.println(); + } + + private static void printLadderResults(LadderResults results) { + results.getValues().forEach(result -> + System.out.print(format(result.getValue())) + ); + System.out.println(); + } + + private static String format(String value) { + return String.format("%6s", value); } private static void printLine(Line line) { - System.out.print(VERTICAL_BAR); + System.out.print(" " + VERTICAL_BAR); line.getPoints().forEach(OutputView::printPoint); System.out.println(); } @@ -30,10 +57,15 @@ private static void printPoint(Point point) { System.out.print(EMPTY + VERTICAL_BAR); } - public static void printResults(Map results) { - System.out.println(); - results.forEach((start, end) -> - System.out.println(start + " -> " + end) + public static void printSingleResult(String result) { + System.out.println("\n실행 결과"); + System.out.println(result); + } + + public static void printAllResults(Map results) { + System.out.println("\n실행 결과"); + results.forEach((name, result) -> + System.out.println(name.getName() + " : " + result.getValue()) ); } } From 33f1f4f49375efc3ac16babd22382c12ef2e2dcc Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:00:17 +0900 Subject: [PATCH 30/34] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=B0=B8=EA=B0=80=EC=9E=90=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EC=9E=85=EB=A0=A5=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=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/ladder/Application.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/ladder/Application.java b/src/main/java/ladder/Application.java index 374ce0e0..7fe80989 100644 --- a/src/main/java/ladder/Application.java +++ b/src/main/java/ladder/Application.java @@ -1,9 +1,13 @@ package ladder; +import java.util.Map; import java.util.Random; +import ladder.controller.LadderGameController; import ladder.domain.Ladder; +import ladder.domain.LadderGameResult; import ladder.domain.LadderHeight; -import ladder.domain.LadderWidth; +import ladder.domain.LadderResults; +import ladder.domain.Participants; import ladder.view.InputView; import ladder.view.OutputView; @@ -12,12 +16,20 @@ public class Application { private static final Random RANDOM = new Random(); public static void main(String[] args) { - LadderWidth width = InputView.inputWidth(); + Participants participants = InputView.inputNames(); + LadderResults results = InputView.inputLadderResults(participants.size()); + LadderHeight height = InputView.inputHeight(); - Ladder ladder = Ladder.of(width, height, RANDOM::nextBoolean); + Ladder ladder = Ladder.of(participants, height, RANDOM::nextBoolean); + + Map path = ladder.generateResults(); + + LadderGameResult gameResult = LadderGameResult.of(participants, results, path); + + OutputView.printLadder(participants, ladder, results); + LadderGameController.runInquiry(gameResult); - OutputView.printLadder(ladder); } } From d5090da9ed834ce9a732bfa93f1a98c6f3c6a54f Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:03:16 +0900 Subject: [PATCH 31/34] =?UTF-8?q?test:=20Name=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=201~5=EC=9E=90=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=20=EC=83=9D=EC=84=B1=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?-=20=EC=9E=85=EB=A0=A5=EA=B0=92=20=EC=95=9E=EB=92=A4=20?= =?UTF-8?q?=EA=B3=B5=EB=B0=B1=20=EC=A0=9C=EA=B1=B0(trim)=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=ED=99=95=EC=9D=B8=20-=20=EB=B9=88=20=EA=B0=92(blan?= =?UTF-8?q?k)=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=20=EB=B0=8F=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20-=205=EC=9E=90=20=EC=B4=88=EA=B3=BC=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=98=88=EC=99=B8=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EB=B0=8F=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ladder/domain/NameTest.java | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/test/java/ladder/domain/NameTest.java diff --git a/src/test/java/ladder/domain/NameTest.java b/src/test/java/ladder/domain/NameTest.java new file mode 100644 index 00000000..8f89ce3f --- /dev/null +++ b/src/test/java/ladder/domain/NameTest.java @@ -0,0 +1,45 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class NameTest { + + @DisplayName("1자 이상 5자 이하의 이름은 정상적으로 생성된다.") + @ParameterizedTest + @ValueSource(strings = {"jin", "hyeon", "soo"}) + void createName_Success(String input) { + Name name = Name.from(input); + assertThat(name.getName()).isEqualTo(input); + } + + @DisplayName("이름 앞뒤에 공백이 있을 경우 제거(trim) 후 저장한다.") + @Test + void createName_Trim() { + Name name = Name.from(" jin "); + assertThat(name.getName()).isEqualTo("jin"); + } + + @DisplayName("이름이 null이거나 빈 문자열, 혹은 공백만 있으면 예외가 발생한다.") + @ParameterizedTest + @ValueSource(strings = {"", " "}) + void createName_Blank_Exception(String input) { + assertThatThrownBy(() -> Name.from(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("이름은 빈 값일 수 없습니다."); + } + + @DisplayName("이름이 5자를 초과하면 예외가 발생한다.") + @Test + void createName_OverLength_Exception() { + assertThatThrownBy(() -> Name.from("sixchar")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("이름은 최대 5글자입니다."); + } + +} From 6f660891eefe5ea5f650bb29665dc20d5dd1fa06 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:08:22 +0900 Subject: [PATCH 32/34] =?UTF-8?q?test:=20LadderResult=20=EB=B0=8F=20Ladder?= =?UTF-8?q?Results=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ladder/domain/LadderResultTest.java | 44 +++++++++++++++++++ .../java/ladder/domain/LadderResultsTest.java | 39 ++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 src/test/java/ladder/domain/LadderResultTest.java create mode 100644 src/test/java/ladder/domain/LadderResultsTest.java diff --git a/src/test/java/ladder/domain/LadderResultTest.java b/src/test/java/ladder/domain/LadderResultTest.java new file mode 100644 index 00000000..15d591a6 --- /dev/null +++ b/src/test/java/ladder/domain/LadderResultTest.java @@ -0,0 +1,44 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class LadderResultTest { + + @DisplayName("1자 이상 5자 이하의 결과는 정상적으로 생성된다.") + @ParameterizedTest + @ValueSource(strings = {"꽝", "5000", "pass", "abcde"}) + void create_Success(String input) { + LadderResult result = LadderResult.from(input); + assertThat(result.getValue()).isEqualTo(input); + } + + @DisplayName("결과 값 앞뒤에 공백이 있을 경우 제거한다.") + @Test + void create_Trim() { + LadderResult result = LadderResult.from(" 꽝 "); + assertThat(result.getValue()).isEqualTo("꽝"); + } + + @DisplayName("결과가 빈 값일 경우 예외가 발생한다.") + @ParameterizedTest + @ValueSource(strings = {"", " "}) + void create_Blank_Exception(String input) { + assertThatThrownBy(() -> LadderResult.from(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("실행 결과는 빈 값일 수 없습니다."); + } + + @DisplayName("결과가 5자를 초과하면 예외가 발생한다.") + @Test + void create_OverLength_Exception() { + assertThatThrownBy(() -> LadderResult.from("sixchar")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("실행 결과는 최대 5글자입니다."); + } +} diff --git a/src/test/java/ladder/domain/LadderResultsTest.java b/src/test/java/ladder/domain/LadderResultsTest.java new file mode 100644 index 00000000..32a83ca0 --- /dev/null +++ b/src/test/java/ladder/domain/LadderResultsTest.java @@ -0,0 +1,39 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LadderResultsTest { + + @DisplayName("참가자 수와 결과의 개수가 일치하면 정상적으로 생성된다.") + @Test + void create_Success() { + // given + List rawResults = List.of("꽝", "5000", "3000"); + int participantCount = 3; + + // when + LadderResults ladderResults = LadderResults.of(rawResults, participantCount); + + // then + assertThat(ladderResults.getValues()).hasSize(3); + assertThat(ladderResults.getValues().get(0).getValue()).isEqualTo("꽝"); + } + + @DisplayName("참가자 수와 결과의 개수가 다르면 예외가 발생한다.") + @Test + void create_SizeMismatch_Exception() { + // given + List rawResults = List.of("꽝", "5000"); + int participantCount = 3; + + // then + assertThatThrownBy(() -> LadderResults.of(rawResults, participantCount)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("참가자 수와 결과의 개수가 일치해야 합니다."); + } +} From eb018670cc998d9a82d449df0eeb1f86fade5778 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:09:23 +0900 Subject: [PATCH 33/34] =?UTF-8?q?test:=20LadderGameResultTest=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=20-=20=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EA=B2=BD=EB=A1=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EB=A7=A4=ED=95=91=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?-=20=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=9C=BC=EB=A1=9C=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20-=20=EC=A0=84=EC=B2=B4=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=AA=A8=EB=93=A0=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ladder/domain/LadderGameResultTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/java/ladder/domain/LadderGameResultTest.java diff --git a/src/test/java/ladder/domain/LadderGameResultTest.java b/src/test/java/ladder/domain/LadderGameResultTest.java new file mode 100644 index 00000000..e9f181fc --- /dev/null +++ b/src/test/java/ladder/domain/LadderGameResultTest.java @@ -0,0 +1,63 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LadderGameResultTest { + + private Participants participants; + private LadderResults results; + private Map ladderPath; + + @BeforeEach + void setUp() { + participants = Participants.from(List.of("jin", "park")); + results = LadderResults.of(List.of("win", "lose"), 2); + + ladderPath = Map.of(0, 1, 1, 0); + } + + @DisplayName("사다리 경로에 따라 이름과 결과가 올바르게 매핑된다.") + @Test + void mapResults_Success() { + // when + LadderGameResult gameResult = LadderGameResult.of(participants, results, ladderPath); + + // then + assertThat(gameResult.getResultByName("jin")).isEqualTo("lose"); + assertThat(gameResult.getResultByName("park")).isEqualTo("win"); + } + + @DisplayName("존재하지 않는 이름으로 결과를 조회하면 예외가 발생한다.") + @Test + void getResult_InvalidName_Exception() { + // given + LadderGameResult gameResult = LadderGameResult.of(participants, results, ladderPath); + + // then + assertThatThrownBy(() -> gameResult.getResultByName("hyeong")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("해당 이름의 참가자가 없습니다."); + } + + @DisplayName("전체 결과 조회 시 모든 매핑 정보가 포함되어야 한다.") + @Test + void getAllResults_Success() { + // given + LadderGameResult gameResult = LadderGameResult.of(participants, results, ladderPath); + + // when + Map allResults = gameResult.getAllResults(); + + // then + assertThat(allResults).hasSize(2); + Name jin = participants.getValues().get(0); + assertThat(allResults.get(jin).getValue()).isEqualTo("lose"); + } +} From 19f0bd50ea737bd44a356ef57e1958227de67570 Mon Sep 17 00:00:00 2001 From: jinhyeongpark <156793718+jinhyeongpark@users.noreply.github.com> Date: Mon, 9 Feb 2026 01:10:45 +0900 Subject: [PATCH 34/34] =?UTF-8?q?test:=20ParticipantsTest=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=202=EB=AA=85=20=EC=9D=B4=EC=83=81,=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EB=B6=88=EA=B0=80=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ladder/domain/ParticipantsTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/ladder/domain/ParticipantsTest.java diff --git a/src/test/java/ladder/domain/ParticipantsTest.java b/src/test/java/ladder/domain/ParticipantsTest.java new file mode 100644 index 00000000..51309064 --- /dev/null +++ b/src/test/java/ladder/domain/ParticipantsTest.java @@ -0,0 +1,52 @@ +package ladder.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ParticipantsTest { + + @DisplayName("2명 이상의 중복되지 않은 이름 리스트로 참가자 명단을 생성할 수 있다.") + @Test + void create_Success() { + // given + List names = List.of("pobi", "honux", "crong"); + + // when + Participants participants = Participants.from(names); + + // then + assertThat(participants.size()).isEqualTo(3); + assertThat(participants.getValues()) + .extracting(Name::getName) + .containsExactly("pobi", "honux", "crong"); + } + + @DisplayName("참여 인원이 2명 미만이면 예외가 발생한다.") + @Test + void validate_Size_Exception() { + // given + List names = List.of("pobi"); + + // then + assertThatThrownBy(() -> Participants.from(names)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("참여할 사람은 최소 2명 이상이어야 합니다."); + } + + @DisplayName("참가자 이름 중에 중복이 있으면 예외가 발생한다.") + @Test + void validate_Duplicate_Exception() { + // given + List names = List.of("pobi", "pobi", "honux"); + + // then + assertThatThrownBy(() -> Participants.from(names)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("이름은 중복될 수 없습니다."); + } + +}