-
Notifications
You must be signed in to change notification settings - Fork 6
Add LadderGame #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 김지우
Are you sure you want to change the base?
The head ref may contain hidden characters: "\uAE40\uC9C0\uC6B0"
Changes from all commits
1e8dfa4
f7e611c
5074fd9
15dc27e
9323885
edecdce
11bb627
53dbd5f
0b40050
cb7e9b9
7961290
e788a14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| .idea/** | ||
| .gradle/** | ||
| build/ | ||
| build/** | ||
| out/** |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,37 @@ | ||
| # java-ladder 게임 | ||
|
|
||
| ## 기능 목록 | ||
|
|
||
| - 사용자로부터 입력 받기 | ||
|
|
||
| - 이름은 쉼표를 기준으로 한다. | ||
|
|
||
| - 이름은 최대 5글자까지 | ||
|
|
||
| - 최대 사다리 높이를 받아야 한다. | ||
|
|
||
| - 높이는 1이상 | ||
|
|
||
| - 사다리 상품을 입력 받는다. | ||
|
|
||
| - 입력 받은 상품의 수와 이름의 수가 같아야 한다. (에러 팡) | ||
|
|
||
| - 사다리 만들기 | ||
|
|
||
| - 이름 길이 5 기준으로 사다리 폭이 정해진다. | ||
|
|
||
| - 사다리 라인이 겹치지 않도록 해야한다. | ||
|
|
||
| - 사다리 게임 실행하기 | ||
|
|
||
| - 사다리 출력하기 | ||
|
|
||
| - 사용자 이름, 사다리 그리고 상품 이름을 함께 출력해야한다. | ||
|
|
||
| - 결과를 보여준다. | ||
|
|
||
| - 한 사람을 물어보면 그 사람 결과를 보여준다. | ||
|
|
||
| - all 이라 입력하면 전체 결과를 보여준다. | ||
|
|
||
| - 없는 사람을 물어보면 없다는 메세지를 보여준다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| public class Application { | ||
| public static void main(String[] args) { | ||
| LadderGameInputData ladderGameInputData = ConsoleInput.getLadderGameInputData(); | ||
| LadderGame ladderGame = LadderGame.with(ladderGameInputData, new RandomRowGeneratorStrategy()); | ||
| ladderGame.generateLadder(); | ||
| ladderGame.run(); | ||
| LadderGameOutputData ladderGameOutputData = ladderGame.getLadderGameOutputData(); | ||
| ConsoleOutput.showLadderGameResultWith(ladderGameOutputData); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.Scanner; | ||
|
|
||
| public class ConsoleInput { | ||
|
|
||
| public static final int INITIAL_POSITION = 0; | ||
| public static final String DELIMITER = ","; | ||
| public static final String MESSAGE_INPUT_USER_NAMES = "참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요.)"; | ||
| public static final String MESSAGE_INPUT_MAX_LADDER_HEIGHT = "최대 사다리 높이는 몇 개인가요?"; | ||
| public static final String MESSAGE_INPUT_GAME_PRIZES = "사다리 상품을 입력해주세요.(상품들은 쉼표(,)로 구분됩니다.)"; | ||
| public static final String ERROR_INPUT_NOT_INTEGER = "정수를 입력하셔야 합니다."; | ||
|
|
||
| public static Scanner sc = new Scanner(System.in); | ||
|
|
||
| public static LadderGameInputData getLadderGameInputData() { | ||
| List<User> users = createUsersFrom(getInputUserNames()); | ||
| LadderHeight height = createHeight(); | ||
| List<Prize> prizes = createPrizesFrom(getInputPrizeNames()); | ||
| return LadderGameInputData.of(users, height, prizes); | ||
| } | ||
|
|
||
| private static List<String> getInputPrizeNames() { | ||
| System.out.println(MESSAGE_INPUT_GAME_PRIZES); | ||
| return Arrays.asList(sc.nextLine().split(DELIMITER)); | ||
| } | ||
|
|
||
| static List<Prize> createPrizesFrom(List<String> prizeNames) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드 순서도 convention! 위에서 아래로 읽을 수 있도록 배치해주시면 어떨까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리고 createUsersFrom 메서드와 마찬가지인데, 해당 메서드는 default 접근제어자를 가지고 있지만 현재 클래스 안에서만 사용하고 있네요. 접근제어자를 default로 하신 것은 테스트에서 사용하기 위함인가요? |
||
| List<Prize> prizes = new ArrayList<>(); | ||
|
|
||
| int position = INITIAL_POSITION; | ||
| for (String prizeName: prizeNames) { | ||
| Prize prize = Prize.with(prizeName, position); | ||
| prizes.add(prize); | ||
| position++; | ||
| } | ||
| return prizes; | ||
| } | ||
|
|
||
| private static List<String> getInputUserNames() { | ||
| System.out.println(MESSAGE_INPUT_USER_NAMES); | ||
| return Arrays.asList(sc.nextLine().split(DELIMITER)); | ||
| } | ||
|
|
||
| static List<User> createUsersFrom(List<String> userNames) { | ||
| List<User> users = new ArrayList<>(); | ||
|
|
||
| int position = INITIAL_POSITION; | ||
| for (String userName: userNames) { | ||
| User user = User.with(UserName.of(userName), position); | ||
| users.add(user); | ||
| position++; | ||
| } | ||
| return users; | ||
| } | ||
|
|
||
| private static LadderHeight createHeight() { | ||
| System.out.println(MESSAGE_INPUT_MAX_LADDER_HEIGHT); | ||
| return LadderHeight.of(getInputHeight()); | ||
| } | ||
|
|
||
| private static int getInputHeight() { | ||
| String height = sc.nextLine(); | ||
| if (isConvertibleIntoInteger(height)) { | ||
| return Integer.parseInt(height); | ||
| } | ||
| throw new IllegalArgumentException(ERROR_INPUT_NOT_INTEGER); | ||
| } | ||
|
|
||
| public static boolean isConvertibleIntoInteger(String str) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도 접근제어자를 조금 더 고민해보아야 할거같아요. |
||
| for (char c: str.toCharArray()) { | ||
| if (c < 48 || c > 57) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 48과 57은 무슨 숫자인가요? |
||
| System.out.println(c); | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Scanner; | ||
|
|
||
| public class ConsoleOutput { | ||
|
|
||
| public static final String MESSAGE_LADDER_GAME_RESULT = "사다리 결과"; | ||
| public static final String NULL = "\0"; | ||
| public static final String BLANK_BETWEEN_NAMES = " "; | ||
| public static final String NEXT_LINE = "\n"; | ||
| public static final String INITIAL_STRING = ""; | ||
| public static final String BAR = "|"; | ||
| public static final String LEFT_MARGIN = " "; | ||
| public static final String BLANK = " "; | ||
| private static final int MAXIMUM_LENGTH = 5; | ||
| public static final String DELIMITER = " : "; | ||
| public static final String ALL = "all"; | ||
| public static final String MESSAGE_NOT_PARTICIPANT = "참가한 유저가 아닙니다."; | ||
| public static final String MESSAGE_WANT_TO_KNOW = "결과를 보고 싶은 사람은?"; | ||
|
|
||
| public static Scanner sc = new Scanner(System.in); | ||
|
|
||
| public static void showLadderGameResultWith(LadderGameOutputData ladderGameOutputData) { | ||
| showLadderGame(ladderGameOutputData.getUsers(), ladderGameOutputData.getLadder(), ladderGameOutputData.getPrizes()); | ||
| showGameResult(ladderGameOutputData.getLadderResult()); | ||
| } | ||
|
|
||
| private static void showLadderGame(List<User> users, Ladder ladder, List<Prize> prizes) { | ||
| System.out.println(MESSAGE_LADDER_GAME_RESULT); | ||
| showUsers(users); | ||
| showLadder(ladder); | ||
| showPrizes(prizes); | ||
| } | ||
|
|
||
| private static void showUsers(List<User> users) { | ||
| users.forEach(user -> showNameToMaximumLength(user.getUserName().getName())); | ||
| System.out.print(NEXT_LINE); | ||
| } | ||
|
|
||
| private static void showPrizes(List<Prize> prizes) { | ||
| prizes.forEach(prize -> showNameToMaximumLength(prize.getPrizeName())); | ||
| System.out.print(NEXT_LINE); | ||
| } | ||
|
|
||
| private static void showNameToMaximumLength(String name) { | ||
| int blankSpaceNums = MAXIMUM_LENGTH - name.length(); | ||
| String blank = new String(new char[blankSpaceNums]).replace(NULL, BLANK); | ||
| System.out.print(blank + name); | ||
| System.out.print(BLANK_BETWEEN_NAMES); | ||
| } | ||
|
|
||
| private static void showLadder(Ladder ladder) { | ||
| List<Row> rows = ladder.getRows(); | ||
| rows.forEach(ConsoleOutput::showRow); | ||
| } | ||
|
|
||
| private static void showRow(Row row) { | ||
| System.out.print(LEFT_MARGIN); | ||
| String rowStr = INITIAL_STRING; | ||
| for (int position=0; position<row.getLenOfRow(); position++) { | ||
| String line = row.getLineStartingWith(position); | ||
| rowStr = rowStr.concat(BAR + line); | ||
| } | ||
| System.out.println(rowStr.concat(BAR)); | ||
| } | ||
|
|
||
| private static void showGameResult(Map<User, Prize> prizes) { | ||
| System.out.println(MESSAGE_WANT_TO_KNOW); | ||
| String name = sc.nextLine(); | ||
| if (name.equals(ALL)) { | ||
| showAllResult(prizes); | ||
| return; | ||
| } | ||
| showUserResult(name, prizes); | ||
| } | ||
|
|
||
| private static void showAllResult(Map<User,Prize> prizes) { | ||
| for (User user: prizes.keySet()) { | ||
| System.out.println(user.getUserName().getName() + DELIMITER + prizes.get(user).getPrizeName()); | ||
| } | ||
| } | ||
|
|
||
| private static void showUserResult(String name, Map<User,Prize> prizes) { | ||
| UserName userName = UserName.of(name); | ||
| for (User user: prizes.keySet()) { | ||
| if (user.hasUserName(userName)) { | ||
| System.out.println(prizes.get(user).getPrizeName()); | ||
| return; | ||
| } | ||
| } | ||
| System.out.println(MESSAGE_NOT_PARTICIPANT); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import java.util.List; | ||
|
|
||
| public class Ladder { | ||
|
|
||
| private List<Row> rows; | ||
|
|
||
| private Ladder(List<Row> rows) { | ||
| this.rows = rows; | ||
| } | ||
|
|
||
| public static Ladder with(List<Row> rows) { | ||
| return new Ladder(rows); | ||
| } | ||
|
|
||
| public int startWith(int initialPosition) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 메서드는 특정 위치의 플레이어가 사다리를 끝까지 내려갔을 때 어떤 위치에 있는지 반환하는 메서드인 것 같아요. 메서드 이름만 봤을 때는 메서드가 어떤 역할을 하고 있는지 잘 와닿지 않는것 같아요. 좀 더 적절한 이름은 없을까요? |
||
| int position = initialPosition; | ||
| for (Row row: rows) { | ||
| position = row.getNextPosition(position); | ||
| } | ||
| return position; | ||
| } | ||
|
|
||
| public List<Row> getRows() { | ||
| return rows; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
|
|
||
| public class LadderGame { | ||
|
|
||
| private List<User> users; | ||
| private LadderHeight height; | ||
| private List<Prize> prizes; | ||
| private Ladder ladder; | ||
| private LadderGenerator ladderGenerator; | ||
| private HashMap<User, Prize> ladderResult = new HashMap<>(); | ||
|
|
||
| private LadderGame(LadderGameInputData ladderGameInputData, RowGeneratorStrategy rowGeneratorStrategy) { | ||
| this.users = ladderGameInputData.getUsers(); | ||
| this.height = ladderGameInputData.getHeight(); | ||
| this.prizes = ladderGameInputData.getPrizes(); | ||
| // TODO 생성자에서 데이터를 넣어주느냐 vs 메서드 파라미터로 넣어주느냐 ( 각각 어떤 변화들을 야기하는가?!) | ||
| // TODO 파라미터로 넣어주면 generateRows에 자유도가 생김. | ||
| this.ladderGenerator = new LadderGenerator(rowGeneratorStrategy); | ||
| } | ||
|
|
||
| public static LadderGame with(LadderGameInputData ladderGameInputData, RowGeneratorStrategy rowGeneratorStrategy) { | ||
| return new LadderGame(ladderGameInputData, rowGeneratorStrategy); | ||
| } | ||
|
|
||
| public void generateLadder() { | ||
| int numOfColumn = users.size(); | ||
| ladder = ladderGenerator.generateLadder(numOfColumn, height.getHeight()); | ||
| } | ||
|
|
||
| public void run() { | ||
| users.forEach(this::runWith); | ||
| } | ||
|
|
||
| private void runWith(User user) { | ||
| int position = ladder.startWith(user.getPosition()); | ||
| Prize prize = prizes.stream() | ||
| .filter(p -> p.hasPosition(position)) | ||
| .findAny().orElseThrow(IllegalArgumentException::new); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기에서는 IllegalArgumentException보다는 직접 정의한 exception을 만들어 의미를 담아주면 어떨까요? |
||
| ladderResult.put(user, prize); | ||
| } | ||
|
|
||
| public LadderGameOutputData getLadderGameOutputData() { | ||
| return LadderGameOutputData.of(users, prizes, ladder, ladderResult); | ||
| } | ||
|
|
||
| public List<User> getUsers() { | ||
| return users; | ||
| } | ||
|
|
||
| public LadderHeight getHeight() { | ||
| return height; | ||
| } | ||
|
|
||
| public LadderGenerator getLadderGenerator() { | ||
| return ladderGenerator; | ||
| } | ||
|
|
||
| public Ladder getLadder() { | ||
| return ladder; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import java.util.List; | ||
|
|
||
| public class LadderGameInputData { | ||
|
|
||
| public static final String ERROR_USER_NUMS_PRIZE_NUMS_NOT_EQUAL = "참가자 수와 게임 상품 수가 일치하지 않습니다."; | ||
|
|
||
| private List<User> users; | ||
| private LadderHeight height; | ||
| private List<Prize> prizes; | ||
|
|
||
| private LadderGameInputData(List<User> users, LadderHeight height, List<Prize> prizes) { | ||
| validate(users, prizes); | ||
| this.users = users; | ||
| this.height = height; | ||
| this.prizes = prizes; | ||
| } | ||
|
|
||
| private void validate(List<User> users, List<Prize> prizes) { | ||
| if (users.size() != prizes.size()) { | ||
| throw new IllegalArgumentException(ERROR_USER_NUMS_PRIZE_NUMS_NOT_EQUAL); | ||
| } | ||
| } | ||
|
|
||
| public static LadderGameInputData of(List<User> users, LadderHeight height, List<Prize> prizes) { | ||
| return new LadderGameInputData(users, height, prizes); | ||
| } | ||
|
|
||
| public List<User> getUsers() { | ||
| return users; | ||
| } | ||
|
|
||
| public LadderHeight getHeight() { | ||
| return height; | ||
| } | ||
|
|
||
| public List<Prize> getPrizes() { | ||
| return prizes; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| public class LadderGameOutputData { | ||
|
|
||
| private List<User> users; | ||
| private List<Prize> prizes; | ||
| private Ladder ladder; | ||
| private Map<User, Prize> ladderResult; | ||
|
|
||
| private LadderGameOutputData(List<User> users, List<Prize> prizes, Ladder ladder, Map<User, Prize> ladderResult) { | ||
| this.users = users; | ||
| this.prizes = prizes; | ||
| this.ladder = ladder; | ||
| this.ladderResult = ladderResult; | ||
| } | ||
|
|
||
| public static LadderGameOutputData of(List<User> users, List<Prize> prizes, Ladder ladder, HashMap<User,Prize> ladderResult) { | ||
| return new LadderGameOutputData(users, prizes, ladder, ladderResult); | ||
| } | ||
|
|
||
| public List<User> getUsers() { | ||
| return users; | ||
| } | ||
|
|
||
| public List<Prize> getPrizes() { | ||
| return prizes; | ||
| } | ||
|
|
||
| public Ladder getLadder() { | ||
| return ladder; | ||
| } | ||
|
|
||
| public Map<User, Prize> getLadderResult() { | ||
| return ladderResult; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ConsoleInput에서 너무 많은 일을 하고있는 것 같아요.
Input에서는 순수하게 외부에서부터 문자열 input만 받도록 하고,객체 생성은 다른 곳에서 담당하는 것은 어떨까요?