Skip to content

Commit 603ba16

Browse files
authored
고생하셨습니다.
🎉 PR 머지 완료! 🎉
1 parent fa13b03 commit 603ba16

File tree

14 files changed

+356
-0
lines changed

14 files changed

+356
-0
lines changed

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# 🪜 사다리
2+
3+
## 네이버 사다리 게임 흐름
4+
5+
1. 참여 인원을 입력한다.
6+
2. 시작하면 이름과 항목을 입력한다.
7+
3. 랜덤한 사다리 라인이 생겨난다. (겹치지 않는 가로라인)
8+
4. 결과를 출력한다.
9+
10+
## 요구사항
11+
12+
- 사다리는 4x4 크기 고정
13+
- 클래스는 3개 이상의 인스턴스 변수 가질 수 없음.
14+
- 모든 엔티티 작게
15+
16+
## 구현 기능
17+
18+
### 사다리
19+
20+
- 여러 개의 라인을 가지고 있다.
21+
- 전체 구조를 나타낸다.
22+
23+
### 라인
24+
25+
- 한 줄을 나타내는 포인트 들을 가진다.
26+
- 연결 상태를 관리하고 연결한다.
27+
28+
### 포인트
29+
30+
- 연결 여부를 판단한다.
31+
32+
## 출력 예시
33+
34+
```text
35+
실행결과
36+
37+
| |-----| |
38+
|-----| |-----|
39+
| |-----| |
40+
|-----| | |
41+
```

src/main/java/.gitkeep

Whitespace-only changes.

src/main/java/LadderApplication.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import domain.Ladder;
2+
import strategy.PointGenerator;
3+
import strategy.RandomGenerator;
4+
import view.OutputView;
5+
6+
public class LadderApplication {
7+
public static void main(String[] args) {
8+
int width = 4;
9+
int height = 4;
10+
11+
PointGenerator generator = new RandomGenerator();
12+
Ladder ladder = Ladder.create(width, height, generator);
13+
14+
OutputView.printLadderResultTitle();
15+
OutputView.paintLadder(ladder);
16+
}
17+
}

src/main/java/domain/Ladder.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package domain;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import strategy.PointGenerator;
7+
8+
public class Ladder {
9+
private final List<Line> lines;
10+
11+
private Ladder(final List<Line> lines) {
12+
this.lines = Collections.unmodifiableList(lines);
13+
}
14+
15+
public static Ladder create(final int width, final int height, final PointGenerator generator) {
16+
List<Line> lines = new ArrayList<>();
17+
for (int i = 0; i < height; i++) {
18+
lines.add(Line.create(width, generator));
19+
}
20+
21+
return new Ladder(lines);
22+
}
23+
24+
public List<Line> getLines() {
25+
return lines;
26+
}
27+
}

src/main/java/domain/Line.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package domain;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import strategy.PointGenerator;
7+
8+
public class Line {
9+
10+
private final List<Point> points;
11+
12+
private Line(final List<Point> points) {
13+
this.points = Collections.unmodifiableList(points);
14+
}
15+
16+
public static Line create(final int width, final PointGenerator generator) {
17+
return new Line(generatePoints(width, generator));
18+
}
19+
20+
/**
21+
* 주어진 너비와 PointGenerator를 바탕으로, 왼쪽에서 오른쪽 방향으로 연결된 Point 리스트를 생성한다.
22+
* 첫 번째 Point는 {@code Point.first()} 를 통해 생성되며,
23+
* 이후 Point는 이전 Point의 연결 상태를 기준으로 오른쪽으로 순차적으로 생성된다.
24+
* <p>
25+
* * 사다리는 왼쪽에서 오른쪽으로만 연결된다는 전제 하에 동작한다.
26+
27+
* @param width 사다리의 너비
28+
* @param generator 오른쪽 연결 여부를 결정하는 PointGenerator
29+
* @return 연결된 Point 리스트
30+
*/
31+
private static List<Point> generatePoints(final int width, final PointGenerator generator) {
32+
List<Point> points = new ArrayList<>();
33+
Point first = Point.first(generator.generate());
34+
points.add(first);
35+
36+
for (int i = 1; i < width; i++) {
37+
first = first.connectNext(generator.generate());
38+
points.add(first);
39+
}
40+
41+
return points;
42+
}
43+
44+
public List<Point> getPoints() {
45+
return points;
46+
}
47+
}

