# Trivy - Trivia Multiplayer en Tiempo Real

Trivy Logo

**Trivy** es un juego de trivia multijugador en tiempo real inspirado en Jeopardy. Dos equipos compiten respondiendo preguntas de diferentes categorías, con mecánicas de robo y validación de respuestas por IA. ## Características - **Multijugador en tiempo real** - Hasta 8 jugadores (2 equipos × 4 jugadores) - **8 categorías temáticas** - Nintendo, Xbox, PlayStation, Anime, Música, Películas, Libros, Historia - **5 categorías por partida** - Rotación aleatoria entre partidas - **Pool de 200 preguntas** - 5 opciones por cada categoría/dificultad - **Validación de respuestas por IA** - Claude API para respuestas flexibles - **Sistema de robo** - Oportunidad de robar puntos cuando el equipo contrario falla - **Múltiples temas visuales** - DRRR, Retro Arcade, Minimal, Gaming RGB, Anime 90s - **Efectos de sonido** - Sonidos personalizados por tema - **Chat de equipo** - Comunicación privada entre compañeros - **Reacciones emoji** - Expresiones en tiempo real - **Panel de administración** - Gestión de preguntas, categorías y monitoreo ## Stack Tecnológico ### Backend - **FastAPI** - Framework web async de alto rendimiento - **Python-SocketIO** - WebSockets para comunicación en tiempo real - **PostgreSQL** - Base de datos principal - **Redis** - Estado de salas y sesiones en tiempo real - **SQLAlchemy** - ORM async - **Anthropic Claude API** - Validación inteligente de respuestas ### Frontend - **React 18** - UI declarativa - **TypeScript** - Tipado estático - **Vite** - Build tool rápido - **Zustand** - Estado global ligero - **Framer Motion** - Animaciones fluidas - **Tailwind CSS** - Estilos utilitarios - **Socket.IO Client** - Comunicación WebSocket - **Howler.js** - Gestión de audio ## Requisitos - Python 3.11+ - Node.js 18+ - PostgreSQL 15+ - Redis 7+ - API Key de Anthropic (Claude) ## Instalación ### 1. Clonar repositorio ```bash git clone https://gitea.local/frank/Trivy.git cd Trivy ``` ### 2. Configurar Backend ```bash cd backend # Crear entorno virtual python -m venv venv source venv/bin/activate # Linux/Mac # o: venv\Scripts\activate # Windows # Instalar dependencias pip install -r requirements.txt # Configurar variables de entorno cp .env.example .env # Editar .env con tus credenciales ``` ### 3. Configurar Frontend ```bash cd frontend # Instalar dependencias npm install # Configurar variables de entorno cp .env.example .env # Editar .env con la URL del backend ``` ### 4. Base de datos ```bash # Con Docker docker-compose up -d db redis # O configurar PostgreSQL y Redis manualmente # Crear base de datos: trivy ``` ### 5. Migraciones ```bash cd backend alembic upgrade head ``` ### 6. Datos iniciales ```bash # Crear usuario admin python -c " from app.models.base import get_async_session from app.models.admin import Admin import asyncio async def create_admin(): async with get_async_session()() as db: admin = Admin(username='admin') admin.set_password('admin123') db.add(admin) await db.commit() asyncio.run(create_admin()) " # Crear categorías y preguntas iniciales python scripts/seed_data.py ``` ## Ejecución ### Desarrollo ```bash # Terminal 1 - Backend cd backend source venv/bin/activate uvicorn app.main:socket_app --host 0.0.0.0 --port 8000 --reload # Terminal 2 - Frontend cd frontend npm run dev -- --host ``` ### Producción ```bash # Backend con Gunicorn gunicorn app.main:socket_app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 # Frontend build cd frontend npm run build # Servir dist/ con nginx o similar ``` ## Configuración ### Variables de entorno - Backend (.env) ```env # Base de datos DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/trivy # Redis REDIS_URL=redis://localhost:6379 # Anthropic API ANTHROPIC_API_KEY=sk-ant-... # Configuración del juego STEAL_PENALTY_MULTIPLIER=0.5 STEAL_TIME_MULTIPLIER=0.5 ROOM_TTL_HOURS=3 ``` ### Variables de entorno - Frontend (.env) ```env VITE_API_URL=http://localhost:8000 VITE_WS_URL=http://localhost:8000 ``` ## Arquitectura ``` Trivy/ ├── backend/ │ ├── app/ │ │ ├── api/ # Endpoints REST │ │ │ ├── admin.py # Panel de administración │ │ │ ├── auth.py # Autenticación │ │ │ └── game.py # Datos del juego │ │ ├── models/ # Modelos SQLAlchemy │ │ ├── schemas/ # Schemas Pydantic │ │ ├── services/ # Lógica de negocio │ │ │ ├── room_manager.py # Gestión de salas (Redis) │ │ │ ├── game_manager.py # Lógica del juego │ │ │ ├── ai_validator.py # Validación con Claude │ │ │ └── question_service.py # Carga de preguntas │ │ ├── sockets/ # Eventos WebSocket │ │ │ └── game_events.py │ │ ├── config.py # Configuración │ │ └── main.py # Aplicación ASGI │ ├── alembic/ # Migraciones │ └── requirements.txt │ ├── frontend/ │ ├── src/ │ │ ├── components/ # Componentes React │ │ │ ├── chat/ # Chat y reacciones │ │ │ ├── game/ # Componentes del juego │ │ │ ├── lobby/ # Sala de espera │ │ │ └── ui/ # Componentes UI genéricos │ │ ├── hooks/ # Custom hooks │ │ │ ├── useSocket.ts │ │ │ └── useSound.ts │ │ ├── pages/ # Páginas/rutas │ │ ├── services/ # Servicios (socket) │ │ ├── stores/ # Estado Zustand │ │ ├── themes/ # Temas visuales │ │ └── types/ # Tipos TypeScript │ ├── public/ │ │ └── sounds/ # Archivos de audio │ └── package.json │ └── docs/ # Documentación ``` ## Flujo del Juego ``` 1. CREAR SALA Host → create_room → Código de 6 caracteres 2. UNIRSE Jugadores → join_room(código) → Asignación a equipo A/B 3. INICIAR Host → start_game → Backend carga 5 categorías aleatorias 4. TURNO Jugador actual → Selecciona pregunta del tablero 5. RESPONDER 30 segundos para escribir respuesta Claude valida si es correcta 6. ROBO (si falla) Equipo contrario puede intentar robar Si falla el robo, pierde puntos 7. SIGUIENTE TURNO Rotación de jugadores y equipos 8. FIN Cuando todas las preguntas están contestadas Equipo con más puntos gana ``` ## API REST ### Autenticación - `POST /api/auth/login` - Login admin - `POST /api/auth/logout` - Logout ### Juego - `GET /api/game/categories` - Lista de categorías - `GET /api/game/today-questions` - Preguntas del día ### Admin - `GET /api/admin/questions` - Listar preguntas - `POST /api/admin/questions` - Crear pregunta - `PUT /api/admin/questions/{id}` - Actualizar pregunta - `DELETE /api/admin/questions/{id}` - Eliminar pregunta - `GET /api/admin/categories` - Listar categorías - `GET /api/admin/rooms/active` - Salas activas ## Eventos WebSocket ### Cliente → Servidor - `create_room` - Crear nueva sala - `join_room` - Unirse a sala existente - `start_game` - Iniciar partida (solo host) - `select_question` - Seleccionar pregunta - `submit_answer` - Enviar respuesta - `steal_decision` - Decidir si robar - `chat_message` - Mensaje de chat - `team_message` - Mensaje de equipo - `send_reaction` - Enviar emoji ### Servidor → Cliente - `room_created` - Sala creada - `player_joined` - Jugador se unió - `game_started` - Juego iniciado - `question_selected` - Pregunta seleccionada - `answer_result` - Resultado de respuesta - `steal_prompt` - Oportunidad de robo - `game_finished` - Juego terminado - `error` - Error ## Temas Disponibles | Tema | Descripción | |------|-------------| | DRRR | Inspirado en Durarara!! - Oscuro con acentos amarillos | | Retro Arcade | Estética arcade 80s - Neón sobre negro | | Minimal | Diseño limpio y moderno - Blanco con acentos | | Gaming RGB | Gradientes RGB animados - Estilo gamer | | Anime 90s | Colores pasteles - Nostalgia anime | ## Categorías 1. **Nintendo** 🍄 - Mario, Zelda, Pokémon, etc. 2. **Xbox** 🎮 - Halo, Forza, Game Pass, etc. 3. **PlayStation** 🎯 - God of War, Uncharted, etc. 4. **Anime** ⛩️ - Naruto, One Piece, Dragon Ball, etc. 5. **Música** 🎵 - Artistas, géneros, historia musical 6. **Películas** 🎬 - Cine clásico y moderno 7. **Libros** 📚 - Literatura universal 8. **Historia** 🏛️ - Historia y cultura general ## Contribuir 1. Fork el repositorio 2. Crear rama feature (`git checkout -b feature/nueva-funcionalidad`) 3. Commit cambios (`git commit -m 'feat: descripción'`) 4. Push a la rama (`git push origin feature/nueva-funcionalidad`) 5. Crear Pull Request ## Licencia MIT License - ver [LICENSE](LICENSE) ## Créditos Desarrollado por Frank con asistencia de Claude (Anthropic) ---

¡Que gane el mejor equipo! 🏆