자바 이것이 코딩 테스트다 - chapter04 - 3 게임 개발
문제
현민이는 게임 캐릭터가 맵 안에서 움직이는 시스템을 개발 중이다. 캐릭터가 있는 장소는 1 X 1 크기의 정사각형으로 이뤄진 N X M 크기의 직사각형으로, 각각의 칸은 육지 또는 바다이다. 캐릭터는 동서남북 중 한 곳을 바라본다.
맵의 각 칸은 (A, B)로 나타낼 수 있고, A는 북쪽으로부터 떨어진 칸의 개수, B는 서쪽으로부터 떨어진 칸의 개수이다. 캐릭터는 상하좌우로 움직일 수 있고, 바다로 되어 있는 공간에는 갈 수 없다. 캐릭터의 움직임을 설정하기 위해 정해 놓은 매뉴얼은 이러하다.
- 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.
- 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향으로 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.
- 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어 있는 칸인 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.
현민이는 위 과정을 반복적으로 수행하면서 캐릭터의 움직임에 이상이 있는지 테스트하려고 한다. 메뉴얼에 따라 캐릭터를 이동시킨 뒤에, 캐릭터가 방문한 칸의 수를 출력하는 프로그램을 만드시오.
생각
1. 처음에는 N+1 M+1 맵을 만들어서 외각을 바다로 처리할려했으나 문제에서 외각은 신경안써도 된다고 하여 N M맵으로 함.
2. Map 배열와 check 배열을 만들어서 육지 바다와 방문한곳을 1로 체크함
3. 회전을 하게 되면 바라보는 방향을 반환하는 함수를 만들고 전진하게되면 바뀌는 x,y좌표를 배열로 만든다.
4. while문으로 문제를 그대로 따라 일단 회전시킨후 전진시겼을때 불가하면 다시 회전을 시킨다.
5. 회전을 4번시켰을때도 불가능하다면 뒤로 이동하고(아까 만든 전진 x,y배열을 빼면된다) 바다면 종료한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
st = new StringTokenizer(bf.readLine());
int Fx = Integer.parseInt(st.nextToken()); //북쪽으로 A칸
int Fy = Integer.parseInt(st.nextToken()); //서쪽으로 A칸
int dir = Integer.parseInt(st.nextToken());
int[][] check = new int[N+2][M+2];
int x = Fx+1; //코드에서 사용할 x좌표 Fx가 1,Fy가 1이라면 이제 캐릭터가 위치해있는좌표는 2,2임
int y = Fy+1;
check[x][y]=1; //현재위치 방문처리
int[] dx = {-1,0,1,0};
int[] dy = {0,1,0,-1};
int dirNum =0; //회전한 횟수
int count =1;//움직인횟수
int[][] map = new int[N+2][M+2];
for(int i=1;i<=N;i++) { //map정보저장
st = new StringTokenizer(bf.readLine());
for(int j=1;j<=M;j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
while (true) {
dir = Direction(dir);
int nx = x + dx[dir]; //회전해서 앞으로간 x,y좌표
int ny = y + dy[dir];
if(map[nx][ny]==0 && check[nx][ny]==0) { //맵이 육지고 가본적이없다면
check[nx][ny]=1; //방문표시
x=nx;
y=ny;
count ++;
dirNum=0;
continue;
}
else { //맵이 바다거나 가본곳이면 회전해야함
dirNum++;
}
if(dirNum==4) { //4방향이 다 움직일 수없다면 한칸 뒤로가야함
nx = x - dx[dir];
ny = y - dy[dir];
if(map[nx][ny]==1){
break;
}
else {
x = nx;
y = ny;
}
dirNum=0;
}
}
System.out.println(count);
}
public static int Direction(int i) {
if(i==0) {
return 3;
}
else {
return i-1;
}
}
}
'알고리즘 > 구현' 카테고리의 다른 글
자바 이것이 코딩 테스트다 - chapter04 - 2 왕실의 나이트 (1) | 2024.10.13 |
---|---|
이것이 코딩 테스트다 - chapter04 - 예제4-2 시각 , 백준 자바 18312 시각 (1) | 2024.10.12 |
이것이 코딩 테스트다 - chapter04 - 예제4-1 상하좌우 (0) | 2024.10.12 |
자바알고리즘 - 구현 - 자물쇠와 열쇠 (0) | 2024.02.02 |
자바알고리즘 - 구현 - 문자열 압축 (0) | 2024.01.29 |