|
1 | | -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). |
| 1 | +# Tic Tac Toe |
2 | 2 |
|
3 | | -## Getting Started |
| 3 | +Demo: <a href="https://hellsgor.github.io/tic-tac-toe/" target="_blank">https://hellsgor.github.io/tic-tac-toe/</a> |
4 | 4 |
|
5 | | -First, run the development server: |
| 5 | +--- |
6 | 6 |
|
7 | | -```bash |
8 | | -npm run dev |
9 | | -# or |
10 | | -yarn dev |
11 | | -# or |
12 | | -pnpm dev |
13 | | -# or |
14 | | -bun dev |
15 | | -``` |
| 7 | +<p align="center"> |
| 8 | + <img src="https://img.shields.io/badge/Next.js-000?style=for-the-badge&logo=next.js&logoColor=white" alt="Next.js" /> |
| 9 | + <img src="https://img.shields.io/badge/React-20232a?style=for-the-badge&logo=react&logoColor=61dafb" alt="React" /> |
| 10 | + <img src="https://img.shields.io/badge/TypeScript-007acc?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript" /> |
| 11 | + <img src="https://img.shields.io/badge/Redux_Toolkit-593d88?style=for-the-badge&logo=redux&logoColor=white" alt="Redux Toolkit" /> |
| 12 | + <img src="https://img.shields.io/badge/Tailwind_CSS-38bdf8?style=for-the-badge&logo=tailwind-css&logoColor=white" alt="Tailwind CSS" /> |
| 13 | + <img src="https://img.shields.io/badge/Headless_UI-000000?style=for-the-badge" alt="Headless UI" /> |
| 14 | + <img src="https://img.shields.io/badge/Heroicons-000000?style=for-the-badge" alt="Heroicons" /> |
| 15 | + <img src="https://img.shields.io/badge/ESLint-4B32C3?style=for-the-badge&logo=eslint&logoColor=white" alt="ESLint" /> |
| 16 | + <img src="https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=black" alt="Prettier" /> |
| 17 | +</p> |
| 18 | + |
| 19 | +## Фичи | Features |
| 20 | + |
| 21 | +*in Russian* |
| 22 | + |
| 23 | +- **Классическая игра 3x3** – реализация популярной игры «крестики-нолики» на поле 3x3 для двух игроков (X и O) на одном устройстве. Игроки ходят по очереди. |
| 24 | +- **Переключение ходов** – после каждого хода автоматически сменяется текущий игрок (X ⇄ O). |
| 25 | +- **Логика победы и ничьей** – после каждого хода осуществляется проверка всех выигрышных комбинаций. Если один из игроков заполнил ряд из трех символов – игра завершается победой этого игрока. Если все клетки заполнены и ни одной выигрышной комбинации нет – фиксируется ничья. |
| 26 | +- **Подсветка победной комбинации** – при победе три клетки, образующие победный ряд, подсвечиваются цветом (для X и O – разный оттенок фона, соответствующий их символу). |
| 27 | +- **Отображение статуса игры** – в интерфейсе отображается текущий статус: чей сейчас ход (игрок X или O), порядковый номер хода, а по окончании игры выводится сообщение о результате (победа X/O или ничья Draw). |
| 28 | +- **Ограничение времени на ход** – каждый ход ограничен по времени (примерно 10 секунд). Таймер отображается в интерфейсе рядом с номером хода. Если игрок не успевает сделать ход до истечения времени, ему автоматически засчитывается техническое поражение (победа присуждается оппоненту). |
| 29 | +- **Сброс и новая игра** – после окончания партии доступны кнопки Play again («сыграть ещё раз») и New game («новая игра»). При бездействии новая партия запускается автоматически через ~10 секунд. |
| 30 | +- **Информация о игроках** – интерфейс отображает профили двух игроков с именами, рейтингом и символом (X или O). |
16 | 31 |
|
17 | | -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. |
| 32 | +*in English* |
18 | 33 |
|
19 | | -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. |
| 34 | +- **Classic 3x3 Game** – implementation of the popular tic-tac-toe game on a 3x3 grid for two players (X and O) on a single device. Players take turns. |
| 35 | +- **Turn Switching** – after each move, the active player automatically switches (X ⇄ O). |
| 36 | +- **Win and Draw Logic** – after every move, all winning combinations are checked. If a player fills a row of three symbols, the game ends with that player’s victory. If all cells are filled without any winner – the game ends in a draw. |
| 37 | +- **Winning Combination Highlight** – the three cells forming the winning row are highlighted with a background color (different for X and O). |
| 38 | +- **Game Status Display** – the interface shows the current status: whose turn it is (X or O), the move number, and after the game ends, a message about the result (winner X/O or draw). |
| 39 | +- **Turn Time Limit** – each move is time-limited (approx. 10 seconds). A countdown timer is shown in the UI. If a player fails to make a move in time, they forfeit, and the opponent wins. |
| 40 | +- **Reset and New Game** – after a game ends, "Play again" and "New game" buttons are available. If no action is taken, a new game starts automatically after ~10 seconds. |
| 41 | +- **Player Info** – the interface shows profiles for both players, including names, rating, and symbols (X or O). |
20 | 42 |
|
21 | | -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. |
| 43 | +### Технологический стек | Tech Stack |
22 | 44 |
|
23 | | -## Learn More |
| 45 | +- Next.js |
| 46 | +- React |
| 47 | +- TypeScript |
| 48 | +- Redux Toolkit + React-Redux |
| 49 | +- Tailwind CSS |
| 50 | +- Headless UI |
| 51 | +- Heroicons |
| 52 | +- ESLint + Prettier |
24 | 53 |
|
25 | | -To learn more about Next.js, take a look at the following resources: |
| 54 | +### Структура проекта | Project Structure |
26 | 55 |
|
27 | | -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. |
28 | | -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. |
| 56 | +```python |
| 57 | +tic-tac-toe/ |
| 58 | +├── src/ |
| 59 | +│ ├── app/ # Next.js App Router: страницы и общий макет приложения |
| 60 | +│ │ ├── layout.tsx # Корневой компонент макета (оформление <html>, <body>), подключает глобальные стили, провайдер хранилища и шапку |
| 61 | +│ │ ├── page.tsx # Главная страница приложения – игровое поле и информационная панель |
| 62 | +│ │ ├── StoreProvider.tsx# Компонент-провайдер Redux Store для App Router (обёртка над React-Redux Provider) |
| 63 | +│ │ └── globals.css # Глобальные стили (подключение Tailwind CSS, определение CSS-переменных темы) |
| 64 | +│ ├── components/ # Общие компоненты приложения (не зависят от конкретной логики игры) |
| 65 | +│ │ ├── Header/ # Шапка приложения с логотипом и профилем пользователя |
| 66 | +│ │ └── Player/ # Компоненты для отображения профиля игрока (аватар, имя, рейтинг) |
| 67 | +│ ├── lib/ # Логика приложения и хранилище состояний |
| 68 | +│ │ ├── store.ts # Конфигурация Redux Store (собранные редьюсеры) |
| 69 | +│ │ ├── reducers.ts # Корневой редьюсер, подключает слайсы (игровой reducer и др.) |
| 70 | +│ │ ├── hooks.ts # Вспомогательные хуки `useAppDispatch`, `useAppSelector` для типизированного доступа к Redux |
| 71 | +│ │ └── features/ # Реализация функциональных модулей (фич). В данном проекте основная фича – игра Tic Tac Toe |
| 72 | +│ │ └── game/ # Модуль игры крестики-нолики |
| 73 | +│ │ ├── game.ts # Redux-slice игры: начальное состояние, reducers (ход, победа, ничья, сброс и т.д.) |
| 74 | +│ │ ├── selectors.ts # Селекторы для выборки данных игры из состояния (например, состояние конкретной клетки) |
| 75 | +│ │ ├── thunks/ # Thunk-функции (асинхронная или комплексная логика): |
| 76 | +│ │ │ └── checkGame.ts # Проверка состояния игры после каждого хода (выявление победы или ничьи) |
| 77 | +│ │ ├── hooks/ # Специфичные хуки для игровой логики: |
| 78 | +│ │ │ ├── useDoMove.ts # Хук для выполнения хода: обрабатывает нажатие на клетку (обновляет состояние и запускает проверки) |
| 79 | +│ │ │ └── useMoveTimer.ts # Хук таймера хода: отсчитывает время на ход, при нуле инициирует техническую победу другого игрока |
| 80 | +│ │ └── components/ # UI-компоненты, связанные с игровым процессом: |
| 81 | +│ │ ├── Field/ # Компоненты игрового поля |
| 82 | +│ │ │ └── Field.tsx # Поле 3x3, состоящее из ячеек (клеток) |
| 83 | +│ │ ├── Cell/ # Компоненты ячейки поля |
| 84 | +│ │ │ ├── Cell.tsx # Отдельная клетка поля (кнопка) с логикой хода |
| 85 | +│ │ │ ├── CellIcon.tsx # Отображение иконки X/O внутри клетки (с учетом состояния и наведения) |
| 86 | +│ │ │ └── getClasses.ts# Определение CSS-классов для клетки (обычная, выигрышная и т.д.) |
| 87 | +│ │ └── Info/ # Компоненты информационной панели игры |
| 88 | +│ │ ├── Info.tsx # Контейнер панели: отображает информацию о двух игроках, статус и действия |
| 89 | +│ │ ├── InfoPlayer.tsx # Компонент отображения профиля игрока (имя, рейтинг, символ) |
| 90 | +│ │ ├── InfoMove.tsx # Компонент отображения хода: номер хода, статус (чей ход/результат) и таймер |
| 91 | +│ │ ├── InfoActions.tsx# Компонент действий после игры: кнопки "Play again" и "New game", с таймером автоматического рестарта |
| 92 | +│ │ └── Status/Status.tsx # Компонент статуса игры (текущий игрок или победитель/ничья) с соответствующей иконкой |
| 93 | +│ ├── UI/ # Набор универсальных UI-компонентов (используются в разных частях приложения) |
| 94 | +│ │ ├── Button/ # Кнопка (с использованием React.memo для оптимизации) |
| 95 | +│ │ ├── Container/ # Контейнер для центровки контента (задает max-width и отступы) |
| 96 | +│ │ ├── Modal/ # Модальное окно (обертка для отображения всплывающих панелей) |
| 97 | +│ │ ├── Panel/ # Панель (контейнер с фоном и скругленными углами для блоков интерфейса) |
| 98 | +│ │ ├── Avatar/ # Аватар (круглый контейнер для изображения игрока или иконки по умолчанию) |
| 99 | +│ │ ├── Logo/ # Логотип приложения (текстовая ссылка "Tic Tac Toe") |
| 100 | +│ │ ├── InputText/ # Компоненты для текстового поля ввода (с меткой, сообщением об ошибке и пр.) |
| 101 | +│ │ ├── Select/ # Выпадающий список (select) на базе Headless UI для выбора значений |
| 102 | +│ │ └── icons/ # SVG-иконки приложения: |
| 103 | +│ │ ├── XIcon.tsx # Иконка крестика (X) |
| 104 | +│ │ └── OIcon.tsx # Иконка нолика (O) |
| 105 | +│ ├── constants/ # Константы, используемые в логике игры и настройках |
| 106 | +│ │ ├── winCombinations.ts # Набор выигрышных комбинаций для поля 3x3 (массив из индексов клеток) |
| 107 | +│ │ ├── durations.ts # Настройки таймеров (длительность хода, время до автоматического рестарта игры и др.) |
| 108 | +│ │ └── basePath.ts # Базовый путь для приложения (используется при развертывании на подкаталоге, например GitHub Pages) |
| 109 | +│ ├── models/ # Модели данных и типы TypeScript |
| 110 | +│ │ ├── game.ts # Описание интерфейсов игрового состояния (GameState) и типов (ход, победитель и пр.) |
| 111 | +│ │ ├── playerSymbol.ts # Enum типа игрока (X или O) |
| 112 | +│ │ └── cell.ts # Определение типа клетки (значение X/O или пусто) и структур для передачи данных о ходе |
| 113 | +│ └── hooks/ # Глобальные хуки общего назначения |
| 114 | +│ ├── useTimer.ts # Универсальный таймер-хук (логика запуска/остановки таймера, отсчет времени в секундах) |
| 115 | +│ └── useNow.ts # Вспомогательный хук для получения текущего времени с заданным интервалом (используется внутри таймера) |
| 116 | +├── public/ # Статические файлы, доступные напрямую в приложении |
| 117 | +│ ├── fonts/ # Шрифты (например, Chivo Mono, подключаемый для интерфейса) |
| 118 | +│ └── images/ # Изображения (аватары игроков по умолчанию, иконки и др.) |
| 119 | +├── package.json # Файл с информацией о проекте, списком зависимостей и сценариев (scripts) |
| 120 | +├── next.config.ts # Конфигурация Next.js (напр. `basePath` для деплоя приложения в подкаталог `/tic-tac-toe`) |
| 121 | +├── tailwind.config.js # Конфигурация Tailwind CSS (настройки путей, тема с использованием CSS-переменных цвета и пр.) |
| 122 | +├── tsconfig.json # Конфигурация TypeScript |
| 123 | +└── ... и другие файлы конфигураций (.eslintrc, .prettierrc, .gitignore и т.д.) |
| 124 | +``` |
| 125 | + |
| 126 | +### Скрипты | Scripts |
| 127 | + |
| 128 | +The project defines the following npm scripts for building and running the application: |
29 | 129 |
|
30 | | -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! |
| 130 | +- `npm run dev` – starts the development server with hot reload at `http://localhost:3000` |
| 131 | +- `npm run build` – builds the project for production into the out directory |
| 132 | +- `npm run start` – runs the production build using a Node.js server (used only for SSR; for static export, serve out folder) |
| 133 | +- `npm run lint` – runs ESLint to check code style and issues |
31 | 134 |
|
32 | | -## Deploy on Vercel |
| 135 | +### Запуск проекта | Run Locally |
33 | 136 |
|
34 | | -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. |
| 137 | +```bash |
| 138 | +git clone https://github.com/hellsgor/tic-tac-toe.git |
| 139 | +cd tic-tac-toe |
| 140 | +npm install |
| 141 | +npm run dev |
| 142 | +``` |
35 | 143 |
|
36 | | -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. |
| 144 | +Открыть в браузере | Open your browser at: `http://localhost:3000` |
0 commit comments