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

[부산대 BE_김상해] 미션 제출합니다. #146

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6ebb013
docs: create README.md($Project):
gobad820 Apr 29, 2024
27a3cf9
feat(Application): add function that make computer's number randomly
gobad820 Apr 29, 2024
2b1b6b0
fix(NumberGenerating):
gobad820 Apr 29, 2024
d4d96db
feat(NumberGenerating): create user input function
gobad820 Apr 29, 2024
d3b7080
feat(BaseballStatus): create Status
gobad820 Apr 29, 2024
e605817
fix(NumberGenerating): fix the number is generated not duplicately
gobad820 Apr 30, 2024
b877641
feat(Entity): Add user class
gobad820 May 2, 2024
8a5ad5b
feat(Entity): Add player abstract class
gobad820 May 2, 2024
4faa84e
fix(NumberGenerating): fix the number is generated not duplicately
gobad820 May 2, 2024
546acb2
feat(Entity): Add computer class
gobad820 May 2, 2024
5e7a4ff
feat(main): Add number baseballgame class
gobad820 May 2, 2024
39a97a7
feat(main): Add execution of number baseball game
gobad820 May 2, 2024
1d72cf5
fix($Project): Delete these files
gobad820 May 2, 2024
739985f
test: Add testSetUserNum
gobad820 May 5, 2024
781e693
test: Add testComputerNumbers
gobad820 May 5, 2024
f39a2a3
test: Add number generating test
gobad820 May 5, 2024
0204760
test(ScoreControllerTest): Add baseBallCount score test
gobad820 May 5, 2024
a12c112
chore(Entity): Delete these files
gobad820 May 5, 2024
e74a0c3
feat(view): Create user interface class
gobad820 May 5, 2024
ac94f34
feat: Add baseballcount score compare methods
gobad820 May 5, 2024
7dc18e7
feat: Add converting to string methods
gobad820 May 5, 2024
de0859a
feat: Add number generating methods
gobad820 May 5, 2024
7fd471e
fix: scanner bug
gobad820 May 5, 2024
1d2b433
feat: Add GameController
gobad820 May 5, 2024
a522351
chore: Delete these files
gobad820 May 5, 2024
2793f47
chore: Delete these files
gobad820 May 5, 2024
2d5f50c
feat: Add ballcount status
gobad820 May 5, 2024
dfb91fb
refactor: devide userinterface
gobad820 May 5, 2024
ce005bb
feat: Add computer player class
gobad820 May 5, 2024
2f20a2f
feat: Add user player class
gobad820 May 5, 2024
70903f6
feat: Add readme file
gobad820 May 6, 2024
5559b7f
fix: prevent input of number greater than 9
gobad820 May 6, 2024
1e6de96
fix: prevent input of number greater than 9 not 10
gobad820 May 6, 2024
c34e814
chore: Delete these files
gobad820 May 6, 2024
afdde70
feat: Add input test when the input number is greater than 9
gobad820 May 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,75 @@
# java-baseball-precourse
# java-baseball-precourse
## 기능 목록

- 사용자로부터 3개의 숫자 입력 받기
- 컴퓨터 플레이어의 경우 1~9까지의 중복되지 않은 랜덤 숫자 생성
- 사용자와 컴퓨터의 숫자 비교 하여 볼과 스트라이크 판단
- 반복하여 사용자의 입력을 받아 스트라이크와 볼 비교
- 자리와 숫자까지 맞으면 스트라이크
- 숫자만 맞으면 볼
- 아무것도 맞지 않으면 낫싱
- 3스트라이크면 게임 종료하기
- 숫자는 3대만 들어오게 함
- 숫자는 10이상의 숫자는 들어오지 않게 함

## 과제 요구 사항

* 미션은 숫자 야구 저장소를 포크하고 클론하는 것으로 시작한다.
* 기능을 구현하기 전 README.md 에 구현할 기능 목록을 정리해 추가한다.
* Git의 커밋 단위는 앞 단계에서 README.md 에 정리한 기능 목록 단위로 추가한다.
* AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성한다.

## 기능 요구 사항

