Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c907d1c
feat: 사다리의 가로, 세로 값에 대한 원시값 포장
jinhyeongpark Feb 7, 2026
3df5893
feat: 사다리의 지점 상태를 관리하는 Point 도메인 구현
jinhyeongpark Feb 7, 2026
8d03131
feat: 사다리의 가로 한 줄을 담당하는 Line 도메인 구현
jinhyeongpark Feb 7, 2026
9b6cb0c
feat: 사다리의 전체 구조를 관리하는 Ladder 도메인 구현
jinhyeongpark Feb 7, 2026
0342e8f
feat: 사다리의 시각화를 위한 OutputView 구현\
jinhyeongpark Feb 7, 2026
301cd44
feat: 사용자 입력을 담당하는 InputView 구현
jinhyeongpark Feb 7, 2026
5ca9ff3
feat: 프로그램 실행을 담당하는 Application 메인 로직 구현
jinhyeongpark Feb 7, 2026
c5552c9
feat: Line의 유무를 판단하는 Point의 boolean에 대해 BooleanSupplier 적용
jinhyeongpark Feb 7, 2026
ae958f0
feat: 사용하지 않는 기존 canDraw 메서드 삭제
jinhyeongpark Feb 7, 2026
a6ea645
test: 값 객체(Point, Width, Height)에 대한 단위 테스트 추가
jinhyeongpark Feb 7, 2026
605275b
test: Line의 다리 생성 및 가로 중복 금지 로직 검증 테스트 추가
jinhyeongpark Feb 7, 2026
a9ff74b
test: 사다리 전체 구조 및 조립 로직 검증 테스트 추가
jinhyeongpark Feb 7, 2026
a5ed58a
feat: 하나의 Line 내에서의 이동 로직 메서드 move 구현
jinhyeongpark Feb 8, 2026
2071d3e
feat: Ladder에서 사다리 게임 수행 및 결과를 생성하는 메서드 구현
jinhyeongpark Feb 8, 2026
28fe4d9
feat: OutputView에서 사다리게임 결과 출력 메서드 구현
jinhyeongpark Feb 8, 2026
d101e00
test: move에 대한 테스트코드 작성
jinhyeongpark Feb 8, 2026
614c62d
test: climb과 generateResults에 대한 테스트코드 작성
jinhyeongpark Feb 8, 2026
49d73b3
refactor: LadderTest에서 반복되는 Participants 생성에 대해 상수 및 메서드로 분리
jinhyeongpark Feb 8, 2026
b3ac3e1
feat: Ladder의 정적 팩터리 메서드 파라미터 변경
jinhyeongpark Feb 8, 2026
349cf9f
feat: 사용하지 않는 LadderWidth 관련 클래스 삭제
jinhyeongpark Feb 8, 2026
ff2eb5e
feat: 실행 결과와 결과를 담는 일급 컬렉션 구현
jinhyeongpark Feb 8, 2026
10df688
feat: 참여자 명과 참여자들을 관리하는 일급 컬렉션 구현
jinhyeongpark Feb 8, 2026
076b917
feat: 참여자와 실행 결과에 대한 입력 로직 구현
jinhyeongpark Feb 8, 2026
b21eb78
feat: 단일 필드를 반환하는 메서드를 추가하여 toString() 없이 문자열로 출력되도록 함
jinhyeongpark Feb 8, 2026
11048f6
feat: 단일 필드를 반환하는 메서드를 추가하여 toString() 없이 문자열로 출력되도록 함
jinhyeongpark Feb 8, 2026
bbd4b73
feat: 사다리 게임 결과 매핑을 위한 LadderGameResult 클래스 추가
jinhyeongpark Feb 8, 2026
591482a
feat: 게임 결과 조회 흐름을 제어하는 LadderGameController 추가
jinhyeongpark Feb 8, 2026
3c81f19
feat: 특정 참여자의 결과를 요청하는 입력 메서드 구현
jinhyeongpark Feb 8, 2026
8dbf07e
feat: 사다리 시각화 정렬 및 게임 결과 출력 기능 구현
jinhyeongpark Feb 8, 2026
33f1f4f
feat: 사다리 게임 참가자 및 결과 입력 처리 로직 추가
jinhyeongpark Feb 8, 2026
d5090da
test: Name 클래스 단위 테스트 구현
jinhyeongpark Feb 8, 2026
6f66089
test: LadderResult 및 LadderResults 클래스 단위 테스트 구현
jinhyeongpark Feb 8, 2026
eb01867
test: LadderGameResultTest 클래스 단위 테스트 구현
jinhyeongpark Feb 8, 2026
19f0bd5
test: ParticipantsTest 구현
jinhyeongpark Feb 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/main/java/ladder/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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.LadderResults;
import ladder.domain.Participants;
import ladder.view.InputView;
import ladder.view.OutputView;

