[JAVA] 포켓몬 게임 프로젝트 - 2

2024. 7. 12. 12:15·프로젝트

https://yn98.tistory.com/26

 

[JAVA] 포켓몬 게임 프로젝트

JAVA를 이용하여 약 5일간의 프로젝트를 만들어보았다.자세한 과정과 내용은 아래 노션에다가 기록해놓았다. ↓ ↓ ↓ ↓ ↓https://www.notion.so/TeamProject-e27a469100534f86843b034b4dca48ad TeamProject | Notion멤

yn98.tistory.com

이전 글에서 완성된 포켓몬 게임 프로젝트이다.

사실 위 글의 코드는 접근제어자와 추상메서드를 이용하지 않았다.  -> 이는 객체지향을 완전히 살렸다고 볼 수 없는 코드이다.

 

피드백받았던 부분을 수정하였고, 오탈자도 수정하고, 객체지향의 특징을 살려서 코드를 다시 짜보았다.

package class02;

import java.util.Random;
import java.util.Scanner;

abstract class Pokemon{

	/*멤버변수선언 */
	private String type;  // 타입 (강제)
	private String name;  // 이름 (강제)
	private int level; // 레벨
	private int exp; // 경험치

	/*클래스변수 선언*/
	static final int attackExpMin = 50; // 공격 성공 시 추가되는 최소 경험치
	static final int attackExpMax = 500; // 공격 성공 시 추가되는 최대 경험치
	static Random rand = new Random();
	static final int maxLevel =30;

	// 생성자
	Pokemon(String type,String name) { //초기화
		this.type = type;
		this.name = name;
		this.level = rand.nextInt(5)+1; // 1에서 5까지 레벨
		this.exp = 0; 
	}
	// 함수
	boolean attack(){ // attack 메서드
		// 공격 50% 확률로 성공

		attackVoice();  // 기술명 외침 ex ) 전기공격!
		hello();        // 울음소리 ex) 삐까삐까!

		if(rand.nextDouble() < 0.5 ){// 공격에 성공했을 경우 - 50%확률, random 함수는 0~1 사이를 랜덤값 반환하니까!
			int attackExp = rand.nextInt(attackExpMax - attackExpMin + 1) + attackExpMin;
			// attackExpMin에서 attackExpMax 사이의 랜덤한 경험치 획득
			this.exp += attackExp; // 현재 경험치에 방금 획득한 경험치를 증가시킴
			if(this.level >= maxLevel) { // 이미 만렙인 경우
				System.out.println(this.name+"은(는) 만렙을 달성해서 더이상 경험치를 획득할 수 없습니다!");
				this.exp = 0; // 만렙은 exp = 0 으로 고정함
				return true; // 만렙을 달성했기 때문에 true 반환
			}
			System.out.println(this.name + " 공격 성공! " + attackExp + " 의 경험치 획득 !");
			while (this.exp >= 100) { // 경험치가 100 이상이 되면
				levelUp();// 레벨업 메서드 실행
			}


			return true;// 레벨업이 없는경우
		}
		else{   // 공격에 실패했을 경우
			System.out.println("공격에 실패했습니다.");
		}
		return false;

	}
	void levelUp(){ // levelUp 메서드
		int additionalLevels = this.exp / 100; // 현재 경험치를 100으로 나눈 몫을 추가 레벨로 설정
		this.level += additionalLevels; // 포켓몬의 레벨을 추가 레벨만큼 증가
		this.exp %= 100; // 남은 경험치를 100으로 나눈 나머지로 설정하여 경험치 초기화
		if (this.level >= maxLevel) { // 레벨이 만렙에 도달한 경우
			System.out.println("축하합니다!" + this.name + " 만렙 달성!"); // 만렙 달성 문구 출력
			this.level = maxLevel; // 레벨을 최대 레벨(maxLevel)로 설정
			this.exp = 0; // 추가 경험치 초기화
			return; // 더 이상 경험치를 처리할 필요 없으므로 return		
		}

		else {
			// 레벨업 메시지 출력
			System.out.println(this.name + "의 레벨 업! 레벨 " + additionalLevels + " 증가! 현재 레벨은" + this.level+" 입니다!");

		}
	}


	abstract void hello(); // 울음소리
	abstract void attackVoice(); // 공격할 때 기술명


