리버스 체스 ( 1 ) - 회고
게임 링크 : https://reversechess.perfect.ai.kr/
리버스 체스
reversechess.perfect.ai.kr

총 개발 시간 55시간
리버스 체스는 체스의 변형 규칙 버전이다.
< 리버스 체스 개발기 리스트 >
익숙한 부분 ( 엔진, UI, 튜토리얼, 2인 플레이 )
https://helloworld.ai.kr/30
'그 긴 거' ( AI 알고리즘, 1인 플레이 )
https://helloworld.ai.kr/31
구글 애널리틱스, 모바일 UI ( 디버깅 )
https://helloworld.ai.kr/32
개발 범위
1. 2인 플레이 (1:1 테이블 모드)
온라인 매칭 시스템은 없고 한 화면에서 같이 플레이하는 형태
2. 튜토리얼 페이지
규칙을 쉽게 이해할 수 있도록 체스판과 특정 상황을 직접 제공
3. 컴퓨터 대전 모드
난이도는 쉬움 / 어려운 두 단계로 구성
리버스 체스 규칙
1. 체스의 특수 규칙 중 캐슬링, 앙파상은 없고 프로모션만 적용된다. 기본적인 기물의 행마는 동일하다.
2. 흑이 선이다.
3. 게임 종료 및 승리 조건은 다음과 같다.
- 내 말이 모두 잡히고 킹만 남으면 승리
- 체크메이트를 당하면 승리
- 내가 체크 상태가 아니며, 움직일 수 있는 말이 킹뿐이면 승리 (외딴섬)
- 스테일메이트는 무승부
4. 체크 상태라면 반드시 피해야 하며 , 내가 체크가 되도록 둘 수 없다.
5. 4번을 지키는 범위 내에서 잡을 수 있는 말이 있다면 반드시 그 중 하나를 잡아야 한다. (강제 캡처)
개발 목적
1. 포트폴리오로 활용 및 개발 연습
AI 플레이어 만들 때 연습이 많이 되었음. 그동안 덜 신경 쓰던 부분(UI 등)을 의식적으로 다뤄보았음.
2. 실사용 가능성
- 원안자가 지니어스 행사에서 데스매치로 리버스 체스를 활용했는데, 웹으로 만들어두면 쓸 곳이 있을 것 같았음.
- 지인들에게 잠깐의 두뇌 운동과 재미를 전달하고 싶었음.
3. 재미
아키텍쳐
- 프론트엔드 온리 웹 페이지
- Typescript + React, Vercel 배포
- 컴퓨터 플레이어는 web worker에서 실행되도록 구현
개발 방식
이번 프로젝트에서는 Cursor와 Lovable의 기여율을 이전보다 크게 낮췄다.
Cursor 도움 없이 직접 작성하거나 재작성한 코드가 80% 이상
Lovable이 만든 UI도 그대로 쓰지 않고 CSS 또는 컴포넌트 단위로 가져와 수정
그 결과 시간은 1.5배 이상 더 들었지만 코드에 대한 신뢰도가 크게 올라갔다. 다만 다음 프로젝트에서는 Cursor 기여율을 조금 더 높여도 괜찮을 것 같다.
배운 점
1. TT와 미니맥스 알고리즘을 응용한 AI 플레이어 제작
다음 조합을 구상해서 구현했다.
- 미니맥스 + 알파베타 프루닝
- 비균일 깊이 탐색
- Zobrist Hash 기반 Transposition Table(LRU)
- Anytime Iterative Deepening
2. 웹 워커 활용
브라우저에서 UI 렌더링이 막히지 않도록, AI 탐색을 워커 스레드로 분리했다.
3. heisenbug 이해
관찰하려고 하면 사라지거나 재현이 어려운 버그를 하이젠베르크의 불확정성 원리에 빗대어 heisenbug라고 한다. 비동기 웹워커 구조에서 발생하는 버그를 확인하려고 console.log를 찍는 순간 타이밍이 바뀌어서 버그가 사라지는 현상을 직접 겪었다.
4. 구글 애널리틱스 활용
유저의 체류시간이나 행동을 이벤트로 정의해서 수집하고 분석할 수 있다는 점이 꽤 감탄스러웠다.
5. 모바일 UI 기초
모바일을 고려하면 고정 픽셀 크기를 피하고 비율로 정의하는 편이 좋다. 특히 sm: ~~ 같은 브레이크포인트나 clamp(최소, 크기 정의, 최대) 같은 CSS를 잘 활용하니 확실히 편했다.
아쉬운 점
1. Zobrist 해시의 증분 업데이트 실패
보드를 업데이트할 때 해시도 증분 방식으로 같이 업데이트하려 했는데, 어느 순간부터 보드 상태와 해시가 어긋나는 문제가 발생했다. 결국 에러를 없애기 위해 매 수마다 해시를 통째로 재계산하도록 바꿨다. 크리티컬하진 않지만, 그만큼 불필요한 계산이 늘었을 것이다.
2. AI warm up 적용 실패
웹 워커 구조라서, 사용자 차례에도 AI가 계속 생각하며 TT 엔트리를 채우는 워밍업이 가능하다. 그래서 유저 턴에도 계산을 지속하다가 요청이 들어오면 계산을 종료하고 다음 수 계산을 시작하는 구조를 시도했는데, 원인을 특정할 수 없는 동시성 문제가 계속 나서 롤백했다.
3. invalid move 원인을 찾지 못함
한 판에 한 번 정도 AI가 규칙상 불가능한 수를 내는 문제가 남아 있다. 아마 AI가 참조하는 보드 상태가 꼬이는 것 같은데, 디버깅에 실패했다. 끝없이 시간을 태우기보다는 일단 억지로 틀어막는 쪽을 택했다.
- invalid move 발생 시 1회 재시도
- 그래도 실패하면 합법 수 중 랜덤 1개 선택
4. 어려움 난이도가 생각만큼 높지 않음
- 쉬움 : 최대 1초 / 6수
- 어려움 : 최대 10초 / 9수
어렵긴 한데, “압도적으로 어렵다” 수준은 아니다. 1~3번 문제를 해결하고 오프닝 북까지 도입하면 난이도를 더 끌어올릴 수 있을 것 같다.
5. 모바일 다크모드 문제
모바일 UI가 깨지지 않도록 신경은 썼지만 다크모드는 해결하지 못했다. 크롬 다크모드에서 턴 표시 컴포넌트와 체스 말 색이 이상하게 변해서 흑/백이 헷갈린다. CSS만으로는 확실한 해결책을 찾지 못했고, 이미지 리소스로 고정하면 근본 해결이 가능하겠지만 시간상 진행하지 못했다.
6. 예상보다 과도한 시간 투입
원래 목표는 20시간이었는데 결과적으로 55시간이 들었다.
중간에 미완성으로 접는 게 맞았나 생각해보면 꼭 그렇진 않다. 가끔 이렇게 끝까지 붙잡는 프로젝트가 있어야 배우는 것도 많은 것 같다. 다만 제 시간 안에 끝내지 못한 내 실력이 아쉬울 뿐이다.
기술 스택 고민 : 프론트엔드 온리로 충분한가?
프로젝트 시작 때 가장 먼저 고민한 건 “백엔드 서버가 필요한가”였다.
- 웹소켓은 필요 없다.
유저 간 온라인 플레이가 없고, 실시간 쌍방향 통신이 필요 없기 때문 - 튜토리얼과 2인 플레이는 프론트만으로 충분
- 관건은 결국 AI를 브라우저에서 돌릴 수 있느냐였다.
GPT 조언을 참고해 “브라우저로도 충분하다” 쪽에 베팅했다. 최대한 가벼운 구조로 시작하고, 필요하면 그때 덧붙이는 게 맞다고 생각했다. 실제로 성능은 충분했다.
다음 글부터는 개발 과정을 단계별로 좀 더 상세히 다루도록 하겠다.
다음 글 보러가기 : https://helloworld.ai.kr/30
리버스 체스 ( 2 ) - 익숙한 부분
게임 링크 : https://reversechess.perfect.ai.kr/ 리버스 체스 reversechess.perfect.ai.kr리버스 체스 기록 처음부터 보기 : https://helloworld.ai.kr/29엔진과 UI 파트 분리카드 게임 개발 때나 Echo of Mana 컨셉 플레이를
helloworld.ai.kr