시즌 1 · 알파고편 / PART 7 · PART 7 · AlphaZero (2017) / Ch 1 · 같은 코드로 여러 게임

게임 인터페이스 — 알고리즘 vs 게임 분리

"같은 코드로 여러 게임"이 가능하려면 알고리즘과 게임을 분리해야 함.

📖 핵심 아이디어 — 인터페이스

알고리즘 측이 알아야 할 게임 정보:

  • 현재 상태에서 가능한 수의 리스트
  • 수를 두면 다음 상태
  • 현재 상태가 종료인지
  • 종료라면 누가 이김 (1, -1, 0)
  • 현재 상태를 신경망 입력으로 변환

이 5개 함수만 있으면 알고리즘 동작. "게임 = 5개 함수의 묶음".

🎯 의사 코드 — Game 인터페이스
class Game:
    def possible_moves(self):
        """가능한 수의 리스트"""
        ...
    def play(self, move):
        """수를 두고 다음 상태 반환"""
        ...
    def is_terminal(self):
        """게임 끝났나"""
        ...
    def winner(self):
        """승자 (1 / -1 / 0)"""
        ...
    def to_input(self):
        """신경망 입력 (numpy array)"""
        ...

# 게임마다 이 인터페이스 구현:
class GoGame(Game): ...
class ChessGame(Game): ...
class ShogiGame(Game): ...
class TicTacToeGame(Game): ...

# 알고리즘은 게임에 무관:
def mcts(game, net): ...        # 모든 Game에 동작
def self_play(game, net): ...   # 모든 Game에 동작
def train(games_data, net): ... # 모든 Game에 동작
  
💡 객체지향 설계의 힘

같은 코드로 여러 게임을 가능하게 하는 건 "인터페이스 기반 설계":

  • 알고리즘 측: "Game이라는 추상 타입을 받음"
  • 게임 측: "Game을 구현하면 자동으로 알고리즘에 호환"
  • 새 게임 추가: 인터페이스만 구현하면 끝

이게 좋은 SW 설계의 본질이고 AlphaZero의 일반성의 비결.

📊 입력의 게임별 차이
  • 바둑: 19x19x17 (현재 차례 8수 + 상대 8수 + 차례 표시)
  • 체스: 8x8x119 (12 기물 종류 × 8수 + 추가 정보)
  • 쇼기: 9x9x362 (14 기물 종류 × 8수 + 손에 든 기물 등)

입력 채널은 게임마다 다름. 그러나 신경망은 같은 구조 (잔차 39블록 등). 출력 크기만 게임마다 (361+1 vs 4672 vs 11259).