	@Override
	public String toString(){//[포켓몬이름,포켓몬타입,포켓몬레벨,포켓몬경험치가 출력되게 설정
		return "[ "+this.name+", "+this.type+" 타입 , 현재 레벨 : "+this.level+", 현재 경험치 : "+this.exp+"]";
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	public int getExp() {
		return exp;
	}
	public void setExp(int exp) {
		this.exp = exp;
	}



} // 포켓몬 클래스 닫기

//자식클래스들//
class Ditto extends Pokemon{ // 자식클래스, 메타몽
	// 생성자, 타입/이름 고정
	Ditto(){
		super("노말", "메타몽"); // 부모생성자 호출
	}

	// 함수
	@Override
	void hello() { // 울음소리 출력, 오버라이딩
		System.out.println("어라?😭");
	}
	@Override
	void attackVoice() { // 공격시 출력되는 attackVoice, 오버라이딩
		System.out.print("변신!! ");
	}
}

class Zorua extends Pokemon{ // 자식클래스, 조로아
	// 생성자, 타입/이름 고정
	Zorua(){
		super("악", "조로아"); // 부모생성자 호출
	}
	// 함수
	@Override
	void hello() { // 울음소리 출력, 오버라이딩
		System.out.println("조르륵😭");
	}
	@Override
	void attackVoice() { // 공격시 출력되는 attackVoice, 오버라이딩
		System.out.print("물기!! ");
	}
}

class Cubone extends Pokemon{ // 자식클래스, 탕구리
	// 생성자, 타입/이름 고정
	Cubone(){
		super("땅", "탕구리"); // 부모생성자 호출
	}

	// 함수
	@Override
	void hello() { // 울음소리 출력, 오버라이딩
		System.out.println("구리😭");
	}

	@Override
	void attackVoice() { // 공격시 출력되는 attackVoice, 오버라이딩
		System.out.print("탕!탕! ");
	}
}

class Oddish extends Pokemon{ // 자식클래스, 뚜벅쵸
	// 생성자, 타입/이름 고정
	Oddish(){
		super("풀", "뚜벅쵸"); // 부모생성자 호출
	}
	// 함수
	@Override
	void hello() { // 울음소리 출력, 오버라이딩
		System.out.println("뚜벅😭");
	}

	@Override
	void attackVoice() { // 공격시 출력되는 attackVoice, 오버라이딩
		System.out.print("잎날가르기!! ");
	}
}
////////////////

public class Test02{

	public static int menu(){ // 메뉴판 출력
		System.out.println("★★포켓몬 게임★★");
		System.out.println("====== 메 뉴 ======");
		System.out.println("1. 게임하기");
		System.out.println("2. 전체 상태 출력");
		System.out.println("3. 울음소리 듣기");
		System.out.println("4. 포켓몬 잡기");			
		System.out.println("0. 게임종료");			
		System.out.println("==================");
		System.out.print("메뉴를 선택해주세요 >> ");

		// 메뉴 선택
		int num = getValidInput(0,4);
		return num;
	}
	public static boolean isEmpty(int cnt){
		/*보유포켓몬 없으면*/
		if(cnt<=0) {
			System.out.println("소유한 포켓몬이 없습니다!");
			return true;
		}
		return false;
	}
	public static boolean isFull(int cnt, Pokemon[] datas){
		/*포켓몬 가득차면*/
		if(cnt>=datas.length) {
			return true;
		}
		return false;
	}

	/* 포켓몬 선택, 유효성 검사*/
	public static int getValidInput(int start, int end) {
		Scanner sc = new Scanner(System.in);
		int n = 0;
		while (true) {
			try {
				n = Integer.parseInt(sc.nextLine()); // 문자열로 입력받고 정수로 변환
				if (start <= n && n <= end) { // 범위 내의 숫자를 알맞게 입력했다면
					return n;
				} else { // 범위 밖의 숫자를 입력한 경우
					System.out.print("잘못된 입력입니다. 다시 선택해주세요 >> "); 
				}
			} catch (NumberFormatException e) { // 숫자가 아닌 문자를 입력한 경우
				System.out.print("잘못된 입력입니다. 다시 선택해주세요 >> ");
			}

		}

	}

