Do you want to play? Try it here!
We are a coordinated team working across different layers of the stack to deliver a seamless gaming experience:
| Member | Role | Contact |
|---|---|---|
| Elena Quintes | Frontend | UO269665@uniovi.es |
| Luis Sánchez de Posada | Frontend | UO277488@uniovi.es |
| Marcos José Hernández | Backend | UO300022@uniovi.es |
| David Alonso | Frontend | UO300569@uniovi.es |
| Ceyda Tolunay | Backend | UO318869@uniovi.es |
| Lucas Uña García | Backend | UO302165@uniovi.es |
- 🎮 Classic Game Y: Fully functional hexagonal board game.
- 🧠 Smart AI: Multiple difficulty levels powered by our high-performance Rust engine.
- 💬 Text Chat: Integrated real-time text interaction for competitive matches.
- ⏪ Player QoL: Strategic Hints and Undo functionality to improve learning.
- 📊 Rankings: Competitive leaderboard based on specialized Winrate Metrics.
- 🤖 Bot Friendly: Documented API using YEN notation for external developers.
yovi_en3b/
├── 📁 docs/ # Arc42 documentation & meeting minutes
├── 📁 gamey/ # Rust-based Game Engine (Logic & AI)
├── 📁 users/ # Node.js + Express backend (Business Logic)
├── 📁 webapp/ # React + TypeScript frontend (User Interface)
└── 🐳 docker-compose.yml # System orchestration
- User Registration: The web application provides a simple form to register new users.
- User Service: The user service receives the registration request, it process the data sent and allow or disallow the registration.
- GameY: A Game engine in which we can choose to play against an IA bot or a bot based on computational algorithms.
The webapp is a single-page application (SPA) created with Vite and React.
src/App.tsx: The main component of the application.src/RegisterForm.tsx: The component that renders the user registration form.package.json: Contains scripts to run, build, and test the webapp.vite.config.ts: Configuration file for Vite.Dockerfile: Defines the Docker image for the webapp.
The users service is a simple REST API built with Node.js and Express.
index.js: The main file for the user service. It defines the different endpoints that will be used in the service (/users, /matches, /ranking).package.json: Contains scripts to start the service.Dockerfile: Defines the Docker image for the user service.
The gamey component is a Rust-based game engine with bot support, built with Rust and Cargo.
src/main.rs: Entry point for the application.src/lib.rs: Library exports for the gamey engine.src/bot/: Bot implementation and registry.src/core/: Core game logic including actions, coordinates, game state, and player management.src/notation/: Game notation support (YEN, YGN).src/web/: Web interface components.Cargo.toml: Project manifest with dependencies and metadata.Dockerfile: Defines the Docker image for the gamey service.
The application includes a comprehensive ranking system that tracks player performance and calculates competitive standings.
- Match Completion: When a match finishes, the winner and loser are recorded in the database
- Ranking Initialization: If a player is new, their ranking entry is automatically created
- Score Calculation: Rankings are calculated using the formula:
score = 50 * (2 * wins - total_matches) - Position Calculation: Player positions are determined by sorting all players by score in descending order
Get My Ranking Position
GET /ranking/me?userId={userId}
Response:
{
"position": 5,
"totalPlayers": 127
}Finish a Match (Record Winner)
POST /matches/finish
Content-Type: application/json
{
"matchId": "match-uuid",
"winnerId": "winner-user-id"
}
This endpoint automatically:
- Records the match winner
- Updates both players' ranking statistics
- Initializes new player rankings if needed
Get Global Rankings
GET /ranking/global
Response: Array of players with their stats, ranked by score.
When a match completes in the game, call the /matches/finish endpoint with:
matchId: The ID of the completed matchwinnerId: The UUID of the winning player
After calling this endpoint, the user's ranking will be updated and visible in their profile.
1. Player finishes a game (wins)
↓
2. Frontend calls: POST /matches/finish
{ matchId: "abc123", winnerId: "user-uuid" }
↓
3. Backend records match result
4. Backend initializes/updates player rankings
↓
5. User opens profile
6. Frontend fetches: GET /ranking/me?userId=user-uuid
7. Display updated ranking position
Generated by contrib.rocks