From 75e05135cafc4012009ed8864843869d6aa1454f Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Fri, 7 Mar 2025 11:16:55 +0900 Subject: [PATCH 1/6] =?UTF-8?q?Feat:=201=EB=8B=A8=EA=B3=84=20-=20=EC=82=AC?= =?UTF-8?q?=EB=8B=A4=EB=A6=AC=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++ src/main/java/Application.java | 14 ++++++ src/main/java/model/Ladder.java | 17 +++++++ src/main/java/model/LadderGenerator.java | 7 +++ src/main/java/model/LadderValidator.java | 32 +++++++++++++ src/main/java/model/Line.java | 23 +++++++++ src/main/java/model/LineGenerator.java | 27 +++++++++++ src/main/java/model/Lines.java | 15 ++++++ .../java/model/ReservedPositionGenerator.java | 19 ++++++++ src/main/java/model/SingleLineGenerator.java | 47 +++++++++++++++++++ src/main/java/utils/ExceptionHandler.java | 12 +++++ src/main/java/view/LadderView.java | 31 ++++++++++++ 12 files changed, 247 insertions(+) create mode 100644 src/main/java/Application.java create mode 100644 src/main/java/model/Ladder.java create mode 100644 src/main/java/model/LadderGenerator.java create mode 100644 src/main/java/model/LadderValidator.java create mode 100644 src/main/java/model/Line.java create mode 100644 src/main/java/model/LineGenerator.java create mode 100644 src/main/java/model/Lines.java create mode 100644 src/main/java/model/ReservedPositionGenerator.java create mode 100644 src/main/java/model/SingleLineGenerator.java create mode 100644 src/main/java/utils/ExceptionHandler.java create mode 100644 src/main/java/view/LadderView.java diff --git a/build.gradle b/build.gradle index 239f9e7..43c8651 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,9 @@ dependencies { testImplementation platform('org.assertj:assertj-bom:3.25.1') testImplementation('org.junit.jupiter:junit-jupiter') testImplementation('org.assertj:assertj-core') + implementation 'org.slf4j:slf4j-api:2.0.9' + implementation 'org.slf4j:slf4j-simple:2.0.9' + testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' } test { diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 0000000..2efec5d --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,14 @@ +import model.Ladder; +import utils.ExceptionHandler; +import view.LadderView; + +public class Application { + public static void main(String[] args) { + try { + Ladder ladder = Ladder.of(4, 4); + LadderView.printLadder(ladder); + } catch (Exception e) { + ExceptionHandler.handleException(e); + } + } +} diff --git a/src/main/java/model/Ladder.java b/src/main/java/model/Ladder.java new file mode 100644 index 0000000..e6fee46 --- /dev/null +++ b/src/main/java/model/Ladder.java @@ -0,0 +1,17 @@ +package model; + +public class Ladder { + private final Lines lines; + + public Ladder(Lines lines) { + this.lines = lines; + } + + public static Ladder of(int width, int height) { + return new Ladder(LadderGenerator.generate(width, height)); + } + + public Lines getLines() { + return lines; + } +} diff --git a/src/main/java/model/LadderGenerator.java b/src/main/java/model/LadderGenerator.java new file mode 100644 index 0000000..7fe2252 --- /dev/null +++ b/src/main/java/model/LadderGenerator.java @@ -0,0 +1,7 @@ +package model; + +public class LadderGenerator { + public static Lines generate(int width, int height) { + return LineGenerator.generate(width, height); + } +} diff --git a/src/main/java/model/LadderValidator.java b/src/main/java/model/LadderValidator.java new file mode 100644 index 0000000..8211983 --- /dev/null +++ b/src/main/java/model/LadderValidator.java @@ -0,0 +1,32 @@ +package model; + +import java.util.*; +import java.util.stream.*; + +public class LadderValidator { + private static final Random RANDOM = new Random(); + + public static void validate(List lines, int width) { + IntStream.rangeClosed(0, width) + .forEach(i -> validateColumn(lines, i, width)); + } + + private static void validateColumn(List lines, int col, int width) { + boolean emptyColumn = lines.stream().noneMatch(line -> hasBridgeAt(line, col, width)); + if (emptyColumn) { + connect(lines.get(RANDOM.nextInt(lines.size())), col, width); + } + } + + private static boolean hasBridgeAt(Line line, int col, int width) { + if (col == 0) return line.hasBridgeAt(col); + if (col == width) return line.hasBridgeAt(col - 1); + return line.hasBridgeAt(col - 1) || line.hasBridgeAt(col); + } + + + private static void connect(Line line, int col, int width) { + if (col == width) line.setBridgeAt(col - 1); + else line.setBridgeAt(col); + } +} diff --git a/src/main/java/model/Line.java b/src/main/java/model/Line.java new file mode 100644 index 0000000..46cdef1 --- /dev/null +++ b/src/main/java/model/Line.java @@ -0,0 +1,23 @@ +package model; + +import java.util.*; + +public class Line { + private final List points; + + public Line(List points) { + this.points = points; + } + + public List getPoints() { + return points; + } + + public boolean hasBridgeAt(int index) { + return points.get(index); + } + + public void setBridgeAt(int index) { + points.set(index, true); + } +} diff --git a/src/main/java/model/LineGenerator.java b/src/main/java/model/LineGenerator.java new file mode 100644 index 0000000..ff93a04 --- /dev/null +++ b/src/main/java/model/LineGenerator.java @@ -0,0 +1,27 @@ +package model; + +import java.util.*; + +public class LineGenerator { + + public static Lines generate(int width, int height) { + List> reserved = ReservedPositionGenerator.generate(width - 1, height); + List lines = new ArrayList<>(); + + for (int row = 0; row < height; row++) { + Line previous = getPreviousLine(lines, row); + Line line = SingleLineGenerator.generate(width - 1, reserved.get(row), previous); + lines.add(line); + } + + LadderValidator.validate(lines, width - 1); + return new Lines(lines); + } + + private static Line getPreviousLine(List lines, int row) { + if (row == 0) { + return null; + } + return lines.get(row - 1); + } +} diff --git a/src/main/java/model/Lines.java b/src/main/java/model/Lines.java new file mode 100644 index 0000000..287fb87 --- /dev/null +++ b/src/main/java/model/Lines.java @@ -0,0 +1,15 @@ +package model; + +import java.util.List; + +public class Lines { + private final List lines; + + public Lines(List lines) { + this.lines = lines; + } + + public List getLines() { + return lines; + } +} diff --git a/src/main/java/model/ReservedPositionGenerator.java b/src/main/java/model/ReservedPositionGenerator.java new file mode 100644 index 0000000..10246eb --- /dev/null +++ b/src/main/java/model/ReservedPositionGenerator.java @@ -0,0 +1,19 @@ +package model; + +import java.util.*; +import java.util.stream.*; + +public class ReservedPositionGenerator { + private static final Random RANDOM = new Random(); + + public static List> generate(int width, int height) { + List> reserved = IntStream.range(0, height) + .mapToObj(i -> new HashSet()) + .collect(Collectors.toList()); + + IntStream.range(0, width) + .forEach(i -> reserved.get(RANDOM.nextInt(height)).add(i)); + + return reserved; + } +} diff --git a/src/main/java/model/SingleLineGenerator.java b/src/main/java/model/SingleLineGenerator.java new file mode 100644 index 0000000..ecb35d6 --- /dev/null +++ b/src/main/java/model/SingleLineGenerator.java @@ -0,0 +1,47 @@ +package model; + +import java.util.*; +import java.util.stream.*; + +public class SingleLineGenerator { + private static final Random RANDOM = new Random(); + + public static Line generate(int width, Set reserved, Line prev) { + List points = new ArrayList<>(Collections.nCopies(width, false)); + + reserved.forEach(i -> { + if (isNotOverlap(points, prev, i)) { + points.set(i, true); + } + }); + + IntStream.range(0, width).forEach(i -> { + if (!points.get(i) && isNotOverlap(points, prev, i)) { + points.set(i, RANDOM.nextBoolean()); + } + }); + + ensureOneBridge(points, prev); + return new Line(points); + } + + private static boolean isNotOverlap(List points, Line prev, int i) { + if (prev != null && prev.hasBridgeAt(i)) return false; + if (i > 0 && points.get(i - 1)) return false; + return true; + } + + private static void ensureOneBridge(List points, Line prev) { + if (points.contains(true)) return; + + IntStream.range(0, points.size()) + .filter(i -> canSetBridge(points, prev, i)) + .findFirst() + .ifPresent(i -> points.set(i, true)); + } + + private static boolean canSetBridge(List points, Line prev, int index) { + return (prev == null || !prev.hasBridgeAt(index)) + && (index == 0 || !points.get(index - 1)); + } +} diff --git a/src/main/java/utils/ExceptionHandler.java b/src/main/java/utils/ExceptionHandler.java new file mode 100644 index 0000000..7156a5e --- /dev/null +++ b/src/main/java/utils/ExceptionHandler.java @@ -0,0 +1,12 @@ +package utils; + +import org.slf4j.*; + +public class ExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class); + + public static void handleException(Exception e) { + System.err.println("시스템 오류 : " + e.getMessage()); + logger.error("시스템 오류 : ", e); + } +} diff --git a/src/main/java/view/LadderView.java b/src/main/java/view/LadderView.java new file mode 100644 index 0000000..08d760a --- /dev/null +++ b/src/main/java/view/LadderView.java @@ -0,0 +1,31 @@ +package view; + +import model.*; + +public class LadderView { + private static final String BRIDGE = "-----|"; + private static final String SPACE = " |"; + private static final String BAR = "|"; + + public static void printLadder(Ladder ladder) { + printLines(ladder.getLines()); + } + + private static void printLines(Lines lines) { + lines.getLines().forEach(LadderView::printLine); + } + + private static void printLine(Line line) { + System.out.print(BAR); + line.getPoints().forEach(LadderView::printPoint); + System.out.println(); + } + + private static void printPoint(Boolean point) { + if (point) { + System.out.print(BRIDGE); + return; + } + System.out.print(SPACE); + } +} From ca3bd926542d1bc33cc3bc98990dad57ab440c3e Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Fri, 7 Mar 2025 11:43:11 +0900 Subject: [PATCH 2/6] =?UTF-8?q?Refactor:=20=EC=BD=94=EB=93=9C=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EC=A4=80=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/model/LadderValidator.java | 1 - src/main/java/model/LineGenerator.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/model/LadderValidator.java b/src/main/java/model/LadderValidator.java index 8211983..dca4e9a 100644 --- a/src/main/java/model/LadderValidator.java +++ b/src/main/java/model/LadderValidator.java @@ -24,7 +24,6 @@ private static boolean hasBridgeAt(Line line, int col, int width) { return line.hasBridgeAt(col - 1) || line.hasBridgeAt(col); } - private static void connect(Line line, int col, int width) { if (col == width) line.setBridgeAt(col - 1); else line.setBridgeAt(col); diff --git a/src/main/java/model/LineGenerator.java b/src/main/java/model/LineGenerator.java index ff93a04..b7420c7 100644 --- a/src/main/java/model/LineGenerator.java +++ b/src/main/java/model/LineGenerator.java @@ -3,7 +3,6 @@ import java.util.*; public class LineGenerator { - public static Lines generate(int width, int height) { List> reserved = ReservedPositionGenerator.generate(width - 1, height); List lines = new ArrayList<>(); From 083c07ede55c5a23631e151ee5462e478c3973f3 Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Mon, 10 Mar 2025 10:28:46 +0900 Subject: [PATCH 3/6] =?UTF-8?q?Refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 4 ++-- src/main/java/{model => domain}/Ladder.java | 4 +++- src/main/java/{model => domain}/Line.java | 4 ++-- src/main/java/{model => domain}/Lines.java | 2 +- .../java/utils/{ => exception}/ExceptionHandler.java | 5 +++-- .../{model => utils/generator}/LadderGenerator.java | 4 +++- .../java/{model => utils/generator}/LineGenerator.java | 9 +++++++-- .../generator}/ReservedPositionGenerator.java | 10 +++++++--- .../generator}/SingleLineGenerator.java | 5 +++-- .../{model => utils/validator}/LadderValidator.java | 9 ++++++--- src/main/java/view/LadderView.java | 4 +++- 11 files changed, 40 insertions(+), 20 deletions(-) rename src/main/java/{model => domain}/Ladder.java (84%) rename src/main/java/{model => domain}/Line.java (90%) rename src/main/java/{model => domain}/Lines.java (93%) rename src/main/java/utils/{ => exception}/ExceptionHandler.java (78%) rename src/main/java/{model => utils/generator}/LadderGenerator.java (76%) rename src/main/java/{model => utils/generator}/LineGenerator.java (80%) rename src/main/java/{model => utils/generator}/ReservedPositionGenerator.java (71%) rename src/main/java/{model => utils/generator}/SingleLineGenerator.java (94%) rename src/main/java/{model => utils/validator}/LadderValidator.java (88%) diff --git a/src/main/java/Application.java b/src/main/java/Application.java index 2efec5d..c6ce0c7 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -1,5 +1,5 @@ -import model.Ladder; -import utils.ExceptionHandler; +import domain.Ladder; +import utils.exception.ExceptionHandler; import view.LadderView; public class Application { diff --git a/src/main/java/model/Ladder.java b/src/main/java/domain/Ladder.java similarity index 84% rename from src/main/java/model/Ladder.java rename to src/main/java/domain/Ladder.java index e6fee46..06dfb36 100644 --- a/src/main/java/model/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -1,4 +1,6 @@ -package model; +package domain; + +import utils.generator.LadderGenerator; public class Ladder { private final Lines lines; diff --git a/src/main/java/model/Line.java b/src/main/java/domain/Line.java similarity index 90% rename from src/main/java/model/Line.java rename to src/main/java/domain/Line.java index 46cdef1..4a8369e 100644 --- a/src/main/java/model/Line.java +++ b/src/main/java/domain/Line.java @@ -1,6 +1,6 @@ -package model; +package domain; -import java.util.*; +import java.util.List; public class Line { private final List points; diff --git a/src/main/java/model/Lines.java b/src/main/java/domain/Lines.java similarity index 93% rename from src/main/java/model/Lines.java rename to src/main/java/domain/Lines.java index 287fb87..7cba8da 100644 --- a/src/main/java/model/Lines.java +++ b/src/main/java/domain/Lines.java @@ -1,4 +1,4 @@ -package model; +package domain; import java.util.List; diff --git a/src/main/java/utils/ExceptionHandler.java b/src/main/java/utils/exception/ExceptionHandler.java similarity index 78% rename from src/main/java/utils/ExceptionHandler.java rename to src/main/java/utils/exception/ExceptionHandler.java index 7156a5e..a14ca3d 100644 --- a/src/main/java/utils/ExceptionHandler.java +++ b/src/main/java/utils/exception/ExceptionHandler.java @@ -1,6 +1,7 @@ -package utils; +package utils.exception; -import org.slf4j.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class); diff --git a/src/main/java/model/LadderGenerator.java b/src/main/java/utils/generator/LadderGenerator.java similarity index 76% rename from src/main/java/model/LadderGenerator.java rename to src/main/java/utils/generator/LadderGenerator.java index 7fe2252..b723845 100644 --- a/src/main/java/model/LadderGenerator.java +++ b/src/main/java/utils/generator/LadderGenerator.java @@ -1,4 +1,6 @@ -package model; +package utils.generator; + +import domain.Lines; public class LadderGenerator { public static Lines generate(int width, int height) { diff --git a/src/main/java/model/LineGenerator.java b/src/main/java/utils/generator/LineGenerator.java similarity index 80% rename from src/main/java/model/LineGenerator.java rename to src/main/java/utils/generator/LineGenerator.java index b7420c7..91d6e0a 100644 --- a/src/main/java/model/LineGenerator.java +++ b/src/main/java/utils/generator/LineGenerator.java @@ -1,6 +1,11 @@ -package model; +package utils.generator; -import java.util.*; +import domain.Line; +import domain.Lines; +import utils.validator.LadderValidator; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; public class LineGenerator { public static Lines generate(int width, int height) { diff --git a/src/main/java/model/ReservedPositionGenerator.java b/src/main/java/utils/generator/ReservedPositionGenerator.java similarity index 71% rename from src/main/java/model/ReservedPositionGenerator.java rename to src/main/java/utils/generator/ReservedPositionGenerator.java index 10246eb..6b9e133 100644 --- a/src/main/java/model/ReservedPositionGenerator.java +++ b/src/main/java/utils/generator/ReservedPositionGenerator.java @@ -1,7 +1,11 @@ -package model; +package utils.generator; -import java.util.*; -import java.util.stream.*; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class ReservedPositionGenerator { private static final Random RANDOM = new Random(); diff --git a/src/main/java/model/SingleLineGenerator.java b/src/main/java/utils/generator/SingleLineGenerator.java similarity index 94% rename from src/main/java/model/SingleLineGenerator.java rename to src/main/java/utils/generator/SingleLineGenerator.java index ecb35d6..e2e0c1b 100644 --- a/src/main/java/model/SingleLineGenerator.java +++ b/src/main/java/utils/generator/SingleLineGenerator.java @@ -1,7 +1,8 @@ -package model; +package utils.generator; +import domain.Line; import java.util.*; -import java.util.stream.*; +import java.util.stream.IntStream; public class SingleLineGenerator { private static final Random RANDOM = new Random(); diff --git a/src/main/java/model/LadderValidator.java b/src/main/java/utils/validator/LadderValidator.java similarity index 88% rename from src/main/java/model/LadderValidator.java rename to src/main/java/utils/validator/LadderValidator.java index dca4e9a..c1ca738 100644 --- a/src/main/java/model/LadderValidator.java +++ b/src/main/java/utils/validator/LadderValidator.java @@ -1,7 +1,10 @@ -package model; +package utils.validator; + +import domain.Line; +import java.util.List; +import java.util.Random; +import java.util.stream.IntStream; -import java.util.*; -import java.util.stream.*; public class LadderValidator { private static final Random RANDOM = new Random(); diff --git a/src/main/java/view/LadderView.java b/src/main/java/view/LadderView.java index 08d760a..5d1010a 100644 --- a/src/main/java/view/LadderView.java +++ b/src/main/java/view/LadderView.java @@ -1,6 +1,8 @@ package view; -import model.*; +import domain.Ladder; +import domain.Lines; +import domain.Line; public class LadderView { private static final String BRIDGE = "-----|"; From 99959e7e4446e19a933f3b701026386c91fe5d73 Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Tue, 11 Mar 2025 17:12:26 +0900 Subject: [PATCH 4/6] =?UTF-8?q?Refactor:=20RandomUtil,=20Controller,=20DTO?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=B1=85=EC=9E=84=20?= =?UTF-8?q?=EB=B6=84=EB=B0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 8 +++--- .../java/controller/LadderController.java | 16 ++++++++++++ src/main/java/dto/LadderDto.java | 26 +++++++++++++++++++ src/main/java/utils/RandomUtil.java | 15 +++++++++++ .../generator/ReservedPositionGenerator.java | 6 ++--- .../utils/generator/SingleLineGenerator.java | 6 ++--- .../java/utils/validator/LadderValidator.java | 7 ++--- src/main/java/view/LadderView.java | 18 +++++-------- 8 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 src/main/java/controller/LadderController.java create mode 100644 src/main/java/dto/LadderDto.java create mode 100644 src/main/java/utils/RandomUtil.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java index c6ce0c7..18eeee7 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -1,12 +1,14 @@ -import domain.Ladder; +import controller.LadderController; +import dto.LadderDto; import utils.exception.ExceptionHandler; import view.LadderView; public class Application { public static void main(String[] args) { try { - Ladder ladder = Ladder.of(4, 4); - LadderView.printLadder(ladder); + LadderController ladderController = new LadderController(4, 4); + LadderDto ladderDto = ladderController.getLadderData(); + LadderView.printLadder(ladderDto); } catch (Exception e) { ExceptionHandler.handleException(e); } diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java new file mode 100644 index 0000000..522692d --- /dev/null +++ b/src/main/java/controller/LadderController.java @@ -0,0 +1,16 @@ +package controller; + +import domain.Ladder; +import dto.LadderDto; + +public class LadderController { + private final Ladder ladder; + + public LadderController(int width, int height) { + this.ladder = Ladder.of(width, height); + } + + public LadderDto getLadderData() { + return LadderDto.from(ladder); + } +} diff --git a/src/main/java/dto/LadderDto.java b/src/main/java/dto/LadderDto.java new file mode 100644 index 0000000..902f159 --- /dev/null +++ b/src/main/java/dto/LadderDto.java @@ -0,0 +1,26 @@ +package dto; + +import domain.Ladder; +import domain.Line; +import java.util.List; +import java.util.stream.Collectors; + +public class LadderDto { + private final List> ladderData; + + public LadderDto(List> ladderData) { + this.ladderData = ladderData; + } + + public static LadderDto from(Ladder ladder) { + return new LadderDto( + ladder.getLines().getLines().stream() + .map(Line::getPoints) + .collect(Collectors.toList()) + ); + } + + public List> getLadderData() { + return ladderData; + } +} diff --git a/src/main/java/utils/RandomUtil.java b/src/main/java/utils/RandomUtil.java new file mode 100644 index 0000000..b45582a --- /dev/null +++ b/src/main/java/utils/RandomUtil.java @@ -0,0 +1,15 @@ +package utils; + +import java.util.Random; + +public class RandomUtil { + public static final Random random = new Random(); + + public static boolean nextBoolean() { + return random.nextBoolean(); + } + + public static int nextInt(int bound) { + return random.nextInt(bound); + } +} diff --git a/src/main/java/utils/generator/ReservedPositionGenerator.java b/src/main/java/utils/generator/ReservedPositionGenerator.java index 6b9e133..ddff58a 100644 --- a/src/main/java/utils/generator/ReservedPositionGenerator.java +++ b/src/main/java/utils/generator/ReservedPositionGenerator.java @@ -1,22 +1,20 @@ package utils.generator; +import utils.RandomUtil; import java.util.HashSet; import java.util.List; -import java.util.Random; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; public class ReservedPositionGenerator { - private static final Random RANDOM = new Random(); - public static List> generate(int width, int height) { List> reserved = IntStream.range(0, height) .mapToObj(i -> new HashSet()) .collect(Collectors.toList()); IntStream.range(0, width) - .forEach(i -> reserved.get(RANDOM.nextInt(height)).add(i)); + .forEach(i -> reserved.get(RandomUtil.nextInt(height)).add(i)); return reserved; } diff --git a/src/main/java/utils/generator/SingleLineGenerator.java b/src/main/java/utils/generator/SingleLineGenerator.java index e2e0c1b..fdef546 100644 --- a/src/main/java/utils/generator/SingleLineGenerator.java +++ b/src/main/java/utils/generator/SingleLineGenerator.java @@ -1,12 +1,12 @@ package utils.generator; import domain.Line; +import utils.RandomUtil; + import java.util.*; import java.util.stream.IntStream; public class SingleLineGenerator { - private static final Random RANDOM = new Random(); - public static Line generate(int width, Set reserved, Line prev) { List points = new ArrayList<>(Collections.nCopies(width, false)); @@ -18,7 +18,7 @@ public static Line generate(int width, Set reserved, Line prev) { IntStream.range(0, width).forEach(i -> { if (!points.get(i) && isNotOverlap(points, prev, i)) { - points.set(i, RANDOM.nextBoolean()); + points.set(i, RandomUtil.nextBoolean()); } }); diff --git a/src/main/java/utils/validator/LadderValidator.java b/src/main/java/utils/validator/LadderValidator.java index c1ca738..4ffb0ca 100644 --- a/src/main/java/utils/validator/LadderValidator.java +++ b/src/main/java/utils/validator/LadderValidator.java @@ -1,14 +1,11 @@ package utils.validator; import domain.Line; +import utils.RandomUtil; import java.util.List; -import java.util.Random; import java.util.stream.IntStream; - public class LadderValidator { - private static final Random RANDOM = new Random(); - public static void validate(List lines, int width) { IntStream.rangeClosed(0, width) .forEach(i -> validateColumn(lines, i, width)); @@ -17,7 +14,7 @@ public static void validate(List lines, int width) { private static void validateColumn(List lines, int col, int width) { boolean emptyColumn = lines.stream().noneMatch(line -> hasBridgeAt(line, col, width)); if (emptyColumn) { - connect(lines.get(RANDOM.nextInt(lines.size())), col, width); + connect(lines.get(RandomUtil.nextInt(lines.size())), col, width); } } diff --git a/src/main/java/view/LadderView.java b/src/main/java/view/LadderView.java index 5d1010a..f0623e8 100644 --- a/src/main/java/view/LadderView.java +++ b/src/main/java/view/LadderView.java @@ -1,25 +1,21 @@ package view; -import domain.Ladder; -import domain.Lines; -import domain.Line; +import dto.LadderDto; + +import java.util.List; public class LadderView { private static final String BRIDGE = "-----|"; private static final String SPACE = " |"; private static final String BAR = "|"; - public static void printLadder(Ladder ladder) { - printLines(ladder.getLines()); - } - - private static void printLines(Lines lines) { - lines.getLines().forEach(LadderView::printLine); + public static void printLadder(LadderDto ladderDto) { + ladderDto.getLadderData().forEach(LadderView::printLine); } - private static void printLine(Line line) { + private static void printLine(List line) { System.out.print(BAR); - line.getPoints().forEach(LadderView::printPoint); + line.forEach(LadderView::printPoint); System.out.println(); } From fb279036bcb18b6164969b76b8b5979e8105c159 Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Wed, 12 Mar 2025 00:03:34 +0900 Subject: [PATCH 5/6] =?UTF-8?q?Refactor:=20=EA=B0=9D=EC=B2=B4=20=EB=AC=B4?= =?UTF-8?q?=EA=B2=B0=EC=84=B1=20=EB=B3=B4=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Ladder.java | 36 +++++++++++++++- src/main/java/domain/Line.java | 39 +++++++++++++++-- src/main/java/domain/Lines.java | 2 +- .../java/utils/generator/LadderGenerator.java | 2 +- .../java/utils/generator/LineGenerator.java | 15 ++++--- .../generator/ReservedPositionGenerator.java | 14 +++++-- .../utils/generator/SingleLineGenerator.java | 42 ++++--------------- .../java/utils/validator/LadderValidator.java | 31 -------------- 8 files changed, 99 insertions(+), 82 deletions(-) delete mode 100644 src/main/java/utils/validator/LadderValidator.java diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java index 06dfb36..c63b549 100644 --- a/src/main/java/domain/Ladder.java +++ b/src/main/java/domain/Ladder.java @@ -1,11 +1,14 @@ package domain; +import utils.RandomUtil; import utils.generator.LadderGenerator; +import java.util.List; +import java.util.stream.IntStream; public class Ladder { private final Lines lines; - public Ladder(Lines lines) { + private Ladder(Lines lines) { this.lines = lines; } @@ -16,4 +19,35 @@ public static Ladder of(int width, int height) { public Lines getLines() { return lines; } + + public static void validate(List lines, int width) { + IntStream.rangeClosed(0, width) + .forEach(i -> validateColumn(lines, i, width)); + } + + private static void validateColumn(List lines, int col, int width) { + boolean emptyColumn = lines.stream().noneMatch(line -> hasBridgeAt(line, col, width)); + if (emptyColumn) { + int randomIndex = RandomUtil.nextInt(lines.size()); + connect(lines, randomIndex, col, width); + } + } + + private static boolean hasBridgeAt(Line line, int col, int width) { + if (col == 0) return line.hasBridgeAt(col); + if (col == width) return line.hasBridgeAt(col - 1); + return line.hasBridgeAt(col - 1) || line.hasBridgeAt(col); + } + + private static void connect(List lines, int randomIndex, int col, int width) { + Line oldLine = lines.get(randomIndex); + + int index = col; + if (col == width) { + index = col - 1; + } + + Line updatedLine = oldLine.setBridgeAt(index); + lines.set(randomIndex, updatedLine); + } } diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index 4a8369e..d13ecbd 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -1,12 +1,17 @@ package domain; +import utils.RandomUtil; + +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.IntStream; public class Line { private final List points; public Line(List points) { - this.points = points; + this.points = List.copyOf(points); } public List getPoints() { @@ -17,7 +22,35 @@ public boolean hasBridgeAt(int index) { return points.get(index); } - public void setBridgeAt(int index) { - points.set(index, true); + public Line setBridgeAt(int index) { + List newPoints = new ArrayList<>(points); + newPoints.set(index, true); + return new Line(newPoints); + } + + public static void applyBridges(List points, Set reserved, Line prev, boolean isReserved) { + IntStream.range(0, points.size()).forEach(i -> { + boolean shouldAddBridge = (isReserved && reserved.contains(i)) || (!isReserved && RandomUtil.nextBoolean()); + + if (shouldAddBridge && isValidBridgePosition(points, prev, i)) { + points.set(i, true); + } + }); + } + + public static void ensureOneBridge(List points, Line prev) { + if (points.contains(true)) return; + + IntStream.range(0, points.size()) + .filter(i -> isValidBridgePosition(points, prev, i)) + .findFirst() + .ifPresent(i -> points.set(i, true)); + } + + private static boolean isValidBridgePosition(List points, Line prev, int index) { + if (prev != null && prev.hasBridgeAt(index)) return false; + if (index > 0 && points.get(index - 1)) return false; + if (index < points.size() - 1 && points.get(index + 1)) return false; + return true; } } diff --git a/src/main/java/domain/Lines.java b/src/main/java/domain/Lines.java index 7cba8da..c912bd3 100644 --- a/src/main/java/domain/Lines.java +++ b/src/main/java/domain/Lines.java @@ -6,7 +6,7 @@ public class Lines { private final List lines; public Lines(List lines) { - this.lines = lines; + this.lines = List.copyOf(lines); } public List getLines() { diff --git a/src/main/java/utils/generator/LadderGenerator.java b/src/main/java/utils/generator/LadderGenerator.java index b723845..70295c3 100644 --- a/src/main/java/utils/generator/LadderGenerator.java +++ b/src/main/java/utils/generator/LadderGenerator.java @@ -2,7 +2,7 @@ import domain.Lines; -public class LadderGenerator { +public final class LadderGenerator { public static Lines generate(int width, int height) { return LineGenerator.generate(width, height); } diff --git a/src/main/java/utils/generator/LineGenerator.java b/src/main/java/utils/generator/LineGenerator.java index 91d6e0a..1dc8b70 100644 --- a/src/main/java/utils/generator/LineGenerator.java +++ b/src/main/java/utils/generator/LineGenerator.java @@ -1,25 +1,28 @@ package utils.generator; +import domain.Ladder; import domain.Line; import domain.Lines; -import utils.validator.LadderValidator; import java.util.ArrayList; import java.util.List; import java.util.Set; -public class LineGenerator { +public final class LineGenerator { public static Lines generate(int width, int height) { List> reserved = ReservedPositionGenerator.generate(width - 1, height); - List lines = new ArrayList<>(); + List lines = generateLines(width, height, reserved); + Ladder.validate(lines, width - 1); + return new Lines(lines); + } + private static List generateLines(int width, int height, List> reserved) { + List lines = new ArrayList<>(); for (int row = 0; row < height; row++) { Line previous = getPreviousLine(lines, row); Line line = SingleLineGenerator.generate(width - 1, reserved.get(row), previous); lines.add(line); } - - LadderValidator.validate(lines, width - 1); - return new Lines(lines); + return lines; } private static Line getPreviousLine(List lines, int row) { diff --git a/src/main/java/utils/generator/ReservedPositionGenerator.java b/src/main/java/utils/generator/ReservedPositionGenerator.java index ddff58a..697ba6f 100644 --- a/src/main/java/utils/generator/ReservedPositionGenerator.java +++ b/src/main/java/utils/generator/ReservedPositionGenerator.java @@ -7,15 +7,21 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -public class ReservedPositionGenerator { +public final class ReservedPositionGenerator { public static List> generate(int width, int height) { - List> reserved = IntStream.range(0, height) + List> reserved = initializeReservedPositions(height); + applyRandomReservations(reserved, width, height); + return reserved; + } + + private static List> initializeReservedPositions(int height) { + return IntStream.range(0, height) .mapToObj(i -> new HashSet()) .collect(Collectors.toList()); + } + private static void applyRandomReservations(List> reserved, int width, int height) { IntStream.range(0, width) .forEach(i -> reserved.get(RandomUtil.nextInt(height)).add(i)); - - return reserved; } } diff --git a/src/main/java/utils/generator/SingleLineGenerator.java b/src/main/java/utils/generator/SingleLineGenerator.java index fdef546..4f841df 100644 --- a/src/main/java/utils/generator/SingleLineGenerator.java +++ b/src/main/java/utils/generator/SingleLineGenerator.java @@ -1,48 +1,20 @@ package utils.generator; import domain.Line; -import utils.RandomUtil; - -import java.util.*; -import java.util.stream.IntStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; public class SingleLineGenerator { public static Line generate(int width, Set reserved, Line prev) { List points = new ArrayList<>(Collections.nCopies(width, false)); - reserved.forEach(i -> { - if (isNotOverlap(points, prev, i)) { - points.set(i, true); - } - }); - - IntStream.range(0, width).forEach(i -> { - if (!points.get(i) && isNotOverlap(points, prev, i)) { - points.set(i, RandomUtil.nextBoolean()); - } - }); + Line.applyBridges(points, reserved, prev, true); + Line.applyBridges(points, null, prev, false); + Line.ensureOneBridge(points, prev); - ensureOneBridge(points, prev); return new Line(points); } - private static boolean isNotOverlap(List points, Line prev, int i) { - if (prev != null && prev.hasBridgeAt(i)) return false; - if (i > 0 && points.get(i - 1)) return false; - return true; - } - - private static void ensureOneBridge(List points, Line prev) { - if (points.contains(true)) return; - - IntStream.range(0, points.size()) - .filter(i -> canSetBridge(points, prev, i)) - .findFirst() - .ifPresent(i -> points.set(i, true)); - } - - private static boolean canSetBridge(List points, Line prev, int index) { - return (prev == null || !prev.hasBridgeAt(index)) - && (index == 0 || !points.get(index - 1)); - } } diff --git a/src/main/java/utils/validator/LadderValidator.java b/src/main/java/utils/validator/LadderValidator.java deleted file mode 100644 index 4ffb0ca..0000000 --- a/src/main/java/utils/validator/LadderValidator.java +++ /dev/null @@ -1,31 +0,0 @@ -package utils.validator; - -import domain.Line; -import utils.RandomUtil; -import java.util.List; -import java.util.stream.IntStream; - -public class LadderValidator { - public static void validate(List lines, int width) { - IntStream.rangeClosed(0, width) - .forEach(i -> validateColumn(lines, i, width)); - } - - private static void validateColumn(List lines, int col, int width) { - boolean emptyColumn = lines.stream().noneMatch(line -> hasBridgeAt(line, col, width)); - if (emptyColumn) { - connect(lines.get(RandomUtil.nextInt(lines.size())), col, width); - } - } - - private static boolean hasBridgeAt(Line line, int col, int width) { - if (col == 0) return line.hasBridgeAt(col); - if (col == width) return line.hasBridgeAt(col - 1); - return line.hasBridgeAt(col - 1) || line.hasBridgeAt(col); - } - - private static void connect(Line line, int col, int width) { - if (col == width) line.setBridgeAt(col - 1); - else line.setBridgeAt(col); - } -} From 8abac53c00b3d95b8ce5f1fb597d9cf7d3d2ee48 Mon Sep 17 00:00:00 2001 From: "Park, seun" Date: Fri, 21 Mar 2025 19:45:50 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20Input?= =?UTF-8?q?View=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 2 +- src/main/java/controller/LadderController.java | 6 ++++-- src/main/java/domain/Line.java | 2 +- src/main/java/view/InputView.java | 18 ++++++++++++++++++ src/main/java/view/LadderView.java | 3 +++ 5 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/main/java/view/InputView.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java index 18eeee7..ff54458 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -6,7 +6,7 @@ public class Application { public static void main(String[] args) { try { - LadderController ladderController = new LadderController(4, 4); + LadderController ladderController = new LadderController(); LadderDto ladderDto = ladderController.getLadderData(); LadderView.printLadder(ladderDto); } catch (Exception e) { diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java index 522692d..db5f42a 100644 --- a/src/main/java/controller/LadderController.java +++ b/src/main/java/controller/LadderController.java @@ -2,12 +2,14 @@ import domain.Ladder; import dto.LadderDto; +import view.InputView; public class LadderController { private final Ladder ladder; + private final InputView inputView = new InputView(); - public LadderController(int width, int height) { - this.ladder = Ladder.of(width, height); + public LadderController() { + this.ladder = Ladder.of(inputView.getWidth(), inputView.getHeight()); } public LadderDto getLadderData() { diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java index d13ecbd..f8e4466 100644 --- a/src/main/java/domain/Line.java +++ b/src/main/java/domain/Line.java @@ -15,7 +15,7 @@ public Line(List points) { } public List getPoints() { - return points; + return List.copyOf(points); } public boolean hasBridgeAt(int index) { diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000..a924d03 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,18 @@ +package view; + +import java.util.Scanner; + +public class InputView { + private final Scanner scanner = new Scanner(System.in); + + public int getWidth() { + System.out.println("사다리의 넓이는 몇 개인가요?"); + return scanner.nextInt(); + } + + public int getHeight() { + System.out.println(); + System.out.println("사다리의 높이는 몇 개인가요?"); + return scanner.nextInt(); + } +} diff --git a/src/main/java/view/LadderView.java b/src/main/java/view/LadderView.java index f0623e8..cee69d2 100644 --- a/src/main/java/view/LadderView.java +++ b/src/main/java/view/LadderView.java @@ -10,6 +10,9 @@ public class LadderView { private static final String BAR = "|"; public static void printLadder(LadderDto ladderDto) { + System.out.println(); + System.out.println("실행결과"); + System.out.println(); ladderDto.getLadderData().forEach(LadderView::printLine); }