diff --git a/build.gradle b/build.gradle index 8172fb73f..78d53d073 100644 --- a/build.gradle +++ b/build.gradle @@ -17,3 +17,7 @@ dependencies { test { useJUnitPlatform() } + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} \ No newline at end of file diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 000000000..8d8d9638f --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,43 @@ +import baseball.Balls; +import baseball.MapComputerInput; +import baseball.PlayResult; + +import java.util.*; +import java.util.stream.Collectors; + +public class Main { + + public static void main(String[] args) { + + // 정답 + List input_com = new MapComputerInput().mapComputerInput(); + + while (true) { + + Balls balls = new Balls(input_com); + + Scanner sc = new Scanner(System.in); + System.out.println("숫자를 입력해주세요: "); + + List input_user = Arrays.stream(sc.nextLine().split("")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + + // 게임 + PlayResult result = balls.play(input_user); + System.out.println(result.toString()); + + if (result.isGameEnd()) { + System.out.println("3개의 숫자를 모두 맞히셨습니다.! 게임 종료\n게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + + if (!balls.again(sc.nextInt())) { + break; + } + + input_com = new MapComputerInput().mapComputerInput(); + } + } + } +} + + diff --git a/src/main/java/baseball/Ball.java b/src/main/java/baseball/Ball.java new file mode 100644 index 000000000..a4603eadc --- /dev/null +++ b/src/main/java/baseball/Ball.java @@ -0,0 +1,49 @@ +package baseball; + +import java.util.Objects; + +public class Ball { + + + private final int position; + private final int no; + + public Ball(int position, int no) throws IllegalArgumentException { + if (!ValidationUtils.ValidNo(no)) { + throw new IllegalArgumentException("1 ~ 9 사이의 숫자를 입력하세요."); + } + + this.position = position; + this.no = no; + } + + public BallStatus play(Ball ball) { + + if (this.equals(ball)) { + return BallStatus.STRIKE; + } + + if (this.isMatchNo(ball.no)) { + return BallStatus.BALL; + } + + return BallStatus.NOTHING; + } + + private boolean isMatchNo(int no) { + return this.no == no; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Ball ball = (Ball) o; + return position == ball.position && no == ball.no; + } + + @Override + public int hashCode() { + return Objects.hash(position, no); + } +} diff --git a/src/main/java/baseball/BallStatus.java b/src/main/java/baseball/BallStatus.java new file mode 100644 index 000000000..042f88e40 --- /dev/null +++ b/src/main/java/baseball/BallStatus.java @@ -0,0 +1,5 @@ +package baseball; + +public enum BallStatus { + BALL, STRIKE, NOTHING +} diff --git a/src/main/java/baseball/Balls.java b/src/main/java/baseball/Balls.java new file mode 100644 index 000000000..729f1817f --- /dev/null +++ b/src/main/java/baseball/Balls.java @@ -0,0 +1,58 @@ +package baseball; + +import java.util.ArrayList; +import java.util.List; + +public class Balls { + + private static final int PLAY_AGAIN = 1; + + private final List answers; + + public Balls(List answers) { + if (!ValidationUtils.ValidNoList(answers)) { + throw new IllegalArgumentException("입력한 수를 다시 확인해 주세요."); + } + + this.answers = mapBall(answers); + } + + private static List mapBall(List answers) { + List balls = new ArrayList<>(); + for (int i = 0; i < answers.size(); i++) { + balls.add(new Ball(i + 1, answers.get(i))); + } + + return balls; + } + + + public PlayResult play(List balls) { + Balls userBalls = new Balls(balls); + + PlayResult result = new PlayResult(); + for (Ball answer : answers) { + BallStatus status = userBalls.play(answer); + + result.report(status); + } + + return result; + } + + public BallStatus play(Ball userBall) { + return answers.stream() + .map(answer -> answer.play(userBall)) + .filter(status -> status != BallStatus.NOTHING) + .findFirst() + .orElse(BallStatus.NOTHING); + } + + public boolean again(int input) { + if (input == PLAY_AGAIN) { + return true; + } + + return false; + } +} diff --git a/src/main/java/baseball/MapComputerInput.java b/src/main/java/baseball/MapComputerInput.java new file mode 100644 index 000000000..013955e90 --- /dev/null +++ b/src/main/java/baseball/MapComputerInput.java @@ -0,0 +1,23 @@ +package baseball; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class MapComputerInput { + + public List mapComputerInput() { + + List digits = new ArrayList<>(); + for (int i = 1; i <= 9; i++) digits.add(i); + Collections.shuffle(digits); + + int number = digits.get(0) * 100 + digits.get(1) * 10 + digits.get(2); + + return Arrays.stream(String.valueOf(number).split("")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/baseball/PlayResult.java b/src/main/java/baseball/PlayResult.java new file mode 100644 index 000000000..13a967051 --- /dev/null +++ b/src/main/java/baseball/PlayResult.java @@ -0,0 +1,48 @@ +package baseball; + +public class PlayResult { + + private int strike = 0; + + private int ball = 0; + + public int getStrike() { + return this.strike; + } + + public int getBall() { + return this.ball; + } + + public void report(BallStatus status) { + if (status.equals(BallStatus.STRIKE)) { + this.strike += 1; + } + + if (status.equals(BallStatus.BALL)) { + this.ball += 1; + } + } + + public boolean isGameEnd() { + return this.strike == 3; + } + + @Override + public String toString() { + + if (this.ball > 0 && this.strike > 0) { + return ball + "볼 " + strike + "스트라이크"; + } + + if (this.ball > 0) { + return ball + "볼"; + } + + if (this.strike > 0) { + return strike + "스트라이크"; + } + + return "낫싱"; + } +} diff --git a/src/main/java/baseball/ValidationUtils.java b/src/main/java/baseball/ValidationUtils.java new file mode 100644 index 000000000..28a717c74 --- /dev/null +++ b/src/main/java/baseball/ValidationUtils.java @@ -0,0 +1,23 @@ +package baseball; + +import java.util.List; + +public class ValidationUtils { + + private static final int MIN_NO = 0; + + private static final int MAX_NO = 10; + + public static boolean ValidNo(int no) { + return no > MIN_NO && no < MAX_NO; + } + + public static boolean ValidNoList(List answerNoList) { + + if (answerNoList.size() != 3) { + return false; + } + + return true; + } +} diff --git a/src/test/java/baseball/ValidationUtilsTest.java b/src/test/java/baseball/ValidationUtilsTest.java new file mode 100644 index 000000000..15c52cbd6 --- /dev/null +++ b/src/test/java/baseball/ValidationUtilsTest.java @@ -0,0 +1,16 @@ +package baseball; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class ValidationUtilsTest { + + @Test + void 야구_숫자_1_9_검증() { + + Assertions.assertTrue(ValidationUtils.ValidNo(9)); + Assertions.assertTrue(ValidationUtils.ValidNo(1)); + Assertions.assertFalse(ValidationUtils.ValidNo(0)); + Assertions.assertFalse(ValidationUtils.ValidNo(10)); + } +} \ No newline at end of file diff --git a/src/test/java/baseball/ballTest.java b/src/test/java/baseball/ballTest.java new file mode 100644 index 000000000..58f2ba157 --- /dev/null +++ b/src/test/java/baseball/ballTest.java @@ -0,0 +1,37 @@ +package baseball; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ballTest { + + private Ball input_com; + + @BeforeEach + void setUp() { + input_com = new Ball(1, 4); + } + + @Test + void strike() { + Assertions.assertEquals(input_com.play(new Ball(1, 4)), BallStatus.STRIKE); + } + + @Test + void ball() { + Assertions.assertEquals(input_com.play(new Ball(2, 4)), BallStatus.BALL); + } + + @Test + void nothing() { + Assertions.assertEquals(input_com.play(new Ball(3, 6)), BallStatus.NOTHING); + } + + @Test + void error() { + org.assertj.core.api.Assertions.assertThatThrownBy(() -> input_com.play(new Ball(3, 10))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("1 ~ 9 사이의 숫자를 입력하세요."); + } +} diff --git a/src/test/java/baseball/ballsTest.java b/src/test/java/baseball/ballsTest.java new file mode 100644 index 000000000..c3139e963 --- /dev/null +++ b/src/test/java/baseball/ballsTest.java @@ -0,0 +1,62 @@ +package baseball; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +public class ballsTest { + + + private Balls answer; + + @BeforeEach + void setUp() { + answer = new Balls(Arrays.asList(1, 2, 3)); + + } + + @Test + void 세자리수_3_strike() { + + PlayResult result = answer.play(Arrays.asList(1, 2, 3)); + + Assertions.assertEquals(result.getStrike(), 3); + Assertions.assertEquals(result.getBall(), 0); + Assertions.assertTrue(result.isGameEnd()); + } + + @Test + void 세자리수_1_strike_1_ball() { + + PlayResult result = answer.play(Arrays.asList(1, 4, 2)); + + Assertions.assertEquals(result.getStrike(), 1); + Assertions.assertEquals(result.getBall(), 1); + } + + @Test + void 세자리수_nothing() { + + PlayResult result = answer.play(Arrays.asList(4, 5, 6)); + + Assertions.assertEquals(result.getStrike(), 0); + Assertions.assertEquals(result.getBall(), 0); + } + + @Test + void strike() { + Assertions.assertEquals(answer.play(new Ball(1, 1)), BallStatus.STRIKE); + } + + @Test + void ball() { + Assertions.assertEquals(answer.play(new Ball(1, 3)), BallStatus.BALL); + } + + @Test + void nothing() { + Assertions.assertEquals(answer.play(new Ball(1, 4)), BallStatus.NOTHING); + } +}