diff --git a/src/main/java/ladder/controller/LadderGame.java b/src/main/java/ladder/controller/LadderGame.java new file mode 100644 index 0000000..71c9f09 --- /dev/null +++ b/src/main/java/ladder/controller/LadderGame.java @@ -0,0 +1,30 @@ +package ladder.controller; + +import ladder.domain.*; +import ladder.view.Input; +import ladder.view.Output; + +public class LadderGame { + public static void main(String[] args) { + UsersNameReader usersNameReader = Input.getUsersName(); + Users users = usersNameReader.convertNamesToUsers(); + + ExpectingResultReader expectingResultReader = + ExpectingResultReader.newInstance(Input.getExectingResult()); + + LadderMaterial ladderMaterial = LadderMaterial.newInstance(users.getNumberOfUsers(), Input.getHeightOfLadder()); + BridgeGenerator bridgeGenerator = BridgeGenerator.newInstance(ladderMaterial); + bridgeGenerator.create(); + + WinnerDTO winnerDto = WinnerDTO.newInstance(); + winnerDto.add(users, expectingResultReader.convertToResultData(), bridgeGenerator.getBridgeStates()); + + WinningChecker winningChecker = WinningChecker.newInstance(); + Winners winners = Winners.newInstance(winningChecker.checkWinners(winnerDto)); + + Output.showUserNames(users); + Output.showResult(bridgeGenerator.getBridgeStates()); + Output.showExpecting(expectingResultReader.toString()); + Output.showWinners(winners); + } +} diff --git a/src/main/java/ladder/domain/BridgeGenerator.java b/src/main/java/ladder/domain/BridgeGenerator.java new file mode 100644 index 0000000..51833d4 --- /dev/null +++ b/src/main/java/ladder/domain/BridgeGenerator.java @@ -0,0 +1,55 @@ +package ladder.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class BridgeGenerator { + private final LadderMaterial ladderParts; + private final List bridgeStates = new ArrayList<>(); + + public BridgeGenerator(LadderMaterial ladderParts) { + this.ladderParts = ladderParts; + } + + public static BridgeGenerator newInstance(LadderMaterial ladderParts) { + return new BridgeGenerator(ladderParts); + } + + public void create() { + for (int i = 0; i < ladderParts.getHeigthOfLadder(); i += 1) { + Line line = Line.newInstance(makeRandomStates()); + bridgeStates.add(line); + } + } + + private List makeRandomStates() { + Random random = new Random(); + + List states = new ArrayList<>(); + for (int i = 0; i < ladderParts.getNumberOfUsers() - 1; i += 1) { + addState(random, states, i); + } + + return states; + } + + private void addState(Random random, List states, int index) { + if (states.size() == 0) { + states.add(random.nextInt() % 2 == 0); + return; + } + + if (!states.get(index - 1)) { + states.add(random.nextInt() % 2 == 0); + return; + } + + states.add(false); + } + + public List getBridgeStates() { + return Collections.unmodifiableList(this.bridgeStates); + } +} diff --git a/src/main/java/ladder/domain/ExpectingResultReader.java b/src/main/java/ladder/domain/ExpectingResultReader.java new file mode 100644 index 0000000..9c6dab3 --- /dev/null +++ b/src/main/java/ladder/domain/ExpectingResultReader.java @@ -0,0 +1,28 @@ +package ladder.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class ExpectingResultReader { + private final String result; + + public ExpectingResultReader(String result) { + this.result = result; + } + + public static ExpectingResultReader newInstance(String result) { + return new ExpectingResultReader(result); + } + + public List convertToResultData() { + return Arrays.stream(this.result.replaceAll("꽝", "0").split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); + } + + @Override + public String toString() { + String[] results = this.result.split(","); + + return String.join(" ", results); + } +} diff --git a/src/main/java/ladder/domain/LadderMaterial.java b/src/main/java/ladder/domain/LadderMaterial.java new file mode 100644 index 0000000..ab6a8ec --- /dev/null +++ b/src/main/java/ladder/domain/LadderMaterial.java @@ -0,0 +1,23 @@ +package ladder.domain; + +public class LadderMaterial { + private final int numberOfUsers; + private final int heigthOfLadder; + + public LadderMaterial(int numberOfUsers, int heigthOfLadder) { + this.numberOfUsers = numberOfUsers; + this.heigthOfLadder = heigthOfLadder; + } + + public static LadderMaterial newInstance(int numberOfUsers, int heigthOfLadder) { + return new LadderMaterial(numberOfUsers, heigthOfLadder); + } + + public int getNumberOfUsers() { + return this.numberOfUsers; + } + + public int getHeigthOfLadder() { + return this.heigthOfLadder; + } +} diff --git a/src/main/java/ladder/domain/Line.java b/src/main/java/ladder/domain/Line.java new file mode 100644 index 0000000..4964de3 --- /dev/null +++ b/src/main/java/ladder/domain/Line.java @@ -0,0 +1,50 @@ +package ladder.domain; + +import java.util.List; + +public class Line { + private final List bridgeStates; + + public static Line newInstance(List bridgeStates) { + return new Line(bridgeStates); + } + + public Line(List bridgeStates) { + this.bridgeStates = bridgeStates; + } + + public Boolean get(int index) { + return bridgeStates.get(index); + } + + public int size() { + return bridgeStates.size(); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + + for (Boolean state : bridgeStates) { + appendColumn(result); + appendBridge(result, state); + } + appendColumn(result); + + return " " + String.valueOf(result); + } + + private void appendColumn(StringBuilder result) { + result.append("|"); + } + + private void appendBridge(StringBuilder result, Boolean state) { + if (state) { + result.append("------"); + } + + if (!state) { + result.append(" "); + } + } +} diff --git a/src/main/java/ladder/domain/User.java b/src/main/java/ladder/domain/User.java new file mode 100644 index 0000000..9e4e54c --- /dev/null +++ b/src/main/java/ladder/domain/User.java @@ -0,0 +1,25 @@ +package ladder.domain; + +public class User { + private final String name; + private final int MAX_NUMBER_OF_CHARACTERS = 5; + + private User(String name) { + this.name = name; + } + + public static User newInstance(String name) { + return new User(name); + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + int blankCount = MAX_NUMBER_OF_CHARACTERS - name.length(); + + return " ".repeat(Math.max(0, blankCount)) + name; + } +} diff --git a/src/main/java/ladder/domain/Users.java b/src/main/java/ladder/domain/Users.java new file mode 100644 index 0000000..8f22c2e --- /dev/null +++ b/src/main/java/ladder/domain/Users.java @@ -0,0 +1,33 @@ +package ladder.domain; + +import java.util.List; + +public class Users { + private final List users; + + private Users(List users) { + this.users = users; + } + + public static Users newInstance(List users) { + return new Users(users); + } + + public User get(int index) { + return this.users.get(index); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for (User user : this.users) { + result.append(user.toString()).append(" "); + } + + return result.toString(); + } + + public int getNumberOfUsers() { + return users.size(); + } +} diff --git a/src/main/java/ladder/domain/UsersNameReader.java b/src/main/java/ladder/domain/UsersNameReader.java new file mode 100644 index 0000000..01311ea --- /dev/null +++ b/src/main/java/ladder/domain/UsersNameReader.java @@ -0,0 +1,44 @@ +package ladder.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class UsersNameReader { + private final String names; + + private UsersNameReader(String names) { + this.validator(names); + this.names = names; + } + + public static UsersNameReader newInstace(String names) { + return new UsersNameReader(names); + } + + private void validator(String names) { + Optional optNames = Optional.ofNullable(names); + if (optNames.isEmpty()) { + throw new IllegalArgumentException(); + } + + for (String name : names.split(",")) { + checkNameLength(name); + }; + } + + private void checkNameLength(String name) { + if (name.length() > 5 || name.length() < 1) { + throw new IllegalArgumentException(); + } + } + + public Users convertNamesToUsers() { + List userNames = Arrays.stream(this.names.split(",")) + .map(User::newInstance) + .collect(Collectors.toList()); + + return Users.newInstance(userNames); + } +} diff --git a/src/main/java/ladder/domain/WinnerDTO.java b/src/main/java/ladder/domain/WinnerDTO.java new file mode 100644 index 0000000..f093a10 --- /dev/null +++ b/src/main/java/ladder/domain/WinnerDTO.java @@ -0,0 +1,31 @@ +package ladder.domain; + +import java.util.List; + +public class WinnerDTO { + private Users users; + private List resultData; + private List bridgeStates; + + public static WinnerDTO newInstance() { + return new WinnerDTO(); + } + + public void add(Users users, List resultData, List bridgeStates) { + this.users = users; + this.resultData = resultData; + this.bridgeStates = bridgeStates; + } + + public Users getUsers() { + return this.users; + } + + public List getResultData() { + return this.resultData; + } + + public List getBridgeStates() { + return this.bridgeStates; + } +} diff --git a/src/main/java/ladder/domain/Winners.java b/src/main/java/ladder/domain/Winners.java new file mode 100644 index 0000000..563af32 --- /dev/null +++ b/src/main/java/ladder/domain/Winners.java @@ -0,0 +1,19 @@ +package ladder.domain; + +import java.util.Map; + +public class Winners { + private final Map winners; + + public Winners(Map winners) { + this.winners = winners; + } + + public static Winners newInstance(Map winners) { + return new Winners(winners); + } + + public Map getWinners() { + return this.winners; + } +} diff --git a/src/main/java/ladder/domain/WinningChecker.java b/src/main/java/ladder/domain/WinningChecker.java new file mode 100644 index 0000000..9f36e50 --- /dev/null +++ b/src/main/java/ladder/domain/WinningChecker.java @@ -0,0 +1,71 @@ +package ladder.domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class WinningChecker { + public static WinningChecker newInstance() { + return new WinningChecker(); + } + + public Map checkWinners(WinnerDTO dto) { + Users users = dto.getUsers(); + List resultData = dto.getResultData(); + List bridgeStates = dto.getBridgeStates(); + + int[] position = getIndexElementsArray(users); + executeLadderGameLogic(bridgeStates, position); + + return compilePosition(users, resultData, position); + } + + private Map compilePosition(Users users, List resultData, int[] position) { + Map resultPosition = new HashMap<>(); + for (int i = 0; i < position.length; i += 1) { + String userName = users.get(i).getName(); + Integer winning = resultData.get(findIndex(position, i)); + + resultPosition.put(userName, winning); + } + return resultPosition; + } + + private void executeLadderGameLogic(List bridgeStates, int[] position) { + for (Line state : bridgeStates) { + swapPositionInLine(position, state); + } + } + + private int[] getIndexElementsArray(Users users) { + int[] position = new int[users.getNumberOfUsers()]; + for (int i = 0; i < position.length; i += 1) { + position[i] = i; + } + return position; + } + + private void swapPositionInLine(int[] position, Line state) { + for (int j = 0; j < state.size(); j += 1) { + swapPosition(state, position, j); + } + } + + private void swapPosition(Line state, int[] position, int index) { + if (state.get(index)) { + int tempt = position[index]; + position[index] = position[index + 1]; + position[index + 1] = tempt; + } + } + + private int findIndex(int[] arr, int value) { + for (int i = 0; i < arr.length; i += 1) { + if (arr[i] == value) { + return i; + } + } + + return -1; + } +} diff --git a/src/main/java/ladder/view/Input.java b/src/main/java/ladder/view/Input.java new file mode 100644 index 0000000..e53bbf5 --- /dev/null +++ b/src/main/java/ladder/view/Input.java @@ -0,0 +1,28 @@ +package ladder.view; + +import ladder.domain.UsersNameReader; + +import java.util.Scanner; + +public class Input { + public static UsersNameReader getUsersName() { + System.out.println("참여할 사람의 이름을 입력하세요. 이름은 쉼표(,)로 구분합니다"); + Scanner scanner = new Scanner(System.in); + + return UsersNameReader.newInstace(scanner.nextLine()); + } + + public static String getExectingResult() { + System.out.println("실행 결과를 입력하세요. 이름은 쉼표(,)로 구분합니다"); + Scanner scanner = new Scanner(System.in); + + return scanner.nextLine(); + } + + public static int getHeightOfLadder() { + System.out.println("최대 사다리 높이는 몇 개 인가요?"); + Scanner scanner = new Scanner(System.in); + + return scanner.nextInt(); + } +} diff --git a/src/main/java/ladder/view/Output.java b/src/main/java/ladder/view/Output.java new file mode 100644 index 0000000..2696bb4 --- /dev/null +++ b/src/main/java/ladder/view/Output.java @@ -0,0 +1,31 @@ +package ladder.view; + +import ladder.domain.Line; +import ladder.domain.Users; +import ladder.domain.Winners; + +import java.util.List; + +public class Output { + public static void showUserNames(Users users) { + System.out.println(users.toString()); + } + + public static void showResult(List bridgeStates) { + bridgeStates.forEach(v -> System.out.println(v.toString())); + } + + public static void showWinners(Winners winners) { + System.out.println(""); + winners.getWinners().forEach((key, value) -> { + if (value == 0) { + System.out.printf("%s: %s\n", key, "꽝"); + } + System.out.printf("%s: %d\n", key, value); + }); + } + + public static void showExpecting(String data) { + System.out.println(data); + } +} diff --git a/src/test/java/ladder/BridgeGeneratorTest.java b/src/test/java/ladder/BridgeGeneratorTest.java new file mode 100644 index 0000000..964e250 --- /dev/null +++ b/src/test/java/ladder/BridgeGeneratorTest.java @@ -0,0 +1,19 @@ +package ladder; + +import ladder.domain.BridgeGenerator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BridgeGeneratorTest { + @Test + void add() { + int numberOfUsers = 4; + int heightOfLadder = 3; + BridgeGenerator bridgeGenerator = BridgeGenerator.newInstance(numberOfUsers, heightOfLadder); + + bridgeGenerator.create(); + + assertThat(bridgeGenerator.getBridgeStates()).hasSize(3); + } +} diff --git a/src/test/java/ladder/ExpectingResultReaderTest.java b/src/test/java/ladder/ExpectingResultReaderTest.java new file mode 100644 index 0000000..38b0ce8 --- /dev/null +++ b/src/test/java/ladder/ExpectingResultReaderTest.java @@ -0,0 +1,19 @@ +package ladder; + +import ladder.domain.ExpectingResultReader; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ExpectingResultReaderTest { + @Test + void convertToResultData() { + ExpectingResultReader reader = ExpectingResultReader.newInstance("꽝,3000,꽝,5000"); + + List resultData = List.of(0, 3000, 0, 5000); + + assertThat(reader.convertToResultData()).isEqualTo(resultData); + } +} diff --git a/src/test/java/ladder/LineTest.java b/src/test/java/ladder/LineTest.java new file mode 100644 index 0000000..185a23b --- /dev/null +++ b/src/test/java/ladder/LineTest.java @@ -0,0 +1,21 @@ +package ladder; + +import ladder.domain.Line; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LineTest { + @Test + @DisplayName("toString") + void toStringMethod() { + List bridgeStates = List.of(true, false); + + Line line = Line.newInstance(bridgeStates); + + assertThat(line.toString()).isEqualTo(" |------| |"); + } +} diff --git a/src/test/java/ladder/UserTest.java b/src/test/java/ladder/UserTest.java new file mode 100644 index 0000000..cf0aa43 --- /dev/null +++ b/src/test/java/ladder/UserTest.java @@ -0,0 +1,17 @@ +package ladder; + +import ladder.domain.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UserTest { + @Test + @DisplayName("toString") + void toStringMethod() { + User user = User.newInstance("din"); + + assertThat(user.toString()).isEqualTo(" din"); + } +} diff --git a/src/test/java/ladder/UsersNameReaderTest.java b/src/test/java/ladder/UsersNameReaderTest.java new file mode 100644 index 0000000..31ae042 --- /dev/null +++ b/src/test/java/ladder/UsersNameReaderTest.java @@ -0,0 +1,33 @@ +package ladder; + +import ladder.domain.UsersNameReader; +import ladder.domain.Users; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class UsersNameReaderTest { + @Test + void nullCheck() { + assertThatThrownBy(() -> { + UsersNameReader usersNameReader = UsersNameReader.newInstace(null); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void invalidNames() { + assertThatThrownBy(() -> { + UsersNameReader usersNameReader = UsersNameReader.newInstace("john,christina"); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void getUsers() { + UsersNameReader usersNameReader = UsersNameReader.newInstace("john,tom,jenny"); + + Users users = usersNameReader.convertNamesToUsers(); + + assertThat(users.toString()).isEqualTo(" john tom jenny "); + } +} diff --git a/src/test/java/ladder/UsersTest.java b/src/test/java/ladder/UsersTest.java new file mode 100644 index 0000000..cfe4417 --- /dev/null +++ b/src/test/java/ladder/UsersTest.java @@ -0,0 +1,28 @@ +package ladder; + +import ladder.domain.UsersNameReader; +import ladder.domain.Users; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UsersTest { + Users users; + @BeforeEach + void init() { + users = UsersNameReader.newInstace("john,james,tom,buddy,din").convertNamesToUsers(); + } + + @Test + @DisplayName("toString") + void toStringMethod() { + assertThat(users.toString()).isEqualTo(" john james tom buddy din "); + } + + @Test + void getNumberOfUsers() { + assertThat(users.getNumberOfUsers()).isEqualTo(5); + } +} diff --git a/src/test/java/ladder/WinningCheckerTest.java b/src/test/java/ladder/WinningCheckerTest.java new file mode 100644 index 0000000..53b1738 --- /dev/null +++ b/src/test/java/ladder/WinningCheckerTest.java @@ -0,0 +1,28 @@ +package ladder; + +import ladder.domain.*; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class WinningCheckerTest { + @Test + void checkWinners() { + WinningChecker winningChecker = WinningChecker.newInstance(); + + Users users = Users.newInstance(List.of( + User.newInstance("eric"), + User.newInstance("jimmy"), + User.newInstance("kim") + )); + ExpectingResultReader reader = ExpectingResultReader.newInstance("꽝,1000,2000"); + List expectingResultData = reader.convertToResultData(); + BridgeGenerator bridgeGenerator = BridgeGenerator.newInstance(3, 3); + bridgeGenerator.create(); + List bridgeStates = bridgeGenerator.getBridgeStates(); + + assertThat(winningChecker.checkWinners(users, expectingResultData, bridgeStates)).hasSize(3); + } +}