BOJ 킹 시뮬레이션

문제출저


풀이

문제 자체는 어렵지 않으나 행에서 가장 아래쪽이 1, 가장 위가 8이여서 인덱스를 유의해서 봐줘야 한다.
보통 가장 위 가장 왼쪽이 0,0 인 구조의 문제가 많은데 이문제는 보통과 다른 경우이다.

java contiune, enum 을 활용해서 문제를 풀었다.
처음에 킹이 움직일 수 있는 8가지 방향을 2차원 int형 배열 DIR에 선언해주었다.

// T, RT, R, RB, B, LB, L, LT  
int[][] DIR = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, 
                { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };    	

그 다음 입력으로 주어지는 “T”, “RT”, “LT” 와 같은 명령들을 어떻게 저 DIR배열과 매핑시킬 수 있는지 고민했는데,
처음에는 Map을 이용하였다가 (map.put(“T”, 0), map.put(“RT”, 1)… )
java enum을 이용하는 방식으로 수정하였다.

enum MOVING_DIR = { T, RT, R, RB, B, LB, L, LT  };

enum은 서로 연관된 상수들의 집합을 의미하는데,
서로 관련있는 상수들을 모아 상수들을 대표할 수 있는 이름으로 타입을 정의할 때 주로 사용된다.
처음의 Map을 이용할때보다 가독성과 코드량 부분을 개선시킬 수 있었다.

만약, 명령어가 “RT”라고 입력되었을때, DIR 배열에서 움직어야할 방향좌표를 가져오는 방법은 아래와 같다.

int nextY = DIR[MOVING_DIR.valueOf("RT").original()][0];
int nextX = DIR[MOVING_DIR.valueOf("RT").original()][1];

valueOf(String)은 String값을 enum에서 가져오는데, 만약 없을경우 Exception이 발생한다.
original()은 해당 값이 enum에서 정의된 순서를 리턴한다.

(enum과 관련된 설명은 여기를 참고하면 더 자세한 정보를 얻을 수 있음!)

그 다음으로는, 명령에 따라서 킹이 이동할 수 있는지를 먼저 확인하고,
킹이 이동가능한데 돌을 만나게 되는 경우, 돌이 이동가능한지의 여부를 확인하여서,
이동가능하면 킹과 돌을 이동시켜주고 아니면 그 다음 명령으로 넘어가도록 하였다.

여기서 continue를 사용하였는데, continue는 반복문 문장에서 어떤 조건을 검사해서 조건이 맞지않은경우,
해당 조건문을 빠져나가는 것(break)이 아닌 다시 다음 반복문으로 돌아가고자 할때 사용된다.


소스코드

전체소스

킹을 이동시키는 함수

	public void moveKing() throws IOException {
		for (int c = 0; c < cmdCnt; c++) {
			String cmd = IOUtils.readInput();
			int cmdDir = MOVING_DIR.valueOf(cmd).ordinal();
			Pos nextKingPos = new Pos(king.getY() + DIR[cmdDir][0], king.getX() + DIR[cmdDir][1]);

			// 킹의 이동가능 여부 확인, 이동불가능하면 다음명령 진행
			if (!isAccessible(nextKingPos)) {
				continue;
			}
			// 킹과 돌이 만나는지 확인
			if (isMeetStone(nextKingPos)) {
				Pos nextStonePos = new Pos(stone.getY() + DIR[cmdDir][0], stone.getX() + DIR[cmdDir][1]);
				// 돌을 이동시킬 수 없으면 킹도 이동못시킴. 다음 명령 진행  
				if (!isAccessible(nextStonePos)) {
					continue;
				}
				stone = nextStonePos;
				king = nextKingPos;
			} else {
				king = nextKingPos;
			}
		}
	}