
2023년 11월쯤 출시된 '붕대감기'라는 pccp 기출문제입니다.
문제만 봤을때는 턴제 게임에서 heal 스킬을 사용할 때, 몬스터가 공격할 때 얼마나 힐이 되는지 죽는지 시뮬레이션을 만드는 것 같았습니다.
개인적으로 문제가 재미있었습니다.
알고리즘을 짤 때 모든 상황을 변수로 만들고 최대한 코드를 나눠서 하기때문에 코드가 좀 길 수 있습니다.
문제 링크
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제

입출력 예시

입출력 예시 설명

풀이
전체적인 틀은 적의 마지막 공격에 있습니다.
0초 부터 적의 마지막 공격까지 for문을 돌려서 매 초마다 공격인지 힐 타임 인지 체크를 해가며 시뮬레이션을 돌리는 solution을 만들 것입니다.
0초부터 저의 마지막 공격까지 시간흐름을 기준으로 두 가지 상황으로 나누었습니다.
1. 힐 성공 (공격을 받지 않는다면)
2. 공격받는 상황
이중 힐 성공할 시 일어나는 상황들을 정리하자면
1.1 연속 성공 count ++
1.2 최대 연속 성공 시 최대 체력만큼 추가 회복
1.3 초당 힐 량 만큼 힐
2. 공격받는 상황에서 일어나는 상황들은
2.1 hp가 0이 되면 -1 return
2.2 연속 heal 성공 =0으로 초기화
2.3 공격만큼 체력을 깎는다.
주석으로 달아두고 코드를 짜기 전에 저는 재료를 먼저 만들어 두는 편입니다.
int answer = 0; //마지막 공격 이후 캐릭터의 체력
int limitTime = attacks[attacks.length -1][0]; // 최대 시간 (시간 제한)
int successCount = 0; //연속 성공 count == limitSuccess가 된다면 bandage [2]만큼 hp+++++++
int limitSuccess = bandage[0]; // 추가힐 발동 조건
int hp = health; //주인공 최력 health = maxHP
// 공격받는 타이밍을 체크 -1이라면 공격 타이밍아 아니다 // 공격 타이밍이라면 데미지를 배열에 넣는다.
int[] attackPatternArray = new int[limitTime +1];
Arrays.fill(attackPatternArray, -1); // default = -1;
//attack 타이밍을 전부 가져와서 attackBooleanArray에 적용
for (int[] attack : attacks) {
int attackTime = attack[0];
attackPatternArray[attackTime] = attack[1];
}
이렇게 알고리즘을 짜기전 주석과 사용할 것들을 변수에 따로 저장해 둡니다.
심지어 위에서 안사용하는 코드도 있는데 일단 예시로 전부 적었습니다.
다음으로 큰 틀을 잡고 상황을 부여해서 for문을 돌립니다.
for( int time = 0 ; time<=limitTime ; time++){
System.out.println("\n\n======\n\n"+time + "초 입니다.");
/*
* 구현하는곳
*/
System.out.println("현재 hp =" + hp);
}
각 게임마다 마지막 공격에 대한 time을 잡아 for문을 돌렸습니다.
이 안에 if문들을 넣을 것입니다.
테스트하기 편하게 time을 콘솔에 찍었습니다.
적 공격 패턴 코드
// =========================== 공격 패턴 ==================
System.out.println("공격 타이밍인가? 데미지는 ? (-1 : skip) "+attackPatternArray[time]);
if(attackPatternArray[time] != -1){
hp-=attackPatternArray[time];
System.out.println("캐릭터가 맞았습니다. 남은 체력" + hp);
successCount=0;
//죽었는지 체크
if(hp<=0){
System.out.println("캐릭터가 죽었습니다");
return hp =-1;
}
나의 힐 패턴 코드
}else { // ============================= attack타이밍이 아니라면 heal ======================================
// 1.3. 초당 힐량 만큼 힐 (최대 체력보다 낮을 경우(최대 체력 만큼만 회복))
System.out.println("힐타이밍입니다."+bandage[1]+"만큼 회복했습니다.");
hp+=bandage[1];
successCount++;
if(successCount ==limitSuccess){
System.out.println("연속 성공 => 추가 heal");
hp+=bandage[2];
successCount=0;
}
//최대 체력보다 많을시 최대체력으로 조정
if (health<hp){
System.out.println("최대 체력입니다");
hp = health;
}
}
이렇게 상황을 넣어보고 console 찍은 것을 확인합니다.


