본문 바로가기
구름톤

[구름톤 챌린지, Java] 10일차, GameJam(완전탐색)

by 열정적인 이찬형 2023. 8. 26.

문제 링크

 

구름LEVEL

난이도별 다양한 문제를 해결함으로써 SW 역량을 향상시킬 수 있습니다.

level.goorm.io


접근 방법

이 문제에 핵심

1. N × N의 격자 보드 각 칸에는 지시가 저장되어 있습니다.

2. 게임의 점수는 방문한 칸의 개수입니다.

3. 게임은 한 번 방문했었던 칸에 다시 방문할 때 종료합니다.

4. 이동 중 보드 바깥에 나가게 되면 반대쪽 첫 번째 칸으로 이동합니다.

5. 플레이어와 구름의 게임 점수를 통한 결과를 출력합니다.

 

알고리즘 진행 순서.

 

1. 입력된 정보를 저장합니다.

 

2. 구름과 플레이어의 게임을 진행하여 점수를 계산합니다.

 

3. 게임을 통해 얻은 점수를 기반으로 이긴 사람과 점수를 결과로 출력합니다.

 

 

구현

 

상하좌우 이동

 

  U(-1, 0)  
L(0, -1) 폭탄 R(0, 1)
  D(1, 0)  

 

dr[] : {-1, 1, 0, 0} , 상하좌우 y 변경값

 

dc[] : {0, 0, -1, 1}, 상하좌우 x 변경값

 

구름이와 플레이어에 시작 위치를 기준으로

 

상, 하, 좌, 우로 이동을 진행하며 게임을 진행합니다.

 

이동 중 보드 바깥에 나가게되면, 반대쪽 첫 칸으로 이동합니다.

 

     
←(1L)👨    
     

 

이동하면

 

     
    👨
     

 

 

게임을 진행하며, 방문했었던 칸에 재방문했을 때 종료하면서 점수를 계산합니다.

 

예제입력 1.

1. 입력된 정보를 저장합니다.

 

N : 3

 

👨 : 플레이어

💭 : 구름

 

1L💭 2L 1D
2U 3R 1D
2R 2R 1U👨

 

2. 구름과 플레이어의 게임을 진행하여 점수를 계산합니다.

 

구름 게임 진행

 

1L💭 2L 1D💭
2U 3R 1D💭💭(X)
2R 2R 1U💭

 

(1, 1) ▶ (1, 3) ▶ (2, 3) ▶(3, 3) ▶ (2, 3) X

 

방문한 칸 : 4칸

 

플레이어 게임 진행

 

1L 2L 1D
2U 3R 1D👨
2R 2R 1U👨👨(X)

 

(3, 3) ▶ (2, 3) ▶ (3, 3) X

 

방문한 칸 : 2칸

 

3. 게임을 통해 얻은 점수를 기반으로 이긴 사람과 점수를 결과로 출력합니다.

 
구름(💭) : 4점
 
플레이어(👨) : 2점
 
구름 승!
 
 
goorm 4 을 결과로 출력합니다.
 
  • BufferedReader를 사용하여 입력되는 정보를 저장합니다.
  • StringTokenizer을 통해 띄어쓰기 기준 입력값을 나누었습니다.
  • 구름이와 플레이어가 search함수를 통해 게임을 진행합니다.
  • 게임이 진행한 뒤 점수에 따른 결과를 BufferedWriter에 저장합니다.
  • BufferedWriter에 저장된 결과를 출력합니다.
  • search함수는 보드 각 칸에 지시에 따른 상하좌우 움직임을 진행합니다.
  • search함수는 재방문하였을 때 지금까지 방문했던 칸을 점수로 반환합니다.
  • search함수는 바깥으로 이동하면 반대쪽으로 이동해야하기 때문에 삼항연산자를 사용하였습니다.

 

결과코드

import java.io.*;
import java.util.*;
class Main {
    public static void main(String[] args) throws Exception {
        //입력값 처리하는 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //결과값 출력하는 BufferedWriter
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        //입력값 저장
        int N = Integer.parseInt(br.readLine());
        StringTokenizer st;
        int[][] start = new int[2][2];
        for(int i=0;i<2;i++){
            st = new StringTokenizer(br.readLine()," ");
            start[i][0] = Integer.parseInt(st.nextToken())-1;
            start[i][1] = Integer.parseInt(st.nextToken())-1;
        }
        String[][] gradle = new String[N][N];
        for(int i=0;i<N;i++){
            st = new StringTokenizer(br.readLine()," ");
            for(int j=0;j<N;j++){
                gradle[i][j] = st.nextToken();
            }
        }
        //구름 게임 진행
        int goorm = search(start[0][0], start[0][1], gradle, N);
        //플레이어 게임 진행
        int player = search(start[1][0], start[1][1], gradle, N);
        //구름이 점수가 더 높을 때
        if(goorm > player){
            bw.write("goorm ");
            bw.write(String.valueOf(goorm));
        }else{		//플레이어 점수가 더 높을 때
            bw.write("player ");
            bw.write(String.valueOf(player));
        }
        bw.flush();		//결과 출력
        bw.close();
        br.close();
    }
    //게임 진행하는 함수
    static int search(int r, int c, String[][] gradle, int N){
        int result = 1;
        //방문 확인 배열
        boolean[][] visited = new boolean[N][N];
        visited[r][c] = true;
        while(true){
            //이동하는 횟수
            int move = Integer.parseInt(gradle[r][c].substring(0, gradle[r][c].length()-1));
            //이동하는 방향
            char dir = gradle[r][c].charAt(gradle[r][c].length()-1);
            //상하좌우 이동시 바깥으로 나가면 반대쪽으로 나와야 하기 때문에
            //삼항연산자를 활용하였습니다.
            for(int i=0;i<move;i++){
                if(dir == 'U') {		//상
                    r = r - 1 < 0 ? N-1 : r-1;
                }else if(dir == 'D') {		//하
                    r = r + 1 == N ? 0 : r+1;
                }else if(dir == 'L') {		//좌
                    c = c - 1 < 0 ? N-1 : c-1;
                }else {		//우
                    c = c + 1 == N ? 0 : c+1;
                }
                //재방문일 때
                if(visited[r][c]){
                    return result;
                }
                //새로운 칸 방문할 때
                result++;
                visited[r][c] = true;
            }
        }
    }
}

 


느낀 점

 

바깥에 이동할 때 다시 반대편으로 이동해야하는 부분을 생각해서 if문이 아닌 삼항연산자로 코드를 깔끔하게 작성했던 것 같아서 뿌듯하였습니다.

댓글