diff --git a/README.md b/README.md index 8d7e8aee..18801bd8 100644 --- a/README.md +++ b/README.md @@ -1 +1,25 @@ -# java-baseball-precourse \ No newline at end of file +## 구현 기능 + +### BaseBallApplication + +- 숫자 야구 시작 기능 + +### MajorLeague + +- 야구 게임의 전반적인 흐름 제어 기능 + +### AutomaticBallStrikeSystem + +- 볼(Strike/Ball) 판독 기능 + +### RandomBall + +- 컴퓨터의 랜덤 공 생성 기능 + +### Result + +- 판독된 볼의 리턴을 담당하는 클래스 + +### ValidBall + +- 사용자로부터 입력받은 숫자가 유효한지 확인하는 기능 diff --git a/src/main/java/AutomaticBallStrikeSystem.java b/src/main/java/AutomaticBallStrikeSystem.java new file mode 100644 index 00000000..1bc4e632 --- /dev/null +++ b/src/main/java/AutomaticBallStrikeSystem.java @@ -0,0 +1,45 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +public class AutomaticBallStrikeSystem { + + public Result determine(int number, int answer) { + int strikeCount = determineStrike(number, answer); + int ballCount = determineBall(number, answer); + return new Result(strikeCount, ballCount); + } + + private int determineStrike(int number, int answer) { + int strike = 0; + while (number > 0) { + Integer unitsOfNumber = number % 10; + Integer unitsOfAnswer = answer % 10; + if (unitsOfNumber == unitsOfAnswer) { + strike += 1; + } + number /= 10; + answer /= 10; + } + return strike; + } + + private int determineBall(Integer number, Integer answer) { + int ball = 0; + String numToStr = number.toString(); + String ansToStr = answer.toString(); + + for (int i = 0; i < numToStr.length(); i++) { + char numChar = numToStr.charAt(i); + for (int j = 0; j < ansToStr.length(); j++) { + char ansChar = ansToStr.charAt(j); + if (i != j && numChar == ansChar) { + ball += 1; + } + } + } + return ball; + } +} + diff --git a/src/main/java/BaseBallApplication.java b/src/main/java/BaseBallApplication.java new file mode 100644 index 00000000..48f94408 --- /dev/null +++ b/src/main/java/BaseBallApplication.java @@ -0,0 +1,15 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Scanner; + +public class BaseBallApplication { + + public static void main(String[] args) throws IOException { + do { + if (!MajorLeague.playBaseball()) { + break; + } + } while (true); + } +} \ No newline at end of file diff --git a/src/main/java/MajorLeague.java b/src/main/java/MajorLeague.java new file mode 100644 index 00000000..3ee17ed5 --- /dev/null +++ b/src/main/java/MajorLeague.java @@ -0,0 +1,69 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class MajorLeague { + + static boolean playBaseball() throws IOException { + + AutomaticBallStrikeSystem ABS = new AutomaticBallStrikeSystem(); + RandomBall random = new RandomBall(); + ValidBall validBall = new ValidBall(); + int number = random.makeRandomBall(); + + while (true) { + + System.out.println("숫자를 입력해 주세요 :"); + Integer answer = getUserInput(); + validBall.validate(answer); + + Result result = ABS.determine(number, answer); + + int ballCount = result.getBallCount(); + int strikeCount = result.getStrikeCount(); + referee(ballCount, strikeCount); + } + } + + private static void referee(int ballCount, int strikeCount) throws IOException { + if ((ballCount == 0) && (strikeCount == 0)) { + System.out.println("낫싱"); + } else if ((ballCount != 0) && (strikeCount != 0)) { + System.out.println("결과: " + ballCount + "볼, " + strikeCount + "스트라이크"); + } + else if (strikeCount == 3) { + decideGameEnd(); + } + } + + private static boolean decideGameEnd() throws IOException { + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + + Integer answer = getUserInput(); + if (answer == 1) { + MajorLeague.playBaseball(); + } + if (answer == 2) { + return false; + } + handleInvalidInput(); + return decideGameEnd(); + } + + + private static Integer getUserInput() throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + Integer answer = Integer.parseInt(br.readLine()); + return answer; + } + + + private static void handleInvalidInput() { + System.out.println("잘못된 입력입니다. 다시 시도하세요."); + } + +} \ No newline at end of file diff --git a/src/main/java/RandomBall.java b/src/main/java/RandomBall.java new file mode 100644 index 00000000..1d307df5 --- /dev/null +++ b/src/main/java/RandomBall.java @@ -0,0 +1,25 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class RandomBall { + + public int makeRandomBall() { + List numbers = new ArrayList<>(); + + for (int i = 1; i <= 9; i++) { + numbers.add(i); + } + + Collections.shuffle(numbers); + StringBuilder randomNumberBuilder = new StringBuilder(); + + for (int i = 0; i < 3; i++) { + randomNumberBuilder.append(numbers.get(i)); + } + + int randomNumber = Integer.parseInt(randomNumberBuilder.toString()); + + return randomNumber; + } +} diff --git a/src/main/java/Result.java b/src/main/java/Result.java new file mode 100644 index 00000000..806bfdd6 --- /dev/null +++ b/src/main/java/Result.java @@ -0,0 +1,17 @@ +public class Result { + private Integer strikeCount; + private Integer ballCount; + + public Result(Integer strikeCount, Integer ballCount) { + this.strikeCount = strikeCount; + this.ballCount = ballCount; + } + + public Integer getStrikeCount() { + return strikeCount; + } + + public Integer getBallCount() { + return ballCount; + } +} diff --git a/src/main/java/ValidBall.java b/src/main/java/ValidBall.java new file mode 100644 index 00000000..f2577805 --- /dev/null +++ b/src/main/java/ValidBall.java @@ -0,0 +1,26 @@ +import java.util.HashSet; + +public class ValidBall { + + public void validate(int answer) { + validateRange(answer); + validateDuplication(answer); + } + + private void validateDuplication(int answer) { + HashSet set = new HashSet<>(); + while (answer > 0) { + int digit = answer % 10; + if (!set.add(digit)) { + throw new IllegalArgumentException("입력된 숫자 중 중복되는 숫자가 있습니다."); + } + answer /= 10; + } + } + + private void validateRange(int number) { + if ((number < 111) || (number > 999)) { + throw new IllegalArgumentException("잘못된 범위의 입력입니다"); + } + } +}