본문 바로가기

CS/알고리즘

게임개발 구현 문제풀이(좌표값 이동)

난이도 ●●○ | 풀이 시간 40분 | 시간 제한 1초 | 

맵은 N × M 크기의 직사각형이며, 맵의 각 칸은 (A, B)로 나타낼 수 있다.
캐릭터는 상하좌우로 움직일 수 있고, 바다로 되어있는 공간에는 갈 수 없다.
매뉴얼은 아래와 같다.
* 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.
* 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향을 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.
* 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어있는 칸의 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.
캐릭터가 방문한 칸의 출력하는 프로그램을 만드시오.

**입력 조건**
* 첫째 줄에 맵의 세로 크기 N과 가로크기 M을 공백으로 구분하여 입력한다. (3 ≤ N, M ≤ 50)
* 둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 서로 공백으로 구분하여 주어진다. 방향 d의 값으로는 다음과 같이 4가지가 존재한다.
    * 0 : 북쪽
    * 1 : 동쪽
    * 2 : 남쪽
    * 3 : 서쪽
* 셋째 줄부터 맵이 육지인지 바다인지에 대한 정보가 주어진다. N개의 줄에 맵의 상태가 북쪽부터 남쪽 순서대로, 각 줄의 데이터는 서쪽부터 동쪽 순서대로 주어진다. 맵의 외곽은 항상 바다로 되어있다.
    * 0 : 육지
    * 1 : 바다
* 처음에 게임 캐릭터가 위치한 칸의 상태는 항상 육지이다.
 
**출력 조건**
*  첫째 줄에 이동을 마친 후 캐릭터가 방문한 칸의 수를 출력한다.

 

테스트 케이스 추가)

 

4 4
1 1 0
1 1 1 1
1 0 1 1
1 0 1 1
1 1 1 1

 

출력 : 2

 


 

40분 안에 풀지 못했다... 두 배는 걸렸다ㅠㅠㅠㅠㅠㅠㅠㅠㅠ 

그래도 좌표에 대해 확실히 알게되었다...!

 

문제 풀이시 처음 캐릭터가 위치한 곳의 좌표를 표시해주어야 하는데,

그 점을 대해 생각하지 못해서 헤맨점이 아쉽다.! 그것만 아니었으면 더 빨리 풀었을텐데... 아쉽다.


 

 

각 방향으로 좌표값 이동하기

모든 방향으로 이동한 위치값을 확인할 때 반복문으로 이를 구할 수 있다.

 

좌표는(x,y)로 구성되었다.

 

남쪽 : (1,0)

동쪽 : (0,1)

북쪽 : (-1,0)

서쪽 : (0,-1)

이렇게 값이 변화한다. 

이를 배열로 저장해서 반복문 수행이 가능하다.

 

상하좌우로 이동했을 때 배열


int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};

 

아래와 같이 활용이 가능하다.(nextX는 새로 이동하는 좌표)

for(int i = startIndex; i<startIndex+4;i++){
    int nextX = x+dx[i%4];
    int nextY = y+dy[i%4];

문제 풀이

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Test11052 {
    public static void main(String[] args) {
        int count = 1;
        // 서, 남, 동, 북
        // 3   2   1  0
        List<Integer> direction = new ArrayList<>();
        for(int i = 3; i>=0;i--)
            direction.add(i);
        int[] dx = {0,1,0,-1};
        int[] dy = {-1,0,1,0};

        Scanner scanner = new Scanner(System.in);
        int maxX = scanner.nextInt();
        int maxY = scanner.nextInt();
        //캐릭터 위치
        int x = scanner.nextInt();
        int y = scanner.nextInt();
        //캐릭터 방향
        int dir = scanner.nextInt();

        // 북인경우 index = 3 -> index0부터 시작하게함
        // 3 - 3 = 0
        // 1 - 3 = 2
        int startIndex = (direction.indexOf(dir)+1)%4; // 왼쪽방향

        // 지도 입력 받기
        int map[][] = new int[maxX][maxY];
        for(int i=0; i<maxX; i++){
            for(int j=0; j<maxY; j++){
                map[i][j]=scanner.nextInt();
            }
        }

        // 시작점 표시
        map[x][y]=1;
        boolean flag = true;
        while(flag){
            //왼쪽방향돌리기
            for(int i = startIndex; i<startIndex+4;i++){
                int nextX = x+dx[i%4];
                int nextY = y+dy[i%4];
                //전진한다
                if(map[nextX][nextY]==0){
                    x = nextX;
                    y = nextY;
                    dir = i%4;
                    startIndex = (i+1)%4;
                    map[x][y]=1;
                    count++;
                }
            }
            // 네방향 모두 1일때 바라보는 방향을 유지한채로 한칸 뒤로 간다
            int back = (direction.indexOf(dir)+2)%4;
            int backX = x+dx[back%4];
            int backY = y+dy[back%4];

            if(map[backX][backY]==0){
                x = backX;
                y = backY;
                map[x][y]=1;
                count++;

            }else{
                flag=false;
            }
        }
        System.out.println(count);
    }
}

'CS > 알고리즘' 카테고리의 다른 글

재귀로 푸는 괄호 추가하기 문제  (0) 2023.11.16
윷놀이 문제, Map merge 메소드  (0) 2023.11.16
하노이의 탑  (0) 2023.10.27
시간 계산하기(손코딩)  (0) 2023.10.20
재귀함수와 반복문의 차이점  (0) 2023.10.19