본문 바로가기
Programming/Java

[우아한테크코스 3기 프리코스 1주차] 숫자 야구 게임

by IN.0 2019. 12. 6.
728x90
반응형

지난주 수요일(11.27)에 미션 메일을 받았다.

메일 받은 내용

 

일단 pdf에 필요한 링크들은 다 있었다.

github 클론도 처음 해보고, branch도 만들어 본 적이 없어서 구글링도 몇 번 했다.

그리고 README 작성하는 것도...

github를 eclipse로 클론 후에 파일을 살펴보니까 뭔가 이것저것 많이 들어있었다.

요렇게...

내가 아는 것은 src에서 main에 코드를 담아야 한다는 것 밖에 없었다.

github에서 README 파일을 일단 업데이트했다.

처음 하는 것 치고는 꽤 깔끔하지 않나..^^ 생각한다.

README 업데이트 후에 eclipse로 돌아와서 main.java 파일 안에 Main.java와 Computer.java 파일을 생성했다.

이렇게 하는 것이 맞나 모르겠는데, 이 주에 많이 바빴던 터라.. 다른 사람들 코드를 확인해 볼 시간이 안됐다.

Main.java는 다른 .java 파일(클래스)을 호출해서 사용하는 큰 줄기(??) 느낌으로 생각했다.

그리고 Computer.java는 Random Number를 생성하는 용도의 클래스를 가지고 있다.

package main.java;

public class Computer {
	
	int[] com_arr = new int[3];
	
	public int[] make_list() {
	
		for (int i=0; i<3; i++) {
			int random_number = (int) (Math.random() * 9) + 1;
			com_arr[i] = random_number;
		}
		
		return com_arr;
	}
}

Computer.java

array를 생성하고 랜덤 넘버를 생성하는 메서드를 만들어 돌린다.

 

package main.java;

public class Main {
	public static void main (String[] args) {
		Computer computer = new Computer();
		
		int[] target = computer.make_list();
    }
	
}

Main.java

메인에서 Computer.java 파일을 불러온 후 랜덤 넘버 array를 target이라는 변수에 저장한다.

그리고 User와 Userhelp 클래스를 생성한다.

 

package main.java;

import java.util.InputMismatchException;
import java.util.Scanner;

public class User {
	Scanner scanner = new Scanner(System.in);
	int input_num = 0;			// 유저에게 받을 값 정의. 기본값 0
	int[] result;			// 결과로 리턴 할 array 정의
	Userhelp userhelp = new Userhelp();
	
	public int[] input() {
		
		System.out.print("숫자를 입력해주세요 : ");
		try {
			
			input_num = scanner.nextInt();			// 유저에게 값을 받음
			
		} catch(InputMismatchException ime) {			// 문자를 포함한 값을 입력할 경우 예외처리
			
		    System.out.println("숫자만 입력 가능합니다.");
		    scanner = new Scanner(System.in);			// 스캐너 값 리셋 후 다시 받음
		    input();
		}
		
		int error_num = userhelp.exception(input_num);			// 에러 값 받기 (0-에러없음, 1,2-에러있음)
		
		
		if (error_num == 0) {			// 에러 없을 경우
			result = userhelp.num_to_arr(input_num);			// int 값을 array로 변경
			
		}else {			// 에러 있을 경우
			System.out.println("1~9로 이루어진 3자리 숫자만 입력 가능합니다.");
			scanner = new Scanner(System.in);			// 스캐너 값 리셋 후 다시 받음
			input();
		}
		return result;			// 유저 array 값 리턴
		
	}

}

User.java

 

package main.java;

public class Userhelp {
	
	
	public int exception(int number) {			// 예외(에러)처리
		int error = 0;			// 에러 기본값 0 (에러 없음)
		
		if (number < 111 || number > 999) {			// 1에서 9까지의 세자리 수가 아닌 경우
			error = 1;
		}
		if (Integer.toString(number).indexOf("0") != -1) {			// 숫자에 0이 포함된 경우
			error = 2;
		}
		
		return error;			// 에러값 리턴
	}
	
	public int[] num_to_arr(int num) {			// 숫자를 array 형태로 변환
		
		int[] user_arr = new int[3];			// 새로운 array 생성
		int div_num = 100;			// 나누는 값 100으로 기본 설정
	
		for (int i=0; i<3; i++) {
			user_arr[i] = num / div_num;			// 숫자를 div_num으로 나눈 몫 저장
			num -= user_arr[i]*div_num;			// 숫자에서 위의 값 제거
			div_num /= 10;			// div_num 10으로 나눠 자릿수 옮기기
		}
		return user_arr;			// array 리턴
	}
}

Userhelp.java

처음에는 유저 안에 모든 기능을 다 담으려고 했는데, 복잡해질 것 같아서.. 그리고 한 파일 안에

여러 클래스를 생성하는 것이 헷갈려서 Userhelp 클래스를 다른 파일에 따로 분리해 호출하여 사용했다.

예외 처리와 형변환 메서드를 Userhelp로 따로 빼줬다.

여기까지 진행한 상태에서 메인은 이렇게 된다.

package main.java;

public class Main {
	public static void main (String[] args) {
		Computer computer = new Computer();
		User user = new User();
		
		int[] target = computer.make_list();			// 랜덤 넘버(3개)를 array로 가져옴
		int[] answer = user.input();			// 사용자가 답한 숫자
	}
	
}

Main.java

이제 타겟 넘버(컴퓨터)와 사용자 입력 값이 넘어왔으니, 스트라이크와 볼 또는 낫싱을 체크해야 한다.

 

package main.java;

