본문 바로가기
Algorithm/Baekjoon

3190. 뱀 (Python)

by 원만사 2022. 4. 13.
반응형

 

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

 

풀이

 뱀의 위치 정보만 잘 기록하면 크게 어려움 없이 해결할 수 있다. 보드에서 뱀의 몸이 있는 위치를 deque을 통해 관리한다. 해당 deque에 있는 위치 정보는 (꼬리의 위치, 몸, 몸, 몸, ......, 머리의 위치)로 되어있다.

 뱀이 이동할 때마다 deque의 rear에 머리의 위치를 추가한다. 이렇게 하면 기존 머리의 위치는 몸이 되고 새롭게 rear에 추가된 위치 정보가 머리의 위치가 된다. 

 뱀이 이동했을 때 사과를 먹지 못했다면 deque의 front 정보를 pop해주면 된다. 그렇게 되면 꼬리의 다음 위치에 있는 몸이 새로운 꼬리의 위치가 된다. 

  

 

코드

from collections import deque


# 뱀이 보드의 범위 안에서 움직였는 가를 판단하기 위한 함수
def isRange(x, y):
    return 1 <= x <= N and 1 <= y <= N


# 뱀의 이동을 처리하는 함수
def moveSnake():
    global headX, headY

    # 뱀이 쳐다보는 방향으로 머리를 이동시키고 
    # 뱀의 위치 정보를 기록하는 deque의 rear에 새로운 머리의 위치를 넣어준다.
    headX += dx[snakeDir]
    headY += dy[snakeDir]
    snake.append((headX, headY))

    # 벽 또는 뱀의 몸과 부딪히면 게임 종료
    if not isRange(headX, headY) or board[headX][headY] == -1:
        return False


    # 뱀이 사과를 먹지 못했을 경우
    if board[headX][headY] != 1:
        tailX, tailY = snake.popleft() # 뱀의 꼬리의 위치를 dqeue에서 pop해준다.
        board[tailX][tailY] = 0 # 기존에 꼬리가 있던 위치를 빈 공간으로 설정해준다.
    
    board[headX][headY] = -1 # 새로운 머리의 위치에 뱀이 위치함을 표시해준다.
    
    return True 


# [board에 있는 값 정보]
# 0 : 비어있는 공간
# 1 : 사과가 위치한 공간
# -1 : 뱀의 머리 또는 몸 또는 꼬리가 위치한 공간
if __name__ == '__main__':
    N = int(input())  # 보드의 크기
    K = int(input())  # 사과의 개수
    board = [[0 for _ in range(N+2)] for _ in range(N+2)]
    board[1][1] = -1 # 처음 뱀의 위치를 -로 설정 

    # 오른쪽, 아래쪽, 왼쪽, 위쪽 
    dx = [0, 1, 0, -1] 
    dy = [1, 0, -1, 0]

    snake = deque() # 뱀의 위치 좌표들을 모아놓은 deque
    snake.append((1, 1))  # 꼬리, 몸, 몸, 몸, .....,머리
    headX, headY = 1, 1  # 뱀의 머리 위치
    snakeDir = 0  # 처음 방향은 오른쪽

    for _ in range(K):
        a, b = map(int, input().split())
        board[a][b] = 1 # 사과 위치 설정 

    L = int(input())  # 뱀의 방향 변환 횟수
    snakeInfo = [] # 뱀의 방향 변환 정보를 담아 놓는 배열 
    for _ in range(L):
        x, c = map(str, input().split())
        x = int(x)
        snakeInfo.append((x, c))

    time = 0 # 게임 시간 
    snakeChangeTime, snakeChangeDir = snakeInfo.pop(0) # 방향 변환 시간, 방향 변환 방향

    while True:
        time += 1

        # 뱀이 이동했을 때 벽이나 자신의 몸과 부딪히면 게임 종료 
        if not moveSnake():
            break
        
        # 뱀이 방향을 변환하는 시간일 경우 
        if time == snakeChangeTime:
            if snakeChangeDir == 'L': # 왼쪽으로 90도
                snakeDir -= 1
                if snakeDir == -1:
                    snakeDir = 3
            else: # 오른쪽으로 90도 
                snakeDir += 1
                if snakeDir == 4:
                    snakeDir = 0

            # 아직 방향 변환 정보가 남아있으면 새로운 시간과 방향으로 값 변경 
            if len(snakeInfo) != 0: 
                snakeChangeTime, snakeChangeDir = snakeInfo.pop(0)

    print(time)
반응형

'Algorithm > Baekjoon' 카테고리의 다른 글

2668. 숫자고르기 (Python)  (0) 2022.04.15
14466. 소가 길을 건너간 이유 6 (Python)  (0) 2022.04.14
1027. 고층 건물 (Python)  (0) 2022.04.12
1167. 트리의 지름 (Python)  (0) 2022.04.11
1005. ACM Craft (Python)  (0) 2022.04.11

댓글