* 기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다#
* 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.
```textmate
* e.g.
* 상대방(컴퓨터)의 수가 425일 때,
* 123을 제시한 경우: 1스트라이크
* 456을 제시한 경우: 1볼 1스트라이크
* 789를 제시한 경우: 낫싱
* ```
위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는
3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.
이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.
게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.
사용자가 잘못된 값을 입력할 경우 IllegalArgumentException 을 발생시킨 후 애플리케이션은 종료되어야 한다.

## 실행 결과

숫자를 입력해 주세요 : 123
1볼 1스트라이크
숫자를 입력해 주세요 : 145
1볼
숫자를 입력해 주세요 : 671
2볼
숫자를 입력해 주세요 : 216
1스트라이크
숫자를 입력해 주세요 : 713
3스트라이크
3개의 숫자를 모두 맞히셨습니다! 게임 종료
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1
숫자를 입력해 주세요 : 123
1볼

## 프로그래밍 요구 사항 1

JDK 17 버전에서 실행 가능해야 한다.
프로그램 실행의 시작점은 Application 의 main() 이다.
build.gradle 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.
프로그램 종료 시 System.exit() 를 호출하지 않는다.
프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다.

## 프로그래밍 요구 사항 2

자바 코드 컨벤션을 지키면서 프로그래밍한다.
기본적으로 Google Java Style Guide을 원칙으로 한다.
단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다.
indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
3항 연산자를 쓰지 않는다.
함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
21 changes: 21 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import model.Computer;
import model.User;
import controller.GameController;
import view.UserInterface;

public class Application {

public static void main(String[] args) {
User user = new User();
Computer computer = new Computer();

UserInterface userInterface = new UserInterface();
GameController gameController = new GameController(user, computer);

UserInterface.printStartingGame();
gameController.startGame();
UserInterface.printEndingGame();

userInterface.closeScanner();
}
}
43 changes: 43 additions & 0 deletions src/main/java/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package controller;

import model.BallCountStatus;
import model.Computer;
import model.User;

import java.util.*;

public class GameController {
private User user;
private Computer computer;
private InputController inputController;
private ScoreController scoreController;
private static final String ALL_STRIKE_MESSAGE = "3스트라이크";


public GameController(User user, Computer computer) {
this.user = user;
this.computer = computer;
this.inputController = new InputController();
this.scoreController = new ScoreController();
}

public void startGame() {
setComputerNumbers();
String result = "";
while (!result.equals(ALL_STRIKE_MESSAGE)) {
setUserNumbers();
result = scoreController.calculateScore(user, computer);
System.out.println(result);
}
System.out.println("승리!");
}

public void setUserNumbers() {
user.setNumberList(inputController.generateUserNum());
}

public void setComputerNumbers() {
computer.setNumberSet(inputController.generateComputerNum());
}

}
33 changes: 33 additions & 0 deletions src/main/java/controller/InputController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package controller;

import java.util.*;

public class InputController {
public ArrayList<Integer> generateUserNum() {
ArrayList<Integer> userNumber = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
System.out.print("숫자를 입력하세요: ");
for (int i = 0; i < 3; i++) {
if (scanner.hasNextInt()) {
userNumber.add(scanner.nextInt());
} else {
scanner.next();
i = 0;
}
}
if(userNumber.stream().anyMatch(x->x>9)){
System.out.println("한자리 수만 입력할 수 있습니다. 다시 입력해주세요");
userNumber.clear();
}
return userNumber;
}

public Set<Integer> generateComputerNum() {
Set<Integer> numbers = new LinkedHashSet<>();
Random random = new Random();
while (numbers.size() < 3) {
numbers.add(random.nextInt(1, 10));
}
return numbers;
}
}
73 changes: 73 additions & 0 deletions src/main/java/controller/ScoreController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package controller;

import model.BallCountStatus;
import model.Computer;
import model.User;

import java.util.ArrayList;