	public static int pokemonMenu(int cnt, Pokemon[] datas) {	//
		System.out.println("포켓몬을 선택해주세요.");
		for (int i = 0; i < cnt; i++) {
			System.out.println((i+1)+". " +datas[i]);
		}
		// 출력된 포켓몬 중 선택
		int num = getValidInput(1, cnt);
		return num-1;  // 배열의 위치를 돌려줌
	}

	public static void main(String[] args) {
		// 포켓몬을 담을 배열 생성
		Pokemon[] datas = new Pokemon[3];
		int cnt = 0;
		Scanner sc = new Scanner(System.in);
		// 게임을 끝내기 전까지 무한 반복
		while(true) {

			// 메뉴 출력 ,선택 함수를 불러 정수값을 받음
			int menu = menu();

			// 메뉴값에 따른 if문
			// 만약 menu가 0이면
			if(menu == 0) {		// 게임 종료 (맡은 부분)
				System.out.println("게임을 종료합니다.");
				break;
			}
			// 만약 menu가 1이면
			else if(menu == 1) {	// 게임 시작하기 (맡은 부분)
				// 지니고 있는 포켓몬이 있는지 확인
				if(isEmpty(cnt)) {  // 만약 비어있다면 
					continue;
				}

				// Y/N 답을 담을 문자열 변수 answer
				String answer;

				System.out.println("야생 포켓몬이 나타났습니다.");
				System.out.print("공격하시겠습니까? (Y/N)");
				answer = sc.next();

				// 선택할 포켓몬 위치를 담을 변수
				int num;
				// 만약 공격한다면
				if(answer.equals("Y")) {
					// 포켓몬을 고름, pokemonMenu
					num = pokemonMenu(cnt, datas);
				}
				// 아니라면 도망
				else {
					System.out.println("무사히 도망쳤습니다.");
					continue;
				}

				// 실패시 다시 도전하는 프로그램
				// 전투 반복
				while(true) {
					// 공격 시도 attack() 함수

					// 공격 실패시
					if(!(datas[num].attack())) {
						// 다시 공격하겠습니까?(answer)
						System.out.print("다시 공격하시겠습니까? (Y/N)");
						answer = sc.next();

						// Y면 다시 while문 처음의 attack 다시 실행
						if(answer.equals("Y")) {
							System.out.println("다시 공격을 시도합니다.");
						}
						// N 또는 그 외의 답이면 전투에서 벗어남
						else {
							System.out.println("무사히 도망쳤습니다.");
							break;
						}
					}
					// 성공했을 때
					else {
						break;
					}
				}
			}

			// 만약 menu가 2이면
			else if(menu==2) {//전체상태 출력
				if(isEmpty(cnt)) {//소유한 포켓몬이 없는지 유효성 검사
					continue;
				}

				System.out.println("================");
				for(int i=0;i<cnt;i++) {
					System.out.println(datas[i].toString());
				}
				System.out.println("================");
			}
			else if(menu == 3) { // 3. 울음소리 듣기
				// 보유한 포켓몬이 있는지 유효성 검사(isNull)
				if(isEmpty(cnt)) {
					continue;
				}
				//포켓몬 선택 
				int num;
				num=pokemonMenu(cnt, datas); // 포켓몬 선택 메뉴 출력

				// 울음소리 출력
				System.out.print(datas[num].getName() + " : ");
				datas[num].hello();
			}
			// 만약 menu가 4이면
			else if(menu == 4) {	// 포켓몬 잡기
				// 포켓몬을 더 잡을 수 있는지 확인
				if(isFull(cnt, datas)) {	//만약 공간이 꽉 찼다면
					System.out.println("더 이상 포켓몬을 잡을 수 없습니다!");
					continue;
				}

				// 포켓몬 이름 배열
				String[] pokemonName = {"메타몽", "조로아", "탕구리", "뚜벅쵸"};

				// 잡을 수 있는 포켓몬 출력
				System.out.println("잡을 수 있는 포켓몬");
				// 포켓몬 이름 배열을 차례로 출력(for each문)
				int i = 1; // 번호 출력용
				for(String name : pokemonName) {
					// 이름들 차례로 출력
					System.out.println(i+". "+ name);
					i++;
				}

				// 포켓몬을 선택 받음
				System.out.print("잡을 포켓몬을 선택해주세요 >> ");
				int num = getValidInput(1, 4);

				// 포켓몬을 잡음
				if(num == 1) {		// 메타몽, 1이라면
					// 메타몽 객체 생성
					datas[cnt] = new Ditto();
					System.out.println("메타몽을 잡았습니다!");
				}
				else if(num == 2) {	// 조로아, 2라면
					// 조로아 객체 생성
					datas[cnt] = new Zorua();
					System.out.println("조로아를 잡았습니다!");
				}
				else if(num == 3) {	// 탕구리, 3이라면
					// 탕구리 객체 생성
					datas[cnt] = new Cubone();
					System.out.println("탕구리를 잡았습니다!");
				}
				else if(num == 4) {	// 뚜벅쵸, 4라면
					// 뚜벅초 객체 생성
					datas[cnt] = new Oddish();
					System.out.println("뚜벅쵸를 잡았습니다!");
				}
				// 소지 포켓몬 추가
				cnt++;
			}
			else {		// 잘못 입력시
				System.out.println("잘못 입력하셨습니다.");
			}

		}

	}
}

 

< 수정 반영한 부분>

