Skip to content

[BCSD Lab] 박종범 4차시 미션 제출합니다. #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
74 changes: 74 additions & 0 deletions src/main/java/LadderSimulator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import java.util.List;

import model.Ladder;
import model.Person;
import util.InputParser;
import view.InputView;
import view.OutPutView;

public class LadderSimulator {

private Ladder ladder;
private int height;
private int width;

public void start() {
processLadderInput();
processLadderPersonMove();
processLadderResult();
}

private void processLadderInput() {
List<Person> persons = InputParser.parsePersons(InputView.inputPersons());
List<String> results = InputParser.parseResults(InputView.inputResults());
height = InputParser.parseLadderHeight(InputView.inputLadderHeight());
width = persons.size() - 1;

this.ladder = new Ladder(height, width, persons, results);
OutPutView.printLadder(ladder);
}

private void processLadderPersonMove() {
for (Person person : ladder.getPersons()) {
PersonMovement(person);
}
}

private void processLadderResult() {
while (true) {
String resultPersonName = InputView.inputResultPerson();

if (resultPersonName.equals("all")) { // all 입력시 모든 사람의 결과 출력
OutPutView.printLadderResult(ladder);
return;
}

Person resultPerson = ladder.getPersonByName(resultPersonName);
OutPutView.printPersonResult(resultPerson, ladder);
}
}

// 우측우선이동임
private void personMovement(Person person) {
for (int nowHeight = 0; nowHeight < height; nowHeight++) {
if (canMoveRight(person, ladder, nowHeight)) {
person.moveRight();
continue;
}

if (canMoveLeft(person, ladder, nowHeight)) {
person.moveLeft();
continue;
}
}
}

private boolean canMoveLeft(Person person, Ladder ladder, int nowHeight) {
return person.getPosition() > 0 && ladder.isPoint(nowHeight, person.getPosition() - 1);
}

private boolean canMoveRight(Person person, Ladder ladder, int nowHeight) {
return person.getPosition() < width && ladder.isPoint(nowHeight, person.getPosition());
}

}
6 changes: 6 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
public class Main {
public static void main(String[] args) {
LadderSimulator simulator = new LadderSimulator();
simulator.start();
}
}
46 changes: 46 additions & 0 deletions src/main/java/model/Ladder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package model;

import java.util.List;
import java.util.stream.Stream;

public class Ladder {

private final List<Line> lines;
private List<Person> persons;
private List<String> results;

public Ladder(int height, int width, List<Person> persons, List<String> results) {
this.lines = Stream.generate(() -> new Line(width))
.limit(height)
.toList();
this.persons = persons;
this.results = results;
}

public List<Line> getLines() {
return lines;
}

public List<Person> getPersons() {
return persons;
}

public List<String> getResults() {
return results;
}

public boolean isPoint(int lineIndex, int pointIndex) {
if (lineIndex < 0 || lineIndex >= lines.size()) {
throw new IndexOutOfBoundsException("인덱스 범위 초과");
}
return lines.get(lineIndex).isPoint(pointIndex);
}

public Person getPersonByName(String name) {
return persons.stream()
.filter(person -> person.getName().equals(name))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("해당 이름의 사람이 없습니다: "));
}

}
36 changes: 36 additions & 0 deletions src/main/java/model/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package model;

import java.util.List;

import util.LadderRandomGenerator;

public class Line {

private final List<Boolean> points;

public Line(int length) {
this.points = LadderRandomGenerator.generateRandomLine(length);
}

public List<Boolean> getPoints() {
return points;
}

public boolean isPoint(int index) {
if (index < 0 || index >= points.size()) {
throw new IndexOutOfBoundsException("인덱스 범위 초과");
}
return points.get(index);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Boolean point : points) {
sb.append("|");
sb.append(point ? "-----" : " ");
}
sb.append("|");
return sb.toString();
}
}
37 changes: 37 additions & 0 deletions src/main/java/model/Person.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package model;

import java.util.List;

