https://github.com/MinWoo1995/RunningTeam-TASK3
[필수 미션] - 랜덤 1:1 전투 시뮬레이션
이제 서로의 팀에서 랜덤한 챔피언 하나씩 꺼내 싸우게 해보자.
[선택 미션]
1. 제네릭 와일드카드(? extends Champion) 적용해보기
미션 내용
- 아래 메서드를 설계하세요.
public static void printTeamMembers(List<? extends Champion> team)
- List<Garen> , List<Champion> 모두 받을 수 있어야 합니다.
2. 잘못된 제네릭 설계 사례 만들고 고쳐보기
미션 내용
- 아래와 같은 잘못된 설계를 먼저 작성합니다.
public class Team<T> {
private List<T> members;
}
- 왜 이 설계가 위험한지 설명한 뒤
- T extends Champion 으로 수정하세요.
Main
package Task_LOLChampion;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Garen garen1 = new Garen("Garen1");
Garen garen2 = new Garen("Garen2");
Ash ash1 = new Ash("Ash1");
Ash ash2 = new Ash("Ash2");
//가렌1과 에쉬1이 서로 공격을 주고받음
garen1.attackTo(ash1);
ash1.attackTo(garen1);
//Q/W/E/R 스킬을 모두 추상 메서드로 확장해보기
ash2.useQ(garen2,garen2);
ash2.useW(garen2);
ash2.useE(garen2);
ash2.useR(garen2);
//Lux, Teemo 등 챔피언 2명 더 만들기
Lux lux1 = new Lux("Lux1");
Teemo teemo1 = new Teemo("Teemo1");
//가렌에게 “레벨업(levelUp)” 메서드를 만들어 체력·공격력 증가하게 해보기
garen1.levelUp(200);
garen1.useR(ash1);
//takeDamage 후 체력이 0 이하가 되면 “가렌 사망!” 메시지 출력
ash1.useW(garen1);
//attackDamage 값을 난수(랜덤)로 만들어 “치명타 개념” 추가해보기
garen2.useE(ash2);
//인터페이스를 2개 이상 조합한 챔피언 만들기(예: 근거리 + 탱커)
garen2.defenseDamageUp();
garen2.dash();
//“치명타 확률” 같은 고유 패시브를 메서드로 추가해보기
garen1.useE(ash1);
//기본 체력, 기본 공격력, 기본 방어력 값 GameConstants의 static final 상수 사용
Ash ash3 = new Ash("Ash3");
//모든 챔피언의 전투 횟수(static) 카운팅 기능 추가
System.out.println("모든 챔피언의 총 전투 횟수 : "+GameConstants.battleCount);
//고정된 부활(resurrect) 규칙을 final 메서드로 만들기
Ash ash4 = new Ash("Ash4");
ash4.setattackDamage(1000);//어택데미지 변수가 상수로 초기 셋팅 되어 기존 어택데미지를 높게 재설정
ash4.useQ(garen1,garen1);
//인터페이스 otherResurrect을 만들어 추상메서드를 선언하여 서로 다른 챔피언의 부활 조건을 결정
//가렌은 최대 2번만 부활이 가능하다.
//에쉬는 최대 3번만 부활이 가능하다.
ash4.useQ(garen1,garen1);
ash4.useQ(garen1,garen1);
garen1.useQ(ash4,ash4);
garen1.useQ(ash4,ash4);
garen1.useQ(ash4,ash4);
garen1.useQ(ash4,ash4);
//전투 로그 기록 출력
GameConstants.LogPrint();
//static 변수 두 개가 서로 참조할 때 초기화 순서 문제를 경험해보기
/*int a = 5;
int c = a + b;//일반 변수의경우 선언되지 않고 먼저 사용하면 오류가 발생
int b = 5;
System.out.println(c);*/
/*
GameConstants클래스
public static int a = b+10;
public static int b = 20;
public static void test(){
System.out.println("a :" + a);<-10출력
System.out.println("b :" + b);<-20출력
}
GameConstants.test();
//확인해보니, 논리적으로 실행이 되어야하는데, 자바 버전에 따라 실행이 불가능함
*/
//전투 횟수(battleCount)를 인스턴스 필드로 바꾸면 어떤 문제가 생기는지 실험
//GameConstants.battleCount을 인스턴스로 변경시 모든 챔피언의 전투횟수를 수집할수 없다.
//챔피언별 battleCount를 가지게 되고 자기의 카운트만 저장하게 됩니다.
//챔피언별 저장한 카운트를 게터로 받아와서 한대모아 더해서 출력하는 방법이 가능하다.
//상수 그룹을 Enum으로 표현해보기 [속성(체력/공격/방어)를 상수화 시켜 챔피언 생성시 상수조합으로 챔피언 생성하기]
//실행 결과 확인하기 GameConstants.championsValue에서 이넘을 정의하고 챔피언 클래스의 생성자에 마력을 설정하게 로직을 구현
//부활(resurrect) 메서드를 템플릿 메서드 패턴으로 확장해보기
//3차 과제 시작
//서로의 팀에서 랜덤한 챔피언 하나씩 꺼내 싸우게 해보자.
//레드팀 블루팀을 만들고 거기서 랜덤하게 챔피언을 꺼내어 전투하게 하기
List<Champion> redTeam = new ArrayList<Champion>();
List<Champion> blueTeam = new ArrayList<Champion>();
List<Champion> allChampions = new ArrayList<Champion>();
allChampions.add(new Garen("가렌1"));
allChampions.add(new Ash("에쉬1"));
allChampions.add(new Ash("에쉬2"));
allChampions.add(new Garen("가렌2"));
allChampions.add(new Ash("에쉬3"));
allChampions.add(new Ash("에쉬4"));
//레드팀 블루팀 분류
for (int i = 0 ; i < allChampions.size(); i++) {
Champion a = allChampions.get(i);
if(a.getTeamcolor()==0){
redTeam.add(a);
}else{
blueTeam.add(a);
}
}
//랜덤 전투하기
RandomBattle randomBattle = new RandomBattle(redTeam, blueTeam);//배틀 객채 생성
while(true) {
//체력을 어떻게 설정할지 입력받기
System.out.print("몇 라운드로 진행 하시겠습니까?(정수로 입력하세요) : ");
Scanner scan = new Scanner(System.in);
String scan1 = scan.nextLine();//입력받기
int scanInt = Integer.parseInt(scan1);//int로 변환
if (0<scanInt) {
for (int i = 0; i <= scanInt; i++) {
randomBattle.randomBattleManager(redTeam,blueTeam);
}
break;
} else {
System.out.println("입력을 잘못하셨습니다. 음수,소수점 제외 양의 정수만 입력하세요");
}
}
//클래스 Team 에서 설계된 내용중에 어떻게 문제가 발생하는지 작성해둠
//제네릭 와일드 카드 적용해보기->RandomBattle클래스에 매개변수를 와일드 카드로 수정
//printTeamMembers클래스를 만들어 가렌끼리 에쉬끼리 팀을 구성해보기
List<Garen> garenList = new ArrayList<>();
List<Ash> ashList = new ArrayList<>();
garenList.add(garen1);
garenList.add(garen2);
ashList.add(ash1);
ashList.add(ash2);
ashList.add(ash3);
ashList.add(ash4);
System.out.println("----------가렌 챔피언 목록입니다.----------");
printTeamMembers.printTeamMembers(garenList);
System.out.println("----------에쉬 챔피언 목록입니다.----------");
printTeamMembers.printTeamMembers(ashList);
//[문제]allChampion.getMembers() 메서드 호출시 Task_LOLChampion.Garen@728938a9 해쉬값이 나오게 됨
//[해결]Champion 클래스에 toString()을 오버라이드 하여 List 컬렉션을 출력할때 JVM이 오버라이드로 정의된 toString()을 호출하여 문자열을 받아간다.
}
}










