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

[보스 몬스터 잡기] 김선호 미션 제출합니다. #22

Open
wants to merge 18 commits into
base: SHKim55
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
27ce39f
feat(Boss): make Boss class with status field, status controlling me…
SHKim55 Feb 9, 2024
6ed3ab5
feat(Player): make Player class with status field, status controllin…
SHKim55 Feb 9, 2024
b61dbb4
refactor: delete getRandomHp method to make users set the HP of boss …
SHKim55 Feb 9, 2024
7d17113
feat(main): link main method to execute GameUI
SHKim55 Feb 9, 2024
513b513
refactor: fix printFigure to print separation line at the top
SHKim55 Feb 10, 2024
4038951
refactor: fix printStat, printFigure method to change console gui
SHKim55 Feb 10, 2024
1231b77
refactor: fix printStat method to change console gui
SHKim55 Feb 10, 2024
59953f9
add: exception class concerning unusual mp status
SHKim55 Feb 10, 2024
ec9de04
refactor: change main method to start the program by executing method…
SHKim55 Feb 10, 2024
f1b8971
add: service class controlling core logic of the program including at…
SHKim55 Feb 10, 2024
1090f16
add: controller class managing user input & console output
SHKim55 Feb 10, 2024
cbc5ee8
fix: remove unnecessary print statement
SHKim55 Feb 11, 2024
131b1ab
refactor: add NoMPException handling logic
SHKim55 Feb 11, 2024
9214352
feat: add exception class for invalid boss hp input
SHKim55 Feb 11, 2024
a58e74c
feat: add exception class for invalid player hp, mp input
SHKim55 Feb 11, 2024
b49093e
feat: add exception class for invalid player name input
SHKim55 Feb 11, 2024
211caf4
add: add readme file for checking implementation details
SHKim55 Feb 12, 2024
1d6576e
refactor: add exception handling code for user input process
SHKim55 Feb 12, 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
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# 미션 - 보스 몬스터 잡기

## ✔️ 구현사항

- 플레이어 클래스 구현
- [X] HP, MP
- [X] 물리 공격, 마법 공격
- [X] 상태 업데이트 메서드
- 보스몬스터 클래스 구현
- [X] HP, MP
- [X] 랜덤 데미지 공격
- [X] 상태 업데이트 메서드
- [X] 몬스터 그림 GUI 구현
- 입력 예외처리 구현
- [X] Exception Class
- [X] 게임 초기 설정 예외처리
- [X] 게임 중간 공격 입력 예외처리
- 로직 구현
- [X] 게임 core 로직 구현
- [X] 디버깅&테스트
- 인터페이스 구현
- [X] 게임 진행상태 안내 메시지 UI


## 🔍 진행방식

- 미션은 **기능 요구사항, 프로그래밍 요구사항, 과제 진행 요구사항** 세 가지로 구성되어 있습니다.
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/bossmonster/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package bossmonster;

import bossmonster.controller.GameUI;

public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
public static void main(String[] args) throws Exception {
GameUI gameUI = new GameUI();
gameUI.execute();
}
}
91 changes: 91 additions & 0 deletions src/main/java/bossmonster/controller/GameUI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package bossmonster.controller;

import bossmonster.exception.InvalidBossHPException;
import bossmonster.exception.InvalidPlayerHpMpException;
import bossmonster.exception.InvalidPlayerNameException;
import bossmonster.service.GameService;
import java.util.Scanner;

