[Python] 백준 3190 - 뱀 (deque와 list를 활용한 queue 구현)

2025. 3. 25. 21:18·Algorithm

주의
제 능력 부족으로 딱히 도움이 안될 확률이 높습니다

문제는 여기에서

 

https://imgur.com/you-can-actually-win-snake-who-knew-ord27qI


문제 자체는 고오전 게임인 뱀 게임을 구현하는 내용이다.
게임판을 생성하고, 그 위에 뱀이 먹으면 길어지는 사과를 놓고
뱀이 사과를 먹으면 길어질 뿐인
단?순한 게임이다

결론부터 말하면, 난 이 문제를 하루종일 붙들게되었다
뭐 다른 문제들도 다 비슷한 상황이지만

가장 많은 시간을 차지한건 구현 구상인데,
도저히 어떻게 큐를 사용해서 게임을 구현하라는건데 라는 생각만 계속 맴돌았다

그간 해온건 배열, 탐색뿐인데 아니 들어오고 나가는게 왜 뱀이되는건데..

반나절을 그렇게 시간을 보내고, 결국 기계의 손을 빌렸다

그렇다, 내 수 시간은 그에게 단 '2초'일 뿐이다

아무튼 그렇게 핵버튼과 같은 최후의 수단인 GPT 딸깍을 해버린 나는
몰려오는 자괴감을 뒤로하고 구현에 몰두하는데,

그래봐야 돌아오는건 뱀이 왜 큐가 되는건데ㅔㅔㅔㅔ 였음..

그래서 결국 다른이의 아이디어를 묻게되어 해결한게,

뱀을 큐로 구현하는데, 각 머리 - 몸통 - 꼬리의 내부 정보는 현재 위치한 게임판 좌표를 튜플로 저장하는 것 이었다.

그 정도 가닥을 잡으니 일단 떠오르는대로 코드를 치기 시작했다

©AaronsAnimals

다음 난관들이 산재하였는데, 어떻게 방향전환을 시킬지 와 입력받았던 방향전환 명령을 어떻게 제때 입력 시킬것인가? 였음

방향전환 아이디어는 다행히도 금방 떠올랐는데,

직전에 백준 11866 - 요세푸스 문제 0을 풀며 활용했던 deque.rotate() 함수가 생각났다

© 나

대충 이런문제다, n(1~n까지의 수)과 몇칸마다 수를 날릴지 주어지면,
그 규칙에 따라 어떤 수열이 만들어지는지 결과값을 도출하는 문제

아무튼 저 문제에서 내보낼걸 rotate로 돌려서 arr[0]으로 가져오고 내보낸 기억이났다.

while len(numbers) != 0:
    for i in range(len(numbers)):
        numbers.rotate(-T+1)
        arr.append(numbers.popleft())

.rotate(n) 함수는 양수의 경우 n만큼 시계방향으로, 음수는 반대방향으로 배열을 돌려준다
ex) arr = ['1','2','3','4','5','6']을
arr.rotate(2) 해주면
['3','4','5','6','1','2']라는 값으로 변경되는 것이다

암튼 여기에 착안해서 일단 움직이는건 차치하고,

    while True:
        # 초에 따른 움직임은, for 문으로 구현
        # 움직임을 받는 함수 별도로? 일단 내부에 구현
        second += 1 # while문이 동작할 때 마다 1초씩 지나는 것으로 간주

        if dirrection[0] == 'right':
            col += 1
        if dirrection[0] == 'down' :
            row += 1
        if dirrection[0] == 'left' :
            col -= 1
        if dirrection[0] == 'up' :
            row -= 1

        if move(row,col) == False :
            break

이런식으로 dirrection 배열의 0번째를 지속적으로 관측하게해주고,

# 초기에 뱀은 우측으로 이동한다는 전제가 있다.
dirrection = deque([('right'),('down'),('left'),('up')]) 

# 생략


def set_dir(C):
    if C == 'L':
        dirrection.rotate(1)
    elif C == 'D':
        dirrection.rotate(-1)

요로코롬 구현하게되었다.

그 뒤에 명령을 지연해서 받는 부분은 시간값을 별도로 카운트하게 해주고
(게임이 종료된 시점을 리턴해줘야하니까)

방향전환에 대한 명령어는 튜플로 배열을 저장해서,
현재 시간값과 명령어의 시간이 일치하게되면
방향 커맨드를 내보내줌과 동시에 배열에서 제거해줬다.

내 코드를 보고 눈에 잘 들어오게 요약해준 GPT에게 감사하며,

비루한 코드 구성과 원본으로 글을 마친다

 


🔍 1. 게임판 (board)

  • 게임판은 2차원 배열.
  • 값은:
    • 0: 빈 공간
    • 1: 사과
    • 2: 뱀의 몸통

🔍 2. 뱀 (snake)

  • 뱀은 deque로 구현.
  • 머리부터 꼬리까지의 위치를 (i, j) 튜플로 저장.
  • 머리 이동 시 새로운 좌표는 append(), 꼬리 이동 시 popleft()로 제거.

