diff --git a/src/main/java/ladder/Main.java b/src/main/java/ladder/Main.java
new file mode 100644
index 0000000000..34713d0885
--- /dev/null
+++ b/src/main/java/ladder/Main.java
@@ -0,0 +1,24 @@
+package ladder;
+
+import ladder.domain.Ladder;
+import ladder.domain.LadderGenerator;
+import ladder.domain.player.Players;
+import ladder.domain.player.PlayersGenerator;
+import ladder.view.InputView;
+import ladder.view.ResultView;
+
+public class Main {
+    public static void main(String[] args) {
+        Players players = PlayersGenerator.create(InputView.getPlayerNames());
+        int width = players.getPlayerNumber();
+        System.out.println();
+
+        int height = InputView.getLadderHeight();
+        System.out.println();
+
+        Ladder ladder = new LadderGenerator().generate(height, width);
+        ResultView.showResultMessage();
+        ResultView.showPlayers(players);
+        ResultView.showLadder(ladder);
+    }
+}
diff --git a/src/main/java/ladder/README.md b/src/main/java/ladder/README.md
new file mode 100644
index 0000000000..1d69597365
--- /dev/null
+++ b/src/main/java/ladder/README.md
@@ -0,0 +1,14 @@
+# ๐Ÿš€2๋‹จ๊ณ„ - ์‚ฌ๋‹ค๋ฆฌ(์ƒ์„ฑ)
+
+## ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ
+
+- ์‚ฌ๋‹ค๋ฆฌ ๊ฒŒ์ž„์— ์ฐธ์—ฌํ•˜๋Š” ์‚ฌ๋žŒ์— ์ด๋ฆ„์„ ์ตœ๋Œ€5๊ธ€์ž๊นŒ์ง€ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ๋‹ค๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ ์‚ฌ๋žŒ ์ด๋ฆ„๋„ ๊ฐ™์ด ์ถœ๋ ฅํ•œ๋‹ค.
+- ์‚ฌ๋žŒ ์ด๋ฆ„์€ ์‰ผํ‘œ(,)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
+- ์‚ฌ๋žŒ ์ด๋ฆ„์„ 5์ž ๊ธฐ์ค€์œผ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋‹ค๋ฆฌ ํญ๋„ ๋„“์–ด์ ธ์•ผ ํ•œ๋‹ค.
+- ์‚ฌ๋‹ค๋ฆฌ ํƒ€๊ธฐ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ ค๋ฉด ๋ผ์ธ์ด ๊ฒน์น˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
+- |-----|-----| ๋ชจ์–‘๊ณผ ๊ฐ™์ด ๊ฐ€๋กœ ๋ผ์ธ์ด ๊ฒน์น˜๋Š” ๊ฒฝ์šฐ ์–ด๋Š ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™ํ• ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†๋‹ค.
+
+## ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ
+
+- ์ž๋ฐ” 8์˜ ์ŠคํŠธ๋ฆผ๊ณผ ๋žŒ๋‹ค๋ฅผ ์ ์šฉํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•œ๋‹ค.
+- ๊ทœ์น™ 6: ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ž‘๊ฒŒ ์œ ์ง€ํ•œ๋‹ค.
\ No newline at end of file
diff --git a/src/main/java/ladder/domain/AdjacentVerticalLines.java b/src/main/java/ladder/domain/AdjacentVerticalLines.java
new file mode 100644
index 0000000000..8cd56194b5
--- /dev/null
+++ b/src/main/java/ladder/domain/AdjacentVerticalLines.java
@@ -0,0 +1,43 @@
+package ladder.domain;
+
+import ladder.exception.IllegalAdjacentVerticalLinesException;
+
+public class AdjacentVerticalLines {
+    private final VerticalLine leftVerticalLine;
+    private final VerticalLine rightVerticalLine;
+
+    public AdjacentVerticalLines(VerticalLine firstVerticalLine, VerticalLine secondVerticalLine) {
+        checkAdjacentVerticalLines(firstVerticalLine, secondVerticalLine);
+
+        this.leftVerticalLine = min(firstVerticalLine, secondVerticalLine);
+        this.rightVerticalLine = max(firstVerticalLine, secondVerticalLine);
+    }
+
+    public VerticalLine getLeftVerticalLine() {
+        return leftVerticalLine;
+    }
+
+    public VerticalLine getRightVerticalLine() {
+        return rightVerticalLine;
+    }
+
+    private void checkAdjacentVerticalLines(VerticalLine firstVerticalLine, VerticalLine secondVerticalLine) {
+        if (Math.abs(firstVerticalLine.getIndex() - secondVerticalLine.getIndex()) > 1) {
+            throw new IllegalAdjacentVerticalLinesException(
+                    String.format("์ž…๋ ฅ๋œ ์ธ๋ฑ์Šค : %d, %d", firstVerticalLine.getIndex(), secondVerticalLine.getIndex())
+            );
+        }
+    }
+
+    private VerticalLine max(VerticalLine firstVerticalLine, VerticalLine secondVerticalLine) {
+        return firstVerticalLine.getIndex() > secondVerticalLine.getIndex()
+                ? firstVerticalLine
+                : secondVerticalLine;
+    }
+
+    private VerticalLine min(VerticalLine firstVerticalLine, VerticalLine secondVerticalLine) {
+        return firstVerticalLine.getIndex() > secondVerticalLine.getIndex()
+                ? secondVerticalLine
+                : firstVerticalLine;
+    }
+}
diff --git a/src/main/java/ladder/domain/HorizontalLine.java b/src/main/java/ladder/domain/HorizontalLine.java
new file mode 100644
index 0000000000..b7cf1d7367
--- /dev/null
+++ b/src/main/java/ladder/domain/HorizontalLine.java
@@ -0,0 +1,44 @@
+package ladder.domain;
+
+import ladder.exception.IllegalHorizontalLineHeightException;
+
+public class HorizontalLine {
+    static final int MINIMUM_HEIGHT = 0;
+
+    private final AdjacentVerticalLines adjacentVerticalLines;
+    private final int height;
+
+    public HorizontalLine(AdjacentVerticalLines adjacentVerticalLines, int height) {
+        checkHeight(height);
+
+        this.adjacentVerticalLines = adjacentVerticalLines;
+        this.height = height;
+    }
+
+    private void checkHeight(int height) {
+        if (height < MINIMUM_HEIGHT) {
+            throw new IllegalHorizontalLineHeightException(String.format("์ตœ์†Œ ๋†’์ด : %d", MINIMUM_HEIGHT));
+        }
+    }
+
+    public AdjacentVerticalLines getAdjacentVerticalLines() {
+        return adjacentVerticalLines;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public VerticalLine getLeftVerticalLine() {
+        return adjacentVerticalLines.getLeftVerticalLine();
+    }
+
+    public VerticalLine getRightVerticalLine() {
+        return adjacentVerticalLines.getRightVerticalLine();
+    }
+
+    public boolean isConnected(VerticalLine verticalLine) {
+        return verticalLine == adjacentVerticalLines.getLeftVerticalLine()
+                || verticalLine == adjacentVerticalLines.getRightVerticalLine();
+    }
+}
diff --git a/src/main/java/ladder/domain/HorizontalLines.java b/src/main/java/ladder/domain/HorizontalLines.java
new file mode 100644
index 0000000000..8498a55d46
--- /dev/null
+++ b/src/main/java/ladder/domain/HorizontalLines.java
@@ -0,0 +1,44 @@
+package ladder.domain;
+
+import ladder.exception.IllegalHorizontalLineHeightException;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class HorizontalLines {
+    private final Set<HorizontalLine> horizontalLineSet;
+    private final int maxHeight;
+
+    public HorizontalLines(Set<HorizontalLine> horizontalLineSet, int maxHeight) {
+        checkValidHorizontalLineHeight(horizontalLineSet, maxHeight);
+
+        this.horizontalLineSet = horizontalLineSet;
+        this.maxHeight = maxHeight;
+    }
+
+    private void checkValidHorizontalLineHeight(Set<HorizontalLine> horizontalLineSet, int maxHeight) {
+        if (horizontalLineSet.stream()
+                .anyMatch(it -> it.getHeight() >= maxHeight)
+        ) {
+            throw new IllegalHorizontalLineHeightException(String.format("์ตœ๋Œ€ ๋†’์ด : %d", maxHeight));
+        }
+    }
+
+    public Set<HorizontalLine> getHorizontalLineSet() {
+        return Set.copyOf(horizontalLineSet);
+    }
+
+    public Set<HorizontalLine> getHorizontalLineSetByHeight(int height) {
+        return horizontalLineSet.stream()
+                .filter(it -> it.getHeight() == height)
+                .collect(Collectors.toSet());
+    }
+
+    public int getMaxHeight() {
+        return maxHeight;
+    }
+
+    public int getSize() {
+        return horizontalLineSet.size();
+    }
+}
diff --git a/src/main/java/ladder/domain/Ladder.java b/src/main/java/ladder/domain/Ladder.java
new file mode 100644
index 0000000000..98f586122c
--- /dev/null
+++ b/src/main/java/ladder/domain/Ladder.java
@@ -0,0 +1,66 @@
+package ladder.domain;
+
+import ladder.exception.ContinuousHorizontalLineException;
+import ladder.exception.NotEnoughVerticalLinesException;
+
+import java.util.Set;
+
+public class Ladder {
+    static final int MINIMUM_VERTICAL_LINES_QUANTITY = 2;
+
+    private final VerticalLines verticalLines;
+    private final HorizontalLines horizontalLines;
+
+    public Ladder(VerticalLines verticalLines, HorizontalLines horizontalLines) {
+        checkVerticalLines(verticalLines);
+        checkValidLines(verticalLines, horizontalLines);
+
+        this.verticalLines = verticalLines;
+        this.horizontalLines = horizontalLines;
+    }
+
+    private void checkVerticalLines(VerticalLines verticalLines) {
+        if (verticalLines.getSize() < MINIMUM_VERTICAL_LINES_QUANTITY) {
+            throw new NotEnoughVerticalLinesException(String.format("์„ธ๋กœ์„  ๊ฐฏ์ˆ˜ : %d", verticalLines.getSize()));
+        }
+    }
+
+    private void checkValidLines(VerticalLines verticalLines, HorizontalLines horizontalLines) {
+        for (int i = 0; i < horizontalLines.getMaxHeight(); i++) {
+            Set<HorizontalLine> horizontalLineSet = horizontalLines.getHorizontalLineSetByHeight(i);
+            checkExistContinuousHorizontalLinesOnSameHeight(verticalLines, horizontalLineSet);
+        }
+    }
+
+    private void checkExistContinuousHorizontalLinesOnSameHeight(VerticalLines verticalLines, Set<HorizontalLine> horizontalLineSet) {
+        verticalLines.getVerticalLineSet()
+                .forEach(verticalLine ->
+                        checkConnectingWithManyHorizontalLines(verticalLine, horizontalLineSet)
+                );
+    }
+
+    private void checkConnectingWithManyHorizontalLines(VerticalLine verticalLine, Set<HorizontalLine> horizontalLineSet) {
+        if (horizontalLineSet.stream()
+                .filter(it -> it.isConnected(verticalLine))
+                .count() > 1
+        ) {
+            throw new ContinuousHorizontalLineException(String.format("์ค‘๋ณต๋˜๋Š” ์„ธ๋กœ์„  ์œ„์น˜ : %d", verticalLine.getIndex()));
+        }
+    }
+
+    public int getHeight() {
+        return horizontalLines.getMaxHeight();
+    }
+
+    public int getWidth() {
+        return verticalLines.getMaxWidth();
+    }
+
+    public VerticalLines getVerticalLines() {
+        return verticalLines;
+    }
+
+    public HorizontalLines getHorizontalLines() {
+        return horizontalLines;
+    }
+}
diff --git a/src/main/java/ladder/domain/LadderGenerateStrategy.java b/src/main/java/ladder/domain/LadderGenerateStrategy.java
new file mode 100644
index 0000000000..275bf245ea
--- /dev/null
+++ b/src/main/java/ladder/domain/LadderGenerateStrategy.java
@@ -0,0 +1,5 @@
+package ladder.domain;
+
+public interface LadderGenerateStrategy {
+    boolean canGenerate();
+}
diff --git a/src/main/java/ladder/domain/LadderGenerator.java b/src/main/java/ladder/domain/LadderGenerator.java
new file mode 100644
index 0000000000..e76f9201d4
--- /dev/null
+++ b/src/main/java/ladder/domain/LadderGenerator.java
@@ -0,0 +1,71 @@
+package ladder.domain;
+
+import ladder.exception.IllegalLadderParameterException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class LadderGenerator {
+    private static final double DEFAULT_CHANCE = 0.5;
+
+    private final LadderGenerateStrategy ladderGenerateStrategy;
+
+    public LadderGenerator() {
+        this.ladderGenerateStrategy = () -> Math.random() < DEFAULT_CHANCE;
+    }
+
+    public LadderGenerator(LadderGenerateStrategy ladderGenerateStrategy) {
+        this.ladderGenerateStrategy = ladderGenerateStrategy;
+    }
+
+    public Ladder generate(int height, int width) {
+        checkHeightAndWidth(height, width);
+
+        VerticalLines verticalLines = VerticalLines.create(width);
+        HorizontalLines horizontalLines = createHorizontalLines(verticalLines, height);
+
+        return new Ladder(verticalLines, horizontalLines);
+    }
+
+    private HorizontalLines createHorizontalLines(VerticalLines verticalLines, int height) {
+        HashSet<HorizontalLine> horizontalLineHashSet = new HashSet<>();
+
+        for (int i = 0; i < height; i++) {
+            Set<HorizontalLine> sameHeightHorizontalLineSet = createSameHeightHorizontalLineSet(verticalLines, i);
+            horizontalLineHashSet.addAll(sameHeightHorizontalLineSet);
+        }
+
+        return new HorizontalLines(horizontalLineHashSet, height);
+    }
+
+    private Set<HorizontalLine> createSameHeightHorizontalLineSet(VerticalLines verticalLines, int height) {
+        HashSet<HorizontalLine> sameHeightHorizontalLineHashSet = new HashSet<>();
+
+        for (int i = 0; i < verticalLines.getMaxWidth() - 1; i++) {
+            VerticalLine nowVerticalLine = verticalLines.getVerticalLineByIndex(i);
+            VerticalLine nextVerticalLine = verticalLines.getVerticalLineByIndex(i + 1);
+
+            boolean notExistPreviousHorizontalLine = sameHeightHorizontalLineHashSet.stream()
+                    .noneMatch(horizontalLine ->
+                            horizontalLine.getRightVerticalLine() == nowVerticalLine
+                    );
+
+            if (notExistPreviousHorizontalLine && ladderGenerateStrategy.canGenerate()) {
+                sameHeightHorizontalLineHashSet.add(
+                        new HorizontalLine(
+                                new AdjacentVerticalLines(nowVerticalLine, nextVerticalLine),
+                                height
+                        )
+                );
+            }
+        }
+        return sameHeightHorizontalLineHashSet;
+    }
+
+    private void checkHeightAndWidth(int height, int width) {
+        if (height < HorizontalLine.MINIMUM_HEIGHT
+                || width < Ladder.MINIMUM_VERTICAL_LINES_QUANTITY) {
+            throw new IllegalLadderParameterException(String.format("์ž…๋ ฅ๋œ ๋†’์ด : %d, ์ž…๋ ฅ๋œ ๋„ˆ๋น„ : %d", height, width));
+        }
+    }
+}
diff --git a/src/main/java/ladder/domain/VerticalLine.java b/src/main/java/ladder/domain/VerticalLine.java
new file mode 100644
index 0000000000..f40c18b99f
--- /dev/null
+++ b/src/main/java/ladder/domain/VerticalLine.java
@@ -0,0 +1,13 @@
+package ladder.domain;
+
+public class VerticalLine {
+    private final int index;
+
+    public VerticalLine(int index) {
+        this.index = index;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+}
diff --git a/src/main/java/ladder/domain/VerticalLines.java b/src/main/java/ladder/domain/VerticalLines.java
new file mode 100644
index 0000000000..e9931f7255
--- /dev/null
+++ b/src/main/java/ladder/domain/VerticalLines.java
@@ -0,0 +1,53 @@
+package ladder.domain;
+
+import ladder.exception.IllegalVerticalLineWidthException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class VerticalLines {
+    private final Set<VerticalLine> verticalLineSet;
+    private final int maxWidth;
+
+    public VerticalLines(Set<VerticalLine> verticalLineSet, int maxWidth) {
+        checkValidVerticalLineWidth(verticalLineSet, maxWidth);
+
+        this.verticalLineSet = verticalLineSet;
+        this.maxWidth = maxWidth;
+    }
+
+    private void checkValidVerticalLineWidth(Set<VerticalLine> verticalLineSet, int maxWidth) {
+        if (verticalLineSet.stream()
+                .anyMatch(it -> it.getIndex() >= maxWidth)
+        ) {
+            throw new IllegalVerticalLineWidthException(String.format("์ตœ๋Œ€ ๋„ˆ๋น„ : %d", maxWidth));
+        }
+    }
+
+    public Set<VerticalLine> getVerticalLineSet() {
+        return Set.copyOf(verticalLineSet);
+    }
+
+    public int getMaxWidth() {
+        return maxWidth;
+    }
+
+    public VerticalLine getVerticalLineByIndex(int index) {
+        return verticalLineSet.stream()
+                .filter(it -> it.getIndex() == index)
+                .findFirst()
+                .orElse(null);
+    }
+
+    public int getSize() {
+        return verticalLineSet.size();
+    }
+
+    public static VerticalLines create(int count) {
+        HashSet<VerticalLine> verticalLineHashSet = new HashSet<>();
+        for (int i = 0; i < count; i++) {
+            verticalLineHashSet.add(new VerticalLine(i));
+        }
+        return new VerticalLines(verticalLineHashSet, count);
+    }
+}
diff --git a/src/main/java/ladder/domain/player/Player.java b/src/main/java/ladder/domain/player/Player.java
new file mode 100644
index 0000000000..6cb175eaef
--- /dev/null
+++ b/src/main/java/ladder/domain/player/Player.java
@@ -0,0 +1,21 @@
+package ladder.domain.player;
+
+import ladder.exception.IllegalPlayerNameException;
+
+public class Player {
+    private static final int MAX_PLAYER_NAME_LENGTH = 5;
+
+    private final String name;
+
+    public Player(String name) {
+        if (name.length() > MAX_PLAYER_NAME_LENGTH) {
+            throw new IllegalPlayerNameException(String.format("์ž…๋ ฅํ•œ ์ด๋ฆ„ : %s", name));
+        }
+
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
diff --git a/src/main/java/ladder/domain/player/Players.java b/src/main/java/ladder/domain/player/Players.java
new file mode 100644
index 0000000000..8d70145f0e
--- /dev/null
+++ b/src/main/java/ladder/domain/player/Players.java
@@ -0,0 +1,19 @@
+package ladder.domain.player;
+
+import java.util.List;
+
+public class Players {
+    private final List<Player> playerList;
+
+    public Players(List<Player> playerList) {
+        this.playerList = playerList;
+    }
+
+    public List<Player> getPlayerList() {
+        return List.copyOf(playerList);
+    }
+
+    public int getPlayerNumber() {
+        return playerList.size();
+    }
+}
diff --git a/src/main/java/ladder/domain/player/PlayersGenerator.java b/src/main/java/ladder/domain/player/PlayersGenerator.java
new file mode 100644
index 0000000000..f4eb10df41
--- /dev/null
+++ b/src/main/java/ladder/domain/player/PlayersGenerator.java
@@ -0,0 +1,20 @@
+package ladder.domain.player;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PlayersGenerator {
+    private static final String DEFAULT_SEPARATOR = ",";
+
+    private PlayersGenerator() {
+    }
+
+    public static Players create(String playerNames) {
+        List<Player> playerList = Arrays.stream(playerNames.split(DEFAULT_SEPARATOR))
+                .map(Player::new)
+                .collect(Collectors.toList());
+
+        return new Players(playerList);
+    }
+}
diff --git a/src/main/java/ladder/exception/ContinuousHorizontalLineException.java b/src/main/java/ladder/exception/ContinuousHorizontalLineException.java
new file mode 100644
index 0000000000..4d7075c650
--- /dev/null
+++ b/src/main/java/ladder/exception/ContinuousHorizontalLineException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class ContinuousHorizontalLineException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "๋™์ผํ•œ ๋†’์ด์—์„œ ์—ฐ์†๋˜๋Š” ๊ฐ€๋กœ์„ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.";
+
+    public ContinuousHorizontalLineException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/IllegalAdjacentVerticalLinesException.java b/src/main/java/ladder/exception/IllegalAdjacentVerticalLinesException.java
new file mode 100644
index 0000000000..37f9a6150e
--- /dev/null
+++ b/src/main/java/ladder/exception/IllegalAdjacentVerticalLinesException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class IllegalAdjacentVerticalLinesException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "์ธ๋ฑ์Šค์˜ ์ฐจ์ด๊ฐ€ 2 ์ด์ƒ์ธ ์ธ์ ‘ํ•˜์ง€ ์•Š์€ VerticalLine์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.";
+
+    public IllegalAdjacentVerticalLinesException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/IllegalHorizontalLineHeightException.java b/src/main/java/ladder/exception/IllegalHorizontalLineHeightException.java
new file mode 100644
index 0000000000..30a17a56cd
--- /dev/null
+++ b/src/main/java/ladder/exception/IllegalHorizontalLineHeightException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class IllegalHorizontalLineHeightException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "์ ์ ˆํ•˜์ง€ ์•Š์€ ๋†’์ด์˜ ๊ฐ€๋กœ์„ ์ž…๋‹ˆ๋‹ค.";
+
+    public IllegalHorizontalLineHeightException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/IllegalLadderParameterException.java b/src/main/java/ladder/exception/IllegalLadderParameterException.java
new file mode 100644
index 0000000000..24013e3503
--- /dev/null
+++ b/src/main/java/ladder/exception/IllegalLadderParameterException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class IllegalLadderParameterException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "๋†’์ด๋Š” 0 ์ด์ƒ, ๋„ˆ๋น„๋Š” 2 ์ด์ƒ์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.";
+
+    public IllegalLadderParameterException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/IllegalPlayerNameException.java b/src/main/java/ladder/exception/IllegalPlayerNameException.java
new file mode 100644
index 0000000000..368f5fb088
--- /dev/null
+++ b/src/main/java/ladder/exception/IllegalPlayerNameException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class IllegalPlayerNameException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "ํ”Œ๋ ˆ์ด์–ด ์ด๋ฆ„์€ 5์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.";
+
+    public IllegalPlayerNameException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/IllegalVerticalLineWidthException.java b/src/main/java/ladder/exception/IllegalVerticalLineWidthException.java
new file mode 100644
index 0000000000..f5918b9248
--- /dev/null
+++ b/src/main/java/ladder/exception/IllegalVerticalLineWidthException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class IllegalVerticalLineWidthException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "์ตœ๋Œ€ ๋„ˆ๋น„๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ์„ธ๋กœ์„ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.";
+
+    public IllegalVerticalLineWidthException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/exception/NotEnoughVerticalLinesException.java b/src/main/java/ladder/exception/NotEnoughVerticalLinesException.java
new file mode 100644
index 0000000000..fc1b261917
--- /dev/null
+++ b/src/main/java/ladder/exception/NotEnoughVerticalLinesException.java
@@ -0,0 +1,9 @@
+package ladder.exception;
+
+public class NotEnoughVerticalLinesException extends RuntimeException {
+    private static final String DEFAULT_MESSAGE = "์ตœ์†Œ ๋‘ ๊ฐœ ์ด์ƒ์˜ ์„ธ๋กœ์„ ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.";
+
+    public NotEnoughVerticalLinesException(String message) {
+        super(String.format("%s %s", DEFAULT_MESSAGE, message));
+    }
+}
diff --git a/src/main/java/ladder/view/InputView.java b/src/main/java/ladder/view/InputView.java
new file mode 100644
index 0000000000..4db1b76bfc
--- /dev/null
+++ b/src/main/java/ladder/view/InputView.java
@@ -0,0 +1,20 @@
+package ladder.view;
+
+import java.util.Scanner;
+
+public class InputView {
+    private static final Scanner scanner = new Scanner(System.in);
+
+    private InputView() {
+    }
+
+    public static String getPlayerNames() {
+        System.out.println("์ฐธ์—ฌํ•  ์‚ฌ๋žŒ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”. (์ด๋ฆ„์€ ์‰ผํ‘œ(,)๋กœ ๊ตฌ๋ถ„ํ•˜์„ธ์š”");
+        return scanner.nextLine();
+    }
+
+    public static int getLadderHeight() {
+        System.out.println("์ตœ๋Œ€ ์‚ฌ๋‹ค๋ฆฌ ๋†’์ด๋Š” ๋ช‡ ๊ฐœ์ธ๊ฐ€์š”?");
+        return Integer.parseInt(scanner.nextLine());
+    }
+}
diff --git a/src/main/java/ladder/view/ResultView.java b/src/main/java/ladder/view/ResultView.java
new file mode 100644
index 0000000000..de6e3021a4
--- /dev/null
+++ b/src/main/java/ladder/view/ResultView.java
@@ -0,0 +1,56 @@
+package ladder.view;
+
+import ladder.domain.Ladder;
+import ladder.domain.player.Players;
+
+import java.util.Arrays;
+
+public class ResultView {
+    private static final int HORIZONTAL_CHARACTER_LENGTH = 6;
+
+    private ResultView() {
+    }
+
+    public static void showResultMessage() {
+        System.out.println("์‹คํ–‰๊ฒฐ๊ณผ\n");
+    }
+
+    public static void showPlayers(Players players) {
+        System.out.print("   ");
+        players.getPlayerList()
+                .forEach(player -> System.out.printf("%-6s", player.getName()));
+        System.out.println();
+    }
+
+    public static void showLadder(Ladder ladder) {
+        int maxHeight = ladder.getHeight();
+        int maxWidth = ladder.getWidth() * HORIZONTAL_CHARACTER_LENGTH;
+        char[][] ladderCharacters = new char[maxHeight][maxWidth];
+        Arrays.stream(ladderCharacters).forEach(it -> Arrays.fill(it, ' '));
+
+        for (int i = 0; i < maxHeight; i++) {
+            int height = i;
+            ladder.getVerticalLines()
+                    .getVerticalLineSet()
+                    .stream()
+                    .map(it -> (it.getIndex() + 1) * HORIZONTAL_CHARACTER_LENGTH - 1)
+                    .forEach(it -> ladderCharacters[height][it] = '|');
+
+            ladder.getHorizontalLines().getHorizontalLineSetByHeight(height)
+                    .forEach(horizontalLine -> {
+                        int from = horizontalLine.getLeftVerticalLine().getIndex();
+                        int to = horizontalLine.getRightVerticalLine().getIndex();
+                        for (int j = (from + 1) * HORIZONTAL_CHARACTER_LENGTH; j < (to + 1) * HORIZONTAL_CHARACTER_LENGTH - 1; j++) {
+                            ladderCharacters[height][j] = '-';
+                        }
+                    });
+        }
+
+        for (int i = 0; i < ladder.getHeight(); i++) {
+            for (int j = 0; j < ladder.getWidth() * HORIZONTAL_CHARACTER_LENGTH; j++) {
+                System.out.print(ladderCharacters[i][j]);
+            }
+            System.out.println();
+        }
+    }
+}
diff --git a/src/main/java/nextstep/fp/Conditional.java b/src/main/java/nextstep/fp/Conditional.java
deleted file mode 100644
index 1d48b1b856..0000000000
--- a/src/main/java/nextstep/fp/Conditional.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package nextstep.fp;
-
-public interface Conditional {
-    boolean test(Integer number);
-}
diff --git a/src/main/java/nextstep/fp/Lambda.java b/src/main/java/nextstep/fp/Lambda.java
index 66e752a24d..ebb937e3af 100644
--- a/src/main/java/nextstep/fp/Lambda.java
+++ b/src/main/java/nextstep/fp/Lambda.java
@@ -23,9 +23,9 @@ public static void runThread() {
         new Thread(() -> System.out.println("Hello from thread")).start();
     }
 
-    public static int sumAll(List<Integer> numbers, Conditional conditional) {
+    public static int sumAll(List<Integer> numbers, Predicate<Integer> predicate) {
         return numbers.stream()
-                .filter(conditional::test)
+                .filter(predicate)
                 .mapToInt(it -> it)
                 .sum();
     }
diff --git a/src/main/java/nextstep/optional/Expression.java b/src/main/java/nextstep/optional/Expression.java
index 969e4d5b04..e87d58001a 100644
--- a/src/main/java/nextstep/optional/Expression.java
+++ b/src/main/java/nextstep/optional/Expression.java
@@ -11,13 +11,13 @@ enum Expression {
         this.expression = expression;
     }
 
-    private static boolean matchExpression(Expression e, String expression) {
-        return expression.equals(e.expression);
+    private boolean matchExpression(String expression) {
+        return expression.equals(this.expression);
     }
 
     static Expression of(String expression) {
         return Arrays.stream(values())
-                .filter(it -> matchExpression(it, expression))
+                .filter(it -> it.matchExpression(expression))
                 .findFirst()
                 .orElseThrow(() -> new IllegalArgumentException(String.format("%s๋Š” ์‚ฌ์น™์—ฐ์‚ฐ์— ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š” ํ‘œํ˜„์‹์ž…๋‹ˆ๋‹ค.", expression)));
     }
diff --git a/src/main/java/nextstep/optional/User.java b/src/main/java/nextstep/optional/User.java
index 5fac8a2821..b898f07c05 100644
--- a/src/main/java/nextstep/optional/User.java
+++ b/src/main/java/nextstep/optional/User.java
@@ -36,8 +36,8 @@ public static boolean ageIsInRange1(User user) {
 
     public static boolean ageIsInRange2(User user) {
         return Optional.ofNullable(user)
-                .map(it -> it.age)
-                .filter(it -> it >= 30 && it <= 45)
+                .filter(it -> it.age != null)
+                .filter(it -> it.age >= 30 && it.age <= 45)
                 .isPresent();
     }
 
diff --git a/src/test/java/ladder/domain/AdjacentVerticalLinesTest.java b/src/test/java/ladder/domain/AdjacentVerticalLinesTest.java
new file mode 100644
index 0000000000..afd5b22e96
--- /dev/null
+++ b/src/test/java/ladder/domain/AdjacentVerticalLinesTest.java
@@ -0,0 +1,35 @@
+package ladder.domain;
+
+import ladder.exception.IllegalAdjacentVerticalLinesException;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class AdjacentVerticalLinesTest {
+    private final VerticalLine verticalLine0 = new VerticalLine(0);
+    private final VerticalLine verticalLine1 = new VerticalLine(1);
+    private final VerticalLine verticalLine2 = new VerticalLine(2);
+
+    @Test
+    void ์ธ์ ‘ํ•œ_์ˆ˜์ง์„ ๋“ค๋กœ_AdjacentVerticalLines๋ฅผ_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        AdjacentVerticalLines adjacentVerticalLines = new AdjacentVerticalLines(verticalLine0, verticalLine1);
+
+        assertThat(adjacentVerticalLines.getLeftVerticalLine()).isEqualTo(verticalLine0);
+        assertThat(adjacentVerticalLines.getRightVerticalLine()).isEqualTo(verticalLine1);
+    }
+
+    @Test
+    void ์ƒ์„ฑ_์‹œ_์ˆœ์„œ์—_๊ด€๊ณ„์—†์ด_left_right๋ฅผ_๊ตฌ๋ถ„ํ• _์ˆ˜_์žˆ๋‹ค() {
+        AdjacentVerticalLines adjacentVerticalLines = new AdjacentVerticalLines(verticalLine1, verticalLine0);
+
+        assertThat(adjacentVerticalLines.getLeftVerticalLine()).isEqualTo(verticalLine0);
+        assertThat(adjacentVerticalLines.getRightVerticalLine()).isEqualTo(verticalLine1);
+    }
+
+    @Test
+    void ๊ฐ_์ˆ˜์ง์„ ์˜_index_์ฐจ์ด๊ฐ€_2_์ด์ƒ์ด๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new AdjacentVerticalLines(verticalLine0, verticalLine2))
+                .isInstanceOf(IllegalAdjacentVerticalLinesException.class);
+    }
+}
diff --git a/src/test/java/ladder/domain/HorizontalLineTest.java b/src/test/java/ladder/domain/HorizontalLineTest.java
new file mode 100644
index 0000000000..793d80133e
--- /dev/null
+++ b/src/test/java/ladder/domain/HorizontalLineTest.java
@@ -0,0 +1,52 @@
+package ladder.domain;
+
+import ladder.exception.IllegalHorizontalLineHeightException;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class HorizontalLineTest {
+    private final VerticalLine verticalLine0 = new VerticalLine(0);
+    private final VerticalLine verticalLine1 = new VerticalLine(1);
+    private final VerticalLine verticalLine2 = new VerticalLine(2);
+    private final AdjacentVerticalLines adjacentVerticalLines = new AdjacentVerticalLines(verticalLine0, verticalLine1);
+
+    @Test
+    void ํŠน์ •_์ธ๋ฑ์Šค์˜_์„ธ๋กœ์„ ์„_์ž‡๋Š”_HorizontalLine์„_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 0);
+
+        assertThat(horizontalLine.getAdjacentVerticalLines().getLeftVerticalLine()).isEqualTo(verticalLine0);
+        assertThat(horizontalLine.getAdjacentVerticalLines().getRightVerticalLine()).isEqualTo(verticalLine1);
+        assertThat(horizontalLine.getHeight()).isEqualTo(0);
+    }
+
+    @Test
+    void ์™ผ์ชฝ์œผ๋กœ_๋งž๋‹ฟ์€_์„ธ๋กœ์„ ์„_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 0);
+
+        assertThat(horizontalLine.getLeftVerticalLine()).isEqualTo(verticalLine0);
+    }
+
+    @Test
+    void ์˜ค๋ฅธ์ชฝ์œผ๋กœ_๋งž๋‹ฟ์€_์„ธ๋กœ์„ ์„_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 0);
+
+        assertThat(horizontalLine.getRightVerticalLine()).isEqualTo(verticalLine1);
+    }
+
+    @Test
+    void ์„ธ๋กœ์„ ๊ณผ_๋งž๋‹ฟ์•„์žˆ๋Š”์ง€_ํ™•์ธํ• _์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 0);
+
+        assertThat(horizontalLine.isConnected(verticalLine0)).isTrue();
+        assertThat(horizontalLine.isConnected(verticalLine1)).isTrue();
+        assertThat(horizontalLine.isConnected(verticalLine2)).isFalse();
+    }
+
+    @Test
+    void ์Œ์ˆ˜_๋†’์ด๋ฅผ_๊ฐ€์ง€๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new HorizontalLine(adjacentVerticalLines, -1))
+                .isInstanceOf(IllegalHorizontalLineHeightException.class);
+    }
+}
diff --git a/src/test/java/ladder/domain/HorizontalLinesTest.java b/src/test/java/ladder/domain/HorizontalLinesTest.java
new file mode 100644
index 0000000000..030aa169e6
--- /dev/null
+++ b/src/test/java/ladder/domain/HorizontalLinesTest.java
@@ -0,0 +1,58 @@
+package ladder.domain;
+
+import ladder.exception.IllegalHorizontalLineHeightException;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class HorizontalLinesTest {
+    private final VerticalLine verticalLine0 = new VerticalLine(0);
+    private final VerticalLine verticalLine1 = new VerticalLine(1);
+    private final AdjacentVerticalLines adjacentVerticalLines = new AdjacentVerticalLines(verticalLine0, verticalLine1);
+    private final HorizontalLine horizontalLine0 = new HorizontalLine(adjacentVerticalLines, 0);
+    private final HorizontalLine horizontalLine1 = new HorizontalLine(adjacentVerticalLines, 1);
+    private final Set<HorizontalLine> horizontalLineSet = Set.of(
+            horizontalLine0, horizontalLine1
+    );
+
+    @Test
+    void HorizontalLineSet์™€_์ตœ๋Œ€_๋†’์ด๋กœ_์ƒ์„ฑํ•˜์—ฌ_์ด๋ฅผ_๋ฆฌ์ŠคํŠธ๋กœ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new HorizontalLines(horizontalLineSet, 3)
+                .getHorizontalLineSet()
+                .containsAll(horizontalLineSet)
+        ).isTrue();
+    }
+
+    @Test
+    void ๋†’์ด๋ณ„๋กœ_HorizontalLineSet๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLines horizontalLines = new HorizontalLines(horizontalLineSet, 3);
+        Set<HorizontalLine> horizontalLineSet0 = horizontalLines.getHorizontalLineSetByHeight(0);
+        Set<HorizontalLine> horizontalLineSet1 = horizontalLines.getHorizontalLineSetByHeight(1);
+
+        assertThat(horizontalLineSet0.contains(horizontalLine0)).isTrue();
+        assertThat(horizontalLineSet0.contains(horizontalLine1)).isFalse();
+        assertThat(horizontalLineSet1.contains(horizontalLine0)).isFalse();
+        assertThat(horizontalLineSet1.contains(horizontalLine1)).isTrue();
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋†’์ด๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new HorizontalLines(horizontalLineSet, 3).getMaxHeight()).isEqualTo(3);
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋†’์ด๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_horizontalLine์ด_์žˆ์œผ๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 5);
+        assertThatThrownBy(() -> new HorizontalLines(Set.of(horizontalLine), 3))
+                .isInstanceOf(IllegalHorizontalLineHeightException.class);
+    }
+
+    @Test
+    void HorizontalLine๋“ค์˜_๊ฐฏ์ˆ˜๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        HorizontalLines horizontalLines = new HorizontalLines(horizontalLineSet, 3);
+        assertThat(horizontalLines.getSize()).isEqualTo(2);
+    }
+}
diff --git a/src/test/java/ladder/domain/LadderGeneratorTest.java b/src/test/java/ladder/domain/LadderGeneratorTest.java
new file mode 100644
index 0000000000..eac917eb7a
--- /dev/null
+++ b/src/test/java/ladder/domain/LadderGeneratorTest.java
@@ -0,0 +1,41 @@
+package ladder.domain;
+
+import ladder.exception.IllegalLadderParameterException;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class LadderGeneratorTest {
+    @Test
+    void ์ตœ๋Œ€_๋†’์ด์—_์Œ์ˆ˜๋ฅผ_์ž…๋ ฅํ•˜๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new LadderGenerator().generate(-1, 2))
+                .isInstanceOf(IllegalLadderParameterException.class);
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋„ˆ๋น„์—_1_์ดํ•˜์˜_๊ฐ’์„_์ž…๋ ฅํ•˜๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new LadderGenerator().generate(2, 1))
+                .isInstanceOf(IllegalLadderParameterException.class);
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋†’์ด์™€_์ตœ๋Œ€_๋„ˆ๋น„๋ฅผ_์ง€์ •ํ•˜๋ฉด_์‚ฌ๋‹ค๋ฆฌ๋ฅผ_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        int maxHeight = 2;
+        int maxWidth = 2;
+        LadderGenerator LadderGenerator = new LadderGenerator();
+        Ladder ladder = LadderGenerator.generate(maxHeight, maxWidth);
+
+        assertThat(ladder.getHeight()).isEqualTo(maxHeight);
+        assertThat(ladder.getWidth()).isEqualTo(maxWidth);
+        assertThat(ladder.getVerticalLines().getSize()).isEqualTo(2);
+    }
+
+    @Test
+    void ์‚ฌ๋‹ค๋ฆฌ_์ƒ์„ฑ_์ „๋žต์—_๋”ฐ๋ผ_์‚ฌ๋‹ค๋ฆฌ๊ฐ€_์ƒ์„ฑ๋œ๋‹ค() {
+        LadderGenerator LadderGenerator = new LadderGenerator(() -> false);
+        Ladder ladder = LadderGenerator.generate(2, 2);
+
+        assertThat(ladder.getHorizontalLines().getSize()).isEqualTo(0);
+    }
+}
diff --git a/src/test/java/ladder/domain/LadderTest.java b/src/test/java/ladder/domain/LadderTest.java
new file mode 100644
index 0000000000..6171447470
--- /dev/null
+++ b/src/test/java/ladder/domain/LadderTest.java
@@ -0,0 +1,75 @@
+package ladder.domain;
+
+import ladder.exception.ContinuousHorizontalLineException;
+import ladder.exception.NotEnoughVerticalLinesException;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class LadderTest {
+    private final int maxWidth = 3;
+    private final int maxHeight = 2;
+    private final VerticalLine verticalLine0 = new VerticalLine(0);
+    private final VerticalLine verticalLine1 = new VerticalLine(1);
+    private final AdjacentVerticalLines adjacentVerticalLines = new AdjacentVerticalLines(verticalLine0, verticalLine1);
+    private final HorizontalLine horizontalLine = new HorizontalLine(adjacentVerticalLines, 0);
+    private final VerticalLines verticalLines = new VerticalLines(Set.of(verticalLine0, verticalLine1), maxWidth);
+    private final HorizontalLines horizontalLines = new HorizontalLines(Set.of(horizontalLine), maxHeight);
+
+    @Test
+    void ์‚ฌ๋‹ค๋ฆฌ๋Š”_์ตœ๋Œ€_๋†’์ด๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new Ladder(verticalLines, horizontalLines).getHeight()).isEqualTo(maxHeight);
+    }
+
+    @Test
+    void ์‚ฌ๋‹ค๋ฆฌ๋Š”_์ตœ๋Œ€_๋„ˆ๋น„๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new Ladder(verticalLines, horizontalLines).getWidth()).isEqualTo(maxWidth);
+    }
+
+    @Test
+    void ์‚ฌ๋‹ค๋ฆฌ๋Š”_์„ธ๋กœ์„ ๋“ค์„_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(
+                new Ladder(verticalLines, horizontalLines).getVerticalLines()
+                        .getVerticalLineSet()
+                        .containsAll(Set.of(verticalLine0, verticalLine1))
+        ).isTrue();
+    }
+
+    @Test
+    void ์‚ฌ๋‹ค๋ฆฌ๋Š”_๊ฐ€๋กœ์„ ๋“ค์„_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(
+                new Ladder(verticalLines, horizontalLines).getHorizontalLines()
+                        .getHorizontalLineSet()
+                        .contains(horizontalLine)
+        ).isTrue();
+    }
+
+    @Test
+    void ๋™์ผํ•œ_๋†’์ด์—์„œ_์—ฐ์†๋˜๋Š”_๊ฐ€๋กœ์„ ์ด_์กด์žฌํ•˜๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        VerticalLine verticalLine2 = new VerticalLine(2);
+        AdjacentVerticalLines adjacentVerticalLines12 = new AdjacentVerticalLines(verticalLine1, verticalLine2);
+        HorizontalLine wrongHorizontalLine = new HorizontalLine(adjacentVerticalLines12, 0);
+
+        assertThatThrownBy(() ->
+                new Ladder(
+                        new VerticalLines(
+                                Set.of(verticalLine0, verticalLine1, verticalLine2),
+                                maxWidth
+                        ),
+                        new HorizontalLines(
+                                Set.of(horizontalLine, wrongHorizontalLine),
+                                maxHeight
+                        )
+                )
+        ).isInstanceOf(ContinuousHorizontalLineException.class);
+    }
+
+    @Test
+    void ์„ธ๋กœ์„ ์ด_ํ•˜๋‚˜_์ดํ•˜์ด๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new Ladder(new VerticalLines(Set.of(verticalLine0), 1), horizontalLines))
+                .isInstanceOf(NotEnoughVerticalLinesException.class);
+    }
+}
diff --git a/src/test/java/ladder/domain/VerticalLineTest.java b/src/test/java/ladder/domain/VerticalLineTest.java
new file mode 100644
index 0000000000..76ef54b1af
--- /dev/null
+++ b/src/test/java/ladder/domain/VerticalLineTest.java
@@ -0,0 +1,12 @@
+package ladder.domain;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+public class VerticalLineTest {
+    @Test
+    void ์ธ๋ฑ์Šค๋ฅผ_์ง€์ •ํ•˜์—ฌ_VerticalLine์„_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new VerticalLine(3).getIndex()).isEqualTo(3);
+    }
+}
diff --git a/src/test/java/ladder/domain/VerticalLinesTest.java b/src/test/java/ladder/domain/VerticalLinesTest.java
new file mode 100644
index 0000000000..b983a43253
--- /dev/null
+++ b/src/test/java/ladder/domain/VerticalLinesTest.java
@@ -0,0 +1,53 @@
+package ladder.domain;
+
+import ladder.exception.IllegalVerticalLineWidthException;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class VerticalLinesTest {
+    private final VerticalLine verticalLine0 = new VerticalLine(0);
+    private final VerticalLine verticalLine1 = new VerticalLine(1);
+    private final Set<VerticalLine> verticalLineSet = Set.of(verticalLine0, verticalLine1);
+
+    @Test
+    void VerticalLineSet๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new VerticalLines(verticalLineSet, 2)
+                .getVerticalLineSet()
+                .containsAll(verticalLineSet)
+        ).isTrue();
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋„ˆ๋น„๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new VerticalLines(verticalLineSet, 2).getMaxWidth()).isEqualTo(2);
+    }
+
+    @Test
+    void ์ตœ๋Œ€_๋„ˆ๋น„๋ฅผ_์ดˆ๊ณผํ•˜๋Š”_verticalLine์ด_์žˆ์œผ๋ฉด_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        VerticalLine verticalLine = new VerticalLine(5);
+        assertThatThrownBy(() -> new VerticalLines(Set.of(verticalLine), 3))
+                .isInstanceOf(IllegalVerticalLineWidthException.class);
+    }
+
+    @Test
+    void ์ฃผ์–ด์ง„_index์—_ํ•ด๋‹นํ•˜๋Š”_VerticalLine์„_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        VerticalLines verticalLines = new VerticalLines(verticalLineSet, 2);
+
+        assertThat(verticalLines.getVerticalLineByIndex(0)).isEqualTo(verticalLine0);
+        assertThat(verticalLines.getVerticalLineByIndex(1)).isEqualTo(verticalLine1);
+    }
+
+    @Test
+    void ์ฃผ์–ด์ง„_index์—_ํ•ด๋‹นํ•˜๋Š”_VerticalLine์ด_์—†์œผ๋ฉด_null์„_๋ฐ˜ํ™˜ํ•œ๋‹ค() {
+        assertThat(new VerticalLines(verticalLineSet, 2).getVerticalLineByIndex(5)).isNull();
+    }
+
+    @Test
+    void ์ˆซ์ž_๋งŒํผ์˜_VerticalLine๋“ค์„_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        assertThat(VerticalLines.create(3).getSize()).isEqualTo(3);
+    }
+}
diff --git a/src/test/java/ladder/domain/player/PlayerTest.java b/src/test/java/ladder/domain/player/PlayerTest.java
new file mode 100644
index 0000000000..89df50bb0d
--- /dev/null
+++ b/src/test/java/ladder/domain/player/PlayerTest.java
@@ -0,0 +1,19 @@
+package ladder.domain.player;
+
+import ladder.exception.IllegalPlayerNameException;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+
+public class PlayerTest {
+    @Test
+    void ์ฃผ์–ด์ง„_๋ฌธ์ž์—ด๋กœ_ํ”Œ๋ ˆ์ด์–ด_์ด๋ฆ„์„_์ง€์ •ํ•˜์—ฌ_ํ”Œ๋ ˆ์ด์–ด๋ฅผ_์ƒ์„ฑํ• _์ˆ˜_์žˆ๋‹ค() {
+        assertThat(new Player("abc").getName()).isEqualTo("abc");
+    }
+
+    @Test
+    void ํ”Œ๋ ˆ์ด์–ด_์ด๋ฆ„์ด_5์ž๋ฅผ_๋„˜์–ด๊ฐˆ_๊ฒฝ์šฐ_์˜ˆ์™ธ๊ฐ€_๋ฐœ์ƒํ•œ๋‹ค() {
+        assertThatThrownBy(() -> new Player("abcdef")).isInstanceOf(IllegalPlayerNameException.class);
+    }
+}
diff --git a/src/test/java/ladder/domain/player/PlayersGeneratorTest.java b/src/test/java/ladder/domain/player/PlayersGeneratorTest.java
new file mode 100644
index 0000000000..eefbadb5f2
--- /dev/null
+++ b/src/test/java/ladder/domain/player/PlayersGeneratorTest.java
@@ -0,0 +1,18 @@
+package ladder.domain.player;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+public class PlayersGeneratorTest {
+    @Test
+    void ์‰ผํ‘œ๋กœ_๊ตฌ๋ถ„๋œ_๋ฌธ์ž์—ด๋กœ_ํ”Œ๋ ˆ์ด์–ด๋“ค์„_๋งŒ๋“ค_์ˆ˜_์žˆ๋‹ค() {
+        String playerNames = "pobi,honux,crong,jk";
+        Players players = PlayersGenerator.create(playerNames);
+        assertThat(players.getPlayerList()
+                .stream()
+                .map(Player::getName)
+                .toArray()
+        ).containsExactly("pobi", "honux", "crong", "jk");
+    }
+}
diff --git a/src/test/java/ladder/domain/player/PlayersTest.java b/src/test/java/ladder/domain/player/PlayersTest.java
new file mode 100644
index 0000000000..8f9d573c39
--- /dev/null
+++ b/src/test/java/ladder/domain/player/PlayersTest.java
@@ -0,0 +1,21 @@
+package ladder.domain.player;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+public class PlayersTest {
+    @Test
+    void ์—ฌ๋Ÿฌ_ํ”Œ๋ ˆ์ด์–ด๋“ค๋กœ_Players๋ฅผ_์ƒ์„ฑํ•˜๊ณ _Player_๋ฆฌ์ŠคํŠธ๋ฅผ_๋ฐ˜ํ™˜ํ• _์ˆ˜_์žˆ๋‹ค() {
+        List<Player> playerList = List.of(new Player("a"), new Player("b"));
+        assertThat(new Players(playerList).getPlayerList().containsAll(playerList)).isTrue();
+    }
+
+    @Test
+    void ํ”Œ๋ ˆ์ด์–ด๊ฐ€_๋ช‡_๋ช…์ธ์ง€_์•Œ_์ˆ˜_์žˆ๋‹ค() {
+        List<Player> playerList = List.of(new Player("a"), new Player("b"));
+        assertThat(new Players(playerList).getPlayerNumber()).isEqualTo(2);
+    }
+}