public class GameUI {
private final Scanner sc;
private Integer bossHp, playerHp, playerMp;
private String playerName;

public GameUI() {
this.sc = new Scanner(System.in);
this.setBossHp();
this.setPlayerName();
this.setPlayerHpMp();
}

private void setBossHp() {
System.out.println("! Welcome to Boss Monster Game !");
while(true) {
try {
System.out.println("보스 몬스터의 HP를 입력해주세요. (100이상 300이하)");
this.bossHp = this.sc.nextInt();

if(this.bossHp < 100 || this.bossHp > 300)
throw new InvalidBossHPException();

return;
} catch (InvalidBossHPException e) {
System.out.println("\n[ERROR] 유효한 보스 HP 값을 입력해주세요.");
}
}
}

private void setPlayerName() {
while(true) {
try {
System.out.println("플레이어의 이름을 입력해주세요. (5자 이내)");
this.playerName = this.sc.next();

if(this.playerName.length() > 5)
throw new InvalidPlayerNameException();

this.sc.nextLine();
return;
} catch (InvalidPlayerNameException e) {
System.out.println("\n[ERROR] 올바른 플레이어 이름을 입력해주세요.");
}
}
}

private void setPlayerHpMp() {
while(true) {
String playerStatInput;
try {
System.out.println("플레이어의 HP와 MP를 입력해주세요.(,로 구분 / HP와 MP의 합 최대 200 이내)");
playerStatInput = this.sc.nextLine();

if(!playerStatInput.matches("^[0-9]{1,3},[0-9]{1,3}$")) // 콤마 앞뒤로 숫자 3자리 이내
throw new IllegalArgumentException();

} catch (IllegalArgumentException e) {
System.out.println("\n[ERROR] 유효한 형태의 HP, MP 값을 입력해주세요 (Ex. 100,100)");
continue;
}

try {
String[] playerStat = playerStatInput.split(",");
this.playerHp = Integer.parseInt(playerStat[0]);
this.playerMp = Integer.parseInt(playerStat[1]);

if(this.playerHp + this.playerMp > 200)
throw new InvalidPlayerHpMpException();
} catch (InvalidPlayerHpMpException e) {
e.getStackTrace();
System.out.println("\n[ERROR] 유효한 형태의 HP, MP 값을 입력해주세요 (Ex. 100,100)");
continue;
}

return;
}
}

public void execute() {
GameService gameService = new GameService(this.bossHp, this.playerName, this.playerHp, this.playerMp);
gameService.play();
}
}
72 changes: 72 additions & 0 deletions src/main/java/bossmonster/domain/Boss.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package bossmonster.domain;

import java.util.Random;

public class Boss {
private final Integer maxHp;
private Integer currentHp;

public Boss(Integer hp) {
this.maxHp = hp;
this.currentHp = hp;
printStat();
printFigure(1);
}

public Integer getHp() { return this.currentHp; }

public void printStat() {
System.out.println("\n======================================");
System.out.println("BOSS HP [" + this.currentHp + "/" + this.maxHp + "]");
System.out.println("______________________________________");
}

public void printFigure(final Integer figureType) {
if(figureType == 1) { //initial
System.out.println(
" ^-^\n"
+ " / 0 0 \\\n"
+ "( \" )\n"
+ " \\ - /\n"
+ " - ^ - "
);
System.out.println("______________________________________");
return;
}
if(figureType == 0) { //damaged
System.out.println(
" ^-^\n"
+ " / X X \\\n"
+ "( \"\\ )\n"
+ " \\ - /\n"
+ " - ^ - "
);
System.out.println("______________________________________");
return;
}

System.out.println( //lose
" ^-^\n"
+ " / ^ ^ \\\n"
+ "( \"\\ )\n"
+ " \\ 3 /\n"
+ " - ^ - "
);
System.out.println("______________________________________");
}

public void decreaseHp(final Integer hp) {
if(this.currentHp - hp < 0) {
this.currentHp = 0;
return;
}

this.currentHp -= hp;
}

public Integer attack() {
Random random = new Random();
random.setSeed(System.currentTimeMillis());
return random.nextInt(20);
}
}
55 changes: 55 additions & 0 deletions src/main/java/bossmonster/domain/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package bossmonster.domain;

import bossmonster.exception.NoMPException;

