https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5LyE7KD2ADFAXc 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

문자 의미
. 평지(전차가 들어갈 수 있다.)
* 벽돌로 만들어진 벽
# 강철로 만들어진 벽
- 물(전차는 들어갈 수 없다.)
^ 위쪽을 바라보는 전차(아래는 평지이다.)
v 아래쪽을 바라보는 전차(아래는 평지이다.)
< 왼쪽을 바라보는 전차(아래는 평지이다.)
> 오른쪽을 바라보는 전차(아래는 평지이다.)


다음 표는 사용자가 넣을 수 있는 입력의 종류를 나타낸다.
 

문자 동작
U Up : 전차가 바라보는 방향을 위쪽으로 바꾸고, 한 칸 위의 칸이 평지라면 위 그 칸으로 이동한다.
D Down : 전차가 바라보는 방향을 아래쪽으로 바꾸고, 한 칸 아래의 칸이 평지라면 그 칸으로 이동한다.
L Left : 전차가 바라보는 방향을 왼쪽으로 바꾸고, 한 칸 왼쪽의 칸이 평지라면 그 칸으로 이동한다.
R Right : 전차가 바라보는 방향을 오른쪽으로 바꾸고, 한 칸 오른쪽의 칸이 평지라면 그 칸으로 이동한다.
S Shoot : 전차가 현재 바라보고 있는 방향으로 포탄을 발사한다.


전차가 이동을 하려고 할 때, 만약 게임 맵 밖이라면 전차는 당연히 이동하지 않는다.

전차가 포탄을 발사하면, 포탄은 벽돌로 만들어진 벽 또는 강철로 만들어진 벽에 충돌하거나 게임 맵 밖으로 나갈 때까지 직진한다.

만약 포탄이 벽에 부딪히면 포탄은 소멸하고, 부딪힌 벽이 벽돌로 만들어진 벽이라면 이 벽은 파괴되어 칸은 평지가 된다.

강철로 만들어진 벽에 포탄이 부딪히면 아무 일도 일어나지 않는다.

게임 맵 밖으로 포탄이 나가면 아무런 일도 일어나지 않는다.

초기 게임 맵의 상태와 사용자가 넣을 입력이 순서대로 주어질 때, 모든 입력을 처리하고 나면 게임 맵의 상태가 어떻게 되는지 구하는 프로그램을 작성하라.


[입력]

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 두 정수 H, W (2 ≤ H, W ≤ 20) 이 공백으로 구분되어 주어진다.

이는 게임 맵의 높이가 H, 너비가 W임을 나타낸다.

즉, 게임 맵은 H x W크기의 격자판이다.

다음 H개의 각각의 줄에는 길이가 W인 문자열이 주어진다.

각각의 문자는 위의 게임 맵 구성 요소 표에 있는 문자들만 포함하며, 전차는 단 하나만 있다.

다음 줄에는 사용자가 넣을 입력의 개수를 나타내는 정수 N(0 < N ≤ 100) 이 주어진다.

다음 줄에는 길이가 N인 문자열이 주어진다.

각각의 문자는 위의 사용자가 넣을 수 있는 입력의 종류를 나타내는 표에 있는 문자들만 포함된다.


[출력]

각 테스트 케이스마다 ‘#x’(x는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고 한 칸을 띄운 후, 모든 입력을 처리하고 난 후의 게임 맵을 H개의 줄에 걸쳐 출력한다.

 

import java.util.Scanner;