public class Application {

private static final Random RANDOM = new Random();

public static void main(String[] args) {
Participants participants = InputView.inputNames();
LadderResults results = InputView.inputLadderResults(participants.size());

LadderHeight height = InputView.inputHeight();

Ladder ladder = Ladder.of(participants, height, RANDOM::nextBoolean);

Map<Integer, Integer> path = ladder.generateResults();

LadderGameResult gameResult = LadderGameResult.of(participants, results, path);

OutputView.printLadder(participants, ladder, results);
LadderGameController.runInquiry(gameResult);

}

}
28 changes: 28 additions & 0 deletions src/main/java/ladder/controller/LadderGameController.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
}
54 changes: 54 additions & 0 deletions src/main/java/ladder/domain/Ladder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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 {

private final List<Line> lines;
private final int width;

private Ladder(List<Line> lines, int width) {
this.lines = lines;
this.width = width;
}

public static Ladder of(Participants participants, LadderHeight height, BooleanSupplier strategy) {
int participantCount = participants.size();
List<Line> lines = generateLines(participantCount, height, strategy);

return new Ladder(lines, participantCount);
}

public int climb(int startIndex) {
int currentIndex = startIndex;
for (Line line : lines) {
currentIndex = line.move(currentIndex);
}
return currentIndex;
}

public Map<Integer, Integer> generateResults() {
Map<Integer, Integer> results = new LinkedHashMap<>();
for (int i = 0; i < width; i++) {
results.put(i, climb(i));
}
return results;
}

private static List<Line> generateLines(int participantCount, LadderHeight height, BooleanSupplier strategy) {
List<Line> lines = new ArrayList<>();
int pointCount = participantCount - 1;
for (int i = 0; i < height.getValue(); i++) {
lines.add(Line.from(pointCount, strategy));
}
return lines;
}

public List<Line> getLines() {
return lines;
}
}
41 changes: 41 additions & 0 deletions src/main/java/ladder/domain/LadderGameResult.java
Original file line number Diff line number Diff line change
@@ -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<Name, LadderResult> gameResults;

private LadderGameResult(Map<Name, LadderResult> gameResults) {
this.gameResults = gameResults;
}

public static LadderGameResult of(Participants participants, LadderResults results, Map<Integer, Integer> ladderPath) {
Map<Name, LadderResult> 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<Name, LadderResult> getAllResults() {
return Collections.unmodifiableMap(gameResults);
}

}
25 changes: 25 additions & 0 deletions src/main/java/ladder/domain/LadderHeight.java
Original file line number Diff line number Diff line change
@@ -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명 이상이어야 합니다.");
}
}

}
27 changes: 27 additions & 0 deletions src/main/java/ladder/domain/LadderResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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());
}

public String getValue() {
return value;
}

private void validate(String value) {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("실행 결과는 빈 값일 수 없습니다.");
}
if (value.length() > 5) {
throw new IllegalArgumentException("실행 결과는 최대 5글자입니다.");
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/ladder/domain/LadderResults.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ladder.domain;

import java.util.List;

public class LadderResults {
private final List<LadderResult> results;

private LadderResults(List<LadderResult> results) {
this.results = results;
}

public static LadderResults of(List<String> rawResults, int participantCount) {
if (rawResults.size() != participantCount) {
throw new IllegalArgumentException("참가자 수와 결과의 개수가 일치해야 합니다.");
}

List<LadderResult> results = rawResults.stream()
.map(LadderResult::from)
.toList();
return new LadderResults(results);
}

public List<LadderResult> getValues() {
return results;
}
}
47 changes: 47 additions & 0 deletions src/main/java/ladder/domain/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ladder.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;

public class Line {

private final List<Point> points;

private Line(List<Point> points) {
this.points = points;
}

public static Line from(int size, BooleanSupplier strategy) {
return new Line(generatePoints(size, strategy));
}

public List<Point> 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<Point> generatePoints(int size, BooleanSupplier strategy) {
List<Point> points = new ArrayList<>();
boolean lastBridge = false;
for (int i = 0; i < size; i++) {
lastBridge = addPoint(points, lastBridge, strategy);
}
return points;
}

private static boolean addPoint(List<Point> points, boolean lastBridge, BooleanSupplier strategy) {
boolean currentBridge = !lastBridge && strategy.getAsBoolean();
points.add(Point.from(currentBridge));
return currentBridge;
}
}
29 changes: 29 additions & 0 deletions src/main/java/ladder/domain/Name.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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);
}

public String getName() {
return name;
}

private static void validate(String name) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("이름은 빈 값일 수 없습니다.");
}
if (name.length() > 5) {
throw new IllegalArgumentException("이름은 최대 5글자입니다.");
}
}
}
43 changes: 43 additions & 0 deletions src/main/java/ladder/domain/Participants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ladder.domain;

import java.util.List;
import java.util.stream.Collectors;

public class Participants {

private final List<Name> participants;

private Participants(List<Name> participants) {
validate(participants);
this.participants = participants;
}

public static Participants from(List<String> names) {
List<Name> nameList = names.stream()
.map(Name::from)
.collect(Collectors.toList());
return new Participants(nameList);
}

private void validate(List<Name> 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<Name> getValues() {
return participants;
}

}
24 changes: 24 additions & 0 deletions src/main/java/ladder/domain/Point.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading