diff --git a/src/main/java/LadderApplication.java b/src/main/java/LadderApplication.java new file mode 100644 index 0000000..67f73e9 --- /dev/null +++ b/src/main/java/LadderApplication.java @@ -0,0 +1,10 @@ +import controller.LadderController; + +public class LadderApplication { + public static void main(String[] args) { + LadderController ladderController = LadderController.getInstance(); + + ladderController.run(); + } + +} diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java new file mode 100644 index 0000000..856f460 --- /dev/null +++ b/src/main/java/controller/LadderController.java @@ -0,0 +1,33 @@ +package controller; + +import dto.LineDto; +import model.Ladder; +import model.Line; +import view.LadderOutputView; + +import java.util.List; + +public class LadderController { + private static final LadderController ladderController = new LadderController(); + + private final LadderOutputView ladderOutputView = LadderOutputView.getInstance(); + + private LadderController() { + } + + public static LadderController getInstance() { + return ladderController; + } + + public void run() { + Ladder ladder = new Ladder(4, 4); + List lines = ladder.getLines(); + + ladderOutputView.printResultHeader(); + for (Line line : lines) { + LineDto lineDto = LineDto.from(line); + ladderOutputView.printLine(lineDto); + } + } + +} diff --git a/src/main/java/dto/LineDto.java b/src/main/java/dto/LineDto.java new file mode 100644 index 0000000..bcb17b2 --- /dev/null +++ b/src/main/java/dto/LineDto.java @@ -0,0 +1,29 @@ +package dto; + +import model.Line; +import model.Link; +import model.LinkStatus; + +import java.util.List; + +public class LineDto { + private final List linkExistCollection; + + private LineDto(List linkExistCollection) { + this.linkExistCollection = linkExistCollection; + } + + public static LineDto from(Line line) { + List linkExistCollection = line.getLinks().stream() + .map(Link::getLinkstatus) + .map(LinkStatus::isPresent) + .toList(); + + return new LineDto(linkExistCollection); + } + + public List getLinkExistCollection() { + return List.copyOf(linkExistCollection); + } + +} diff --git a/src/main/java/model/Ladder.java b/src/main/java/model/Ladder.java new file mode 100644 index 0000000..c0df4f6 --- /dev/null +++ b/src/main/java/model/Ladder.java @@ -0,0 +1,23 @@ +package model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Ladder { + private final List lines; + + public Ladder(int width, int height) { + List lines = new ArrayList<>(); + for (int i = 0; i < height; i++) { + lines.add(new Line(width)); + } + + this.lines = Collections.unmodifiableList(lines); + } + + public List getLines() { + return List.copyOf(lines); + } + +} diff --git a/src/main/java/model/Line.java b/src/main/java/model/Line.java new file mode 100644 index 0000000..126ecc5 --- /dev/null +++ b/src/main/java/model/Line.java @@ -0,0 +1,99 @@ +package model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static model.LinkStatus.PRESENT; +import static model.LinkStatus.UNDEFINED; + +public class Line { + private static final Random random = new Random(); + + private final List links; + + public Line(int width) { + int size = width - 1; + List links = initializeLinks(size); + + setupLinks(links); + + this.links = List.copyOf(links); + } + + public List getLinks() { + return List.copyOf(links); + } + + private List initializeLinks(int size) { + List links = new ArrayList<>(); + for (int i = 0; i < size; i++) { + links.add(Link.getUndefinedLink()); + } + + return List.copyOf(links); + } + + private void setupLinks(List links) { + int index = getRandomStartIndex(links); + + while (containsUndefined(links)) { + boolean connectDecider = getConnectDecider(); + boolean connectable = isConnectable(index, links); + + Link link = links.get(index); + link.setLinkStatus(connectDecider, connectable); + + index = getNextIndex(index, links); + } + } + + private int getRandomStartIndex(List links) { + return random.nextInt(links.size()); + } + + private boolean containsUndefined(List links) { + return links.stream() + .anyMatch(link -> link.getLinkstatus() == UNDEFINED); + } + + private boolean getConnectDecider() { + return random.nextBoolean(); + } + + private boolean isConnectable(int index, List links) { + if (isFirstIndex(index)) { + return isRightNotPresent(index, links); + } + if (isLastIndex(index, links)) { + return isLeftNotPresent(index, links); + } + + return isRightNotPresent(index, links) && isLeftNotPresent(index, links); + } + + private boolean isFirstIndex(int index) { + return index == 0; + } + + private boolean isLastIndex(int index, List links) { + return index == links.size() - 1; + } + + private boolean isRightNotPresent(int index, List links) { + Link rightLink = links.get(index + 1); + + return rightLink.getLinkstatus() != PRESENT; + } + + private boolean isLeftNotPresent(int index, List links) { + Link leftLink = links.get(index - 1); + + return leftLink.getLinkstatus() != PRESENT; + } + + private int getNextIndex(int index, List linkStatuses) { + return ++index % linkStatuses.size(); + } + +} diff --git a/src/main/java/model/Link.java b/src/main/java/model/Link.java new file mode 100644 index 0000000..cc007b2 --- /dev/null +++ b/src/main/java/model/Link.java @@ -0,0 +1,39 @@ +package model; + +public class Link { + private LinkStatus linkstatus; + + private Link(LinkStatus linkstatus) { + this.linkstatus = linkstatus; + } + + public static Link getUndefinedLink() { + return new Link(LinkStatus.UNDEFINED); + } + + public void setLinkStatus(boolean connectDecider, boolean connectable) { + validateUpdateStatus(); + + if (connectDecider && connectable) { + this.linkstatus = LinkStatus.PRESENT; + return; + } + + this.linkstatus = LinkStatus.ABSENT; + } + + public LinkStatus getLinkstatus() { + return linkstatus; + } + + private void validateUpdateStatus() { + if (isAlreadyFixed()) { + throw new UnsupportedOperationException("이미 값이 결정된 링크입니다"); + } + } + + private boolean isAlreadyFixed() { + return this.linkstatus != LinkStatus.UNDEFINED; + } + +} diff --git a/src/main/java/model/LinkStatus.java b/src/main/java/model/LinkStatus.java new file mode 100644 index 0000000..479bf2f --- /dev/null +++ b/src/main/java/model/LinkStatus.java @@ -0,0 +1,10 @@ +package model; + +public enum LinkStatus { + UNDEFINED, ABSENT, PRESENT; + + public boolean isPresent() { + return this == PRESENT; + } + +} diff --git a/src/main/java/view/LadderOutputView.java b/src/main/java/view/LadderOutputView.java new file mode 100644 index 0000000..1463885 --- /dev/null +++ b/src/main/java/view/LadderOutputView.java @@ -0,0 +1,47 @@ +package view; + +import dto.LineDto; + +public class LadderOutputView { + + private static final String INDENTATION = " "; + private static final String DASH_COUPLER = "-----"; + private static final String BLANK_COUPLER = " "; + private static final String PILLAR = "|"; + + private LadderOutputView() { + } + + private static final LadderOutputView ladderOutputView = new LadderOutputView(); + + public static LadderOutputView getInstance() { + return ladderOutputView; + } + + public void printResultHeader() { + System.out.println("실행결과"); + System.out.println(); + } + + public void printLine(LineDto lineDto) { + StringBuilder output = new StringBuilder() + .append(INDENTATION) + .append(PILLAR); + + for (boolean isExist : lineDto.getLinkExistCollection()) { + String coupler = getCoupler(isExist); + output.append(coupler) + .append(PILLAR); + } + + System.out.println(output); + } + + private String getCoupler(boolean isLinkExist) { + if (isLinkExist) { + return DASH_COUPLER; + } + return BLANK_COUPLER; + } + +}