본문 바로가기

알고리즘

[이것이코딩테스트] 게임 개발(python)

1. 문제

현민이는 게임 캐릭터가 맵 안에서 움직이는 시스템을 개발 중이다. 캐릭터가 있는 장소는 1 x 1 크기의 정사각형으로 이뤄진 N X M 크기의 직사각형으로, 각각의 칸은 육지 또는 바다이다. 캐릭 터는 동서남북 중 한 곳을 바라본다. 맵의 각 칸은 (A, B)로 나타낼 수 있고, A는 북쪽으로부터 떨어진 칸의 개수, B는 서쪽으로부터 떨 어진 칸의 개수이다. 캐릭터는 상하좌우로 움직일 수 있고, 바다로 되어 있는 공간에는 갈 수 없다. 캐릭터의 움직임을 설정하기 위해 정해 놓은 매뉴얼은 이러하다.

 

1. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.

2. 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향으로 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.

3. 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어 있는 칸인 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.

 

현민이는 위 과정을 반복적으로 수행하면서 캐릭터의 움직임에 이상이 있는지 테스트하려고 한다. 매뉴얼에 따라 캐릭터를 이동시킨 뒤에, 캐릭터가 방문한 칸의 수를 출력하는 프로그램을 만드시오.

 

입력 조건

. 첫째 줄에 맵의 세로 크기 N 과 가로 크기 M을 공백으로 구분하여 입력한다. (3 ≤ N, M S 50) - 둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 서로 공백으로 구분하여 주어진다. 방향 의 값으로는 다음과 같이 4가지가 존재한다.

- 0: 북쪽  1: 동쪽  2: 남쪽 3:서쪽

 

2. 구현 과정

- 현재 위치를 기준으로 방문하지 않은 곳 and 육지인 곳을 찾아 이동하는 문제

- 네 방향의 방향 좌표값을 가진 dx,dy를 선언하여 for 문 4번을 돌면서 탐색하면 된다.

- 게임 캐릭터가 바라보는 방향이 이동 후에도 유지되고 있음에 유의해야 한다. 예를 들어 캐릭터가 남쪽으로 이동했다면, 북쪽에서부터 다시 반시계 방향으로 이동하는게 아니라, 남쪽 기준 반시계 방향인 동쪽에서 부터 방향을 탐색해야 한다. => 캐릭터의 방향성을 direction 변수로 저장해야 함

- 현재 바라보는 방향이 북쪽(0) 이면 차례로 3->2->1 이어야 하고, 동쪽이라면 0 -> 3 -> 2순으로 탐색 진행 해야 함. 

 해당 방향값들을 얻기 위해서 다음의 방식을 사용할 수 있다.

#x : 현재 방향값, nx : 탐색할 방향값
---------------------------------------
dx = [0,1,0,-1]
dy = [-1,0,1,0]
direction = 현재 방향값

for i in range(1,4):
	nx = x + dx[ ( 4 + (direction - i) ) % 4]
    ny = y + dy[ ( 4 + (direction - i) ) % 4]


------------------------------------
def turn_left():
	global direction
    direction -= 1
    if diection == -1:
    	direction = 3

- 만약 4 방향 모두 방문이 불가능 하면 탐색을 종료한다.

 

3. 실수

- 방문하고 싶은 곳이 범위를 벗어났는지 확인을 먼저 한 후 방문 여부 확인하기! (안그러면 index 범위 벗어났다고 오류뜸)

- 네 방향에 대한 index값이 문제에서 주어졌음에 유의하자! ( 처음엔 내 맘대로 서쪽 = 0, 남쪽 = 1,...로 했다가 오류 찾느라 오래걸렸다.)

- for i in range(4, 1, -1) :으로 하면 i = 4,3,2,1의 순으로 for문 탐색 가넝

 

4. 코드

더보기

 

#게임 개발

#반시계 방향 
dx = [0,1,0,-1]
dy = [-1,0,1,0]

#입력 받기
N,M = map(int,input().split())
x,y,direction = map(int,input().split())
board =  [ 0 for _ in range(N)] 

# 1: 바다 , 0 : 육지 
for i in range(N):
	board[i] = list(map(int,input().split()))  

board[x][y] = 1 #시작 부분 방문 처리
count = 1 #캐릭터가 방문한 칸의 수. 맨 처음 포함

# 캐릭터 이동(반시계 방향) 
while True:
	newdirection = direction
	for i in range(1,4):
		nx = x + dx[ (4 + (direction - i)) % 4] 
		ny = y + dy[ (4 + (direction - i)) % 4] 
		
		if nx < 0 or nx >= M or ny < 0 or ny >= N or board[nx][ny] == 1 :
			continue
		
		#네 방향 중 이동할 곳을 찾음
		newdirection =  (4 + (direction - i)) % 4	
		x = nx
		y = ny
		board[nx][ny] = 1
		break 
	
	#더 이상 이동할 수 없음 
	if newdirection == direction:
		break
	else:
	 direction = newdirection
	 count += 1

print(count)

 

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

[이것이코딩테스트] 떡볶이 떡 만들기  (0) 2021.08.17
[1874]스택수열(C++)  (0) 2020.12.14
[Union Find]  (0) 2020.07.28