  • selectOne() 함수 이름을 getValidInput() 으로 수정
  • isNull() 보다는 isEmpty()가 올바르므로 이 함수또한 이름 수정
  • 간단한 오탈자(뚜벅쵸 초 ...) 수정
  • 메뉴에 문자열을 입력한 경우 NumberFormatException 오류가 발생는데, 이를 getValidInput()에서 try-catch 문을 이용하여 예외처리
  • hello()와 attackVoice()는 자식클래스에서 오버라이딩하여 받아오고, 포켓몬 클래스에서는 abstract로 변경(오버라이딩 강제)
  • 멤버변수 pulblic-> private , getter setter 받아옴
  • levelUp()함수 void로 변경
  • 그 외 부드럽지 않았던 부분 수정

 

'프로젝트' 카테고리의 다른 글

COMA 클라이밍 크루 최종 프로젝트 자료  (0) 2024.11.14
[팀 프로젝트] COMA 클라이밍 크루 커뮤니티 중간 프로젝트 후기 및 느낀점  (1) 2024.10.01
[JAVA] 쇼핑몰 프로그램 MVC 패턴으로 구현하기 프로젝트  (0) 2024.07.24
[JAVA] 포켓몬 게임 프로젝트  (2) 2024.07.12
UP - DOWN 게임 만들기 (첫 번째 팀 프로젝트, 셀프 리뷰 )  (0) 2024.07.01
'프로젝트' 카테고리의 다른 글
  • [팀 프로젝트] COMA 클라이밍 크루 커뮤니티 중간 프로젝트 후기 및 느낀점
  • [JAVA] 쇼핑몰 프로그램 MVC 패턴으로 구현하기 프로젝트
  • [JAVA] 포켓몬 게임 프로젝트
  • UP - DOWN 게임 만들기 (첫 번째 팀 프로젝트, 셀프 리뷰 )
yn98
yn98
좌우명 : 여전할 것 인가, 역전할 것 인가? 백엔드 개발자가 되고싶은 역전하고 있는 개발자 꿈나무의 블로그입니다. 개발을 하면서 공부한 것들을 기록합니다. 24.06 ~
  • yn98
    개발 꿈나무
    yn98
  • 전체
    오늘
    어제
    • 분류 전체보기 (131)
      • Python (3)
      • 공부 (7)
      • DB (7)
      • JAVA (24)
      • JSP (9)
      • jQuery (2)
      • HTML (3)
      • Spring (20)
      • 웹 (4)
      • C (1)
      • Git (2)
      • 에러일기 (19)
      • 프로젝트 (6)
      • 책 (21)
        • 멘토씨리즈 자바 (14)
        • 2024 수제비 정보처리기사 (7)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
    • Notion
  • 공지사항

  • 인기 글

  • 태그

    java
    정보처리기사 실기
    멘토씨리즈 자바
    @repository
    객체지향
    정보처리기사
    DispatcherServlet
    정처기 실기
    어노테이션
    티스토리챌린지
    생성자
    이벤트 스케줄러
    정처기
    2-layered 아키텍처
    오버로딩
    상속
    jsp
    오블완
    @Component
    ViewResolver
    MVC
    수제비
    스프링 프레임워크
    aop
    Di
    recoverabledataaccessexception
    codeup 4891 : 행복
    Spring
    @service
    html
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
yn98
[JAVA] 포켓몬 게임 프로젝트 - 2

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.