본문 바로가기

알고리즘 삽질장

[이코테] 구현 - 게임 개발

반응형

해당 포스팅의 문제의 출처는 나동빈님의 이것이 취업을 위한 코딩 테스트 교재를 공부하면서 풀이할 때 본인의 사고 과정 흐름과 문제 풀이를 기록하기 위함 입니다. 

 


문제설명

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

 

  1. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.
  2. 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향으로 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.
  3. 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어 있는 칸인 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이 때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.

위 과정을 반복적으로 수행하면서 매뉴얼에 따라 캐릭터를 이동시킨 뒤에 캐릭터가 방문한 칸의 수(최초 좌표 칸 포함)를 출력하는 프로그램을 만드시오.

입력조건

  • 첫째 줄에 맵의 세로 크기 N과 가로 크기 M을 공백으로 구분하여 입력한다.(3 <= N, M <= 50)
  • 둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 서로 공백으로 구분하여 주어진다. 방향 d의 값으로는 다음과 같이 4가지가 존재한다.
    • 0 : 북쪽
    • 1 : 동쪽
    • 2 : 남쪽
    • 3 : 서쪽
  • 셋째 줄부터 맵이 육지인지 바다인지에 대한 정보가 N개의 줄로 주어진다. 0이면 육지, 1이면 바다를 의미한다
  • 단, 최초의 위치한 칸은 무조건 육지이다.

사고과정

  • 맵 정보 배열, 캐릭터가 이동한 칸 업데이트하는 배열 2가지로 만들지 않고 하나로 시도했으나 어쨌건 시간 안에 풀이는 못함. 해설에서는 2개의 배열 각각 활용함. 즉, 맵 정보에서는 다음 칸이 바다인지 육지인지 찾는 용, 캐릭터 이동 칸 배열은 이동한 칸인지 여부 판단하는 용도로 사용
  • 방향을 매번 바꾸는 함수를 잘 만들었음. 그러나 방향(동서남북)을 나타내는 숫자(0,1,2,3)이 이동방향 인덱스랑 동일하게 설정하는 것을 못함..
  • 또, 뒤로 가기는 앞으로 가기를 빼주면 뒤로가기와 동일하다는 점을 인지 못함..
  • 예전에 풀어본 문제인데도 어렵다...흑

풀이

# 1. 맵과 가본 좌표 업데이트 하는 array를 별도로 2개 만듦
n, m = map(int, input().split())
x, y, direction = map(int, input().split())
gone_array = [[0] * m for _ in range(n)]  # 가본 좌표 저장하기 위한 array
gone_array[x][y] = 1  # 첫 좌표
# 맵 정보
map_array = []
for _ in range(n):
    data = list(map(int, input().split()))
    map_array.append(data)

# 방향 좌표(인덱스 = 방향이랑 동일하게)리스트 생성
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

# 방향 바꾸는 함수
def change_direction():
    global direction
    direction -= 1
    if direction < 0:
        direction = 3

count = 1  # 방문한 칸 횟수(출력할 것)
dir_count = 0  # 몇 번 방향을 바꾸었는지(4되면 한 바퀴돌았다는 뜻)
while True:
    change_direction()
    nx = x + dx[direction]
    ny = y + dy[direction]

    if gone_array[nx][ny] == 0 and map_array[nx][ny] == 0:
        gone_array[nx][ny] = 1
        x, y = nx, ny
        count += 1
        dir_count = 0
        continue
    else:
        dir_count += 1
    # 방향 4번 모두 바꿨을 때
    if dir_count == 4:
        # 바라보던 방향으로 빡구
        nx = x - dx[direction]
        ny = y - dy[direction]
        if map_array[nx][ny] == 0:
            x, y = nx, ny
            dir_count = 0
        else:
            break

print(count)

 

반응형