public class ScoreController {
private static final String ALL_STRIKE_MESSAGE = "3스트라이크";
private static final int MAX_SCORE = 3;
private static final String NO_SCORE = "낫싱";

public String calculateScore(User user, Computer computer) {
if (user.getNumberList().isEmpty()) return "";
ArrayList<BallCountStatus> ballCount = new ArrayList<>();

compareScoreStrike(ballCount, user, computer);

if (ballCount.size() == MAX_SCORE) {
return ALL_STRIKE_MESSAGE;
}

compareScoreBall(ballCount, user, computer);

return convertScoreListToString(ballCount);
}

protected void compareScoreBall(
ArrayList<BallCountStatus> score, User user, Computer computer) {
for (Integer userDatum : user.getNumberList()) {
if (computer.getNumberSet().stream().anyMatch(userDatum::equals)
&& score.size() <= MAX_SCORE) {
score.add(BallCountStatus.Ball);
}
}
}

protected void compareScoreStrike(
ArrayList<BallCountStatus> score, User user, Computer computer) {
ArrayList<Integer> computerNumberList = new ArrayList<>(computer.getNumberSet());
for (int i = 0; i < user.getNumberList().size(); i++) {
if (computerNumberList.get(i).intValue() == user.getNumberList().get(i).intValue()) {
score.add(BallCountStatus.Strike);
}
}
}
//
protected String convertScoreListToString(ArrayList<BallCountStatus> score) {
if (score.isEmpty()) {
return NO_SCORE;
} else {
long ballNumber = getScoreCount(score, BallCountStatus.Ball);
long strikeNumber = getScoreCount(score, BallCountStatus.Strike);
ballNumber -= strikeNumber;
String ballResult = (ballNumber) + "볼";
String strikeResult = strikeNumber + "스트라이크";
StringBuilder result = new StringBuilder();
if (ballNumber > 0) {
result.append(ballResult);
}
if (strikeNumber > 0) {
if (ballNumber > 0) result.append(" ");
result.append(strikeResult);
}
return result.toString();
}
}

private long getScoreCount(ArrayList<BallCountStatus> score, BallCountStatus status) {
return score.stream().filter(x -> x == status).count();
}
}
5 changes: 5 additions & 0 deletions src/main/java/model/BallCountStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package model;

public enum BallCountStatus {
Ball, Strike
}
20 changes: 20 additions & 0 deletions src/main/java/model/Computer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package model;

import java.util.*;

public class Computer {
private Set<Integer> numberSet;

public Computer() {
numberSet = new LinkedHashSet<>();
}

public Computer setNumberSet(Set<Integer> numberSet) {
this.numberSet = numberSet;
return this;
}

public Set<Integer> getNumberSet() {
return numberSet;
}
}
21 changes: 21 additions & 0 deletions src/main/java/model/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package model;

import java.util.ArrayList;
import java.util.List;

public class User {
private List<Integer> numberList;

public User() {
numberList = new ArrayList<>();
}

public User setNumberList(List<Integer> numberList) {
this.numberList = numberList;
return this;
}

public List<Integer> getNumberList() {
return numberList;
}
}
26 changes: 26 additions & 0 deletions src/main/java/view/UserInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package view;

import java.util.Scanner;

public class UserInterface {
private static final String THREE_STRIKE = "3스트라이크";
private Scanner scanner;

public UserInterface() {
this.scanner = new Scanner(System.in);
}

public static void printStartingGame() {
System.out.println("=============== 숫자 야구 ================");
}

public static void printEndingGame() {
System.out.println("=============== 게임 종료 ================");
}

public void closeScanner() {
if (scanner != null) {
scanner.close();
}
}
}
50 changes: 50 additions & 0 deletions src/test/java/controller/GameControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package controller;

import model.Computer;
import model.User;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.*;

class GameControllerTest {
User user = new User();
Computer computer = new Computer();
GameController gameController = new GameController(user, computer);

@Test
void setUserNumbers() {
// Given
ArrayList<Integer> expectedNumbers = new ArrayList<>(Arrays.asList(1, 2, 3));
GameController gameController = new GameController(user, computer);

// When
String input = "1 2 3";
System.setIn(new ByteArrayInputStream(input.getBytes()));
gameController.setUserNumbers();

// Then
Assertions.assertThat(user.getNumberList()).isEqualTo(expectedNumbers);
}

@Test
void setComputerNumbers() {
// Given
Set<Integer> expectedNumbers = new LinkedHashSet<>();
expectedNumbers.add(1);
expectedNumbers.add(2);
expectedNumbers.add(3);

// When
gameController.setComputerNumbers();

// Then
Assertions.assertThat(computer.getNumberSet().size()).isEqualTo(expectedNumbers.size());
}
}
Loading