예상한 데로 숫자가 잘 나와서 바로 테스트 돌려서 합격했습니다.
다른 분들 코드 보면 10줄 만에 끝내는 분들 있더라고요.
진심 대단합니다.
전체 코드
package org.example;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Solution solution = new Solution();
int[] bandage;
int health;
int[][] attacks;
// bandage = new int[]{5,1,5}; // 붕대 감기 스킬 : [시전 시간 , 초당 회복량 , 추가 회복량]
// health = 30; // 체력
// attacks = new int [][]{{2,10},{9,15},{10,5},{11,5}}; // 공격 : [공격 시간, 피해량] (2차원 배열) ex [2, 10] : 2초에 10 데미지
bandage = new int[]{3,2,7}; // 붕대 감기 스킬 : [시전 시간 , 초당 회복량 , 추가 회복량]
health = 20; // 체력
attacks = new int [][]{{1,15},{5,16},{8,6}}; // 공격 : [공격 시간, 피해량] (2차원 배열) ex [2, 10] : 2초에 10 데미지
/*
* 조건
* 1. 최대 체력보다 커지는것은 불가능
* 2. 기술을 쓰는 도중 몬스터에게 공격을 당하면 기술이 취소 됨
* 3. 죽으면 -1을 Return
* */
//result = 5
System.out.println(solution.solution(bandage, health, attacks));
}
}
class Solution{
public int solution(int[] bandage, int health, int[][] attacks) {
int answer = 0; //마지막 공격 이후 캐릭터의 체력
int limitTime = attacks[attacks.length -1][0]; // 최대 시간 (시간 제한)
int successCount = 0; //연속 성공 count == limitSuccess가 된다면 bandage [2]만큼 hp+++++++
int limitSuccess = bandage[0]; // 추가힐 발동 조건
int hp = health; //주인공 최력 health = maxHP
// 공격받는 타이밍을 체크 -1이라면 공격 타이밍아 아니다 // 공격 타이밍이라면 데미지를 배열에 넣는다.
int[] attackPatternArray = new int[limitTime +1];
Arrays.fill(attackPatternArray, -1); // default = -1;
//attack 타이밍을 전부 가져와서 attackBooleanArray에 적용
for (int[] attack : attacks) {
int attackTime = attack[0];
attackPatternArray[attackTime] = attack[1];
}
int checkCount=0;
// 공격 타이밍 출력
for (int b : attackPatternArray ) {
System.out.println(checkCount +"time 공격 타이밍 " + b);
checkCount++;
}
/* 0초 부터 적의 마지막 공격까지 시간 흐름
* 상황***
* 1. 힐 성공 ( 공격을 받지 않았다면 )
* 1. 연속성공++
* 2. 최대 연속 성공시 최대 체력만큼 추가회복
* 3. 초당 힐량 만큼 힐량
* 2. 공격 받는 상황 (if문으로 잡아서 continue로 끝까지 못가게한다.)
* 1. hp가 0이되면 -1 return
* 2. 연속 성공 = 0
* 3. 체력을 깍는다.
* */
for( int time = 0 ; time<=limitTime ; time++){
System.out.println("\n\n======\n\n"+time + "초 입니다.");
// =========================== 공격 패턴 ==================
System.out.println("공격 타이밍인가? 데미지는 ? (-1 : skip) "+attackPatternArray[time]);
if(attackPatternArray[time] != -1){
hp-=attackPatternArray[time];
System.out.println("캐릭터가 맞았습니다. 남은 체력" + hp);
successCount=0;
//죽었는지 체크
if(hp<=0){
System.out.println("캐릭터가 죽었습니다");
return hp =-1;
}
}else { // ============================= attack타이밍이 아니라면 heal ======================================
// 1.3. 초당 힐량 만큼 힐 (최대 체력보다 낮을 경우(최대 체력 만큼만 회복))
System.out.println("힐타이밍입니다."+bandage[1]+"만큼 회복했습니다.");
hp+=bandage[1];
successCount++;
if(successCount ==limitSuccess){
System.out.println("연속 성공 => 추가 heal");
hp+=bandage[2];
successCount=0;
}
//최대 체력보다 많을시 최대체력으로 조정
if (health<hp){
System.out.println("최대 체력입니다");
hp = health;
}
}
System.out.println("현재 hp =" + hp);
}
// 모든 공격 패턴이 끝난 후 ..........................
return hp;
}
}
'코딩 > 알고리즘, cordingTest' 카테고리의 다른 글
[프로그래머스] 공원 산책 JavaScript (2) | 2024.11.10 |
---|---|
코딩테스트 java 프로그래머스 추억점수 (긴 코드 주의) (1) | 2024.01.31 |
Java로 별찍기 알고리즘 풀어보기: 반복문과 조건문의 활용 삼각형, 마름모 (0) | 2024.01.18 |