public class Solution {
	private static void game(int i, int r, int c, char[] go, char[][] map) {
		if (i > go.length)
			return;
		char temp;
		switch (go[i - 1]) { //i는 1부터 들어오므로 index값은 i-1
		case 'U':
			map[r][c] = '^';
			if (r > 0 && map[r - 1][c] == '.') {
				temp = map[r - 1][c];
				map[r - 1][c] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r - 1, c, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'D':
			map[r][c] = 'v';
			if (r < map.length - 1 && map[r + 1][c] == '.') {
				temp = map[r + 1][c];
				map[r + 1][c] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r + 1, c, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'L':
			map[r][c] = '<';
			if (c > 0 && map[r][c - 1] == '.') {
				temp = map[r][c - 1];
				map[r][c - 1] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r, c - 1, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'R':
			map[r][c] = '>';
			if (c < map[0].length - 1 && map[r][c + 1] == '.') {
				temp = map[r][c + 1];
				map[r][c + 1] = map[r][c];
				map[r][c] = temp;
				game(i + 1, r, c + 1, go, map);
			} else
				game(i + 1, r, c, go, map);
			break;
		case 'S':
			switch (map[r][c]) {
			case '^':
				for (int j = r - 1; j >= 0; j--) {
					if (map[j][c] == '*' || map[j][c] == '#') {
						if (map[j][c] == '*') {
							map[j][c] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case 'v':
				for (int j = r + 1; j < map.length; j++) {
					if (map[j][c] == '*' || map[j][c] == '#') {
						if (map[j][c] == '*') {
							map[j][c] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case '<':
				for (int j = c - 1; j >= 0; j--) {
					if (map[r][j] == '*' || map[r][j] == '#') {
						if (map[r][j] == '*') {
							map[r][j] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			case '>':
				for (int j = c + 1; j < map[0].length; j++) {
					if (map[r][j] == '*' || map[r][j] == '#') {
						if (map[r][j] == '*') {
							map[r][j] = '.';
							break;
						}
						break;
					}
				}
				game(i + 1, r, c, go, map);
				break;
			}
			break;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
		int T = sc.nextInt();
		int h, w, N, car_r = 0, car_c = 0;
		char[][] map;

		for (int t = 0; t < T; t++) {
			h = sc.nextInt();
			w = sc.nextInt();
			sc.nextLine();
			map = new char[h][w];

			// 맵 초기화
			for (int i = 0; i < h; i++) {
				char[] map_init = sc.nextLine().toCharArray();
				for (int j = 0; j < w; j++) {
					map[i][j] = map_init[j];
					if (map[i][j] == '^' || map[i][j] == 'v' || map[i][j] == '<' || map[i][j] == '>') {
						car_r = i;
						car_c = j;
					}
				}
			}

			N = Integer.parseInt(sc.nextLine());
			char[] C = sc.nextLine().toCharArray();

			game(1, car_r, car_c, C, map);
			sb.append("#" + (t+1) + " ");
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					sb.append(map[i][j]);
				}
				sb.append("\n");
			}
		}
		System.out.println(sb);
	}
}

재귀함수와 swith문을 이용해 동작에 따른 작업이 수행되도록 하였습니다.

 

*game(int i, int r, int c, char[] go, char[][] map)

-매개변수

int i: 현재 수행중인 동작의 순서

int r: 전차의 현재 위치 row값

int c: 전차의 현재 위치 column값

char[] go: 동작순서가 담긴 배열

char[][] map: 맵 정보가 담긴 배열

 

-종료 조건

i>go.length =현재 수행중인 동작의 순서가 동작 전체의 길이보다 커지면 return

 

-동작

//상하좌우 case에 따라

//⑴ 전차의 방향을 바꾸고

//⑵-① 해당 방향 원소가 평지이면 이동하고, 이동한 위치에서 다음 재귀함수 호출

//⑵-② 아니라면 이동하지 않고 다음 재귀함수 호출

 

//shoot case는 전차가 바라보고 있는 방향의 case에 따라

//현재 위치에서 부터 전차가 바라보는 방향의 끝까지 탐색해

//벽돌 벽이나, 강철 벽을 만나지 않으면 아무 동작없이 현재위치에서 다음 재귀함수 호출

//벽돌 벽을 만나면 포탄은 소멸, 벽돌벽은 평지로 바꾸고 현재위치에서 다음 재귀함수 호출

//강철 벽을 만나면 포탄을 소멸, 아무 동작없이 현재위치 에서 다음 재귀함수 호출

 

 

+입력부에서 전차의 위치가 입력되면 car_r와 car_c 변수에 위치를 저장해

main 함수에서 game을 호출할 때 초기 전차의 위치를 나타내는 매개변수로 넘겨주었습니다.

 

+출력부는 StringBuilder를 사용해 TestCase마다 game 함수를 거치고 난 뒤의 map 함수를 이중for문으로 탐색해 출력해주었습니다.

+ Recent posts