LoGin
article thumbnail
반응형

 


 
 
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;
    }
}

 
 
 

728x90
반응형
profile

LoGin

@LoGinShin

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!