diff --git a/src/main/java/controller/GameController.java b/src/main/java/controller/GameController.java index 4c1f4704..d09779d4 100644 --- a/src/main/java/controller/GameController.java +++ b/src/main/java/controller/GameController.java @@ -1,18 +1,46 @@ package controller; -import domain.service.GameService; -import view.InputUtil; -import view.OutputUtil; +import domain.gameservice.GameService; +import view.InputView; +import view.OutputView; + +import java.util.List; public class GameController { + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + public void run() { - String[] users = InputUtil.getUserNameInput();; - int lineHeight = InputUtil.getLadderSizeInput(); + boolean status = true; + List users = inputView.inputUserName(); + List results = inputView.inputItems(); + int lineHeight = inputView.inputLadderSize(); + + GameService ladderGame = new GameService(lineHeight, users, results); - GameService ladderGame = new GameService(lineHeight, users); - OutputUtil.printLadder(ladderGame.getGameResult()); + outputView.printUsers(ladderGame.getUsers()); + outputView.printLadder(ladderGame.getLadder()); + outputView.printItems(ladderGame.getItems()); + + ladderGame.playGame(); + + while (status) { + String target = inputView.inputResultTarget(); + status = handleTargetInput(target, ladderGame); + } } + public boolean handleTargetInput(String target, GameService ladderGame) { + if (target.equals("춘식이")) { + return false; + } else if (target.equals("all")) { + outputView.printAllResult(ladderGame.getResults()); + return true; + } else { + outputView.printSingleResult(ladderGame.getSingleUserResult(target)); + return true; + } + } } diff --git a/src/main/java/domain/Ladder.java b/src/main/java/domain/Ladder.java deleted file mode 100644 index 32f5f70a..00000000 --- a/src/main/java/domain/Ladder.java +++ /dev/null @@ -1,42 +0,0 @@ -package domain; - -import java.util.ArrayList; -import java.util.List; - -public class Ladder { - private final int ladderWidth; - private final int ladderHeight; - private List ladders; - - - public Ladder(int ladderHeight, int ladderWidth) { - if (!validateLadderHeight(ladderHeight)) { - throw new IllegalArgumentException("입력값이 올바르지 않습니다."); - } - this.ladderHeight = ladderHeight; - this.ladderWidth = ladderWidth; - initLadder(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - ladders.forEach(line->{ - StringBuilder row = new StringBuilder(); - row.append(line.toString()); - sb.append(" " + row + "\n"); - }); - return sb.toString(); - } - - private void initLadder() { - ladders = new ArrayList<>(); - for (int i = 0; i < ladderHeight; i++) { - ladders.add(Line.createRandomStep(ladderWidth)); - } - } - - private boolean validateLadderHeight(int lineCount) { - return lineCount >= 1; - } -} diff --git a/src/main/java/domain/Line.java b/src/main/java/domain/Line.java deleted file mode 100644 index f5af7170..00000000 --- a/src/main/java/domain/Line.java +++ /dev/null @@ -1,58 +0,0 @@ -package domain; - -import util.RandomUtil; - -import java.util.ArrayList; -import java.util.List; - -public class Line { - private static final String USER_LINE = "|"; - private static final String CONNECTION_LINE = "-----"; - private static final String EMPTY_SPACE = " "; - private List row; - - - public static Line createRandomStep(int width) { - return new Line(width); - } - - private Line(int width) { - row = createLadderRow(width); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - row.forEach(element -> sb.append(element)); - return sb.toString(); - } - - private List createLadderRow(int width) { - List row = new ArrayList<>(); - for (int i = 0; i < width; i++) { - row.add(createElement(i, row)); - } - return row; - } - - private String createElement(int point, List row) { - if (point % 2 == 0) { - return USER_LINE; - } - return createRandomStep(point, row); - } - - private String createRandomStep(int point, List row) { - if (point == 1 || !isDoubleConnected(row.get(point - 2))) return createLineByRandom(); - return EMPTY_SPACE; - } - - private String createLineByRandom() { - return RandomUtil.getBoolean() ? CONNECTION_LINE : EMPTY_SPACE; - } - - private boolean isDoubleConnected(String prev) { - return prev.equals(CONNECTION_LINE); - } -} - diff --git a/src/main/java/domain/User.java b/src/main/java/domain/User.java deleted file mode 100644 index d6f05e61..00000000 --- a/src/main/java/domain/User.java +++ /dev/null @@ -1,47 +0,0 @@ -package domain; - -import java.util.*; - -public class User { - private static final int USERNAME_MAXLENGTH = 5; - private static final int USERNAME_MINLENGTH = 1; - private static final String PADDING = " "; - private String name; - - - private User(String user) { - if (!validateUserName(user)) { - throw new InputMismatchException("이름의 길이를 1자 이상, 5자 이하로 작성해주세요."); - } - this.name = addPadding(user); - } - - public static User createUser(String user) { - return new User(user); - } - - public String getName() { - return name; - } - - private String addPadding(String user) { - if (user.length() == USERNAME_MAXLENGTH) { - return user; - } - StringBuilder sb = new StringBuilder(); - int whiteSpace = USERNAME_MAXLENGTH - user.length(); - int frontSpace = whiteSpace / 2; - int backSpace = whiteSpace - frontSpace; - - sb.append(PADDING.repeat(frontSpace)); - sb.append(user); - sb.append(PADDING.repeat(backSpace)); - - return sb.toString(); - } - - - private boolean validateUserName(String name) { - return name.length() >= USERNAME_MINLENGTH && name.length() <= USERNAME_MAXLENGTH; - } -} diff --git a/src/main/java/domain/gameservice/GameService.java b/src/main/java/domain/gameservice/GameService.java new file mode 100644 index 00000000..1cf7ef3f --- /dev/null +++ b/src/main/java/domain/gameservice/GameService.java @@ -0,0 +1,68 @@ +package domain.gameservice; + +import domain.ladder.Ladder; +import domain.ladder.LadderCreator; +import domain.ladder.Line; +import domain.item.Item; +import domain.item.ItemCreator; +import domain.user.User; +import domain.user.UserCreator; + +import java.util.*; + +public class GameService { + private Map users; + private Map items; + private Ladder ladder; + private Map results; + + public GameService( int lineHeight, List users,List items) { + this.users = UserCreator.createUserMap(users); + this.items = ItemCreator.createResultMap(items); + this.ladder = LadderCreator.createLadder(lineHeight, calculateLadderWidth()); + this.results = new HashMap<>(); + } + + public void playGame() { + for (String user : users.keySet()) { + results.putAll(playSinglePlayer(users.get(user))); + } + } + + public List getUsers() { + return new ArrayList<>(users.values()); + } + + public List getItems() { + return new ArrayList<>(items.values()); + } + + public List getLadder() { + return ladder.getLadders(); + } + + public Map getResults() { + return Collections.unmodifiableMap(results); + } + + public String getSingleUserResult(String username) { + return results.get(username); + } + + private Map playSinglePlayer(User user) { + int userPoint = user.getPoint(); + + for (int i = 0; i < ladder.getLadderSize(); i++) { + userPoint += ladder.move(i, userPoint); + } + Item item = items.get(userPoint); + return new HashMap<>(){{ + put(user.getName(), item.getName());}}; + } + + private int calculateLadderWidth() { + return users.size() * 2 - 1; + } + + +} diff --git a/src/main/java/domain/item/Item.java b/src/main/java/domain/item/Item.java new file mode 100644 index 00000000..631bdf49 --- /dev/null +++ b/src/main/java/domain/item/Item.java @@ -0,0 +1,18 @@ +package domain.item; + + +public class Item { + private final String name; + + private Item(String name) { + this.name = name; + } + + public static Item createResult(String name) { + return new Item(name); + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/domain/item/ItemCreator.java b/src/main/java/domain/item/ItemCreator.java new file mode 100644 index 00000000..0ea445ab --- /dev/null +++ b/src/main/java/domain/item/ItemCreator.java @@ -0,0 +1,17 @@ +package domain.item; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ItemCreator { + public static Map createResultMap(List results) { + int i = 0; + Map map = new HashMap<>(); + for (String result : results) { + map.put(i, Item.createResult(result)); + i += 2; + } + return map; + } +} diff --git a/src/main/java/domain/ladder/Ladder.java b/src/main/java/domain/ladder/Ladder.java new file mode 100644 index 00000000..31bcab66 --- /dev/null +++ b/src/main/java/domain/ladder/Ladder.java @@ -0,0 +1,58 @@ +package domain.ladder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Ladder { + private final int ladderWidth; + private final int ladderHeight; + private final List ladders; + + + public Ladder(int ladderHeight, int ladderWidth) { + this.ladderHeight = ladderHeight; + this.ladderWidth = ladderWidth; + ladders = initLadder(); + } + + public int getLadderSize() { + return ladderHeight; + } + + public List getLadders() { + return Collections.unmodifiableList(ladders); + } + + public int move(int rowNumber, int userPoint) { + Line line = ladders.get(rowNumber); + if (userPoint == 0) { + return canMoveRight(line, userPoint); + } + if (userPoint == ladderWidth-1) { + return canMoveLeft(line, userPoint); + } + return canMoveLeft(line, userPoint) + canMoveRight(line, userPoint); + + } + + private int canMoveLeft(Line line, int userPoint) { + if (line.getPrev(userPoint) == 1) return -2; + return 0; + } + + private int canMoveRight(Line line, int userPoint) { + if (line.getNext(userPoint) == 1) return 2; + return 0; + } + + private List initLadder() { + List result = new ArrayList<>(); + for (int i = 0; i < ladderHeight; i++) { + result.add(Line.createRandomStep(ladderWidth)); + } + return result; + } + + +} diff --git a/src/main/java/domain/ladder/LadderCreator.java b/src/main/java/domain/ladder/LadderCreator.java new file mode 100644 index 00000000..4c00868a --- /dev/null +++ b/src/main/java/domain/ladder/LadderCreator.java @@ -0,0 +1,15 @@ +package domain.ladder; + +public class LadderCreator { + public static Ladder createLadder(int ladderHeight, int ladderWidth) { + if (!validateLadderHeight(ladderHeight)) { + throw new IllegalArgumentException("입력값이 올바르지 않습니다."); + } + return new Ladder(ladderHeight, ladderWidth); + } + + private static boolean validateLadderHeight(int lineCount) { + return lineCount >= 1; + } + +} diff --git a/src/main/java/domain/ladder/Line.java b/src/main/java/domain/ladder/Line.java new file mode 100644 index 00000000..522bfc4f --- /dev/null +++ b/src/main/java/domain/ladder/Line.java @@ -0,0 +1,64 @@ +package domain.ladder; + +import util.RandomUtil; + +import java.util.ArrayList; +import java.util.List; + +public class Line { + private static final int USER_LINE = 0; + private static final int CONNECTION_LINE = 1; + private static final int EMPTY_SPACE = -1; + private List row; + + + public static Line createRandomStep(int width) { + return new Line(width); + } + + + public int getPrev(int userPoint) { + return row.get(userPoint - 1); + } + + public int getNext(int userPoint) { + return row.get(userPoint + 1); + } + + public List getLine() { + return row; + } + + private Line(int width) { + row = createLadderRow(width); + } + + private List createLadderRow(int width) { + List row = new ArrayList<>(); + for (int i = 0; i < width; i++) { + row.add(createElement(i, row)); + } + return row; + } + + private int createElement(int point, List row) { + if (point % 2 == 0) { + return USER_LINE; + } + return createRandomStep(point, row); + } + + private int createRandomStep(int point, List row) { + if (point == 1 || !isDoubleConnected(row.get(point - 2))) return createLineByRandom(); + return EMPTY_SPACE; + } + + private int createLineByRandom() { + return RandomUtil.getBoolean() ? CONNECTION_LINE : EMPTY_SPACE; + } + + private boolean isDoubleConnected(int prev) { + return prev == CONNECTION_LINE; + } +} + diff --git a/src/main/java/domain/service/GameService.java b/src/main/java/domain/service/GameService.java deleted file mode 100644 index fda310da..00000000 --- a/src/main/java/domain/service/GameService.java +++ /dev/null @@ -1,42 +0,0 @@ -package domain.service; - -import domain.Ladder; -import domain.User; - -import java.util.ArrayList; -import java.util.List; - -public class GameService { - private List users; - private Ladder ladder; - - public GameService(int ladderHeight, String[] user) { - - this.users = getUserList(user); - this.ladder = new Ladder(ladderHeight, calculateLadderWidth()); - } - - public String getGameResult() { - StringBuilder sb = new StringBuilder(); - - users.forEach(user -> { - sb.append(user.getName() + " "); - }); - sb.append("\n"); - sb.append(ladder.toString()); - - return sb.toString(); - } - - private List getUserList(String[] users) { - List list = new ArrayList<>(); - for (String user : users) { - list.add(User.createUser(user)); - } - return list; - } - - private int calculateLadderWidth() { - return users.size() * 2 - 1; - } -} diff --git a/src/main/java/domain/user/User.java b/src/main/java/domain/user/User.java new file mode 100644 index 00000000..f47a6aa1 --- /dev/null +++ b/src/main/java/domain/user/User.java @@ -0,0 +1,20 @@ +package domain.user; + +public class User { + private final String name; + private final int point; + + + public User(String user, int point) { + this.name = user; + this.point = point; + } + + public String getName() { + return name; + } + + public int getPoint() { + return point; + } +} diff --git a/src/main/java/domain/user/UserCreator.java b/src/main/java/domain/user/UserCreator.java new file mode 100644 index 00000000..95e4be91 --- /dev/null +++ b/src/main/java/domain/user/UserCreator.java @@ -0,0 +1,34 @@ +package domain.user; + +import java.util.HashMap; + +import java.util.InputMismatchException; +import java.util.List; +import java.util.Map; + +public class UserCreator { + private static final int USERNAME_MAXLENGTH = 5; + private static final int USERNAME_MINLENGTH = 1; + private Map users; + + public UserCreator(List users) { + this.users = createUserMap(users); + } + + public static Map createUserMap(List users) { + int i = 0; + Map map = new HashMap<>(); + for (String user : users) { + validateUserName(user); + map.put(user, new User(user, i)); + i += 2; + } + return map; + } + + private static void validateUserName(String name) { + if(!(name.length() >= USERNAME_MINLENGTH && name.length() <= USERNAME_MAXLENGTH)) { + throw new InputMismatchException("이름의 길이를 1자 이상, 5자 이하로 작성해주세요."); + }; + } +} diff --git a/src/main/java/view/InputUtil.java b/src/main/java/view/InputUtil.java deleted file mode 100644 index 7ef3c5ca..00000000 --- a/src/main/java/view/InputUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package view; - -import java.util.InputMismatchException; -import java.util.Scanner; - -public class InputUtil { - private static final Scanner sc = new Scanner(System.in); - private static final String NAME_INPUT_QUESTION = "참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"; - private static final String HEIGHT_INPUT_QUESTION = "최대 사다리 높이는 몇 개인가요?"; - private static final String EXCEPTION_MESSAGE = "참가자의 수가 부족합니다."; - - public static String[] getUserNameInput() { - System.out.println(NAME_INPUT_QUESTION); - - String usernames = sc.nextLine(); - if(!validateUsernameFormat(usernames)){ - throw new InputMismatchException(EXCEPTION_MESSAGE); - } - return usernames.split(","); - } - - public static int getLadderSizeInput() { - System.out.println(HEIGHT_INPUT_QUESTION); - return sc.nextInt(); - } - - public static void close() { - sc.close(); - } - - - public static boolean validateUsernameFormat(String usernames) { - return usernames.split(",").length >= 2; - } -} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..e24ccb05 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,42 @@ +package view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final Scanner sc = new Scanner(System.in); + private static final String NAME_INPUT_QUESTION = "참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"; + private static final String ITEM_INPUT_QUESTION = "실행 결과를 입력하세요. (결과는 쉼표(,)로 구분하세요)"; + private static final String HEIGHT_INPUT_QUESTION = "최대 사다리 높이는 몇 개인가요?"; + private static final String TARGET_QUESTION = "결과를 보고 싶은 사람은?"; + private static final String DELIMITER = ","; + + public List inputUserName() { + System.out.println(NAME_INPUT_QUESTION); + + String usernames = sc.nextLine(); + return Arrays.asList(usernames.split(DELIMITER)); + } + + public List inputItems() { + System.out.println(ITEM_INPUT_QUESTION); + + String resuls = sc.nextLine(); + return Arrays.asList(resuls.split(DELIMITER)); + } + + public int inputLadderSize() { + System.out.println(HEIGHT_INPUT_QUESTION); + return Integer.parseInt(sc.nextLine()); + } + + public String inputResultTarget() { + System.out.println(TARGET_QUESTION); + return sc.nextLine(); + } + + public void close() { + sc.close(); + } +} diff --git a/src/main/java/view/OutputUtil.java b/src/main/java/view/OutputUtil.java deleted file mode 100644 index f4d09d8c..00000000 --- a/src/main/java/view/OutputUtil.java +++ /dev/null @@ -1,7 +0,0 @@ -package view; - -public class OutputUtil { - public static void printLadder(String ladder) { - System.out.println(ladder); - } -} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..95c9c655 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,75 @@ +package view; + +import domain.ladder.Line; +import domain.item.Item; +import domain.user.User; + +import java.util.List; +import java.util.Map; + +public class OutputView { + private static final String USER_LINE = "|"; + private static final String CONNECTION_LINE = "-----"; + private static final String EMPTY_LINE = " "; + private static final String PADDING = " "; + + public void printUsers(List users) { + users.forEach(user -> System.out.print(addPadding(user.getName()))); + System.out.println(); + } + + public void printLadder(List ladder) { + for (Line line : ladder) { + System.out.println(PADDING.repeat(2) + printLadderLine(line.getLine()));; + } + } + + public void printItems(List items) { + items.forEach(item -> System.out.print(addPadding(item.getName()))); + System.out.println(System.lineSeparator()); + } + + public void printAllResult(Map results) { + System.out.println("실행 결과"); + for (String user : results.keySet()) { + System.out.println(user + " : " + results.get(user)); + } + System.out.println(); + } + + public void printSingleResult(String result) { + System.out.println("실행 결과"); + System.out.println(result); + System.out.println(); + } + + private String printLadderLine(List line) { + StringBuilder sb = new StringBuilder(); + for (int i : line) { + if (i % 2 == 0) { + sb.append(USER_LINE); + } else if (i == -1) { + sb.append(EMPTY_LINE); + } else { + sb.append(CONNECTION_LINE); + } + } + return sb.toString(); + } + + private String addPadding(String user) { + if (user.length() == 5) { + return user; + } + StringBuilder sb = new StringBuilder(); + int whiteSpace = 5 - user.length(); + int frontSpace = whiteSpace / 2; + int backSpace = whiteSpace - frontSpace; + + sb.append(PADDING.repeat(frontSpace)); + sb.append(user); + sb.append(PADDING.repeat(backSpace)); + + return sb.toString(); + } +} diff --git a/src/test/java/domain/LineTest.java b/src/test/java/domain/LineTest.java deleted file mode 100644 index ca61bd6f..00000000 --- a/src/test/java/domain/LineTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package domain; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class LineTest { - @Test - @DisplayName("Line 생성 시 중복 줄이 없는지 테스트") - void createLine() { - Line line = Line.createRandomStep(100); - - assertThat(line.toString().contains("-----|-----")).isFalse(); - - } -} diff --git a/src/test/java/domain/UserTest.java b/src/test/java/domain/UserTest.java deleted file mode 100644 index de70026e..00000000 --- a/src/test/java/domain/UserTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package domain; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.InputMismatchException; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class UserTest { - - @Test - @DisplayName("유저 이름의 길이가 범위를 벗어날 경우 예외발생 테스트") - void nameLengthOutOfBound() { - - assertThatThrownBy(() -> User.createUser("suntory")) - .isInstanceOf(InputMismatchException.class) - .hasMessage("이름의 길이를 1자 이상, 5자 이하로 작성해주세요."); - } - - @Test - @DisplayName("이름의 길이가 5자가 아닐경우 공백으로 채워주는 테스트") - void addPaddingToUsername() { - List usernames = Arrays.asList("a","aa", "aaa", "aaaa"); - - usernames.forEach(name->{ - String sut = User.createUser(name).getName(); - assertThat(sut.length()).isEqualTo(5); - }); - } -}