지뢰찾기(Minesweeper) 게임을 React, TypeScript, Vite, Recoil, Tailwind CSS를 사용해 구현한 프로젝트입니다.
- React – UI 구성
- TypeScript – 정적 타입 시스템
- Vite – 빠른 개발 환경 구성 도구
- Recoil – 전역 상태 관리
- Tailwind CSS – 유틸리티 기반 CSS 프레임워크
src/
├── components/ # UI 컴포넌트 (예: Game, GameBoard, GameCell 등)
├── hooks/ # 커스텀 훅 (예: 게임 초기화, 셀 클릭 등)
├── atoms/ # Recoil을 이용한 전역 상태 관리
├── utils/ # 게임 로직 관련 유틸 함수 모음
├── types/ # 공통 타입 정의 (예: Cell, GameStatus 등)
├── assets/ # 이미지, 아이콘 등 정적 리소스 파일
- 왼쪽 클릭 : 셀을 엽니다. 숫자는 주변 8칸의 지뢰 개수를 의미합니다. 지뢰를 클릭하면 게임이 종료됩니다.
- 오른쪽 클릭 : 셀에 깃발을 꽂거나 해제합니다.
- 이모지 버튼 : 게임을 초기화하고 새로 시작합니다.
- 승리 조건 : 모든 지뢰가 아닌 셀을 열거나, 모든 지뢰 위치에 정확히 깃발을 꽂으면 승리합니다.
- 난이도 선택 (초급 / 중급 / 고급)
- 셀 열기 / 깃발 표시 (왼쪽/오른쪽 클릭)
- 빈 칸 자동 오픈
- 게임 상태(진행, 승리, 패배) 실시간 표시
- 타이머 기능
- 반응형 UI
- 새 게임 시작 기능
export const openAdjacentBlank = (
board: cell[][],
startRow: number,
startCol: number
): { openedBoard: cell[][]; updateCellCount: number } => {
const openedBoard = deepCopyBoard(board);
const ROWS = openedBoard.length;
const COLS = openedBoard[0].length;
const visited = Array.from({ length: ROWS }, () => Array(COLS).fill(false));
// BFS를 위한 큐
const queue: [number, number][] = [[startRow, startCol]];
let updateCellCount = 1;
let front = 0;
while (front < queue.length) {
const [row, col] = queue[front++];
// 현재 셀 방문 표시
visited[row][col] = true;
openedBoard[row][col].isOpen = true;
// 주변 8방향의 셀을 큐에 추가
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++) {
if (i === 0 && j === 0) continue; // 현재 셀은 건너뛰기
const [newRow, newCol] = [row + i, col + j];
// 유효한 위치이고 아직 방문하지 않은 경우
if (
newRow >= 0 &&
newRow < ROWS &&
newCol >= 0 &&
newCol < COLS &&
!visited[newRow][newCol]
) {
visited[newRow][newCol] = true;
//빈칸인 경우 계속 탐색해 나가기 위해서 큐에 넣어준다
if (openedBoard[newRow][newCol].value === 0) {
queue.push([newRow, newCol]);
updateCellCount++;
}
// 숫자셀인 경우 셀을 열어준다
if (openedBoard[newRow][newCol].value !== -1) {
openedBoard[newRow][newCol].isOpen = true;
updateCellCount++;
}
}
}
}
}
return { openedBoard, updateCellCount };
};openAdjacentBlank 함수는 빈 셀(값이 0인 셀)을 클릭했을 때, BFS(너비 우선 탐색) 알고리즘을 이용해 인접한 빈 칸들을 한 번에 열어주는 로직입니다.
- queue를 이용해 인접 셀들을 순차적으로 탐색합니다.
- 중복 탐색을 방지하기 위해 visited 배열을 사용합니다.
- 주변 8방향 셀 중 값이 0인 셀을 계속해서 큐에 추가하여 확장합니다.
- 숫자 셀인 경우에는 칸을 열어줍니다.
- 클릭한 셀과 연결된 빈칸과 숫자칸을 열고, 열린 셀의 개수를 함께 반환합니다.

