매치메이킹: 플레이어 짝짓기
낯선 두 사람을 게임에 짝지어 주는 로비 만들기
⏱ 예상 ~7분
01 · 읽기
매치메이킹은 1 인용 게임을 멀티플레이어 경험으로 바꾸는 부분이에요. 개념은 간단해요. 대기 목록을 유지해요. 두 플레이어가 기다리고 있으면 짝지어서 게임 방을 만들고 경기를 시작해요.
어려운 건 엣지 케이스예요. 플레이어가 기다리는 중에 disconnect 되면? 게임 중에 disconnect 되면? 두 플레이어 다 다시 하고 싶으면? 좋은 매치메이킹 시스템은 이런 경우를 모두 깔끔하게 처리해요.
💡 상상해 봐요레스토랑 호스트가 waitlist 를 관리하는 걸 떠올려 봐요. 2 인용 테이블이 비면 다음 2 인 그룹을 안내해요. 누가 waitlist 를 떠나면 명단에서 빼요. 누가 식사 중에 떠나면, 호스트가 그 자리를 계속 잡아 두지 않아요.
핵심 정리
- 매치메이킹이 대기 중인 플레이어 queue 를 유지해요
- queue 에 두 명이 있으면 짝지어서 방에 넣어요
- 각 방은 자체 TicTacToeGame 인스턴스를 가져요
- Disconnect 처리가 중요해요. queue 와 게임 중 모두
02 · 프롬프트 템플릿
Claude에게 매치메이킹 모듈을 만들어 달라고 해요. 데이터 구조와 짝짓기 로직을 명확히 설명해요.
tic-tac-toe 게임용 matchmaking.js 모듈을 만들어 주세요. 요구 사항: (1) 대기 queue (socket 배열) 를 유지해요. (2) addToQueue(socket, io) 함수를 내보내요. 이미 누가 기다리고 있으면 두 사람을 짝지어요. 고유한 room ID 를 생성하고, 새 TicTacToeGame 인스턴스를 만들고, X 와 O 를 무작위로 배정하고, 두 socket 모두 해당 방에 join 시키고, 각자에게 자신의 심볼과 room ID 와 함께 'game-start' 를 emit 해요. 기다리는 사람이 없으면 이 socket 을 queue 에 추가하고 'waiting' 을 emit 해요. (3) removeFromQueue(socket) 함수를 내보내요. disconnect 된 socket 을 대기 queue 에서 제거해요. (4) 진행 중인 게임을 추적할 Map (roomId -> { game, players }) 과, 각 socket 이 어떤 방에 있는지 추적할 또 다른 Map (socketId -> roomId) 을 써요. (5) handleDisconnect(socket, io) 함수를 내보내요. 그 socket 이 queue 에 있으면 제거해요. 진행 중인 게임에 있으면 상대에게 'opponent-left' 를 emit 하고 그 방을 정리해요. ./game 에서 TicTacToeGame class 를 import 해 주세요.03 · 코드 예제
매치메이킹 모듈은 세 가지 데이터 구조를 써요. 각각이 무엇을 저장하고 왜 존재하는지 이해해요.
세 가지 데이터 구조
// Players waiting for a match
const waitingQueue = [];
// Active game rooms: roomId -> { game, players: { X: socket, O: socket } }
const activeGames = new Map();
// Which room each player is in: socket.id -> roomId
const playerRooms = new Map();
waitingQueue 는 'Find Game' 을 눌렀지만 아직 짝이 없는 socket 을 담아요. activeGames 는 각 방을 게임 상태와 플레이어 socket 에 매핑해요. 서버가 어떤 수가 어떤 게임에 속하는지 아는 방법이에요. playerRooms 는 역방향 조회예요. socket ID (disconnect 이벤트에서 받은) 로 그들이 어느 방에 있는지 찾아 상대에게 알릴 수 있어요.
04 · 프롬프트 템플릿
이제 매치메이킹을 서버에 연결해요. Claude에게 server.js 를 새 모듈을 쓰도록 업데이트해 달라고 해요.
server.js 를 업데이트해서 matchmaking 모듈을 쓰게 해 주세요. 'connection' 이벤트에서 클라이언트가 보낸 'find-game' 을 listen 하고 addToQueue 를 호출해요. 'disconnect' 이벤트에서 handleDisconnect 를 호출해요. 'make-move' 도 listen 해요. 플레이어가 한 수를 보내면 playerRooms 에서 그가 있는 방을 찾고, activeGames 에서 해당 game 을 찾아서 game.makeMove(index) 를 호출해요. 유효하면 그 방에 'move-made' 를 emit 하고 수 세부 정보를 같이 보내요. 게임이 끝났으면 그 방에 'game-over' 를 결과와 함께 emit 해요.
05 · 읽기
잠깐, Claude가 만든 걸 읽어 봐요. 이게 여러분이 길러야 할 가장 중요한 습관이에요. 그냥 실행하지 말고 먼저 읽어요.
다음 상황에서 무슨 일이 일어나는지 따라가 봐요:
1. 첫 플레이어가 연결하고 Find Game 을 누름 2. 두 번째 플레이어가 같은 일을 함 3. 둘이 방으로 짝지어짐 4. 첫 플레이어가 한 수를 둠
코드가 레슨 2 의 계획과 맞나요? 서버가 브로드캐스트 전에 수를 검증하나요? Disconnect 처리가 제대로 정리하나요?
계획과 다른 게 있으면 Claude에게 고쳐 달라고 해요. 여러분은 아키텍트고, Claude 는 건축업자예요.
핵심 정리
- 실행하기 전에 읽어요. 항상요
- 머릿속으로 시나리오를 따라가요
- 코드를 계획과 대조해요
- 맞지 않으면 Claude에게 고쳐 달라고 해요
06 · 퀴즈
매치메이킹 queue 에서 기다리던 플레이어가 disconnect 됐어요. 어떻게 돼야 할까요?
- 아무 일도 없어요. 자동으로 다시 연결돼요
- queue 에서 제거돼야 해요. 새로 들어온 플레이어와 짝지어지지 않도록
- 서버가 충돌하고 재시작해야 해요
- 5 분 동안 자리를 유지해야 해요
07 · 빈칸 채우기
두 플레이어가 queue 에 있으면, 매치메이킹 시스템이 게임 _____ 을 만들고 각 플레이어에게 심볼 (X 또는 O) 을 배정해요.
⚠ 전체 인터랙티브 경험에는 JavaScript가 필요해요. JavaScript를 켜고 새로 고침해 주세요.
※ 이 사이트는 독립 운영되는 교육 프로젝트로, Anthropic의 공식 제품이 아니에요. Claude™ 는 Anthropic, PBC 의 상표예요.