게임개발 구현 문제풀이(좌표값 이동)
난이도 ●●○ | 풀이 시간 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);
}
}