A cozy tic-tac-toe game with pastel aesthetics
Telegram Mini App featuring gamification, achievements, and rewards
- Classic - Standard tic-tac-toe against AI (easy/hard difficulty) or local two-player mode
- Zen Mode - Infinite gameplay where oldest moves fade after 3 moves per player
- Hearts - In-game currency for purchases
- Fortune Wheel - Daily rewards with randomized prizes
- Daily Quests - Tasks with progress tracking and rewards
- Achievements - Unlockable badges for gameplay milestones
- Promo Codes - Generated on wins, redeemable for bonuses
- Themes - Classic, Love, Nature visual styles
- Wallpapers - Dreamy, Midnight, Sakura, Fresh backgrounds
- Stickers - Emoji reactions for in-game communication
- Avatars - Cute animal characters (cat, dog, rabbit, etc.)
- Affirmations - Collectible cards with positive messages
- Minimax algorithm for hard difficulty
- Reactive phrases and emotions
- Adaptive difficulty levels
| Category | Technologies |
|---|---|
| Frontend | React 19, TypeScript 5.8, Vite 6 |
| Styling | Tailwind CSS (utility-first) |
| Icons | Lucide React |
| Audio | Web Audio API (synthesized sounds) |
| Storage | LocalStorage |
| Platform | Telegram WebApp API |
| Backend | Express.js, Node.js |
| Deployment | Docker, Docker Compose |
- Node.js 18+
- npm or yarn
# Clone the repository
git clone https://github.com/randomu3/tic-tac-toe-pastel.git
cd tic-tac-toe-pastel
# Install dependencies
npm install
# Start development server
npm run devThe application will be available at http://localhost:3000
# Copy environment template
cp .env.example .env
# Configure required variables in .env
# BOT_TOKEN, TUNA_TOKEN, etc.
# Start the full stack
docker-compose up -d├── App.tsx # Main component - state management, game loop
├── index.tsx # React entry point
├── types.ts # TypeScript types and interfaces
├── components/ # UI components
│ ├── Cell.tsx # Game board cell
│ ├── CardReveal.tsx # Affirmation card animation
│ ├── Decorations.tsx # Background decorations and particles
│ ├── FortuneWheel.tsx # Daily reward wheel
│ ├── JournalModal.tsx # Affirmation journal
│ ├── LivingAvatar.tsx # Animated avatar
│ ├── Overlay.tsx # Win/lose overlays
│ └── StatsModal.tsx # Statistics modal
├── services/ # Business logic
│ ├── gameLogic.ts # Game rules, AI (minimax), configs
│ ├── audioService.ts # Web Audio API sounds
│ ├── storage.ts # LocalStorage persistence
│ └── telegramService.ts # Telegram WebApp API wrapper
├── server/ # Backend API
│ └── src/
│ └── index.ts # Express server
└── docker-compose.yml # Docker configuration
npm run dev # Start dev server (port 3000)
npm run build # Production build
npm run preview # Preview production buildcd server
npm install
npm run dev # Start with hot-reload
npm run test # Run testsCreate a .env file in the project root:
# Required
BOT_TOKEN=your_telegram_bot_token
# Optional (for tunnel deployment)
TUNA_TOKEN=your_tuna_token
TUNA_FRONTEND_SUBDOMAIN=your-frontend-subdomain
TUNA_BACKEND_SUBDOMAIN=your-backend-subdomain
WEBAPP_URL=https://your-frontend-url
BACKEND_URL=https://your-backend-url- Open @BotFather in Telegram
- Send
/newbotand follow the prompts - Save the bot token (format:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
Send these commands to @BotFather:
/setmenubutton
Select your bot, then choose "Configure menu button" and set:
- Button text:
Play Game - Web App URL: Your deployed frontend URL
Alternatively, use the Telegram Bot API:
curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setChatMenuButton" \
-H "Content-Type: application/json" \
-d '{
"menu_button": {
"type": "web_app",
"text": "Play Game",
"web_app": {"url": "https://your-frontend-url"}
}
}'curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-backend-url/webhook"}'curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setMyCommands" \
-H "Content-Type: application/json" \
-d '{
"commands": [
{"command": "start", "description": "Start the game"},
{"command": "play", "description": "Quick play"},
{"command": "stats", "description": "View statistics"},
{"command": "daily", "description": "Daily rewards"},
{"command": "shop", "description": "Open shop"},
{"command": "promo", "description": "Promo codes info"},
{"command": "hearts", "description": "Hearts balance"},
{"command": "about", "description": "About the game"},
{"command": "support", "description": "Get help"}
]
}'Tuna is a tunneling service that exposes local servers to the internet with custom subdomains.
-
Get a Tuna token from tuna.am
-
Configure environment variables:
TUNA_TOKEN=your_tuna_token
TUNA_FRONTEND_SUBDOMAIN=myapp
TUNA_BACKEND_SUBDOMAIN=myapp-api- Start with Docker Compose:
docker-compose up -dYour app will be available at:
- Frontend:
https://myapp.ru.tuna.am - Backend:
https://myapp-api.ru.tuna.am
# Install tuna CLI
# See: https://tuna.am/docs
# Save token
tuna config save-token YOUR_TOKEN
# Start tunnel
tuna http 3000 --subdomain=myapp| Achievement | Description |
|---|---|
| First Steps | Win your first game |
| On Fire | Win 3 games in a row |
| Veteran | Play 20 games |
| Champion | Reach 10 total wins |
| Peacekeeper | Get 5 draws |
| Command | Description |
|---|---|
/start |
Launch the game |
/stats |
View player statistics |
/daily |
Check daily rewards |
/shop |
Open the shop |
/promo |
Promo codes information |
/hearts |
Hearts balance |
/about |
About the application |
/support |
Get help |
MIT License - feel free to use and modify!
Built with React and TypeScript