public class Matching {
	public int strike(int[] com_arr, int[] user_arr) {
		
		int strike = 0;			// 스트라이크 기본 값 0으로 셋팅
		
		for (int i=0; i<3; i++) {
			if (user_arr[i] == com_arr[i]) {			// 유저와 컴퓨터의 같은 배열 위치에 같은 값이 있으면
				strike += 1;			// 스트라이크 값에 1 더하기
			}
		}
		
		return strike;			// 스트라이크 값 리턴
	}
	
	public int ball(int[] com_arr, int[] user_arr) {
		int ball = 0;			// 볼 기본 값 0으로 셋팅
		int[] com_arr_tmp = com_arr.clone();			// 컴퓨터 배열을 클론하여 값이 바뀌어도 영향이 가지 않게 함
		int strike = strike(com_arr, user_arr);			// 스트라이크 값 받기
		
		for (int i=0; i<3; i++) {
			if (user_arr[0] == com_arr_tmp[i]) {			// 유저의 첫번째 값과 같은 값이 있으면
				ball += 1;			// 볼 값에 1을 더하고
				com_arr_tmp[i] = 0;			// 컴퓨터 배열에서 해당 값을 0으로 바꾸기 (중복 카운트 방지)
				continue;
			}
			if (user_arr[1] == com_arr_tmp[i]) {			// 유저의 두번째 값도 마찬가지
				ball += 1;
				com_arr_tmp[i] = 0;
				continue;
			}
			if (user_arr[2] == com_arr_tmp[i]) {			// 유저의 세번째 값도 마찬가지
				ball += 1;
				com_arr_tmp[i] = 0;
				continue;
			}
		}
		
		return ball-strike;			// 볼 값에서 스트라이크 값을 빼고 리턴 (볼은 스트라이크도 포함하기 때문)
	}
}

Matching.java

스트라이크와 볼의 개수를 리턴하는 메서드를 가진 Matching이라는 클래스를 만들었다.

볼의 경우에 반복되는 if문을 for문으로 합치고 싶었는데, indent depth를 2까지만 허용하기 때문에

for문을 추가해버리면 for(for(if)) 이렇게 depth가 3이 되어버려서 보기 싫지만 if 3개를 사용하였다.

다른 방법이 있을 것 같은데(python으로 치면 list.index(값)의 기능) 아직 구글링 실력이 부족해서 찾지 못했다.

그러고 나서 스트라이크와 볼 값을 받아 결과를 출력해주는 클래스를 생성한다.

package main.java;

import java.util.Scanner;

public class Result {
	public int[] release(int strike, int ball) {
		
		int[] check_and_decision = new int[2];			// [성공여부, 재시작여부]
		int check = 0;			// 성공여부 기본값 0 (실패)
		int decision = 0;			// 재시작여부 기본값 0 (불가능)
		if (strike != 3) {			// 답을 맞추지 못했을 때
			
			if (strike != 0) {			// 스트라이크 갯수 출력
				System.out.print(strike + "스트라이크 ");
			}
			
			if (ball != 0) {			// 볼 갯수 출력
				System.out.print(ball + "볼 ");
			}
			
			if (strike == 0 && ball == 0) {			// 낫싱일 때 출력
				System.out.print("낫싱");
			}
			System.out.println();
		}else {			// 답을 맞췄을 때
			System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
			
			while (decision != 1 && decision != 2) {			// 재시작여부 올바른 값 받기
				decision = restart();
			}
			
			check = 1;			// 성공여부 1으로 변경 (성공)
		}
		check_and_decision[0] = check;			// 성공여부 반영
		check_and_decision[1] = decision;			// 재시작여부 반영
		
		return check_and_decision;			// [성공여부, 재시작여부] 리턴
		
	}
	
	
	public int restart() {			// 재시작여부 값 받기
		System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
		Scanner scanner = new Scanner(System.in);
		int start_or_not = scanner.nextInt();
		
		return start_or_not;
	}
}

Result.java

재시작 여부도 사용자에게 값을 받아야 하기 때문에 예외 처리를 메서드로 따로 빼주었다.

마지막으로 메인 클래스를 이렇게 수정한다.

package main.java;

public class Main {
	public static void main (String[] args) {
		Computer computer = new Computer();
		User user = new User();
		Matching matching = new Matching();
		Result result = new Result();
		
		int[] target = computer.make_list();			// 랜덤 넘버(3개)를 array로 가져옴
		int[] success = new int[2];			// [성공여부, 재시작여부]
		
		while (true) {
			int[] answer = user.input();			// 사용자가 답한 숫자
			
			int strike = matching.strike(target, answer);			// 스트라이크 갯수
			int ball = matching.ball(target, answer);			// 볼 갯수
			
			success = result.release(strike, ball);			// 결과 응답
			
			if (success[0] == 1) {
				break;			// 성공여부가 1일때 답을 맞춘 것이며, while 빠져나옴
			}
		}
		
		if (success[1] == 1) {
			main(args);			// 재시작여부가 1일때 재시작을 의미하며, main으로 돌아가서 게임을 재시작함
		}
	}
	
}

Main.java (최종)

끝 !

그리고 중간중간에 클래스를 추가할 때마다 깃으로 커밋하고 푸쉬를 해줬다.

최종 푸쉬를 마치고 Pull Request를 하는데, 제일 처음에 했던 README 업데이트가 branch가 아닌 master로

되어있어서,, branch로 다시 커밋했다.

 

java로 해보는 첫 프로그래밍이라 부족한 점이 많았다.

아직 아는 기능보다 모르는 기능이 훨씬 많으니 열심히 배워야겠다.

728x90
반응형

댓글