Skip to content
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

[지안] step-5 실행 결과 출력 완성 #227

Open
wants to merge 11 commits into
base: jian
Choose a base branch
from
5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 91 additions & 11 deletions src/main/java/kr/ladder/domain/InputValidation.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
import kr.ladder.view.InputView;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class InputValidation {
public static final String ERROR_MASSAGE_PLAYER_NAME = "정해진 형식에 맞지 않습니다. 다시 입력해주세요";
public static final String ERROR_MESSAGE_LADDER_HEIGHT = "다시 입력해주세요. 최소 사다리 높이는 1입니다.";
public static final String ERROR_MESSAGE_LADDER_TYPE = "정수를 입력해 주세요.";
public static final String ERROR_MASSAGE_PRIZES_NUMBER = "경품을 다시 입력해주세요. 인원 수와 같은 수가 들어와야 합니다.";
private static final String ERROR_MASSAGE_NO_PLAYER_NAME = "해당 참가자가 없습니다.";
public static final int MIN_NAME_LENGTH = 1;
public static final int MAX_NAME_LENGTH = 5;
private final InputView inputView;
Expand All @@ -21,12 +29,13 @@ public InputValidation(){
- 각 이름중에 null이 있는 경우
3. 쉼표로 끝난 경우
4. 영어, 한글이 아닌 문자가 들어온 경우
5. 같은 이름을 가진 플레이어가 있을 경우
-> player 입력을 다시 받는다
// 🤔InputView에서 요청해서 다시 받는게 맞나??
return 위에서 검증을 마친(정상적인) 플레이어 이름 배열
*/
public String[] inspectPlayers(String[] players) throws IOException {
return inspectPlayersNameLength(players);
public String[] inspectPlayers() throws IOException {
return inspectPlayersNameLength(inputView.getPlayer());
}

private String[] inspectPlayersNameLength(String[] players) throws IOException {
Expand All @@ -37,16 +46,16 @@ private String[] inspectPlayersNameLength(String[] players) throws IOException {
return players;
}

private boolean correctLength(String[] players){
private boolean correctLength(String[] words){
int errors = 0; // 이름이 1~5글자 사이에 있지 않으면 count
for (String playerName : players) {
errors += countOverScopeName(playerName);
for (String word : words) {
errors += countOverScopeName(word);
}
return (errors == 0);
}

private int countOverScopeName(String playerName){
if (playerName.length() >= MIN_NAME_LENGTH && playerName.length() <= MAX_NAME_LENGTH){
private int countOverScopeName(String word){
if (word.length() >= MIN_NAME_LENGTH && word.length() <= MAX_NAME_LENGTH){
return 0;
}
return 1;
Expand All @@ -55,14 +64,85 @@ private int countOverScopeName(String playerName){
/* 사다리 높이 검사()
while 정상적인 사다리 높이가 아니라면
1. 사다리 높이가 0 이하 ✅
2. int가 아닌 경우
2. int가 아닌 경우
-> 입력을 다시 받는다
return 정상적인 사다리 높이
*/
public int inspectLadderHeight(int ladderHeight) throws IOException {
if (ladderHeight < 1) {
public int inspectLadderHeight() throws IOException {
String ladderHeight = inputView.getLadderHeight();
while (!isInteger(ladderHeight) || !isAvailableHeight(Integer.parseInt(ladderHeight))) {
ladderHeight = inputView.getLadderHeight();
}
return ladderHeight;
return Integer.parseInt(ladderHeight);
}

private boolean isAvailableHeight(int ladderHeight){
if (ladderHeight < 1) {
System.out.println(ERROR_MESSAGE_LADDER_HEIGHT);
return false;
}
return true;
}

private boolean isInteger(String ladderHeight) {
try {
Integer.parseInt(ladderHeight);
return true;
} catch (NumberFormatException e) {
System.out.println(ERROR_MESSAGE_LADDER_TYPE);
return false;
}
}

/*
상품 목록 검사
while 정상적인 경품 목록이 아니라면
1. 1~5 글자 사이가 아닌 경우 ✅(사람 이름 검사 로직 재사용)
2. 플레이어 숫자와 동일한 갯수가 아닐 경우
-> 경품 입력을 다시 받는다.
return 정상적인 경품 목록
*/

public String[] inspectPrizes(int playersNumber) throws IOException {
String[] prizes = inputView.getPrizes();
while (!correctPrizeLength(prizes) || !sameNumberAsPlayers(prizes.length, playersNumber)) {
prizes = inputView.getPrizes();
}
return prizes;
}

private boolean correctPrizeLength(String[] prizes) throws IOException {
if (!correctLength(prizes)) {// 각 이름이 1~5 글자 사이가 아니면
System.out.println(ERROR_MASSAGE_PLAYER_NAME);
return false;
}
return true;
}

private boolean sameNumberAsPlayers(int prizesNumber, int playersNumber){
if (prizesNumber != playersNumber) {
System.out.println(ERROR_MASSAGE_PRIZES_NUMBER);
return false;
}
return true;
}

/*
결과를 보고 싶은 사람 검사
players에 있는 사람만 입력받을 수 있도록 한다.
*/
public String inspectCommand(String[] players) throws IOException {
String command = inputView.getCommand();

if (command.equals("all") || command.equals("춘식이")) { // 모두 출력하거나 실행 종료하는 로직은 다른 클래스에 위임한다.
return command;
}
Optional<String> matchedPlayer = Arrays.stream(players).filter(p -> p.equals(command)).findFirst();
while (matchedPlayer.isEmpty()){
System.out.println(ERROR_MASSAGE_NO_PLAYER_NAME);
String newCommand = inputView.getCommand();
matchedPlayer = Arrays.stream(players).filter(p -> p.equals(newCommand)).findFirst();
}
return command;
}
}
69 changes: 41 additions & 28 deletions src/main/java/kr/ladder/domain/Ladder.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package kr.ladder.domain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Ladder {
private final List<LadderLine> ladder;
Expand All @@ -14,14 +16,15 @@ public void make(int playerNumber, int ladderHeight) {
// 1. 사다리를 만든다
makeLadderLine(playerNumber, ladderHeight);
// 2. 유효성 검사를 한다 (세로줄 공백인지 확인하고, 사다리 재입력 받음)
while (!available()){
while (!available() && ladderHeight != 1){
ladder.clear();
makeLadderLine(playerNumber, ladderHeight);
}
// 3. OutputView에 넘겨서 바로 출력 가능하게 만들어준다.
// generate();
}
private void makeLadderLine(int playerNumber, int ladderHeight){

private void makeLadderLine(int playerNumber, int ladderHeight) {
for (int i = 0; i < ladderHeight; i++) { // 행 넣기
LadderLine ladderLine = new LadderLine();
ladderLine.make(playerNumber);
Expand All @@ -30,7 +33,7 @@ private void makeLadderLine(int playerNumber, int ladderHeight){
}

private boolean available(){
int[] countBlanks = new int[ladder.size()];
int[] countBlanks = new int[ladder.get(0).size()];
for (LadderLine ladderLine : ladder){
countBlank(countBlanks, ladderLine);
}
Expand All @@ -54,37 +57,47 @@ private boolean isFilled(int[] countBlanks){
}
return true;
}

// 욕심 시작...
// private void rebuildColumn(int ladderHeight){
// int[] columnFalses = new int[ladder.size()];
// for (LadderLine ladderLine : ladder) {
// List<Boolean> booleans = ladderLine.ladderLine;
// for (int i = 0; i < booleans.size(); i++) {
// if (!booleans.get(i)){
// columnFalses[i]++;
// }
// }
// }
//
// for (int i = 0; i < columnFalses.length; i++) {
// if (columnFalses[i] == ladderHeight) {
// changeLadderColumn(i);
// }
// }
// }

// 하드 코딩해서 마지막 열에서 추가하는 것으로 생각중..
// private void changeLadderColumn(int falseIndex){
//
// }

public String generate(){
StringBuilder sb = new StringBuilder();
for (LadderLine ladderLine : ladder) {
sb.append(" "); // player name과 맞추기 위해서
sb.append(ladderLine.generate()).append("\n");
}
return sb.toString();
}

public List<Integer> play(){
List<Integer> mappingIndex = new ArrayList<>();
int playerNum = ladder.get(0).size()+1;
for (int i = 0; i < playerNum; i++) { // player 수
int nowIndex = i;
for (int j = 0; j < ladder.size(); j++) { // 사다리 높이
nowIndex += compareRight(nowIndex, playerNum, j) + compareLeft(nowIndex, j);
}
mappingIndex.add(nowIndex);
}
return mappingIndex;
}

private int compareRight(int nowIndex, int playerNum, int height) {
if (nowIndex == playerNum-1) { // 오른쪽 끝
return 0;
}
if (ladder.get(height).get(nowIndex)) { // 오른쪽 발판 있으면
return 1;
}
return 0;
}

private int compareLeft(int nowIndex, int height){
if (nowIndex == 0) { // 왼쪽 끝
return 0;
}
if (ladder.get(height).get(nowIndex-1)) { // 왼쪽 발판 있으면
return -1;
}
return 0;
}

}
52 changes: 31 additions & 21 deletions src/main/java/kr/ladder/domain/LadderGameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,37 @@
import java.io.IOException;

public class LadderGameController {
private final InputView inputView;

private final Ladder ladder;

private final OutputView outputView;
private final InputValidation validation;

public LadderGameController() {
this.inputView = new InputView();
this.ladder = new Ladder();
this.outputView = new OutputView();
this.validation = new InputValidation();
private final Ladder ladder;
private final InputValidation validation;
private final ResultRepository resultRepository;

public LadderGameController() {
this.ladder = new Ladder();
this.validation = new InputValidation();
this.resultRepository = new ResultRepository();
}

public void run() throws IOException {
// 입력
String[] players = validation.inspectPlayers();
String[] prizes = validation.inspectPrizes(players.length);
int ladderHeight = validation.inspectLadderHeight();
// 사다리 만들기
ladder.make(players.length, ladderHeight);
// 플레이어와 경품 맵핑하기
resultRepository.mapping(ladder.play(), players, prizes, ladder.generate());
// 결과를 보고 싶은 사람 입력 받기
String command = validation.inspectCommand(players);
// 출력
while (!command.equals("춘식이")) {
resultRepository.printPrize(command);
command = validation.inspectCommand(players);
}
// 종료
exit();
}

public void run() throws IOException {
// 입력
String[] players = validation.inspectPlayers(inputView.getPlayer());
int ladderHeight = validation.inspectLadderHeight(inputView.getLadderHeight());
// 사다리 만들기
ladder.make(players.length, ladderHeight);
// 출력
outputView.printPlayersAndLadder(players, ladder.generate());
}
private void exit() {
resultRepository.exit();
}
}
46 changes: 46 additions & 0 deletions src/main/java/kr/ladder/domain/ResultRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package kr.ladder.domain;

import kr.ladder.view.OutputView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ResultRepository {
private final Map<String, String> result;
private final OutputView outputView;

public ResultRepository(){
this.result = new HashMap<>();
this.outputView = new OutputView();
}

public void mapping(List<Integer> mappingIndex, String[] players, String[] prizes, String generatedLadder){
// player index, prize index
for (int i = 0; i < mappingIndex.size(); i++) {
result.put(players[i], prizes[mappingIndex.get(i)]);
}
outputView.printAll(players, generatedLadder, prizes);
}

public void printPrize(String command){
if (command.equals("all")) {
outputView.print(resultToString());
}
if (!command.equals("all")) {
outputView.print(result.get(command));
}
}

private String resultToString() {
StringBuilder sb = new StringBuilder();
for (String key : result.keySet()) {
sb.append(key).append(" : ").append(result.get(key)).append("\n");
}
return sb.toString();
}

public void exit() {
outputView.printExitMassage();
}
}
Loading