반응형
숫자 야구 게임
1부터 9까지 서로 다른 수로 이루어진 3 자리의 수를 맞추는 게임입니다.
- 사용되는 숫자는 0에서 9까지 서로 다른 숫자이다.
- 숫자는 맞지만 위치가 틀렸을 경우 [볼].
- 숫자와 위치가 전부 맞으면 [스트라이크].
- 숫자와 위치가 전부 틀리면 [아웃].
-
물론 무엇이 볼이고 스트라이크인지는 알려주지 않는다.
-
두 숫자가 중복되면 경우의 수가 많아져서 그런지 중복 숫자는 잘 사용하지 않는다.
예시
아래 결과는 정답이 0 3 2 일 때의 예시이다.
BaseballGameMain 클래스
package game;
import java.util.ArrayList;
public class BaseballGameMain {
public static void main(String[] args) {
//필요한 객체 일괄 생성
RandomNumber randomNum = new RandomNumber();
InputNumber input = new InputNumber();
Umpire umpire = new Umpire();
RestartGame restartGame = new RestartGame();
boolean restart = true; //게임 재시작 여부
//반복1- 게임 재시작
System.out.println("<>===== BASEBALL GAME =====<>");
while(restart) {
//게임 레벨 설정(숫자의 갯수)
int level = input.getLevel();
System.out.println(">>>> PLAY BALL!!! <<<<");
//랜덤 숫자 생성
ArrayList<Integer> defenceNumber = randomNum.Generate(level);
System.out.println(defenceNumber);
//반복2 - 숫자 정답 전까지 반복(10회 제한) 제한이 없다면 while(true) 반드시 탈출조건
//레벨별 반복횟수 차이 3-10 4-15 5-20
for(int i=5*(level-1)-1;i>=0;i--) {
//입력
ArrayList<Integer> attackNumber = input.generatePlayerNumber(level);
System.out.println(attackNumber);
//결과 판정
String result = umpire.decide(defenceNumber,attackNumber);
//출력
System.out.println(result);
if(result.equals(level+"스트라이크")) break;
System.out.printf("남은 기회: %d회\n",i);
if(i==0) {
System.out.println("경기종료");
break;
}
}
//경기 재시작
restart = restartGame.askOp();
}
}
}
InputNumber 클래스
package game;
import java.util.ArrayList;
import java.util.Scanner;
public class InputNumber {
Scanner scanner = new Scanner(System.in);
public ArrayList<Integer> generatePlayerNumber(int level) {
ArrayList<Integer> attackNum = new ArrayList<>();
String input;
while(true) {
System.out.println(level+"자리 숫자를 입력해주세요.");
input = scanner.next();
//if(input.length()!=level) {
if(!input.matches("\\d{"+level+"}") || duplicateInputCheck(input)) {
System.out.println("올바른 입력이 아닙니다.");
continue;
}
break;
}
for(String number: input.split("")){
attackNum.add(Integer.parseInt(number));
}
return attackNum;
}
public int getLevel() {
System.out.println("레벨을 선택하세요.");
System.out.printf("1: 초보 2: 숙련 3: 달인\n입력:");
String input;
while(true) {
input = scanner.next();
if(!input.matches("[1-3]{1}")) {
System.out.print("레벨을 선택하세요. 입력:");
continue;
}
break;
}
return Integer.parseInt(input)+2;
}
public boolean duplicateInputCheck(String input) {
for(int i=0;i<input.length();i++) {
if(input.substring(i+1).contains(input.substring(i,i+1))) {
System.out.println("중복숫자가 있습니다.");
return true;
}
}
return false;
}
}
String.matches()
특정 패턴 (정규 표현식-Regex) 의 문자열을 포함하는지 확인할 수 있는 메서드입니다.
문자열에 정규표현식이 일치하는지 boolean 타입으로 리턴합니다.
정규표현식을 사용하지 않아도 가능하지만 정확히 일치해야합니다.
특정 문자열을 검색할 때 사용하기보다 정규표현식을 이용하여 한글, 숫자 등과 같이 해당 텍스트의 형태가 존재하는지, 원하는 패턴 형식에 맞는 텍스트가 있는지 알아볼 때 사용합니다.
ex) 이메일, 아이디, 주민등록번호, 전화번호 등
정규표현식 (Regex = Regular Expression)
특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식 언어입니다.
원하는 입력값을 정해진 형식에 맞춰 입력하였는지 검증해야 할 때 정규표현식을 사용하면 쉽게 구현이 가능합니다.
RandomNumber 클래스
package game;
import java.util.ArrayList;
import java.util.Scanner;
public class InputNumber {
Scanner scanner = new Scanner(System.in);
public ArrayList<Integer> generatePlayerNumber(int level) {
ArrayList<Integer> attackNum = new ArrayList<>();
String input;
while(true) {
System.out.println(level+"자리 숫자를 입력해주세요.");
input = scanner.next();
//if(input.length()!=level) {
if(!input.matches("\\d{"+level+"}") || duplicateInputCheck(input)) {
System.out.println("올바른 입력이 아닙니다.");
continue;
}
break;
}
for(String number: input.split("")){
attackNum.add(Integer.parseInt(number));
}
return attackNum;
}
public int getLevel() {
System.out.println("레벨을 선택하세요.");
System.out.printf("1: 초보(3) 2: 숙련(4) 3: 달인(5)\n입력:");
String input;
while(true) {
input = scanner.next();
if(!input.matches("[1-3]{1}")) {
System.out.print("레벨을 선택하세요. 입력:");
continue;
}
break;
}
return Integer.parseInt(input)+2;
}
public boolean duplicateInputCheck(String input) {
for(int i=0;i<input.length();i++) {
if(input.substring(i+1).contains(input.substring(i,i+1))) {
System.out.println("중복숫자가 있습니다.");
return true;
}
}
return false;
}
}
RestartGame 클래스
package game;
import java.util.ArrayList;
import java.util.Random;
public class RandomNumber {
//랜덤 숫자 생성
public int randomNumberMake() {
int result;
// result = (int)(Math.random()*9+1); // Math.random 사용
Random random = new Random(); //Random class 사용
result = random.nextInt(9)+1; // random.nextInt(max) + min;
return result;
}
public ArrayList<Integer> Generate(int level) {
ArrayList<Integer> defenceNumber = new ArrayList<>();
while(defenceNumber.size()<level) {
int randomNumber = randomNumberMake();
if(defenceNumber.contains(randomNumber)) {
continue;
}else {
defenceNumber.add(randomNumber);
}
}
return defenceNumber;
}
}
Umprire 클래스
package game;
import java.util.ArrayList;
class CheckNumber{
public int countAll(ArrayList<Integer> defence, ArrayList<Integer> attack) {
int result = 0;
for(int i = 0; i < attack.size(); i++){
if(defence.contains(attack.get(i))){
result += 1;
}
}
return result;
}
public int countStrike(ArrayList<Integer> defence, ArrayList<Integer> attack) {
int strike=0;
for(int i = 0; i < attack.size(); i++){
if(defence.get(i) == attack.get(i)){
strike += 1;
}
}
return strike;
}
}
public class Umpire {
CheckNumber check = new CheckNumber();
public String decide(ArrayList<Integer> defenceNumber, ArrayList<Integer> attackNumber) {
String result="";
int all = check.countAll(defenceNumber,attackNumber);
int strike = check.countStrike(defenceNumber,attackNumber);
int ball = all-strike;
if(all==0) {
result="Nothing";
}else {
if(strike!=0){
result+=strike+"스트라이크";
}
if(ball!=0) {
result+=ball+"볼";
}
}
return result;
}
}
실행 결과
입력값 [1] : 초보 단계 3 자리의 숫자로 게임을 시작합니다.
입력값 [2] : 숙련 단계 4 자리의 숫자로 게임을 시작합니다.
입력값 [3] : 달인 단계 5 자리의 숫자로 게임을 시작합니다.
BaseballGameMain 클래스의 main 에서
System.out.println(defenceNumber);
해당 코드를 주석처리 하여 defenceNumber를 확인하지 않고 게임을 플레이할 수 있습니다.
아래는 숫자야구게임의 다른 코드입니다.
import java.util.Random;
import java.util.Scanner;
public class BaseBallVarGame {
public static void main(String[] args) {
Random random = new Random();
Scanner scanner = new Scanner(System.in);
//게임에서 사용할 변수
int com1, com2, com3;
int user1, user2, user3;
int randomCnt = 0;//난수생성 카운트
int gameCount = 0;//게임 카운트
int strikeCnt=0, ballCnt=0;//스크라이크,볼 카운트
//게임전체반복
while(true) {
//중복되지 않는 3개의 난수생성
while(true) {
//몇번만에 난수가 생성되는지 확인
randomCnt++;
//1~9사이의 난수생성
com1 = random.nextInt(100) % 9 + 1;
com2 = random.nextInt(100) % 9 + 1;
com3 = random.nextInt(100) % 9 + 1;
if(!(com1==com2 || com2==com3 || com3==com1)) {
//중복되지 않는 난수 생성에 성공하면 루프탈출
break;
}
}////while end
//난수확인
System.out.println(randomCnt+"회:"+com1+" "+com2+" "+com3);
while(true) {
//사용자로부터 3개의 정수를 입력받는다.
System.out.println("3개의정수를 입력하세요(1~9)");
System.out.println("스페이스로 구분하시고 마지막에 Enter를 눌러주세요");
user1 = scanner.nextInt();
user2 = scanner.nextInt();
user3 = scanner.nextInt();
//게임카운트 1회 증가
gameCount++;
//판단1 - 스크라이크(숫자와 위치까지 일치)
if(com1==user1) strikeCnt++;
if(com2==user2) strikeCnt++;
if(com3==user3) strikeCnt++;
//판단2 - 볼(숫자는 일치하나 위치가 다를때)
if(com1==user2 || com1==user3) ballCnt++;
if(com2==user1 || com2==user3) ballCnt++;
if(com3==user1 || com3==user2) ballCnt++;
//게임종료판단
if(strikeCnt==3) {
System.out.println("3스트라이크 게임종료");
System.out.println(gameCount+"번만에 맞추셨습니다.");
break;//루프탈출
}
else {
//하나도 못맞추는 경우
if(strikeCnt==0 && ballCnt==0) {
System.out.println("아웃입니다");
}
else {
System.out.printf("%d스트라이크, %d볼\n",
strikeCnt, ballCnt);
}
//스트라이크, 볼 카운트 초기화
strikeCnt = 0;
ballCnt = 0;
//continue문은 필요없음.
}
}////while end
System.out.println("한게임 더 하시겠습니까?(0:종료,1:재시작)");
int restart = scanner.nextInt();
if(restart==0) {
//게임종료
System.out.println("\n==게임이 종료되었습니다.==\n");
//실행되는 즉시 main함수가 종료된다.
System.exit(0);
}
else if(restart==1){
//게임을 재시작하기 위해 카운트변수 초기화
strikeCnt = 0;
ballCnt = 0;
gameCount = 0;
System.out.println("\n==게임을 재시작합니다.==\n");
}
}//게임 전체 반복 while end
}//main 메서드 end
}//class 끝
https://nakja.tistory.com/81 블로그에서 발견한 코드입니다.
코드가 간결하고 좋아서 참고용으로 첨부하였습니다.
반응형
'Java > 코드' 카테고리의 다른 글
[Java] 예제 풀어보기 - 평균 구하기, 배열의 짝수 홀수 구분, 배열의 정렬, 주민등록번호 구분하기, 문자열 치환 (0) | 2023.02.10 |
---|