주의
제 능력 부족으로 딱히 도움이 안될 확률이 높습니다
문제는 여기에서

https://imgur.com/you-can-actually-win-snake-who-knew-ord27qI
문제 자체는 고오전 게임인 뱀 게임을 구현하는 내용이다.
게임판을 생성하고, 그 위에 뱀이 먹으면 길어지는 사과를 놓고
뱀이 사과를 먹으면 길어질 뿐인 단?순한 게임이다

결론부터 말하면, 난 이 문제를 하루종일 붙들게되었다
뭐 다른 문제들도 다 비슷한 상황이지만
가장 많은 시간을 차지한건 구현 구상인데,
도저히 어떻게 큐를 사용해서 게임을 구현하라는건데 라는 생각만 계속 맴돌았다
그간 해온건 배열, 탐색뿐인데 아니 들어오고 나가는게 왜 뱀이되는건데..

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

그렇다, 내 수 시간은 그에게 단 '2초'일 뿐이다
아무튼 그렇게 핵버튼과 같은 최후의 수단인 GPT 딸깍을 해버린 나는
몰려오는 자괴감을 뒤로하고 구현에 몰두하는데,
그래봐야 돌아오는건 뱀이 왜 큐가 되는건데ㅔㅔㅔㅔ 였음..
그래서 결국 다른이의 아이디어를 묻게되어 해결한게,
뱀을 큐로 구현하는데, 각 머리 - 몸통 - 꼬리의 내부 정보는 현재 위치한 게임판 좌표를 튜플로 저장하는 것 이었다.
그 정도 가닥을 잡으니 일단 떠오르는대로 코드를 치기 시작했다
다음 난관들이 산재하였는데, 어떻게 방향전환을 시킬지 와 입력받았던 방향전환 명령을 어떻게 제때 입력 시킬것인가? 였음
방향전환 아이디어는 다행히도 금방 떠올랐는데,
직전에 백준 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)
'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 |