public class Person {

private final String name;
private int position;

public Person(String name, int position) {
this.name = name;
this.position = position;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

public void moveLeft() {
position--;
}

public void moveRight() {
position++;
}

public static List<Person> fromNames(List<String> names) {
return names.stream()
.map(name -> new Person(name, names.indexOf(name)))
.toList();

}
}
30 changes: 30 additions & 0 deletions src/main/java/util/InputParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package util;

import java.util.Arrays;
import java.util.List;

import model.Person;

public class InputParser {

public static int parseLadderHeight(String input) {
LadderVaildator.validateLadderHeight(input);
return Integer.parseInt(input);
}

public static int parseLadderWidth(String input) {
LadderVaildator.validateLadderWidth(input);
return Integer.parseInt(input);
}

public static List<Person> parsePersons(String input) {
LadderVaildator.validatePersons(input);
String[] names = input.split(",");
return Person.fromNames(Arrays.asList(names));
}

public static List<String> parseResults(String input) {
LadderVaildator.validateResults(input);
return Arrays.asList(input.split(","));
}
}
18 changes: 18 additions & 0 deletions src/main/java/util/LadderRandomGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

package util;

import java.util.List;
import java.util.stream.Stream;

public class LadderRandomGenerator {

public static boolean generateRandomBoolean() {
return Math.random() < 0.5;
}

public static List<Boolean> generateRandomLine(int length) {
return Stream.generate(LadderRandomGenerator::generateRandomBoolean)
.limit(length)
.toList();
}
}
51 changes: 51 additions & 0 deletions src/main/java/util/LadderVaildator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

package util;

public class LadderVaildator {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검증 로직의 위치는 사람마다 다른거 같아요.

지금까지 spring 사용해오던 방식대로는 validate 로직은 검증 대상(여기서는 Ladder)의 외부에 존재하는게 익숙한 것 같아요. 그런데 객체지향적으로 보면 검증 대상의 내부에 있는게 맞는 것 같아요.

개인적으로는 여러곳에서 범용적으로 사용되는 공통적인 validate 로직만 Validator로 분리하고, 나머지는 클래스 내부에 선언하는 방식을 선호해요.

validate의 위치에 대해 어떻게 생각하시나요? 의견이 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 가능하면 분리하는 방향을 선호하는거같아요.
저는 validate로직을 쓸때 if 문-> throw 형식을 자주 사용해서 코드가 길어지는 편인데,
클래스 내부에 위치하게 되면 클래스 코드가 너무 길어보여서 읽기가 힘든느낌을 받은거같아요.

저도 생각해보니 짦게 검증로직이 나올때는 객체 안에 짧게 정의해두는거같은데, 여러 객체들이 있을때는
길어지는 검증로직이 나오는 객체가 있을때를 대비해서 일관성을 위해 검증로직이 있으면 객체마다 validate클래스를 각각만들어두는거같아요


public static void validateLadderHeight(String height) {
if (height == null || height.isEmpty()) {
throw new IllegalArgumentException("사다리 높이는 비어있을 수 없습니다.");
}

if (height.matches("\\D+")) {
throw new IllegalArgumentException("사다리 높이는 숫자로 입력해야 합니다.");
}

int heightValue = Integer.parseInt(height);

if (heightValue <= 0) {
throw new IllegalArgumentException("사다리 높이는 0보다 큰 숫자여야 합니다.");
}

}

public static void validateLadderWidth(String width) {
if (width == null || width.isEmpty()) {
throw new IllegalArgumentException("사다리 넓이는 비어있을 수 없습니다.");
}

if (width.matches("\\D+")) {
throw new IllegalArgumentException("사다리 넓이는 숫자로 입력해야 합니다.");
}

int widthValue = Integer.parseInt(width);

if (widthValue <= 0) {
throw new IllegalArgumentException("사다리 넓이는 0보다 큰 숫자여야 합니다.");
}

}

public static void validatePersons(String persons) {
if (persons == null || persons.isEmpty()) {
throw new IllegalArgumentException("참여자 이름은 비어있을 수 없습니다.");
}
}

public static void validateResults(String results) {
if (results == null || results.isEmpty()) {
throw new IllegalArgumentException("실행 결과는 비어있을 수 없습니다.");
}
}
}
29 changes: 29 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package view;

import java.util.Scanner;

public class InputView {

private static final Scanner scanner = new Scanner(System.in);

public static String inputLadderHeight() {
System.out.print("사다리의 높이는 몇 개인가요?");
return scanner.nextLine();
}

public static String inputPersons() {
System.out.print("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)");
return scanner.nextLine();
}

public static String inputResults() {
System.out.print("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)");
return scanner.nextLine();
}

public static String inputResultPerson() {
System.out.print("결과를 보고 싶은 사람은?");
return scanner.nextLine();
}

}
37 changes: 37 additions & 0 deletions src/main/java/view/OutPutView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package view;

import java.util.List;

import model.Ladder;
import model.Line;
import model.Person;

public class OutPutView {

public static void printLadder(Ladder ladder) {
List<Line> lines = ladder.getLines();
System.out.println("사다리 결과");
for (Person person : ladder.getPersons()) {
System.out.print(person.getName() + " ");
}
System.out.println();
for (Line line : lines) {
System.out.println(line);
}
for (String result : ladder.getResults()) {
System.out.print(result + " ");
}
System.out.println();
}

public static void printLadderResult(Ladder ladder) {
System.out.println("실행 결과");
for (Person person : ladder.getPersons()) {
System.out.println(person.getName() + " : " + ladder.getResults().get(person.getPosition()));
}
}

public static void printPersonResult(Person person, Ladder ladder) {
System.out.println(ladder.getResults().get(person.getPosition()));
}
}