코딩테스트[파이썬]/이것이 코딩테스트다(이코테)

[구현] - 게임 개발

softmoca__ 2024. 1. 25. 15:20
목차

게임 개발

육지(0)와 바다(1)로 구성된 N x M 크기의 직사각형 공간이 있다.

캐릭터는 동서남북으로 이동이 가능하며 바다로는 이동이 불가능하다.

맵의 각 칸은 (A,B)로 나타낼 수 있고 A는 북쪽으로 떨어진 칸의 개수, B는 서쪽으로 떨어진 칸의 개수이다.

아래는 캐릭터의 움직임을 설정하기 위한 메뉴얼이다.

1. 현재 위치에서 현재방향을 기준으로 왼쪾방향(반시계방향 90도로 회전한 방향)부터 차례대로 이동

2.왼쪽 방향에 안가본 곳이 있다면 왼쪽으로 회전후 한칸 전진, 왼쪾 방향에 가보지 않은 칸이 없다면 왼쪽 방향으로 회전만하고

1단계로 돌아간다.

3.만약 네방향 모두 이미 가본칸이거나 바다로 되어있으면 바라본느 방향을 유지한채 한칸 뒤로 가고 1단계로 돌아간다.

단, 이떄 뒤쪽 방향이 바다인칸이라 뒤로 갈수 없으면 움직임 종료.

 

종료 된후 캐릭터가 방문한 칸의 수를 출력.

 

방향 d : 0(북),1(동),2(남),3(서)

 

입력예시)

4 4
1 1 0
1 1 1 1
1 0 0 1
1 1 0 1
1 1 1 1

 

출력 예시)

3

 

나의 코드

n,m=map(int,input().split())
x,y,d=map(int,input().split())

arr=[list(map(int, input().split())) for _ in range(m)]

dx=[-1,0,1,0]
dy=[0,1,0,-1]
d=0
cnt=1

while True:
    flag=0
    for d in range(4):
        d=(d+3)%4
        nx=x+dx[d]
        ny=y+dy[d]
        if arr[nx][ny]==0:
            flag=1
            x=nx
            y=ny
            arr[nx][ny]=1
            cnt+=1
    if flag==0:
        break

print(cnt)

생각보다 고민하는 시간이 걸렸다.

반시계방향으로 회전을 한다고 해서 dx,dy의 방향 벡터 값을 조정해야 하나 싶었지만 조금 더 생각을 해보니

동서남북의 방향(d)가 이미 정해져 있어 dx,dy는 동서남북 대로 저장을 하고

방향 벡터를 순회 하기 위한 for문에서 d+3으로 로직을 꾸렸다.

또한 모든 방향이 1인 경우를 체크하기 위해 체크변수 Flag를 사용했다.

 

+ 생각해보니 첫 캐릭터의 좌표 부분을 1로 체크를 하지 않았다.

   아마 다른 입력값에서는 시간 초과에 걸렸을 수도 있겠다..! 주의하장

 

정답코드

# N, M을 공백을 기준으로 구분하여 입력받기
n, m = map(int, input().split())

# 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화
d = [[0] * m for _ in range(n)]
# 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력받기
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)

역시 정답코드 너무 산만하다..흠..

하지만 작은 세부 기능을 하는 로직들은 함수로 따로 뺴서 작성되었다느 점에서 좋은것 같다.

나도 전체적인 알고리즘과 자료구조 학습이 끝이나면 기능별로 모듈화해서 코드를 작성하는 법을 체화해야겠다.

 

 

+ 음 근데 3번 메뉴얼의 뒤로 4방향 모두 1인 경우 뒤로 한칸 간다는건 왜 있는거지..? 문제 오류인가..