Campion
package Task_LOLChampion;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public abstract class Champion implements otherResurrect {
private String name;
private int levle;
private int attackDamage;
private int defenseDamage;
private int HP;
private int MP;
private int ex;
private int maxEx;
Random rand = new Random();
private int mindamage=100;
private int maxmindamage=300;
private int randomDamage;
private int range = maxmindamage - mindamage+1;
private int resurrectCount = 0;
private int resurrectCount2 = 0;
private int maxresurrectCount = 0;
private int maxresurrectCount2 = 0;
private int teamcolor = 0;
final double CRITICAL_CHANCE = 0.5;//50% 확률
Random random = new Random();
public Champion(String name,int level,int attackDamage,int defenseDamage,int maxEx) {
this.name = name;
this.levle = level;
this.attackDamage=GameConstants.getAttackDamage();//private static final 상수이기 때문에 게터 메서드로 참조
this.defenseDamage = GameConstants.getDefenseDamage();//private static final 상수이기 때문에 게터 메서드로 참조
this.HP = GameConstants.HP;//static final으로 상수를 가져와서 초기화 진행
this.MP = MP;
this.maxEx = maxEx;
GameConstants.setchampionnum(1);
while(true) {
//체력을 어떻게 설정할지 입력받기
System.out.print(this.getName() + "의 L1=300,L2=400,L3=500,L4=1200 원하는 마력값을 입력해주세요 ex)L1 : ");
Scanner scan = new Scanner(System.in);
String scan1 = scan.nextLine();
if (scan1.equals("L1") || scan1.equals("L2") || scan1.equals("L3") || scan1.equals("L4")) {
//[문제] GameConstants.championsValue(scan); 이넘클래스는 이렇게 호출불가능
//[해결] 리턴값을 저장할 공간 = 클래스명.메서드명.해당메서드의 세터로 셋팅후.게터로 리턴해달라
this.MP = GameConstants.championsValue.valueOf(scan1).getValue();
break;
} else {
System.out.println("입력을 잘못하셨습니다. L1,L2,L3,L4 중에서 대소문자를 구분하여 입력해주세요 : ");
}
}
while(true) {
//체력을 어떻게 설정할지 입력받기
System.out.print(this.getName() + "의 RED BLUE 팀을 입력해주세요: ");
Scanner scan = new Scanner(System.in);
String scan1 = scan.nextLine();
if (scan1.equals("RED") || scan1.equals("BLUE")) {
//[문제] GameConstants.championsValue(scan); 이넘클래스는 이렇게 호출불가능
//[해결] 리턴값을 저장할 공간 = 클래스명.메서드명.해당메서드의 세터로 셋팅후.게터로 리턴해달라
this.teamcolor = GameConstants.TeamColor.valueOf(scan1).getValue();
break;
} else {
System.out.println("입력을 잘못하셨습니다. RED,BLUE 중에서 대소문자를 구분하여 입력해주세요 : ");
}
}
}
public int getTeamcolor() {
return teamcolor;
}
public void setTeamcolor(int teamcolor) {}
public int criticalDamage(){
double probabilityCheck = random.nextDouble();
if (probabilityCheck < CRITICAL_CHANCE) {
randomDamage = rand.nextInt(range)+mindamage;
}
return this.randomDamage;
}
public void setresurrectCount(int resurrectCount){
this.resurrectCount = resurrectCount;
}
public int getresurrectCount(){
return this.resurrectCount;
}
public void setmaxresurrectCount(){
this.maxresurrectCount = GameConstants.getmaxresurrectCount();
}
public int getmaxresurrectCount(){
return this.maxresurrectCount;
}
public void setmaxresurrectCount2(){
this.maxresurrectCount2 = GameConstants.getmaxresurrectCount2();
}
public int getmaxresurrectCount2(){
return this.maxresurrectCount2;
}
public void setresurrectCount2(int resurrectCount){
this.resurrectCount2 = resurrectCount;
}
public int getresurrectCount2(){
return this.resurrectCount2;
}
public int getlevel() {
return levle;
}
public void setlevel(int level) {
this.levle += level;
}
public int getrandomDamage(){
return randomDamage;
}
public void setdefenseDamageUp1(int defenseDamage) {
this.defenseDamage += defenseDamage;
}
public int getdefenseDamageUp1(){
return defenseDamage;
}
public int getmaxEx(){
return maxEx;
}
public void setmaxEx(int maxEx) {
this.maxEx = maxEx;
}
public int getEx(){
return ex;
}
public void setEx(int ex){
this.ex = ex;
}
public String getName() {
return name;
}
public int getLevle() {
return levle;
}
public void setHP(int HP) {
this.HP = HP;
}
public int getHP() {
return this.HP;
}
public int getMP() {
return this.MP;
}
public void setMP(int MP) {
this.MP = MP;
}
public int getattackDamage() {
return this.attackDamage;
}
public void setattackDamage(int attackDamage){
this.attackDamage += attackDamage;
}
public void attackTo(Champion target){
int a=target.getHP()-this.attackDamage;
target.setHP(a);
System.out.println(target.getName()+"가"+this.name+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.HP+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
this.MP-=100;
System.out.println(this.name+"의 남은 마력 : "+this.MP);
}
public abstract void useQ(Champion target,otherResurrect target2);
public abstract void useW(Champion target);
public abstract void useE(Champion target);
public abstract void useR(Champion target);
public void takeDamage(int damage) {
System.out.println("------------takeDamage------------");
int m = this.HP - damage;
if (m <= 0) {
System.out.println(this.name + "가 사망 하였습니다.");
System.out.println("-------------------------------");
setHP(0);
} else {
System.out.println(this.name + "의 남은 체력 :" + this.HP);
System.out.println("-------------------------------");
setHP(m);
}
}
//고정된 부활(resurrect) 규칙을 final 메서드로 만들기
final void resurrect1(){
if(this.HP<=0){
this.HP=0;//너무 큰 데미지를 입어 마이너스 체력까지 떨어진 상태일 경우 0으로 체력을 초기화후 20센트 체력을 주입
this.HP+=(int)(GameConstants.HP * 0.2);//해당 변수들이 int 형이기 때문에 더블형이 불가하여 형변환을 해야한다.
System.out.println(this.name + "의 체력이 20% 회복되어 부활 되었습니다. 현재 체력 : " + this.HP);
System.out.println(this.name + "님 어서 우물로 돌아가 체력을 회복하세요~");
}
hook();
}
final void resurrect(){
if(this.HP<=0){
this.HP=0;
}
}
public abstract void checkHP();//공격자가 공격 당한 챔피언의 피를 본인 스스로 확인해보라는 메서드
public void hook(){}
public void ohterResurrect(){}
@Override
public String toString() {
return this.name;
}
}
GameConstants
package Task_LOLChampion;
import java.util.ArrayList;
import java.util.List;
public class GameConstants {//여기에는 static 선언 불가.
//내부에 동일한 이름을 가진 (GameConstants)을 2중 구조로 선언시 내부 클래스에는 static 선언이 가능하다.
//내부에 2중 클래스를 만들어 static을 부여하는 사용법은 크게 2가지 정도이다.
//1.대규모 상수 그룹의 논리적 분리 (Namespacing) 2. 독립적인 Helper Class 제공
//1번 이유
//챔피언 관련 GameConstants.Champion.HP
//시스템 설정 GameConstants.System.TIMEOUT
//UI 색상 GameConstants.UI.COLOR_RED
//2번 이유
//바깥 클래스의 객체 없이도 독립적으로 동작해야 하는 유틸리티성 헬퍼 클래스를 만들 때 사용
static final int HP=100;//final 키워드 사용과 동시에 변수 값을 초기화하기 않으면 오류가 발생
private static final int attackDamage=100;
private static final int defenseDamage=50;//static이 붙게 되면 class 레벨의 변수가 된다!! 객체 생성없이 바로 사용가능하니까
//static final은 외부 클래스에서 접근은 가능 하나 수정이 불가하고 참조만 가능하다.
//static final private은 외부클래스에서 접근이 불가하고 내부 메서드나 생성자를 통해 접근이 가능하다.
static int battleCount = 0;//모든 챔피언의 전투 횟수 카운트하기 위한 독립 변수
private static final int resurrectCount = 0;
private static final int maxresurrectCount = 2;
private static final int maxresurrectCount2 = 3;
private static int championnum = 0;//챔피언 생성 수
private GameConstants(){
throw new AssertionError("이 클래스는 상수만 취급하는 클래스입니다. [클래스명.상수명]으로 호출하세요");
//객체를 생성할려고 한다면, 오류문을 출력하여 올바르게 사용할수 있도록 안내하자!
}
public static int getchampionnum() {
return championnum;
}
public static void setchampionnum(int championnum) {
GameConstants.championnum += championnum;//챔피언 생성시 1씩 증가
}
//스태틱으로 선언된 상수들만 취급함으로, 생성자를 퍼블릭으로 사용하게 되면,
//다른 개발자가 불필요하게 객체를 생성하는 일을 방지하여 자원을 효율적으로 사용할수있다.
//왜냐하면 스태틱 변수들은 객체 생성 없이 바로 클래스명.상수명으로 바로 호출하여 사용하기 때문이다.
public static int getAttackDamage(){
return GameConstants.attackDamage;//static 키워드 때문에 this.변수명이 아닌 [클래스명.상수명]으로 리턴을 하면된다.
}
public static int getDefenseDamage(){
return GameConstants.defenseDamage;
}
public static int getresurrectCount(){
return GameConstants.resurrectCount;
}
public static int getmaxresurrectCount(){
return GameConstants.maxresurrectCount;
}
public static int getmaxresurrectCount2(){
return GameConstants.maxresurrectCount2;
}
public static List<String> log = new ArrayList<>();//전투로그 저장하는 동적배열
public static void Log(String logMassage){
log.add(logMassage);
System.out.println("전투로그가 기록되었습니다.");
}
public static void LogPrint(){
for(int i=0;i<log.size();i++){
System.out.println((i+1)+"번 "+log.get(i));
}
}
public enum championsValue{
//정의
L1(300),
L2(400),
L3(500),
L4(1200);
//속성
private final int value;
//생성자
championsValue(int value){
this.value = value;
}
//게터
public int getValue(){
return value;
}
}
public enum TeamColor{
//정의
RED(0),
BLUE(1);
//속성
private final int color;
//생성자
TeamColor(int color){
this.color = color;
}
//게터
public int getValue(){
return color;
}
}
}
ohterResurrect
package Task_LOLChampion;
public interface otherResurrect {
//인터페이스는 메서드 선언만 해두고, 정의는 각자 클래스에서 알아서 맞춰서 하기
//자바 7버전은 무조건 메서드를 추상메서드로 선언해야함
public abstract void ohterResurrect();
}
ShortDistance
package Task_LOLChampion;
public interface ShortDistance {
public void dash();
}
Tanker
package Task_LOLChampion;
public interface Tanker {
public void defenseDamageUp();
}
Garen
package Task_LOLChampion;
public class Garen extends Champion implements Tanker,ShortDistance,otherResurrect {
public Garen(String name){
super(name,1,1000,50,500);
}
@Override
public void defenseDamageUp() {
System.out.println("------------근거리 패시브------------");
System.out.println("방어력이 100 증가합니다.");
setdefenseDamageUp1(100);
System.out.println(getName()+"의 패시브 반영 방어력 : "+getdefenseDamageUp1());
System.out.println("----------------------------");
}
@Override
public void dash(){
System.out.println("------------탱커 패시브------------");
System.out.println("앞으로 순간이동을 실시합니다!!");
System.out.println("----------------------------");
}
@Override
public void useQ(Champion target, otherResurrect target2) {
System.out.println("------------useQ------------");
System.out.println(getName() + "이(가) 'Q' 스킬을 사용합니다.");
attackTo(target);
System.out.println("----------------------------");
GameConstants.battleCount++;
target2.ohterResurrect();
String logMemo = this.getName()+"의 "+"Q 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useR(Champion target) {
System.out.println("------------useR------------");
System.out.println(getName() + "이(가) 'R' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 100;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
System.out.println("----------------------------");
GameConstants.battleCount++;
String logMemo = this.getName()+"의 "+"R 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useE(Champion target) {
System.out.println("------------useE------------");
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
System.out.println(getName() + "의 'E' 스킬은 랜덤한 확률로 치명타 데미지가 발생합니다.");
int probability = criticalDamage();
if (probability >= 100) {
int hp = target.getHP()-getrandomDamage();
target.setHP(hp);
GameConstants.battleCount++;
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
}else{
System.out.println(getName() + "의 치명타가 발생하지 않았습니다.");
}
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 50;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
System.out.println("---------------------------");
String logMemo = this.getName()+"의 "+"E 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useW(Champion target) {
System.out.println("------------useW------------");
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = getattackDamage();
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
target.takeDamage(hp);
int mp = getMP();
mp -= 20;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
System.out.println("----------------------------");
GameConstants.battleCount++;
String logMemo = this.getName()+"의 "+"W 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
public void levelUp(int ex) {
System.out.println("------------levelUp-------------");
System.out.println(getName()+"이 획득한 경험치 : "+ex);
int getex = getEx();
int ex1 = getex+ex;
setEx(ex1);
System.out.println(getName()+"의 현재 총 경험치 : "+getEx());
int getex1 = getEx();
int maxex = getmaxEx();
int ex2 = maxex-getex1;
System.out.println(getName()+"의 레벨업까지 필요한 경험치 : "+ex2);
if(getex1>=maxex){
setlevel(1);
System.out.println(getName()+"레벨업 하였습니다. : 현재레벨 "+getlevel());
setattackDamage(50);
setHP(150);
System.out.println(getName()+"의 총 체력 : "+getHP()+" 총 공경력 :"+getattackDamage());
}
System.out.println("-------------------------------");
}
@Override
public void checkHP(){
if(getHP()<=0){
System.out.println(getName()+"의 체력이 "+getHP()+" 사망하였습니다.");
resurrect1();
}
}
@Override
public void ohterResurrect(){
this.setmaxresurrectCount();
int b = this.getresurrectCount();
int c = this.getmaxresurrectCount();
if(b<c){
if(this.getHP()<=0){
System.out.println(this.getName()+"의 체력이 "+this.getHP()+" 사망하였습니다.");
resurrect1();
b++;
this.setresurrectCount(b);
}
}else{
System.out.println(this.getName()+"은 부활"+this.getmaxresurrectCount()+"회를 사용 하셨음으로 부활이 불가합니다.");
}
}
public void hook(){
System.out.println(this.getName()+"은 부활하면서 체력 증강 +100 버프를 추가 적용받았습니다.");
int buf = this.getHP()+100;
this.setHP(buf);
}
}
Ash
package Task_LOLChampion;
public class Ash extends Champion implements otherResurrect {
public Ash(String name){
super(name,1,600,50,500);
}
@Override
public void useQ(Champion target, otherResurrect target2) {
System.out.println("------------useQ------------");
System.out.println(getName() + "이(가) 'Q' 스킬을 사용합니다.");
attackTo(target);
System.out.println("----------------------------");
GameConstants.battleCount++;
target2.ohterResurrect();
String logMemo = this.getName()+"의 "+"Q 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useR(Champion target) {
System.out.println(getName() + "이(가) 'R' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 100;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
String logMemo = this.getName()+"의 "+"R 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useE(Champion target) {
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 50;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
String logMemo = this.getName()+"의 "+"E 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void useW(Champion target) {
System.out.println("------------useW------------");
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = getattackDamage();
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
target.takeDamage(hp);
int mp = getMP();
mp -= 20;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
System.out.println("----------------------------");
GameConstants.battleCount++;
String logMemo = this.getName()+"의 "+"W 스킬 전투로그 기록 타겟 : "+ target.getName();
GameConstants.Log(logMemo);
}
@Override
public void checkHP(){
if(getHP()<=0){
resurrect();
}
}
@Override
public void ohterResurrect(){
this.setmaxresurrectCount2();
int b = this.getresurrectCount2();
int c = this.getmaxresurrectCount2();
if(b<c){
if(this.getHP()<=0){
System.out.println(this.getName()+"의 체력이 "+this.getHP()+" 사망하였습니다.");
resurrect1();
b++;
this.setresurrectCount2(b);
}
}else{
System.out.println(this.getName()+"은 부활"+this.getmaxresurrectCount2()+"회를 사용 하셨음으로 부활이 불가합니다.");
}
}
public void hook(){
System.out.println(this.getName()+"은 부활하면서 체력 증강 +200 버프를 추가 적용받았습니다.");
int buf = this.getHP()+100;
this.setHP(buf);
}
}
Lux
package Task_LOLChampion;
public class Lux extends Champion {
public Lux(String name) {
super(name,5,50,10,600);
}
@Override
public void useQ(Champion target, otherResurrect target2) {
System.out.println(getName() + "이(가) 'Q' 스킬을 사용합니다.");
attackTo(target);
GameConstants.battleCount++;
}
@Override
public void useR(Champion target) {
System.out.println(getName() + "이(가) 'R' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 100;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void useE(Champion target) {
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 10;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void useW(Champion target) {
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 40;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void checkHP(){
if(getHP()<=0){
resurrect();
}
}
public void hook(){
System.out.println(this.getName()+"은 부활하면서 체력 증강 +300 버프를 추가 적용받았습니다.");
int buf = this.getHP()+100;
this.setHP(buf);
}
}
Teemo
package Task_LOLChampion;
public class Teemo extends Champion{
public Teemo(String name) {
super(name,2,30,10,400);
}
@Override
public void useQ(Champion target, otherResurrect target2) {
System.out.println(getName() + "이(가) 'Q' 스킬을 사용합니다.");
attackTo(target);
GameConstants.battleCount++;
}
@Override
public void useR(Champion target) {
System.out.println(getName() + "이(가) 'R' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 100;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void useE(Champion target) {
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 60;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void useW(Champion target) {
System.out.println(getName() + "이(가) 'E' 스킬을 사용합니다.");
int hp = target.getHP()-getattackDamage();
target.setHP(hp);
System.out.println(target.getName()+"가"+getName()+"에게 공격 당하였습니다. 현재"+target.getName()+"의 체력은"+target.getHP()+"입니다.");
//출력문을 데미지 계산 위에 위치시켜서 감소된 HP 확인이 안되었다.[문제]
int mp = getMP();
mp -= 80;
setMP(mp);
System.out.println(getName()+"의 남은 마력 : "+getMP());
GameConstants.battleCount++;
}
@Override
public void checkHP(){
if(getHP()<=0){
resurrect();
}
}
public void hook(){
System.out.println(this.getName()+"은 부활하면서 체력 증강 +400 버프를 추가 적용받았습니다.");
int buf = this.getHP()+100;
this.setHP(buf);
}
}
Team
package Task_LOLChampion;
import java.util.List;
public class Team<T> {//클래스명 옆에 <T>을 작성하여 제네릭 클래스임을 명시해야함
private List<T> members;
}
//이렇게 제네릭을 설계하게 된다면 발생하는 문제점
//타입의 안정성이 보장되지 못한다.
//아무런 타입을 다루게 되며, 반데로 저장된 데이터를 활용할때 오류가 발생할수있다.
//그렇기 때문에, 제네릭의 타입을 지정하여 사용하여야 하며,
//아무런 타입의 데이터가 들어가있다면 로직을 구현하는데도 문제가 발생한다.
//그래서 반드시 클래스명 옆에 제네릭의 상한선은 정하는게 맞다!
printTeamMembers
package Task_LOLChampion;
import java.util.ArrayList;
import java.util.List;
public class printTeamMembers{
public static void printTeamMembers(List<? extends Champion> team){
System.out.println("---------- 팀 멤버 목록 ----------");
if (team.isEmpty()) {
System.out.println("팀에 멤버가 없습니다.");
return;
}
for (Champion member : team) {
System.out.println(member.getName());
}
System.out.println("---------------------------------");
}
}
'spring_2기[본캠프] > 과제' 카테고리의 다른 글
| [과제] 커머스2-1 (필수기능 완료 + 도전레벨1) (0) | 2025.12.18 |
|---|---|
| [과제] 커머스1(필수기능 완료) (0) | 2025.12.17 |
| [달리기반 과제] 2회차 과제 (0) | 2025.12.15 |
| [달리기반 과제] 1회차 과제 (0) | 2025.12.09 |
| [과제] 계산기 만들기 2 (0) | 2025.12.08 |