diff --git a/README.md b/README.md index 62e8235761..7fb76d5f87 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # 사디리 ## 기능 요구사항 -* 사다리 게임에 참여하는 사람에 이름을 부여할 수 있다. - * 이름은 최대 5글자로 제한된다. - * 사람의 이름은 띄어쓰기가 존재하지 않는 쉼표로 구분한다. -* 사다리의 모양은 |-----|으로 출력된다. - * 사다리를 출력할 때 사람 이름도 같이 출력한다. - * 참여하는 사람의 숫자에 따라 사다리의 폭과 사다리의 개수가 달라진다. - * |-----|-----| 같이 연속적인 사다리는 가능하지 않다. - * 하나의 라인에는 최소 하나 이상이 사다리가 존재하며 사다리의 개수는 랜덤하다. +[] 사다리 게임에 참여하는 사람에 이름을 부여할 수 있다. + [] 이름은 최대 5글자로 제한된다. + [] 사람의 이름은 띄어쓰기가 존재하지 않는 쉼표로 구분한다. +[] 사다리의 모양은 |-----|으로 출력된다. + [] 사다리를 출력할 때 사람 이름도 같이 출력한다. + [] 참여하는 사람의 숫자에 따라 사다리의 폭과 사다리의 개수가 달라진다. + [] |-----|-----| 같이 연속적인 사다리는 가능하지 않다. + [] 하나의 라인에는 최소 하나 이상이 사다리가 존재하며 사다리의 개수는 랜덤하다. ## 프로그래밍 요구사항 * 최대한 자바 8의 스트림과 람다를 이용한다. diff --git a/src/main/java/nextstep/ladder/application/LadderController.java b/src/main/java/nextstep/ladder/application/LadderController.java index dfa5cb07b3..f36a7ce274 100644 --- a/src/main/java/nextstep/ladder/application/LadderController.java +++ b/src/main/java/nextstep/ladder/application/LadderController.java @@ -11,19 +11,24 @@ public class LadderController { public static void main(String[] args) { InputView inputView = new InputView(); - String[] participants = splitParticipants(inputView); + String[] participants = inputView.inputParticipant(); + String[] results = inputView.inputResults(); int highCount = inputView.inputHighCount(); LadderService ladderService = new LadderService(); - LadderResponse response = ladderService.createLadder(new LadderRequest(participants, highCount)); + LadderResponse createResponse = ladderService.findWinner(new LadderRequest( + participants, + results, + highCount)); LinePrinter printer = new LinePrinter(highCount); - ResultView resultView = new ResultView(printer, participants, response.getLines()); - resultView.showResult(); - } - - private static String[] splitParticipants(InputView inputView) { - return inputView.inputParticipant() - .split(","); + ResultView resultView = new ResultView( + printer, + createResponse.getLines(), + createResponse.getParticipants(), + results); + resultView.showLadder(); + resultView.showParticipant(inputView.inputWantShow()); + resultView.showParticipant(inputView.inputWantShow()); } } diff --git a/src/main/java/nextstep/ladder/application/dto/LadderRequest.java b/src/main/java/nextstep/ladder/application/dto/LadderRequest.java index bff38cc241..6c4a9717ac 100644 --- a/src/main/java/nextstep/ladder/application/dto/LadderRequest.java +++ b/src/main/java/nextstep/ladder/application/dto/LadderRequest.java @@ -3,10 +3,12 @@ public class LadderRequest { private String[] participants; + private String[] results; private int highCount; - public LadderRequest(String[] participants, int highCount) { + public LadderRequest(String[] participants, String[] results, int highCount) { this.participants = participants; + this.results = results; this.highCount = highCount; } @@ -14,6 +16,10 @@ public String[] getParticipants() { return participants; } + public String[] getResults() { + return results; + } + public int getHighCount() { return highCount; } diff --git a/src/main/java/nextstep/ladder/application/dto/LadderResponse.java b/src/main/java/nextstep/ladder/application/dto/LadderResponse.java index 42fc05b86d..5385baef87 100644 --- a/src/main/java/nextstep/ladder/application/dto/LadderResponse.java +++ b/src/main/java/nextstep/ladder/application/dto/LadderResponse.java @@ -1,16 +1,23 @@ package nextstep.ladder.application.dto; import nextstep.ladder.domain.line.Lines; +import nextstep.ladder.domain.participant.Participants; public class LadderResponse { - private final Lines lines; + private Lines lines; + private Participants participants; - public LadderResponse(Lines lines) { + public LadderResponse(Lines lines, Participants participants) { this.lines = lines; + this.participants = participants; } - public Lines getLines() { + public final Lines getLines() { return lines; } + + public final Participants getParticipants() { + return participants; + } } diff --git a/src/main/java/nextstep/ladder/application/service/LadderService.java b/src/main/java/nextstep/ladder/application/service/LadderService.java index 5a07e40b52..f442e960ab 100644 --- a/src/main/java/nextstep/ladder/application/service/LadderService.java +++ b/src/main/java/nextstep/ladder/application/service/LadderService.java @@ -4,16 +4,25 @@ import nextstep.ladder.application.dto.LadderResponse; import nextstep.ladder.domain.line.Line; import nextstep.ladder.domain.line.Lines; +import nextstep.ladder.domain.participant.Participants; import java.util.stream.IntStream; public class LadderService { - public LadderResponse createLadder(LadderRequest request) { - Lines lines = new Lines(request.getHighCount()); - IntStream.range(0, request.getHighCount()) - .forEach(index -> lines.addLine(new Line(request.getParticipants()))); + public LadderResponse findWinner(LadderRequest request) { + Lines lines = createLines(request); + Participants participants = Participants.of(request.getParticipants()); + lines.moveParticipants(participants); + participants.insertMyResult(request.getResults()); + return new LadderResponse(lines, participants); + } - return new LadderResponse(lines); + private Lines createLines(LadderRequest request) { + Lines lines = new Lines(); + int rowLineNumber = request.getParticipants().length - 1; + IntStream.range(0, request.getHighCount()) + .forEach(index -> lines.addLine(new Line(rowLineNumber))); + return lines; } } diff --git a/src/main/java/nextstep/ladder/domain/line/Line.java b/src/main/java/nextstep/ladder/domain/line/Line.java index 95d1849730..3e83860237 100644 --- a/src/main/java/nextstep/ladder/domain/line/Line.java +++ b/src/main/java/nextstep/ladder/domain/line/Line.java @@ -1,15 +1,60 @@ package nextstep.ladder.domain.line; +import nextstep.ladder.domain.participant.Participant; +import nextstep.ladder.domain.participant.Participants; + public class Line { + private final int rowLineNumber; private RowLinePositions rowLinePosition; public Line(String[] participants) { int participantNumber = participants.length; - int rowLineNumber = participantNumber - 1; - rowLinePosition = new RowLinePositions(rowLineNumber); + rowLineNumber = participantNumber - 1; + rowLinePosition = RowLinePositions.create(rowLineNumber); + } + + public Line(int rowLineNumber) { + this.rowLineNumber = rowLineNumber; + rowLinePosition = RowLinePositions.create(rowLineNumber); + } + + public Line(int rowLineNumber, RowLinePositions rowLinePositions) { + this.rowLineNumber = rowLineNumber; + this.rowLinePosition = rowLinePositions; } public boolean isTruePosition(int index) { return rowLinePosition.isTrue(index); } + + public void movableParticipants(Participants participants) { + participants.getParticipantList() + .stream() + .forEachOrdered(participant -> movableParticipant(participant)); + } + + public void movableParticipant(Participant participant) { + if (movableLeft(participant)) { + return; + } + movableRight(participant); + } + + private boolean movableLeft(Participant participant) { + int index = participant.getCurrentIndex(); + if (index != 0 && isTruePosition(index -1)) { + participant.moveLeft(); + return true; + } + return false; + } + + private boolean movableRight(Participant participant) { + int index = participant.getCurrentIndex(); + if (index != rowLineNumber && isTruePosition(index)) { + participant.moveRight(); + return true; + } + return false; + } } diff --git a/src/main/java/nextstep/ladder/domain/line/Lines.java b/src/main/java/nextstep/ladder/domain/line/Lines.java index 1a7939d6a3..086476967b 100644 --- a/src/main/java/nextstep/ladder/domain/line/Lines.java +++ b/src/main/java/nextstep/ladder/domain/line/Lines.java @@ -1,24 +1,25 @@ package nextstep.ladder.domain.line; +import nextstep.ladder.domain.participant.Participants; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.stream.IntStream; public class Lines { private List lineList = new ArrayList<>(); - private int highCount; public Lines() {} - public Lines(int highCount) { - this.highCount = highCount; - } - public void addLine(Line line) { lineList.add(line); } + public void moveParticipants(Participants participants) { + lineList.stream() + .forEachOrdered(line -> line.movableParticipants(participants)); + } + public final List getLineList() { return Collections.unmodifiableList(lineList); } diff --git a/src/main/java/nextstep/ladder/domain/line/RowLinePositions.java b/src/main/java/nextstep/ladder/domain/line/RowLinePositions.java index 0199db55f6..7f0d6dcfcb 100644 --- a/src/main/java/nextstep/ladder/domain/line/RowLinePositions.java +++ b/src/main/java/nextstep/ladder/domain/line/RowLinePositions.java @@ -7,23 +7,29 @@ import java.util.stream.IntStream; public class RowLinePositions { - private List positionList = new ArrayList<>(); - private int rowLineCount; - private Random random = new Random(); + private List positionList; + private int rowLineNumber; + private static final Random random = new Random(); - public RowLinePositions(int rowLineCount) { - this.rowLineCount = rowLineCount; - initializePositionList(); + public RowLinePositions(List positionList, int rowLineNumber) { + this.positionList = positionList; + this.rowLineNumber = rowLineNumber; } - private void initializePositionList() { + public static RowLinePositions create(int rowLineNumber) { + List positionList = new ArrayList<>(); + initializePositionList(positionList, rowLineNumber); + return new RowLinePositions(positionList, rowLineNumber); + } + + private static void initializePositionList(List positionList, int rowLineNumber) { positionList.add(random.nextBoolean()); - IntStream.range(1, rowLineCount) - .forEach(index -> addRandomBoolean(index)); - addTrueIfAllFalse(); + IntStream.range(1, rowLineNumber) + .forEach(index -> addRandomBoolean(positionList, index)); + addTrueIfAllFalse(positionList, rowLineNumber); } - private void addRandomBoolean(int index) { + private static void addRandomBoolean(List positionList, int index) { if (positionList.get(index - 1)) { positionList.add(false); return; @@ -31,11 +37,11 @@ private void addRandomBoolean(int index) { positionList.add(random.nextBoolean()); } - private void addTrueIfAllFalse() { + private static void addTrueIfAllFalse(List positionList, int rowLineNumber) { boolean isAllFalse = positionList.stream() .allMatch(e -> e.equals(Boolean.FALSE)); if (isAllFalse) { - positionList.set(random.nextInt(rowLineCount), Boolean.TRUE); + positionList.set(random.nextInt(rowLineNumber), Boolean.TRUE); } } diff --git a/src/main/java/nextstep/ladder/domain/participant/Participant.java b/src/main/java/nextstep/ladder/domain/participant/Participant.java new file mode 100644 index 0000000000..d096b0fde0 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/participant/Participant.java @@ -0,0 +1,42 @@ +package nextstep.ladder.domain.participant; + + +public class Participant { + private String name; + private int currentIndex; + private String result; + + public Participant(String name, int currentIndex) { + this.name = name; + this.currentIndex = currentIndex; + } + + public void moveLeft() { + currentIndex -= 1; + } + + public void moveRight() { + currentIndex += 1; + } + + public void insertResult(String[] results) { + result = results[currentIndex]; + } + + public String getName() { + return name; + } + + public final int getCurrentIndex() { + return currentIndex; + } + + public String getResult() { + return result; + } + + @Override + public String toString() { + return "{name:" + name + "}" + "{currentPosition:" + currentIndex + "}" + "|"; + } +} diff --git a/src/main/java/nextstep/ladder/domain/participant/Participants.java b/src/main/java/nextstep/ladder/domain/participant/Participants.java new file mode 100644 index 0000000000..64e7ad60a2 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/participant/Participants.java @@ -0,0 +1,41 @@ +package nextstep.ladder.domain.participant; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class Participants { + private final List participantList; + + public Participants(List participantList) { + this.participantList = participantList; + } + + public static Participants of(String[] participants) { + List participantList = new ArrayList<>(); + Arrays.stream(participants) + .forEach(participant -> participantList.add(new Participant(participant, participantList.size()))); + return new Participants(participantList); + } + + public void insertMyResult(String[] results) { + participantList.stream() + .forEach(participant -> participant.insertResult(results)); + } + + public Participant findByName(String name) { + return participantList.stream() + .filter(participant -> participant.getName().equals(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Can not find name")); + } + + public int getParticipantsNumber() { + return participantList.size(); + } + + public final List getParticipantList() { + return Collections.unmodifiableList(participantList); + } +} diff --git a/src/main/java/nextstep/ladder/ui/InputView.java b/src/main/java/nextstep/ladder/ui/InputView.java index 22cd8485ec..775c8b1079 100644 --- a/src/main/java/nextstep/ladder/ui/InputView.java +++ b/src/main/java/nextstep/ladder/ui/InputView.java @@ -6,18 +6,28 @@ public class InputView { private Scanner scanner = new Scanner(System.in); - public String inputParticipant() { + public String[] inputParticipant() { System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - return scanner.nextLine(); + String participants = scanner.nextLine(); + return participants.split(","); + } + + public String[] inputResults() { + System.out.println("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + String results = scanner.nextLine(); + return results.split(","); } public int inputHighCount() { - printEmpty(); + System.out.println(""); System.out.println("최대 사다리 높이는 몇 개인가요?"); return scanner.nextInt(); } - private void printEmpty() { + public String inputWantShow() { System.out.println(""); + Scanner newScanner = new Scanner(System.in); + System.out.println("결과를 보고 싶은 사람은?"); + return newScanner.nextLine(); } } diff --git a/src/main/java/nextstep/ladder/ui/ResultView.java b/src/main/java/nextstep/ladder/ui/ResultView.java index 0da0fee1f8..19e5e67608 100644 --- a/src/main/java/nextstep/ladder/ui/ResultView.java +++ b/src/main/java/nextstep/ladder/ui/ResultView.java @@ -2,34 +2,41 @@ import nextstep.ladder.domain.line.Line; import nextstep.ladder.domain.line.Lines; +import nextstep.ladder.domain.participant.Participant; +import nextstep.ladder.domain.participant.Participants; import java.util.Arrays; +import java.util.stream.IntStream; public class ResultView { private LinePrinter printer; - private final String[] participants; private final Lines lines; + private final Participants participants; + private final String[] results; - public ResultView(LinePrinter printer, String[] participants, Lines lines) { + public ResultView(LinePrinter printer, Lines lines, Participants participants, String[] results) { this.printer = printer; - this.participants = participants; this.lines = lines; + this.participants = participants; + this.results = results; } - public void showResult() { + public void showLadder() { System.out.println(""); System.out.println("실행 결과"); printParticipants(); - printResult(); + printLadder(); + printResults(); } private void printParticipants() { - Arrays.stream(participants) - .forEach(name -> System.out.print(name + " ")); + participants.getParticipantList() + .stream() + .forEach(participant -> System.out.print(participant.getName() + " ")); System.out.println(""); } - private void printResult() { + private void printLadder() { for (Line line : lines.getLineList()) { printLadderByOneLine(line); System.out.println(""); @@ -37,10 +44,41 @@ private void printResult() { } private void printLadderByOneLine(Line line) { - int rowLineNumber = participants.length - 1; + int rowLineNumber = participants.getParticipantsNumber() - 1; System.out.print("|"); for (int index = 0; index < rowLineNumber; index++) { printer.printRefactoring(line.isTruePosition(index)); } } + + private void printResults() { + printResult(results[0]); + IntStream.range(1, results.length) + .forEach(index -> printResult(results[index])); + System.out.println(""); + } + + private void printResult(String result) { + if (result.equals("꽝")) { + System.out.print(result + " ".repeat(results.length - 1)); + return; + } + System.out.print(result + " ".repeat(results.length - result.length())); + } + + public void showParticipant(String name) { + System.out.println(""); + if (name.equalsIgnoreCase("all")) { + participants.getParticipantList() + .stream() + .forEach(participant -> printMyResult(participant)); + return; + } + Participant participant = participants.findByName(name); + printMyResult(participant); + } + + private void printMyResult(Participant participant) { + System.out.println(participant.getName() + " : " + participant.getResult()); + } } diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index 066d4fc4fc..253ca621e6 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -1,9 +1,12 @@ package nextstep.ladder.domain; import nextstep.ladder.domain.line.Line; +import nextstep.ladder.domain.line.RowLinePositions; +import nextstep.ladder.domain.participant.Participant; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; @DisplayName("하나의 사다리 라인 테스트") public class LineTest { @@ -15,4 +18,16 @@ public class LineTest { void line() { Assertions.assertThat(new Line(participants)).isInstanceOf(Line.class); } + + @Test + void moveParticipant() { + Participant participant = new Participant("muel", 0); + RowLinePositions positions = new RowLinePositions( + List.of(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE), + 3); + Line line = new Line(3, positions); + line.movableParticipant(participant); + + System.out.println(participant); + } } diff --git a/src/test/java/nextstep/ladder/domain/ParticipantsTest.java b/src/test/java/nextstep/ladder/domain/ParticipantsTest.java new file mode 100644 index 0000000000..e3835b4688 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/ParticipantsTest.java @@ -0,0 +1,22 @@ +package nextstep.ladder.domain; + +import nextstep.ladder.domain.participant.Participant; +import nextstep.ladder.domain.participant.Participants; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import java.util.List; + +public class ParticipantsTest { + + public static final Participant P1 = new Participant("kwon", 0); + public static final Participant P2 = new Participant("muel", 1); + + @Test + void 생성자() { + String[] givenData = {"park", "sang", "kwom"}; + Participants participants = Participants.of(givenData); + participants.getParticipantList() + .stream() + .forEach(participant -> System.out.print(participant)); + } +} diff --git a/src/test/java/nextstep/ladder/domain/RowLinePositionsTest.java b/src/test/java/nextstep/ladder/domain/RowLinePositionsTest.java index 380c7a8966..5c7c026c04 100644 --- a/src/test/java/nextstep/ladder/domain/RowLinePositionsTest.java +++ b/src/test/java/nextstep/ladder/domain/RowLinePositionsTest.java @@ -15,7 +15,7 @@ public class RowLinePositionsTest { @Test void printRowLinePositionsList() { System.out.println("START"); - RowLinePositions positions = new RowLinePositions(3); + RowLinePositions positions = RowLinePositions.create(3); positions.getPositionList() .stream() .forEach(element -> System.out.println("result : " + element));