public class Player {
private final String name;
private final Integer maxHp;
private Integer currentHp;
private final Integer maxMp;
private Integer currentMp;

public Player(String name, Integer hp, Integer mp) {
this.name = name;
this.maxHp = hp;
this.currentHp = hp;
this.maxMp = mp;
this.currentMp = mp;
printStat();
}

public String getName() { return name; }

public Integer getHp() { return currentHp; }

public void printStat() {
System.out.println(this.name + " HP [" + this.currentHp + "/" + this.maxHp + "]"
+ " MP [" + this.currentMp + "/" + this.maxMp + "]");
System.out.println("======================================\n");
}

public void decreaseHp(final Integer hp) {
if(this.currentHp - hp < 0) {
this.currentHp = 0;
return;
}

this.currentHp -= hp;
}

public Integer physicalAttack() {
if(this.currentMp + 10 > this.maxMp)
this.currentMp = this.maxMp;
else this.currentMp += 10;

return 10;
}

public Integer magicalAttack() throws NoMPException {
if(currentMp < 30)
throw new NoMPException();

this.currentMp -= 30;
return 20;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package bossmonster.exception;

public class InvalidBossHPException extends RuntimeException {
public InvalidBossHPException() { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package bossmonster.exception;

public class InvalidPlayerHpMpException extends RuntimeException {
public InvalidPlayerHpMpException() { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package bossmonster.exception;

public class InvalidPlayerNameException extends RuntimeException {
public InvalidPlayerNameException() { }
}
5 changes: 5 additions & 0 deletions src/main/java/bossmonster/exception/NoMPException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package bossmonster.exception;

public class NoMPException extends RuntimeException {
public NoMPException() { }
}
87 changes: 87 additions & 0 deletions src/main/java/bossmonster/service/GameService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package bossmonster.service;

import bossmonster.domain.Boss;
import bossmonster.domain.Player;
import bossmonster.exception.NoMPException;
import java.util.Scanner;

public class GameService {
private final Scanner sc = new Scanner(System.in);
private final Player player;
private final Boss boss;

private int attackNum = 0;

public GameService(final Integer bossHp, final String playerName, final Integer playerHp, final Integer playerMp) {
System.out.println("\n보스 레이드를 시작합니다.\n");
this.boss = new Boss(bossHp);
this.player = new Player(playerName, playerHp, playerMp);
}

public void play() {
while(true) {
boss.decreaseHp(playerAttack());
player.decreaseHp(bossAttack());
attackNum += 1;

if(boss.getHp() <= 0) {
this.win();
break;
}
if(player.getHp() <= 0) {
this.lose();
break;
}

boss.printStat();
boss.printFigure(0);
player.printStat();
}
}

public Integer playerAttack() {
Integer attackType, damage;

while(true) {
try {
System.out.println("어떤 공격을 하시겠습니까? 공격 번호를 입력해주세요.");
System.out.println("1. 물리 공격\n2. 마법 공격");
attackType = sc.nextInt();

if(attackType == 1) {
damage = player.physicalAttack();
System.out.println("\n물리 공격을 했습니다. (입힌 데미지: " + damage + ")");
return damage;
}

if(attackType == 2) {
damage = player.magicalAttack();
System.out.println("\n마법 공격을 했습니다. (입힌 데미지: " + damage + ")");
return damage;
}
} catch (NoMPException e) {
System.out.println("\n[ERROR] MP가 부족합니다. 다른 공격 방법을 선택해주세요.");
}
}
}

public Integer bossAttack() {
Integer damage;

damage = boss.attack();
System.out.println("보스가 공격했습니다. (입힌 데미지: " + damage + ")");
return damage;
}

public void win() {
System.out.println("\n" + player.getName() + " 님이 " + attackNum + "번의 전투 끝에 보스 몬스터를 잡았습니다.");
}

public void lose() {
boss.printStat();
boss.printFigure(-1);
player.printStat();
System.out.println(player.getName() + "의 HP가 0이 되었습니다.");
System.out.println("보스 레이드에 실패하셨습니다.");
}
}