diff --git a/docs/README.md b/docs/README.md index e69de29bb2..c885035b2b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,56 @@ +# ๐Ÿ“์„ค๊ณ„ ๊ตฌ์กฐ +- Application : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์„ ๊ด€๋ฆฌํ•œ๋‹ค. +- MainController : ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๋ฐ ์ค‘๊ณ„ ์—ญํ• ์„ ํ•œ๋‹ค. +- view + - InputView : ์ž…๋ ฅ๊ณผ ๊ด€๋ จ๋œ ์ฑ…์ž„ ๊ด€๋ฆฌํ•œ๋‹ค. + - OutputView : ์ถœ๋ ฅ๊ณผ ๊ด€๋ จ๋œ ์ฑ…์ž„ ๊ด€๋ฆฌํ•œ๋‹ค. +- message + - ErrorMessage : ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. + - ViewMessage : ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. +- domain + - Computer : List๋ฅผ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ๊ฐ–๋Š”๋‹ค + - User : List๋ฅผ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ๊ฐ–๋Š”๋‹ค + - Numbers : List๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ผ๊ธ‰ ์ปฌ๋ ‰์…˜ +# ๐Ÿ’ช ํ”„๋กœ์ ํŠธ ๊ฐœ์š” +์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„์„ ๊ตฌํ˜„ํ•œ๋‹ค.
+์„œ๋กœ ๋‹ค๋ฅธ 3์ž๋ฆฌ์˜ ์ˆ˜๋ฅผ ๋งž์ถฐ์•ผํ•œ๋‹ค. ์‹คํŒจ์‹œ ํžŒํŠธ๊ฐ€ ๋‚˜์˜จ๋‹ค. +๊ฒŒ์ž„๋๋‚œ๊ฒฝ์šฐ ์žฌ์‹œ์ž‘ or ์ข…๋ฃŒ๋ฅผ 1,2 ๋ฅผ ์„ ํƒํ• ์ˆ˜์žˆ๋‹ค. + +# ๐Ÿ“ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก +### ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™” + +- [x] ๋žœ๋คํ•œ 3์ž๋ฆฌ ์ˆซ์ž ์ƒ์„ฑ๊ฐ€๋ˆ™ + +- [x] ์‚ฌ์šฉ์ž ์ž…๋ ฅ๋ฐ›๊ธฐ +- [x] `์ถœ๋ ฅ ๋ฌธ๊ตฌ` : "์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š” : " + - [x] ์„œ๋กœ ๋‹ค๋ฅธ 3์ž๋ฆฌ์ˆ˜ ์ž…๋ ฅ๋ฐ›๊ธฐ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ๋นˆ ๋ฌธ์ž์—ด ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : 3์ž๋ฆฌ ์ดˆ๊ณผ ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ์ˆซ์ž์™ธ ๋ฌธ์ž ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ์Œ์ˆ˜ ์ž…๋ ฅ ๊ฒ€์ฆ + - [x] `์˜ˆ์™ธ์ฒ˜๋ฆฌ` : ์ค‘๋ณต๋˜๋Š” ์ˆซ์ž ๊ฒ€์ฆ + + +### ๊ฒŒ์ž„ ์ง„ํ–‰ +- [x] ๊ฒŒ์ž„์‹œ์ž‘ ๋ฌธ๊ตฌ ์ถœ๋ ฅ + - [x] `์ถœ๋ ฅ๋ฌธ๊ตฌ' : "์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค." + +- [x] ๋งค ์‹คํ–‰๊ฒฐ๊ณผ ์ถœ๋ ฅ ํ•œ๋‹ค. + + +- [x] ๊ฒŒ์ž„ ๊ธฐ๋Šฅ +- [x] ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ๊ณผ ์ปดํ“จํ„ฐ ์ž…๋ ฅ ์ˆซ์ž ๋น„๊ต + - [x] ๊ฐ™์€ ์ˆ˜๊ฐ€ ๊ฐ™์€ ์ž๋ฆฌ์— ์žˆ์œผ๋ฉด ์ŠคํŠธ๋ผ์ดํฌ + - [x] ๋‹ค๋ฅธ ์ž๋ฆฌ์— ์žˆ์œผ๋ฉด ๋ณผ + - [x] ๊ฐ™์€ ์ˆ˜๊ฐ€ ์ „ํ˜€ ์—†์œผ๋ฉด ๋‚ซ์‹ฑ + - [x] ์‹คํŒจ์‹œ ํžŒํŠธ ์ œ๊ณต + + + + +### ๊ฒŒ์ž„ ์ข…๋ฃŒ +- [x] `์ถœ๋ ฅ๋ฌธ๊ตฌ` : 3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋งžํžˆ์…จ์Šต๋‹ˆ๋‹ค! ๊ฒŒ์ž„ ์ข…๋ฃŒ + ๊ฒŒ์ž„์„ ์ƒˆ๋กœ ์‹œ์ž‘ํ•˜๋ ค๋ฉด 1, ์ข…๋ฃŒํ•˜๋ ค๋ฉด 2๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”. + +- [x] ์žฌ์‹œ์ž‘ ๊ธฐ๋Šฅ + - [ ] 1 ๋˜๋Š” 2 ์ด์™ธ์˜ ๊ฐ’์ž…๋ ฅ์‹œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index dd95a34214..24efa5c057 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -2,6 +2,7 @@ public class Application { public static void main(String[] args) { - // TODO: ํ”„๋กœ๊ทธ๋žจ ๊ตฌํ˜„ + MainController controller = new MainController(); + controller.run(); } } diff --git a/src/main/java/baseball/MainController.java b/src/main/java/baseball/MainController.java new file mode 100644 index 0000000000..0ff820a9cd --- /dev/null +++ b/src/main/java/baseball/MainController.java @@ -0,0 +1,114 @@ +package baseball; + +import baseball.domain.Computer; +import baseball.domain.Numbers; +import baseball.domain.User; +import baseball.view.OutputView; +import camp.nextstep.edu.missionutils.Console; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MainController { + public void run() { + Computer computerNumbers = gameInit(); + gameProceed(computerNumbers); + askForRestart(computerNumbers); + } + + + private static void gameProceed(Computer computerNumbers) { + boolean isCorrect; + do { + User userNumbers = new User(readUserNumbers()); + isCorrect = computerNumbers.compareNumbers(userNumbers); + } while (!isCorrect); + + + } + + + private static Computer gameInit() { + Computer computerNumbers = new Computer(Numbers.createRandomNumber()); + System.out.println("์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค."); + return computerNumbers; + } + private static void askForRestart(Computer computerNumbers) { + System.out.println("๊ฒŒ์ž„์„ ์ƒˆ๋กœ ์‹œ์ž‘ํ•˜๋ ค๋ฉด 1, ์ข…๋ฃŒํ•˜๋ ค๋ฉด 2๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”."); + String input = Console.readLine(); + + if (input.equals("1")) { + computerNumbers.resetNumbers(); + gameProceed(computerNumbers); + } + if (input.equals("2")) { + System.out.println("๊ฒŒ์ž„ ์ข…๋ฃŒ"); + } + } + + + private static Numbers readUserNumbers() { + System.out.printf("์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š” : "); + String userInput = Console.readLine(); + + validateisPositiveInteger(userInput); + + validateStringBlank(userInput); + validateStringLegnth(userInput); + validateDuplicatedInput(userInput); + + return readStringToNumbers(userInput); + } + + private static Numbers readStringToNumbers(String userInput) { + List userNumbers = new ArrayList<>(); + + for (int i = 0; i < userInput.length(); i++) { + int number = Integer.parseInt(String.valueOf(userInput.charAt(i))); + userNumbers.add(number); + } + return new Numbers(userNumbers); + } + + private static void validateisPositiveInteger(String userInput) { + // ๋ฌธ์ž์—ด์ด ์ •ํ™•ํžˆ 3์ž์—ฌ์•ผ ํ•จ์„ ํ™•์ธ + if (userInput.length() != 3) { + throw new IllegalArgumentException("์ž…๋ ฅ์€ ๋ฐ˜๋“œ์‹œ 3๊ฐœ๋ฅผ ์ดˆ๊ณผํ• ์ˆ˜์—†์Šต๋‹ˆ๋‹ค."); + } + + // ๋ฌธ์ž์—ด์˜ ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ '1'์—์„œ '9' ์‚ฌ์ด์˜ ์ˆซ์ž์ธ์ง€ ํ™•์ธ + for (char c : userInput.toCharArray()) { + if (c < '1' || c > '9') { + throw new IllegalArgumentException("๋ฌธ์ž์—ด์€ 1๋ถ€ํ„ฐ 9๊นŒ์ง€์˜ ์ˆซ์ž๋งŒ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + } + } + + private static void validateDuplicatedInput(String userInput) { + Set uniqueChar = new HashSet<>(); + for (int i = 0; i < userInput.length(); i++) { + char currentChar = userInput.charAt(i); + + if (uniqueChar.contains(currentChar)) { + throw new IllegalArgumentException("์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."); + } + uniqueChar.add(currentChar); + } + + } + + private static void validateStringBlank(String userInput) { + if (userInput.isBlank()) { + throw new IllegalArgumentException("๋นˆ๊ฐ’์€ ์ž…๋ ฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + } + } + + private static void validateStringLegnth(String userInput) { + if (userInput.length() != 3) { + throw new IllegalArgumentException("์ž…๋ ฅ์€ ๋ฐ˜๋“œ์‹œ 3๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + } + + +} diff --git a/src/main/java/baseball/domain/Computer.java b/src/main/java/baseball/domain/Computer.java new file mode 100644 index 0000000000..038878ec20 --- /dev/null +++ b/src/main/java/baseball/domain/Computer.java @@ -0,0 +1,48 @@ +package baseball.domain; + +import baseball.view.OutputView; +import camp.nextstep.edu.missionutils.Console; +import java.util.List; + +public class Computer { + + private static Numbers computerNumbers; + + public Computer(Numbers computerNumbers) { + Computer.computerNumbers = computerNumbers; + } + + public List getComputerNumbers() { + return computerNumbers.getNumbers(); + } + + public static boolean compareNumbers(User userNumbers) { + List computerNumberList = computerNumbers.getNumbers(); + List userNumberList = userNumbers.getUserNumbers(); + + int strikes = 0; + int balls = 0; + boolean result = false; + + //์ŠคํŠธ๋ผ์ดํฌ, ๋ณผ ์ฒดํฌ๋กœ์ง + for (int i = 0; i < userNumberList.size(); i++) { + int userNumber = userNumberList.get(i); + + if (computerNumberList.contains(userNumber) && computerNumberList.indexOf(userNumber) != i) { + balls++; // ๊ฐ’์€ ์ผ์น˜ํ•˜์ง€๋งŒ ์œ„์น˜๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ณผ + } + if (userNumberList.get(i) == computerNumberList.get(i)) { + strikes++; // ๊ฐ’๊ณผ ์œ„์น˜๊ฐ€ ๋ชจ๋‘ ์ผ์น˜ํ•˜๋ฉด ์ŠคํŠธ๋ผ์ดํฌ + } + } + if (strikes == 3){ + result = true; + } + OutputView.printGameResult(strikes,balls); + return result; + } + + public void resetNumbers() { + computerNumbers =Numbers.createRandomNumber(); + } +} diff --git a/src/main/java/baseball/domain/Numbers.java b/src/main/java/baseball/domain/Numbers.java new file mode 100644 index 0000000000..ca159662fd --- /dev/null +++ b/src/main/java/baseball/domain/Numbers.java @@ -0,0 +1,25 @@ +package baseball.domain; + +import camp.nextstep.edu.missionutils.Randoms; +import java.util.ArrayList; +import java.util.List; + +public record Numbers(List numbers) { + public List getNumbers() { + return numbers; + } + public static Numbers createRandomNumber() { + List numbers = new ArrayList<>(); + + while (true) { + int randomNumber = Randoms.pickNumberInRange(1, 9); + if (!numbers.contains(randomNumber)) { + numbers.add(randomNumber); + } + if (numbers.size() == 3) { + break; + } + } + return new Numbers(numbers); + } +} diff --git a/src/main/java/baseball/domain/User.java b/src/main/java/baseball/domain/User.java new file mode 100644 index 0000000000..5636287b87 --- /dev/null +++ b/src/main/java/baseball/domain/User.java @@ -0,0 +1,14 @@ +package baseball.domain; + +import java.util.List; + +public class User { + private final Numbers userNumbers; + + public User(Numbers userNumbers) { + this.userNumbers = userNumbers; + } + public List getUserNumbers() { + return userNumbers.getNumbers(); + } +} diff --git a/src/main/java/baseball/message/ErrorMessage.java b/src/main/java/baseball/message/ErrorMessage.java new file mode 100644 index 0000000000..3550e329d4 --- /dev/null +++ b/src/main/java/baseball/message/ErrorMessage.java @@ -0,0 +1,4 @@ +package baseball.message; + +public enum ErrorMessage { +} diff --git a/src/main/java/baseball/message/ViewMessage.java b/src/main/java/baseball/message/ViewMessage.java new file mode 100644 index 0000000000..fd8da8c207 --- /dev/null +++ b/src/main/java/baseball/message/ViewMessage.java @@ -0,0 +1,4 @@ +package baseball.message; + +public enum ViewMessage { +} diff --git a/src/main/java/baseball/view/InputView.java b/src/main/java/baseball/view/InputView.java new file mode 100644 index 0000000000..6474b6e42b --- /dev/null +++ b/src/main/java/baseball/view/InputView.java @@ -0,0 +1,4 @@ +package baseball.view; + +public class InputView { +} diff --git a/src/main/java/baseball/view/OutputView.java b/src/main/java/baseball/view/OutputView.java new file mode 100644 index 0000000000..13a1df5ee1 --- /dev/null +++ b/src/main/java/baseball/view/OutputView.java @@ -0,0 +1,26 @@ +package baseball.view; + +import baseball.domain.Computer; + +public class OutputView { + + + public static void printGameResult(int strikes, int balls) { + if (strikes == 3) { + System.out.println("3์ŠคํŠธ๋ผ์ดํฌ"); + System.out.println("3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋งžํžˆ์…จ์Šต๋‹ˆ๋‹ค! ๊ฒŒ์ž„ ์ข…๋ฃŒ"); + } + if (strikes == 0 && balls == 0) { + System.out.println("๋‚ซ์‹ฑ"); + } + if (balls !=0 && strikes ==0 ) { + System.out.println(balls+"๋ณผ"); + } + if (balls ==0 && strikes !=0 ) { + System.out.println(strikes+"์ŠคํŠธ๋ผ์ดํฌ"); + } + if (balls != 0 && strikes != 0) { + System.out.println(balls +"๋ณผ "+ strikes + "์ŠคํŠธ๋ผ์ดํฌ"); + } + } +} diff --git a/src/test/java/baseball/domain/ComputerTest.java b/src/test/java/baseball/domain/ComputerTest.java new file mode 100644 index 0000000000..f1453f589d --- /dev/null +++ b/src/test/java/baseball/domain/ComputerTest.java @@ -0,0 +1,57 @@ +package baseball.domain; + +import static baseball.domain.Computer.compareNumbers; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +class ComputerTest { + private static Computer computerNumbers; + private static User user; + + @BeforeEach + void setUp() { + // ์˜ˆ์‹œ๋กœ ์ปดํ“จํ„ฐ๊ฐ€ ์„ ํƒํ•œ 3์ž๋ฆฌ ์ˆซ์ž๋ฅผ ์„ค์ • + computerNumbers = new Computer(new Numbers(Arrays.asList(1, 2, 3))); + } + + @Test + @DisplayName("3 ์ŠคํŠธ๋ผ์ดํฌ ํ…Œ์ŠคํŠธ") + void compareNumbersIsTrueTest() { + user = new User(new Numbers(Arrays.asList(1, 2, 3))); + assertTrue(compareNumbers(user)); + } + + + @DisplayName("3๋ณผ, ์ŠคํŠธ๋ผ์ดํฌ,๋ณผ ํ˜ผํ•ฉ, ์ „ํ˜€๋‹ค๋ฅธ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ") + @ParameterizedTest + @MethodSource("provideUserNumbers") + void compareNumbersIsFalseTest() { + user = new User(new Numbers(Arrays.asList(3, 1, 2))); + assertFalse(compareNumbers(user)); + } + static Stream> provideUserNumbers() { + return Stream.of( + Arrays.asList(3, 1, 2), // 3 ๋ณผ + Arrays.asList(1, 3, 2), // 2 ์ŠคํŠธ๋ผ์ดํฌ, 1 ๋ณผ + Arrays.asList(4, 5, 6) // ์ „ํ˜€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ. + ); + } + + + + + @Test + @Disabled + void resetNumbers() { + } +} \ No newline at end of file diff --git a/src/test/java/baseball/domain/NumbersTest.java b/src/test/java/baseball/domain/NumbersTest.java new file mode 100644 index 0000000000..b4b0d95204 --- /dev/null +++ b/src/test/java/baseball/domain/NumbersTest.java @@ -0,0 +1,50 @@ +package baseball.domain; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import javax.swing.JMenuBar; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class NumbersTest { + private Numbers randomNumbers; + + @BeforeEach + void setUpRandomNumbers() { + randomNumbers = Numbers.createRandomNumber(); + } + + @Test + @DisplayName("3์ž๋ฆฌ ๋‚œ์ˆ˜ ์ƒ์„ฑ ์„ฑ๊ณต ํ…Œ์ŠคํŠธ") + void createRandomNumberSuccess() { + //given + //when + //then + assertThat(randomNumbers).isNotNull(); + } + @Test + @DisplayName("์ƒ์„ฑ๋œ ๋‚œ์ˆ˜๊ฐ€ 3์ž๋ฆฌ์ˆ˜์ธ์ง€ ํ™•์ธ") + void createRandomNumber_ThreeDigits() { + //given + //when + List numbers = randomNumbers.getNumbers(); + //then + assertThat(numbers).hasSize(3); + } + @Test + @DisplayName("์ƒ์„ฑ๋œ ๋‚œ์ˆ˜์— ์ค‘๋ณต๋œ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธ") + void createRandomNumber_NoDuplicates() { + //given + //when + List numbers = randomNumbers.getNumbers(); + //then + assertThat(numbers).doesNotHaveDuplicates(); // ์ˆซ์ž๊ฐ€ ์ค‘๋ณต๋˜์ง€ ์•Š๊ณ  ๋ชจ๋‘ ๋‹ค๋ฅธ์ง€ ํ™•์ธ + } + +} \ No newline at end of file