개발로 사고하기

방향 전환 수학 이해를 위한 미니 게임

tues 2025. 8. 14. 14:49

https://github.com/veryyounng/disosaur_game

 

GitHub - veryyounng/disosaur_game

Contribute to veryyounng/disosaur_game development by creating an account on GitHub.

github.com

 

💡 제작 계기

백준 알고리즘 문제 3190번 - 뱀을 풀던 중,
뱀이 방향을 전환하는 로직에서 수학적으로 헷갈리는 부분이 있었다.
특히 방향을 "왼쪽"이나 "오른쪽"으로 바꿀 때 벡터를 수학적으로 회전하는 원리가 직관적이지 않게 느껴졌고,
이를 직접 시각화하며 이해하기 위해 게임을 만들게 되었다.

(그러나 시각화된 뱀이 징그러워서 공룡으로 변경)


🎯 프로젝트 목표

  • 방향 전환을 수학적으로 직접 구현하며 시각적으로 확인
  • 충돌 판정, 아이템 먹기, 길이 증가 로직까지 확장
  • 선형대수학을 실전적으로 적용한 예제로 발전

🏗️ 개발 구성

구성 요소 사용 기술
프론트엔드 HTML + CSS + JS
백엔드 Python + FastAPI
상태 저장 Python 전역 변수 (Dinosaur, ITEM 등)
화면 표시 2D 그리드 (5x5)로 표현

🧠 어떤 선형대수학을 활용했나?

1. 벡터 회전 행렬 (방향 전환 원리)

✅ 방향 벡터 ( \vec{d} )

공룡이 바라보는 방향은 벡터로 나타낸다.

예시:

  • 오른쪽: \[
    \begin{bmatrix}
    0 & 1 \\
    -1 & 0
    \end{bmatrix}
    \cdot
    \begin{bmatrix}
    dx \\
    dy
    \end{bmatrix}
    =
    \begin{bmatrix}
    dy \\
    -dx
    \end{bmatrix}
    \]
  • 위쪽: \[
    \begin{bmatrix}
    0 & -1 \\
    1 & 0
    \end{bmatrix}
    \cdot
    \begin{bmatrix}
    dx \\
    dy
    \end{bmatrix}
    =
    \begin{bmatrix}
    -dy \\
    dx
    \end{bmatrix}
    \]

✅ 이동 수식

공룡이 이동할 다음 위치는 단순한 벡터 덧셈으로 계산된다:

\[
\vec{p}_{\text{next}} = \vec{p}_{\text{current}} + \vec{d}
\]


🔑 핵심 로직 설명 (Python FastAPI)

✅ 이동 방향 및 상태

DIRECTION = [1, 0]  # → 오른쪽
SNAKE = [[2, 4], [2, 3], [2, 2]]  # 공룡 몸 (머리부터)
WALLS = [(3, 4), (4, 4)]
BOARD_SIZE = 5
  • 공룡은 한 칸씩 이동하며, 가장 앞의 위치가 머리(🦖)

✅ 이동 API 핵심 코드

@app.post("/api/move")
def move():
    global SNAKE
    dx, dy = DIRECTION
    head_x, head_y = SNAKE[0]
    nx, ny = head_x + dx, head_y + dy

    if (nx, ny) in WALLS or not (0 <= nx < BOARD_SIZE and 0 <= ny < BOARD_SIZE):
        return {"status": "crash"}

    new_head = [nx, ny]
    SNAKE = [new_head] + SNAKE[:-1]  # 앞에 추가, 뒤에 삭제 (길이 유지)
    return {"status": "ok", "snake": SNAKE}
  • head + direction = 새로운 머리 위치
  • 몸은 그대로 유지되므로, 맨 앞에 추가 + 맨 뒤 제거
  • 선형대수학에서는 단순히 덧셈이지만, 게임에서는 좌표 이동 + 충돌 판정까지 포함된 로직

✅ 화면 그리드 표현

@app.get("/api/state")
def get_state():
    board = [["" for _ in range(5)] for _ in range(5)]
    for x, y in WALLS:
        board[y][x] = "🧱"
    for i, (x, y) in enumerate(SNAKE):
        board[y][x] = "🦖" if i == 0 else "🦕"
    return {"board": board}
  • 🦖: 공룡 머리
  • 🦕: 공룡 몸통
  • 🧱: 벽

🔚 배운점

이번 프로젝트를 통해 가장 헷갈렸던 방향 전환 로직을 선형대수학 관점으로 이해하였다.

이러한 수학적 직관은 향후 다른 알고리즘 문제(예: 회전하는 로봇, 블록 퍼즐 등)에도 유용하게 적용할 것 같다.