🔍 3. 방향 전환 (direction)

  • 뱀은 오른쪽(right) 방향에서 시작.
  • 방향 변경은 회전 방식으로 관리 (deque.rotate() 사용).
  • 'L': 왼쪽 회전 (오른쪽으로 리스트 회전)
  • 'D': 오른쪽 회전 (왼쪽으로 리스트 회전)

🔍 4. 움직임 함수 (move)

  • 머리가 이동할 좌표 계산.
  • 벽이나 뱀의 몸통과 부딪히면 게임 종료.
  • 사과가 있으면 머리만 추가하고 꼬리는 유지.
  • 빈 공간이면 머리 추가하고 꼬리 제거.

🔍 5. 코드 설명

📌 set_dir(C) 함수

  • 방향 전환 처리.
  • L 입력 시 rotate(1)
  • D 입력 시 rotate(-1)

📌 move(row, col) 함수

  • 뱀의 머리를 새 위치로 이동.
  • 충돌 여부 확인하여 종료 처리.
  • 사과나 빈 공간 처리.

📌 snake_game() 함수

  • 메인 게임 루프.
  • 매 초마다 이동하고 방향 전환 처리.
  • 종료 시 결과 출력.

📌 구현 코드

from collections import deque
import sys

N = int(sys.stdin.readline().rstrip())  # 보드 크기
K = int(sys.stdin.readline().rstrip())  # 사과 개수
board = [[0] * N for _ in range(N)]  # 보드 초기화

for i in range(K):
    row, col = map(int, sys.stdin.readline().rstrip().split())
    board[row - 1][col - 1] = 1  # 사과 위치 설정

snake = deque([(0, 0)])  # 뱀 초기 위치 설정
board[0][0] = 2  # 뱀이 위치하는 곳은 2로 표시

direction = deque(['right', 'down', 'left', 'up'])
dir_change = []

L = int(sys.stdin.readline().rstrip())  # 방향 전환 횟수
for i in range(L):
    time, change = sys.stdin.readline().rstrip().split()
    dir_change.append([int(time), change])

second = 0  # 시간 초기화

def set_dir(C):
    if C == 'L':
        direction.rotate(1)
    elif C == 'D':
        direction.rotate(-1)


def move(row, col):
    if row < 0 or row >= N or col < 0 or col >= N:
        return False

    if board[row][col] == 2:
        return False

    if board[row][col] == 1:
        snake.append((row, col))
        board[row][col] = 2
        return True

    if board[row][col] == 0:
        snake.append((row, col))
        tail_row, tail_col = snake.popleft()
        board[tail_row][tail_col] = 0
        board[row][col] = 2
        return True


def snake_game():
    global second
    row, col = 0, 0
    while True:
        second += 1

        if direction[0] == 'right':
            col += 1
        elif direction[0] == 'down':
            row += 1
        elif direction[0] == 'left':
            col -= 1
        elif direction[0] == 'up':
            row -= 1

        if not move(row, col):
            break

        if dir_change and dir_change[0][0] == second:
            set_dir(dir_change[0][1])
            dir_change.pop(0)


snake_game()
print(second)

728x90

'Algorithm' 카테고리의 다른 글

[Python] 다익스트라(Dijkstra) 알고리즘 (최단경로 탐색)  (0) 2025.04.03
[Python] 트리 - 전위, 중위, 후위순회와 이진탐색트리  (0) 2025.04.03
분할 정복 기법 (Divide and Conquer)  (0) 2025.03.25
점화식 (Recurrence)  (0) 2025.03.20
시간복잡도에 따른 정렬의 종류  (0) 2025.03.20
'Algorithm' 카테고리의 다른 글
  • [Python] 다익스트라(Dijkstra) 알고리즘 (최단경로 탐색)
  • [Python] 트리 - 전위, 중위, 후위순회와 이진탐색트리
  • 분할 정복 기법 (Divide and Conquer)
  • 점화식 (Recurrence)
ahpicl64
ahpicl64
in the clouds
  • ahpicl64
    구름
    ahpicl64
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • WIL (4)
      • Jungle (36)
      • AWS (2)
      • SQL (2)
      • CS:APP (17)
      • Algorithm (10)
      • K8s (7)
      • 자료 구조 (10)
      • Spring (4)
      • React (0)
      • 운영체제 (1)
      • 기타등등 (2)
      • 이야기 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    CSAPP
    자료구조
    Spring
    트러블슈팅
    queue
    AWS
    EC2
    k8s
    S3
    github actions
    Spring boot
    IAM
    DB
    컴퓨터시스템
    부하테스트
    CloudFront
    python
    DevOps
    알고리즘
    어셈블리
  • 02-21 21:05
  • hELLO· Designed By정상우.v4.10.3
ahpicl64
[Python] 백준 3190 - 뱀 (deque와 list를 활용한 queue 구현)
상단으로

티스토리툴바