-
Notifications
You must be signed in to change notification settings - Fork 2.3k
숫자 야구게임 구현 #2774
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
base: main
Are you sure you want to change the base?
숫자 야구게임 구현 #2774
Changes from 16 commits
4fe02a2
f86ddca
5db856c
5cfbeda
2793756
52b8e37
6eb2d7b
1a1e3cd
aac9f69
01cbfdb
e420c89
4bec3d6
cb3a5f1
81c2f92
2cfe1de
7201201
ec16338
91a03fc
0a41f1c
0fe393b
e70e394
e237bcc
b3642f0
81e5708
1e13076
94b9fd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <mxfile host="app.diagrams.net" modified="2023-11-06T15:05:38.514Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" etag="ldBo5bSzdiYxctWy_cm0" version="22.0.8" type="github"> | ||
| <diagram name="페이지-1" id="q04Y4RyBtX_a_hriLJLF"> | ||
| <mxGraphModel dx="1195" dy="632" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> | ||
| <root> | ||
| <mxCell id="0" /> | ||
| <mxCell id="1" parent="0" /> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-1" value="Game" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
| <mxGeometry x="110" y="350" width="120" height="60" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-2" value="Computer" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
| <mxGeometry x="420" y="270" width="120" height="60" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-3" value="Judgment" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
| <mxGeometry x="420" y="470" width="120" height="60" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-4" value="Player" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> | ||
| <mxGeometry x="420" y="370" width="120" height="60" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-6" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="nZR88hf0O_DFail2BoQR-1" target="nZR88hf0O_DFail2BoQR-2"> | ||
| <mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
| <mxPoint x="340" y="480" as="sourcePoint" /> | ||
| <mxPoint x="390" y="430" as="targetPoint" /> | ||
| </mxGeometry> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-8" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="nZR88hf0O_DFail2BoQR-1" target="nZR88hf0O_DFail2BoQR-4"> | ||
| <mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
| <mxPoint x="240" y="375" as="sourcePoint" /> | ||
| <mxPoint x="430" y="310" as="targetPoint" /> | ||
| </mxGeometry> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-9" value="정답을 생성" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
| <mxGeometry x="280" y="300" width="70" height="30" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-10" value="정답을 입력" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
| <mxGeometry x="300" y="360" width="70" height="30" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-11" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="nZR88hf0O_DFail2BoQR-1" target="nZR88hf0O_DFail2BoQR-3"> | ||
| <mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
| <mxPoint x="110" y="520" as="sourcePoint" /> | ||
| <mxPoint x="300" y="625" as="targetPoint" /> | ||
| </mxGeometry> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-12" value="정답인지 판단" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> | ||
| <mxGeometry x="320" y="430" width="80" height="30" as="geometry" /> | ||
| </mxCell> | ||
| <mxCell id="nZR88hf0O_DFail2BoQR-14" value="" style="curved=1;endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="nZR88hf0O_DFail2BoQR-1" target="nZR88hf0O_DFail2BoQR-1"> | ||
| <mxGeometry width="50" height="50" relative="1" as="geometry"> | ||
| <mxPoint x="110" y="460" as="sourcePoint" /> | ||
| <mxPoint x="100" y="380" as="targetPoint" /> | ||
| <Array as="points"> | ||
| <mxPoint x="100" y="450" /> | ||
| <mxPoint x="50" y="410" /> | ||
| <mxPoint x="50" y="380" /> | ||
| </Array> | ||
| </mxGeometry> | ||
| </mxCell> | ||
| </root> | ||
| </mxGraphModel> | ||
| </diagram> | ||
| </mxfile> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다. | ||
| 예) 상대방(컴퓨터)의 수가 425일 때 | ||
| 123을 제시한 경우 : 1스트라이크 | ||
| 456을 제시한 경우 : 1볼 1스트라이크 | ||
| 789를 제시한 경우 : 낫싱 | ||
| 위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. | ||
| 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. | ||
| 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, | ||
| 컴퓨터는 입력한 숫자에 대한 결과를 출력한다. | ||
| 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다. | ||
|
|
||
| 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다. | ||
|
|
||
| # 요구사항 분석 | ||
| - 컴퓨터가 수를 선택한다. | ||
| - 수는 3자리 숫자이고, 랜덤으로 정해진다. | ||
| - 정답을 맞출 때 까지 반복한다. | ||
| - 컴퓨터는 입력한 숫자에 대한 결과를 출력한다. | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치는 틀리지만 수가 맞으면 볼을 출력 | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치도 맞고 수가 맞으면 스트라이크를 출력 | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치도, 수도 맞은게 없다면 낫싱을 출력 | ||
| - 사용자가 수를 입력할 수 있다. | ||
| - 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생 후 종료 | ||
| - 컴퓨터의 수를 맞추면 게임 종료. 종료 후 한번 더 할지, 끝낼지 입력받는다. | ||
|
|
||
| # 역할을 나눈다. | ||
|
|
||
| ## 답을 생성하는 역할 | ||
| - 컴퓨터가 수를 선택한다. | ||
| - 수는 서로 다른 3자리 숫자이고, 랜덤으로 정해진다. | ||
|
|
||
| ## 정답을 입력을 할 수 있는 역할 | ||
| - 사용자가 수를 입력할 수 있다. | ||
| - 수는 서로 다른 3자리 숫자이다. (검증필요) | ||
| - 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생 후 종료 | ||
|
|
||
| ## 정답이 맞는지 판단하고 힌트를 주는 역할 | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치는 틀리지만 수가 맞으면 볼을 출력 | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치도 맞고 수가 맞으면 스트라이크를 출력 | ||
| - 컴퓨터수와 사용자의 수를 비교해 위치도, 수도 맞은게 없다면 낫싱을 출력 | ||
|
|
||
| ## 게임을 제어하는 역할 | ||
| - 정답을 맞출 때 까지 반복한다. | ||
| - 정답을 맞추면 게임 종료. | ||
| - 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다. 종료 후 한번 더 할지, 끝낼지 입력받는다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| package baseball; | ||
|
|
||
| public class Application { | ||
|
|
||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| GameLauncher launcher = new NumberBaseBallGameLauncher(); | ||
| launcher.startGame(); | ||
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package baseball; | ||
|
|
||
| import java.util.HashSet; | ||
| import java.util.Set; | ||
|
|
||
| import static camp.nextstep.edu.missionutils.Randoms.pickNumberInRange; | ||
|
|
||
| public class Computer { | ||
| public String createGameValue() { | ||
| // 컴퓨터 수 생성 | ||
| Set<Integer> targetSet = new HashSet<>(); | ||
| while (targetSet.size() < 3) { | ||
| targetSet.add(pickNumberInRange(1, 9)); | ||
| } | ||
|
|
||
| return targetSet.stream() | ||
| .map(String::valueOf) | ||
| .reduce("", String::concat); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| package baseball; | ||
|
|
||
| import baseball.enums.ExceptionMessage; | ||
| import baseball.exception.WrongInputException; | ||
|
|
||
| import java.util.HashSet; | ||
|
|
||
| public class GameInputValue { | ||
|
||
| private String userInputValue; | ||
| private final String computerValue; | ||
|
|
||
| public GameInputValue(String computerValue) { | ||
| this.computerValue = computerValue; | ||
| this.userInputValue = ""; | ||
| } | ||
|
|
||
| public String getUserInputValue() { | ||
| return userInputValue; | ||
| } | ||
|
|
||
| public String getComputerValue() { | ||
| return computerValue; | ||
| } | ||
|
|
||
| // TODO 조금 더 명확한 목적을 띄는 메서드 ... | ||
| public void setUserInputValue(String userInputValue) { | ||
| this.userInputValue = userInputValue; | ||
| checkValidUserInput(); | ||
| } | ||
|
|
||
| public boolean isEqaulsUserAndComputerValue() { | ||
|
||
| return this.userInputValue.equals(this.computerValue); | ||
| } | ||
|
|
||
| public int countSameNumber() { | ||
| int count = 0; | ||
| for (char c : this.userInputValue.toCharArray()) { | ||
| if (this.computerValue.contains(String.valueOf(c))) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
|
|
||
| public int countSamePositionAndNumber(){ | ||
| int count = 0; | ||
| char[] computerValueCharArr = computerValue.toCharArray(); | ||
| char[] userVauleCharArr = userInputValue.toCharArray(); | ||
| for (int i = 0; i < computerValueCharArr.length; i++) { | ||
| if (computerValueCharArr[i] == userVauleCharArr[i]) { | ||
| count++; | ||
| } | ||
| } | ||
| return count; | ||
| } | ||
|
|
||
| public boolean isDuplicationNumberInUserInputValue() { | ||
| HashSet<Character> set = new HashSet<>(); | ||
| for (char c : this.userInputValue.toCharArray()) { | ||
| set.add(c); | ||
| } | ||
| return set.size() != 3; | ||
| } | ||
|
|
||
| public boolean isNothing() { | ||
| return countSameNumber() == 0; | ||
| } | ||
|
|
||
|
|
||
| public void checkValidUserInput() { | ||
| if (!isThreeDigits()) { | ||
| throw new WrongInputException(ExceptionMessage.WRONG_INPUT_NOT_THREE_DIGITS.getMessage()); | ||
| } | ||
|
|
||
| if (!isNumber()){ | ||
| throw new WrongInputException(ExceptionMessage.WRONG_INPUT_NOT_NUMBER.getMessage()); | ||
| } | ||
|
|
||
| if(isDuplicationNumberInUserInputValue()){ | ||
| throw new WrongInputException(ExceptionMessage.WRONG_INPUT_DUPLICATE_VALUE.getMessage()); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| private boolean isThreeDigits() { | ||
| return userInputValue.length() == 3; | ||
| } | ||
|
|
||
| private boolean isNumber() { | ||
| return userInputValue != null && userInputValue.matches("[-+]?\\d*\\.?\\d+"); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package baseball; | ||
|
|
||
| public interface GameLauncher{ | ||
| void startGame(); | ||
|
|
||
| void initGame(); | ||
|
|
||
| void endGame(); | ||
|
|
||
| void play(GameInputValue value); //TODO 확장성이 아쉬운 느낌 ..? | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package baseball; | ||
|
|
||
| import baseball.enums.GameProgressMessage; | ||
|
|
||
| public class Judgement { | ||
|
|
||
| public void judge(GameInputValue gameValue) { | ||
| // 사용자 수와 컴퓨터 수 비교 => 판정하는 클래스가 해야할 일 | ||
| Result result = new Result(gameValue.countSameNumber() - gameValue.countSamePositionAndNumber(), gameValue.countSamePositionAndNumber()); | ||
| if (gameValue.isNothing()) { | ||
| PrintMessage.printlnMessage(GameProgressMessage.NOTHING); | ||
| } else { | ||
| PrintMessage.printlnMessage(GameProgressMessage.makeHintMessage(result)); | ||
| } | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package baseball; | ||
|
|
||
| import baseball.enums.GameFlag; | ||
| import baseball.enums.GameProgressMessage; | ||
| import baseball.enums.OrNot; | ||
|
|
||
| import static camp.nextstep.edu.missionutils.Console.readLine; | ||
| public class NumberBaseBallGameLauncher implements GameLauncher{ | ||
|
||
|
|
||
| private GameFlag flag = GameFlag.START; | ||
| private Computer computer = new Computer(); | ||
| private Judgement judgement = new Judgement(); | ||
|
|
||
| @Override | ||
| public void startGame() { | ||
| PrintMessage.printlnMessage(GameProgressMessage.START); | ||
|
||
| initGame(); | ||
|
||
| } | ||
|
|
||
| @Override | ||
| public void initGame() { | ||
|
||
| if(flag == GameFlag.START){ | ||
| GameInputValue gameValue = new GameInputValue(computer.createGameValue()); | ||
| flag = GameFlag.ING; | ||
| play(gameValue); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void endGame() {} | ||
|
|
||
| @Override | ||
| public void play(GameInputValue gameValue) { | ||
| if (flag == GameFlag.ING) { | ||
| PrintMessage.printMessage(GameProgressMessage.INPUT_NUMBER); | ||
|
||
| gameValue.setUserInputValue(readLine()); | ||
| judgement.judge(gameValue); | ||
|
||
|
|
||
| // 리플레이 또는 종료 | ||
| if(isWin(gameValue)){ | ||
| PrintMessage.printlnMessage(GameProgressMessage.PLAY_NEXT_GAME_OR_NOT); | ||
| replayOrEnd(); | ||
|
||
|
|
||
| if (flag == GameFlag.START) { | ||
|
||
| initGame(); | ||
| } | ||
|
|
||
| if (flag == GameFlag.END) { | ||
| endGame(); | ||
| } | ||
|
|
||
| return; | ||
| } | ||
| play(gameValue); | ||
| } | ||
| } | ||
|
|
||
| public boolean isWin(GameInputValue gameValue) { | ||
|
||
| return gameValue.isEqaulsUserAndComputerValue(); | ||
| } | ||
|
|
||
| public void replayOrEnd() { | ||
| String answer = readLine(); | ||
| if (answer.equals(OrNot.YES.getProcessCode())) { | ||
| flag = GameFlag.START; | ||
|
||
| } | ||
| if (answer.equals(OrNot.NO.getProcessCode())) { | ||
|
||
| flag = GameFlag.END; | ||
| } | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package baseball; | ||
|
|
||
| import baseball.enums.GameProgressMessage; | ||
|
|
||
| public class PrintMessage { | ||
|
|
||
| public static void printlnMessage(GameProgressMessage gameProgressMessage) { | ||
| System.out.println(gameProgressMessage.getKorMessage()); | ||
| } | ||
|
|
||
| public static void printMessage(GameProgressMessage gameProgressMessage) { | ||
|
||
| System.out.print(gameProgressMessage.getKorMessage()); | ||
| } | ||
|
|
||
| public static void printMessage(String message) { | ||
| System.out.print(message); | ||
| } | ||
|
|
||
| public static void printlnMessage(String message) { | ||
| System.out.println(message); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
학습하실 때는 롬복 및 외부 라이브러리 사용 지양해주세요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앗 네!