이것이 코딩 테스트다 - 구현 - 실전문제 : 게임 개발
# 게임 개발 - 내 답
#input
n, m = map(int, input().split()) #맵의 크기 : 세로n, 가로m
y, x, direction = map(int, input().split()) #현재 나의 위치
maps = []
cnt = 1 #방문한 칸의 수 / 처음에 위치한 곳은 항상 육지이므로 초기값은 1
for i in range(n):
maps.append(list(map(int, input().split())))
#기본 정보
directions = [0, 1, 2, 3] #북동남서
moves = [(0,-1), (1,0), (0,1), (-1,0)] #북동남서로 앞으로 한칸 움직일때의 변화되는 좌표값
back_moves = [(0,1), (-1,0), (0,-1), (1,0)] #북동남서로 뒤로 한칸 움직일때 변화되는 좌표값
maps[y][x] = 2 #첫시작위치를 이미 간 곳이라고 표시
while True:
did_move = 0 #네 방향 중 한곳으로라도 이동했는가? 0:이동안함, 1:이동함
t_direction = direction
for i in range(4): #네 방향을 모두 둘러봄.
t_direction = directions[t_direction-1] #현재에서 왼쪽돌았을때의 방향을 임시변수에 저장
tx = x + moves[t_direction][0] #왼쪽으로 한칸 이동했을 때의 위치
ty = y + moves[t_direction][1] #왼쪽으로 한칸 이동했을 때의 위치
if maps[ty][tx] == 0: #왼쪽방향으로 회전하고 왼쪽으로 한 칸 전진했을 때가 -> 아직 가보지않았고, 육지라면 전진
direction = t_direction
cnt += 1 #방문한 칸의 수 1 가
did_move = 1 #이동했다는 증거.
x = tx
y = ty
maps[y][x] = 2 #이동한 위치를 이미 간 곳이라고 표시.
break #이동했으면 더이상 둘러볼 필요없으므로 빠져나감.
#네 방향 모두 이미 가본 칸이거나 바다로 되어있는 경우 == 위의 for문에서 아무런 변화없는 경우
#if 뒤쪽이동했을때가 바다인 경우: 위치 그대로 움직이지 않음.while문 탈출.
#else: 한칸뒤로 이동
if did_move == 0: #네 방향 아무곳도 이동하지 않음.
tx = x + back_moves[direction][0]
ty = y + back_moves[direction][1]
if maps[ty][tx] == 1: #뒤쪽이동햇을때가 바다인 경우 -> 움직임을 멈춤.while문 탈출
break
else: #그냥 네 방향모두 가본 칸인 경우
x = tx
y = ty
print(cnt)
# 게임 개발 - 책 답안 예시
n, m = map(int, input().split())
#방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화
d = [[0] * m for _ in range(n)]
#현재 위치 입력받기
x, y, direction = map(int, input().split())
d[x][y] = 1 #현재 좌표 방문 처리
#전체 맵 정보를 입력받기
array = []
for i in range(n):
array.append(list(map(int, input().split())))
#북, 동, 남, 서 방향정의
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
#왼쪽으로 회전
def turn_left():
global direction
direction -= 1
if direction == -1:
direction = 3
#시뮬레이션 시작
count = 1
turn_time = 0
while True:
#왼쪽으로 회전
turn_left()
nx = x + dx[direction]
ny = y + dy[direction]
#회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동
if d[nx][ny] == 0 and array[nx][ny] == 0:
d[nx][ny] = 1
x = nx
y = ny
count += 1
turn_time = 0
continue
#회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우
else:
turn_time += 1
#네 방향 모두 갈 수 없는 경우
if turn_time == 4:
nx = x - dx[direction]
ny = y - dy[direction]
#뒤로 갈 수 있다면 이동
if array[nx][ny] == 0:
x = nx
y = ny
#뒤가 바다로 막혀있는 경우
else:
break
turn_time = 0
print(count)
코드 비교 : 4가지 방향 차례대로 갈 곳을 정하는 알고리즘
🔒 문제풀이를 위한 테크닉
일반적으로 방향을 설정해서 이동하는 문제 유형에서는 dx, dy라는 별도의 리스트를 만들어 방향을 정하는 것이 효과적이다.
#예시
moves = [(0,-1), (1,0), (0,1), (-1,0)]
array = []
for i in range(n):
array.append(list(map(int, input().split())))
d = [[0] * m for _ in range(n)]
틀렸던/수정한 코드
x,y 입력받을 때 틀림.
문제에서는 A,B를 입력받는데 A는 북쪽으로부터 떨어진 칸의 개수, B는 서쪽으로부터 떨어진 칸의 개수라 했으므로 A는 행, B는 열. 문제를 잘 읽자!
maps[y][x] = 2
이동한 위치를 이미 간 곳이라고 표시해야 함. 수정 전에는 이동하기 전 위치를 이미 간 곳이라고 표시해놔서 마지막 방문한 곳이 방문하지 않은 곳으로 처리되어있었음. 첫 시작위치를 이미 방문했다고 표시해두어야 함.
t_direction = directions[t_direction-1] #현재에서 왼쪽돌았을때의 방향을 임시변수에 저장