diff --git a/src/main/java/controller/LadderController.java b/src/main/java/controller/LadderController.java new file mode 100644 index 00000000..89d152a0 --- /dev/null +++ b/src/main/java/controller/LadderController.java @@ -0,0 +1,31 @@ +package controller; + +import domain.Ladder; +import domain.LadderGame; +import domain.LadderHeight; +import domain.LadderWidth; +import domain.Players; +import domain.Prizes; +import domain.GameResult; +import view.InputView; +import view.OutputView; + +public class LadderController { + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + Players players = inputView.askPlayers(); + Prizes prizes = inputView.askPrizes(); + LadderHeight height = inputView.askHeight(); + LadderWidth width = new LadderWidth(players.size()); + LadderGame ladderGame = new LadderGame(players, prizes, new Ladder(height, width)); + outputView.printLadderGameBoard(ladderGame); + GameResult gameResult = ladderGame.play(); + String query = inputView.askResultName(); + if (query.equals("all")) { + outputView.printResultAll(gameResult); + return; + } + outputView.printResultSingle(gameResult.getResultByPlayerName(query).getPrize()); + } +} diff --git a/src/main/java/domain/Bridge.java b/src/main/java/domain/Bridge.java new file mode 100644 index 00000000..3f1c089e --- /dev/null +++ b/src/main/java/domain/Bridge.java @@ -0,0 +1,20 @@ +package domain; + +public enum Bridge { + CONNECTED, + NOT_CONNECTED; + + public String display() { + if (this == CONNECTED) { + return "-----"; + } + return " "; + } + + public static Bridge fromBoolean(boolean connected) { + if (connected) { + return CONNECTED; + } + return NOT_CONNECTED; + } +} diff --git a/src/main/java/domain/GameResult.java b/src/main/java/domain/GameResult.java new file mode 100644 index 00000000..512c6f84 --- /dev/null +++ b/src/main/java/domain/GameResult.java @@ -0,0 +1,24 @@ +package domain; + +import java.util.List; + +public class GameResult { + private final List results; + + public GameResult(List results) { + this.results = results; + } + + public List getResults() { + return results; + } + + public Result getResultByPlayerName(String name) { + for (Result result : results) { + if (result.getPlayerName().equals(name)) { + return result; + } + } + throw new IllegalArgumentException("해당 이름이 없습니다."); + } +} diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java new file mode 100644 index 00000000..156a41a8 --- /dev/null +++ b/src/main/java/domain/Ladder.java @@ -0,0 +1,36 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Ladder { + private final Lines lines; + + public Ladder(LadderHeight height, LadderWidth width) { + this.lines = new Lines(createLines(height, width)); + } + + private List createLines(LadderHeight height, LadderWidth width) { + List list = new ArrayList<>(); + Line previousLine = null; + for (int i = 0; i < height.getValue(); i++) { + Line current = new Line(width, previousLine); + list.add(current); + previousLine = current; + } + return list; + } + + public List getLadderBody() { + return lines.drawAll(); + } + + public LadderResult play() { + int columnCount = lines.getColumnCount(); + List positions = new ArrayList<>(); + for (int i = 0; i < columnCount; i++) { + positions.add(lines.moveAll(new Position(i))); + } + return new LadderResult(positions); + } +} diff --git a/src/main/java/domain/LadderGame.java b/src/main/java/domain/LadderGame.java new file mode 100644 index 00000000..a09ab630 --- /dev/null +++ b/src/main/java/domain/LadderGame.java @@ -0,0 +1,43 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class LadderGame { + private final Players players; + private final Prizes prizes; + private final Ladder ladder; + + public LadderGame(Players players, Prizes prizes, Ladder ladder) { + if (players.size() != prizes.getPrizes().size()) { + throw new IllegalArgumentException("참여자 수와 결과 수가 일치해야 합니다."); + } + this.players = players; + this.prizes = prizes; + this.ladder = ladder; + } + + public GameResult play() { + LadderResult ladderResult = ladder.play(); + List results = new ArrayList<>(); + for (int i = 0; i < players.size(); i++) { + int finalIndex = ladderResult.getPositions().get(i).getValue(); + String playerName = players.getPlayers().get(i).getName().getValue(); + String prize = prizes.getPrizeAt(finalIndex).getValue(); + results.add(new Result(playerName, prize)); + } + return new GameResult(results); + } + + public Ladder getLadder() { + return ladder; + } + + public Players getPlayers() { + return players; + } + + public Prizes getPrizes() { + return prizes; + } +} diff --git a/src/main/java/domain/LadderHeight.java b/src/main/java/domain/LadderHeight.java new file mode 100644 index 00000000..dc7cfa36 --- /dev/null +++ b/src/main/java/domain/LadderHeight.java @@ -0,0 +1,16 @@ +package domain; + +public class LadderHeight { + private final int value; + + public LadderHeight(int value) { + if (value < 1) { + throw new IllegalArgumentException("사다리의 높이는 1 이상이어야 합니다."); + } + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/domain/LadderResult.java b/src/main/java/domain/LadderResult.java new file mode 100644 index 00000000..541d0732 --- /dev/null +++ b/src/main/java/domain/LadderResult.java @@ -0,0 +1,15 @@ +package domain; + +import java.util.List; + +public class LadderResult { + private final List positions; + + public LadderResult(List positions) { + this.positions = positions; + } + + public List getPositions() { + return positions; + } +} diff --git a/src/main/java/domain/LadderWidth.java b/src/main/java/domain/LadderWidth.java new file mode 100644 index 00000000..f427fc5a --- /dev/null +++ b/src/main/java/domain/LadderWidth.java @@ -0,0 +1,16 @@ +package domain; + +public class LadderWidth { + private final int value; + + public LadderWidth(int value) { + if (value < 2) { + throw new IllegalArgumentException("사다리의 넓이는 2 이상이어야 합니다."); + } + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java new file mode 100644 index 00000000..c520d66a --- /dev/null +++ b/src/main/java/domain/Line.java @@ -0,0 +1,74 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Line { + private final List bridges; + + public Line(LadderWidth ladderWidth, Line previousLine) { + this.bridges = createBridges(ladderWidth, previousLine); + } + + private List createBridges(LadderWidth ladderWidth, Line previousLine) { + List list = new ArrayList<>(); + Random random = new Random(); + boolean previousConnected = false; + List previousBridges = null; + if (previousLine != null) { + previousBridges = previousLine.getBridges(); + } + for (int i = 0; i < ladderWidth.getValue() - 1; i++) { + boolean connected = determineConnection(previousConnected, random, previousBridges, i); + list.add(Bridge.fromBoolean(connected)); + previousConnected = connected; + } + return list; + } + + private boolean determineConnection(boolean previousConnected, Random random, + List previousBridges, int index) { + if (previousConnected) { + return false; + } + if (previousBridges != null && previousBridges.get(index) == Bridge.CONNECTED) { + return false; + } + return random.nextBoolean(); + } + + public List getBridges() { + return bridges; + } + + public String draw() { + StringBuilder builder = new StringBuilder(); + builder.append("|"); + for (Bridge bridge : bridges) { + builder.append(bridge.display()); + builder.append("|"); + } + return builder.toString(); + } + + public Position move(Position position) { + int current = position.getValue(); + if (canMoveLeft(current)) { + return new Position(current - 1); + } + if (canMoveRight(current)) { + return new Position(current + 1); + } + return position; + } + + private boolean canMoveLeft(int current) { + return current > 0 && bridges.get(current - 1) == Bridge.CONNECTED; + } + + private boolean canMoveRight(int current) { + int columnCount = bridges.size() + 1; + return current < columnCount - 1 && bridges.get(current) == Bridge.CONNECTED; + } +} diff --git a/src/main/java/domain/Lines.java b/src/main/java/domain/Lines.java new file mode 100644 index 00000000..dd262dae --- /dev/null +++ b/src/main/java/domain/Lines.java @@ -0,0 +1,39 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Lines { + private final List lines; + + public Lines(List lines) { + this.lines = lines; + } + + public List getLines() { + return lines; + } + + public List drawAll() { + List drawn = new ArrayList<>(); + for (Line line : lines) { + drawn.add(line.draw()); + } + return drawn; + } + + public Position moveAll(Position position) { + Position result = position; + for (Line line : lines) { + result = line.move(result); + } + return result; + } + + public int getColumnCount() { + if (lines.isEmpty()) { + return 0; + } + return lines.get(0).getBridges().size() + 1; + } +} diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java new file mode 100644 index 00000000..c273ce75 --- /dev/null +++ b/src/main/java/domain/Name.java @@ -0,0 +1,16 @@ +package domain; + +public class Name { + private final String value; + + public Name(String value) { + if (value.length() > 5) { + throw new IllegalArgumentException("이름은 최대 5글자여야 합니다."); + } + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/domain/Player.java b/src/main/java/domain/Player.java new file mode 100644 index 00000000..5531920f --- /dev/null +++ b/src/main/java/domain/Player.java @@ -0,0 +1,13 @@ +package domain; + +public class Player { + private final Name name; + + public Player(Name name) { + this.name = name; + } + + public Name getName() { + return name; + } +} diff --git a/src/main/java/domain/Players.java b/src/main/java/domain/Players.java new file mode 100644 index 00000000..283f8eb8 --- /dev/null +++ b/src/main/java/domain/Players.java @@ -0,0 +1,19 @@ +package domain; + +import java.util.List; + +public class Players { + private final List players; + + public Players(List players) { + this.players = players; + } + + public List getPlayers() { + return players; + } + + public int size() { + return players.size(); + } +} diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java new file mode 100644 index 00000000..b7654ccc --- /dev/null +++ b/src/main/java/domain/Position.java @@ -0,0 +1,24 @@ +package domain; + +public class Position { + private final int value; + + public Position(int value) { + if (value < 0) { + throw new IllegalArgumentException("Position은 음수일 수 없습니다."); + } + this.value = value; + } + + public int getValue() { + return value; + } + + public Position moveLeft() { + return new Position(value - 1); + } + + public Position moveRight() { + return new Position(value + 1); + } +} diff --git a/src/main/java/domain/Prize.java b/src/main/java/domain/Prize.java new file mode 100644 index 00000000..713d6dd1 --- /dev/null +++ b/src/main/java/domain/Prize.java @@ -0,0 +1,13 @@ +package domain; + +public class Prize { + private final String value; + + public Prize(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/domain/Prizes.java b/src/main/java/domain/Prizes.java new file mode 100644 index 00000000..8c413d1e --- /dev/null +++ b/src/main/java/domain/Prizes.java @@ -0,0 +1,22 @@ +package domain; + +import java.util.List; + +public class Prizes { + private final List prizes; + + public Prizes(List prizes) { + if (prizes == null || prizes.isEmpty()) { + throw new IllegalArgumentException("결과는 비어 있을 수 없습니다."); + } + this.prizes = prizes; + } + + public Prize getPrizeAt(int index) { + return prizes.get(index); + } + + public List getPrizes() { + return prizes; + } +} diff --git a/src/main/java/domain/Result.java b/src/main/java/domain/Result.java new file mode 100644 index 00000000..187e486c --- /dev/null +++ b/src/main/java/domain/Result.java @@ -0,0 +1,19 @@ +package domain; + +public class Result { + private final String playerName; + private final String prize; + + public Result(String playerName, String prize) { + this.playerName = playerName; + this.prize = prize; + } + + public String getPlayerName() { + return playerName; + } + + public String getPrize() { + return prize; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..2ddae907 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,50 @@ +package view; + +import domain.LadderHeight; +import domain.Name; +import domain.Player; +import domain.Players; +import domain.Prize; +import domain.Prizes; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private final Scanner scanner; + + public InputView() { + scanner = new Scanner(System.in); + } + + public Players askPlayers() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + String input = scanner.nextLine(); + List list = new ArrayList<>(); + for (String name : input.split(",")) { + list.add(new Player(new Name(name.trim()))); + } + return new Players(list); + } + + public Prizes askPrizes() { + System.out.println("실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"); + String input = scanner.nextLine(); + List list = new ArrayList<>(); + for (String prize : input.split(",")) { + list.add(new Prize(prize.trim())); + } + return new Prizes(list); + } + + public LadderHeight askHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + int input = Integer.parseInt(scanner.nextLine()); + return new LadderHeight(input); + } + + public String askResultName() { + System.out.println("결과를 보고 싶은 사람은?"); + return scanner.nextLine().trim(); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..2df70256 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,62 @@ +package view; + +import domain.GameResult; +import domain.LadderGame; +import domain.Player; +import domain.Players; +import domain.Prize; +import domain.Prizes; +import domain.Result; +import java.util.List; + +public class OutputView { + private static final int CELL_WIDTH = 6; + + public void printLadderGameBoard(LadderGame ladderGame) { + printHeader(ladderGame.getPlayers()); + printLadder(ladderGame.getLadder()); + printBottom(ladderGame.getPrizes()); + } + + private void printHeader(Players players) { + StringBuilder builder = new StringBuilder(); + for (Player player : players.getPlayers()) { + builder.append(pad(player.getName().getValue())); + } + System.out.println(builder.toString()); + } + + private void printLadder(domain.Ladder ladder) { + List lines = ladder.getLadderBody(); + for (String line : lines) { + System.out.println(line); + } + } + + private void printBottom(Prizes prizes) { + StringBuilder builder = new StringBuilder(); + for (Prize prize : prizes.getPrizes()) { + builder.append(pad(prize.getValue())); + } + System.out.println(builder.toString()); + } + + private String pad(String text) { + StringBuilder builder = new StringBuilder(text); + while (builder.length() < CELL_WIDTH) { + builder.append(" "); + } + return builder.toString(); + } + + public void printResultSingle(String result) { + System.out.println("실행 결과"); + System.out.println(result); + } + + public void printResultAll(GameResult gameResult) { + for (Result result : gameResult.getResults()) { + System.out.println(result.getPlayerName() + " : " + result.getPrize()); + } + } +}