src/main/java/domain/Point.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package domain;
2+
3+
public record Point(
4+
boolean right
5+
) {
6+
7+
public static Point first(final boolean right) {
8+
return new Point(right);
9+
}
10+
11+
public Point connectNext(final boolean canConnectRight) {
12+
if (this.right) {
13+
return new Point(false);
14+
}
15+
return new Point(canConnectRight);
16+
}
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package strategy;
2+
3+
public interface PointGenerator {
4+
boolean generate();
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package strategy;
2+
3+
import java.util.Random;
4+
5+
public class RandomGenerator implements PointGenerator {
6+
7+
private final Random random = new Random();
8+
9+
@Override
10+
public boolean generate() {
11+
return random.nextBoolean();
12+
}
13+
}

src/main/java/view/OutputView.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package view;
2+
3+
import domain.Ladder;
4+
import domain.Line;
5+
import domain.Point;
6+
import java.util.List;
7+
8+
public final class OutputView {
9+
10+
private static final String LADDER_RESULT_TITLE = "실행결과";
11+
private static final String BLANK = " ";
12+
private static final String VERTICAL = "|";
13+
private static final String HORIZONTAL = "-----";
14+
15+
private OutputView() {
16+
}
17+
18+
public static void printLadderResultTitle() {
19+
System.out.println(LADDER_RESULT_TITLE);
20+
System.out.println();
21+
}
22+
23+
public static void paintLadder(final Ladder ladder) {
24+
for (Line line : ladder.getLines()) {
25+
paintLine(line);
26+
}
27+
}
28+
29+
private static void paintLine(final Line line) {
30+
StringBuilder builder = new StringBuilder();
31+
builder.append(BLANK);
32+
33+
List<Point> points = line.getPoints();
34+
for (int i = 0; i < points.size() - 1; i++) {
35+
builder.append(VERTICAL);
36+
builder.append(paintHorizontalIfConnected(points.get(i)));
37+
}
38+
builder.append(VERTICAL);
39+
System.out.println(builder);
40+
}
41+
42+
private static String paintHorizontalIfConnected(final Point point) {
43+
if (point.right()) {
44+
return HORIZONTAL;
45+
}
46+
return BLANK;
47+
}
48+
}

src/test/java/.gitkeep

Whitespace-only changes.

src/test/java/domain/LadderTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package domain;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
8+
class LadderTest {
9+
10+
@Test
11+
@DisplayName("반환된 리스트는 수정 불가능하다.")
12+
void shouldReturnUnmodifiableList() {
13+
// given
14+
int width = 4;
15+
int height = 4;
16+
17+
// when
18+
Ladder ladder = Ladder.create(width, height, () -> false);
19+
20+
// then
21+
assertThatThrownBy(() -> {
22+
int modifiedWidth = 2;
23+
ladder.getLines().add(Line.create(modifiedWidth, () -> true));
24+
}).isInstanceOf(UnsupportedOperationException.class);
25+
}
26+
27+
}

src/test/java/domain/LineTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package domain;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5+
6+
import java.util.List;
7+
import org.junit.jupiter.api.DisplayName;
8+
import org.junit.jupiter.api.Test;
9+
import strategy.FixedGenerator;
10+
import strategy.PointGenerator;
11+
12+
class LineTest {
13+
14+
@Test
15+
@DisplayName("주어진 넓이에 맞게 포인트를 생성한다.")
16+
void shouldGeneratePoint_whenGivenWidth() {
17+
// given
18+
PointGenerator generator = new FixedGenerator(new boolean[]{true, false, true, false});
19+
int width = 4;
20+
21+
// when
22+
Line line = Line.create(width, generator);
23+
List<Point> points = line.getPoints();
24+
25+
// then
26+
assertThat(points)
27+
.extracting(Point::right)
28+
.containsExactly(true, false, true, false);
29+
}
30+
31+
@Test
32+
@DisplayName("반환된 리스트는 수정 불가능하다.")
33+
void shouldReturnUnmodifiableList() {
34+
// given
35+
PointGenerator generator = new FixedGenerator(new boolean[]{false, false, false, false});
36+
int width = 4;
37+
38+
Line line = Line.create(width, generator);
39+
List<Point> points = line.getPoints();
40+
41+
// when & then
42+
assertThatThrownBy(() -> points.add(Point.first(true)))
43+
.isInstanceOf(UnsupportedOperationException.class);
44+
}
45+
}

src/test/java/domain/PointTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package domain;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
8+
class PointTest {
9+
10+
@Test
11+
@DisplayName("포인트 기준 오른쪽의 여부를 받아 객체를 정상적으로 생성한다.")
12+
void shouldCreatePoint_whenFirstRightStatus() {
13+
// given
14+
boolean isRightTrue = true;
15+
boolean isRightFalse = false;
16+
17+
// when
18+
Point truePoint = Point.first(isRightTrue);
19+
Point falsePoint = Point.first(isRightFalse);
20+
21+
// then
22+
assertThat(truePoint.right()).isTrue();
23+
assertThat(falsePoint.right()).isFalse();
24+
}
25+
26+
@Test
27+
@DisplayName("포인트는 가로로 연속되지 않는다.")
28+
void shouldReturnNextPointFalse_whenPointRightTrue() {
29+
// given
30+
Point point = Point.first(true);
31+
32+
// when
33+
Point next = point.connectNext(true);
34+
35+
// then
36+
assertThat(next.right()).isFalse();
37+
}
38+
39+
@Test
40+
@DisplayName("현재 포인트가 연결되지 않은 경우, 다음 포인트는 입력에 따라 연결된다.")
41+
void shouldReturnNextPointTrueOrFalse_whenPointRightFalse() {
42+
// given
43+
Point point = Point.first(false);
44+
45+
// when
46+
Point nextTrue = point.connectNext(true);
47+
Point nextFalse = point.connectNext(false);
48+
49+
// then
50+
assertThat(nextTrue.right()).isTrue();
51+
assertThat(nextFalse.right()).isFalse();
52+
}
53+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package strategy;
2+
3+
public class FixedGenerator implements PointGenerator {
4+
5+
private final boolean[] values;
6+
private int index = 0;
7+
8+
public FixedGenerator(final boolean[] values) {
9+
this.values = values;
10+
}
11+
12+
@Override
13+
public boolean generate() {
14+
return values[index++];
15+
}
16+
}

0 commit comments

Comments
 (0)