Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Statistiche avanzate e confronti tra giocatori

Implementazione delle statistiche avanzate e delle classifiche per confrontare le performance dei giocatori in un web game
Implementazione delle statistiche avanzate e delle classifiche per confrontare le performance dei giocatori in un web game
Link copiato negli appunti

Dopo aver implementato il sistema di autenticazione, registrazione e login per gestire profili personali e punteggi, in questa lezione arricchiremo il gioco introducendo funzionalità avanzate per visualizzare statistiche dettagliate e per permettere ai giocatori di confrontare le proprie performance con quelle di altri utenti. Queste aggiunte incentivano la competitività e permettono ai giocatori di migliorare i loro risultati.

Cosa vogliamo realizzare

  1. Creazione di statistiche avanzate personali: visualizzare statistiche come il punteggio medio, il numero totale di partite giocate, e il punteggio più alto raggiunto.
  2. Classifica generale dei giocatori: implementare una classifica globale, ordinando i giocatori per punteggio massimo o per numero di vittorie.
  3. Confronto tra giocatori: consentire agli utenti di confrontare le proprie statistiche con quelle di altri giocatori, per stimolare il miglioramento e creare una sana competizione.

Creazione delle statistiche avanzate

Iniziamo calcolando le statistiche avanzate per ogni utente. Creiamo una rotta /api/stats che raccoglie e restituisce informazioni dettagliate sull'andamento di un giocatore.

Aggiornamento del modello di dati per le statistiche

Prima di tutto, verifichiamo che il modello Score contenga i dati necessari per calcolare le statistiche, come la data di ogni partita:

const mongoose = require('mongoose');
const scoreSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  points: Number,
  date: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Score', scoreSchema);

Rotta per il calcolo delle statistiche

Creiamo una rotta protetta che calcoli le statistiche avanzate per l'utente loggato:

app.get('/api/stats', auth, async (req, res) => {
  try {
    const scores = await Score.find({ userId: req.userId });
    const totalGames = scores.length;
    const totalPoints = scores.reduce((sum, score) => sum + score.points, 0);
    const averageScore = totalGames > 0 ? totalPoints / totalGames : 0;
    const maxScore = totalGames > 0 ? Math.max(...scores.map(score => score.points)) : 0;
    res.status(200).json({
      totalGames,
      averageScore,
      maxScore,
      scores
    });
  } catch (error) {
    res.status(500).json({ error: 'Errore nel recupero delle statistiche' });
  }
});

Questa rotta restituisce il numero totale di partite giocate, il punteggio medio, il punteggio massimo e la lista completa dei punteggi. Questi dati potranno essere utilizzati dal frontend per mostrare un'analisi dettagliata all'utente.

Classifica generale dei giocatori

Per creare una classifica dei migliori giocatori, ci baseremo sul punteggio massimo di ogni utente e ordineremo gli utenti in base ai loro migliori risultati. Creiamo una rotta /api/leaderboard che restituisce la classifica generale.

Rotta per la classifica generale

Aggiungiamo la seguente rotta che recupera e ordina gli utenti per punteggio massimo:

// server.js
app.get('/api/leaderboard', async (req, res) => {
  try {
    const users = await User.aggregate([
      {
        $lookup: {
          from: 'scores',
          localField: '_id',
          foreignField: 'userId',
          as: 'scores'
        }
      },
      {
        $project: {
          username: 1,
          maxScore: { $max: '$scores.points' }
        }
      },
      { $sort: { maxScore: -1 } },
      { $limit: 10 } // Limitiamo la classifica ai primi 10 giocatori
    ]);
    res.status(200).json(users);
  } catch (error) {
    res.status(500).json({ error: 'Errore nel recupero della classifica' });
  }
});

Con questa rotta otteniamo una classifica ordinata per il punteggio massimo e limitata ai primi dieci giocatori. Utilizzando l'aggregazione MongoDB con $lookup$project, e $sort, otteniamo risultati performanti ed efficaci.

Confronto tra giocatori

Ora implementiamo una funzione per il confronto diretto tra i punteggi di due giocatori. Questa funzionalità permette agli utenti di confrontare le proprie statistiche con quelle di altri giocatori.

Rotta di confronto

Creiamo una rotta /api/compare che riceve come parametri l'ID di due utenti e restituisce le loro statistiche a confronto:

// server.js
app.get('/api/compare/:userId1/:userId2', async (req, res) => {
  const { userId1, userId2 } = req.params;
  try {
    const user1Scores = await Score.find({ userId: userId1 });
    const user2Scores = await Score.find({ userId: userId2 });
    const getStats = (scores) => ({
      totalGames: scores.length,
      totalPoints: scores.reduce((sum, score) => sum + score.points, 0),
      averageScore: scores.length > 0
        ? scores.reduce((sum, score) => sum + score.points, 0) / scores.length
        : 0,
      maxScore: scores.length > 0
        ? Math.max(...scores.map(score => score.points))
        : 0
    });
    const user1Stats = getStats(user1Scores);
    const user2Stats = getStats(user2Scores);
    res.status(200).json({ user1Stats, user2Stats });
  } catch (error) {
    res.status(500).json({ error: 'Errore nel confronto tra giocatori' });
  }
});

Questa rotta fornisce una struttura di dati per confrontare le statistiche di due giocatori, calcolando i parametri principali (partite totali, punteggio medio e punteggio massimo).

Modifiche al frontend

Ora passiamo al frontend e implementiamo l'interfaccia per visualizzare le statistiche avanzate, la classifica generale e per confrontare le statistiche tra due utenti.

Visualizzazione delle statistiche personali

Aggiungiamo una sezione al componente UserProfile per visualizzare le statistiche avanzate:

// components/UserProfile.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const UserProfile = () => {
  const [stats, setStats] = useState({ totalGames: 0, averageScore: 0, maxScore: 0 });
  useEffect(() => {
    const fetchStats = async () => {
      const token = localStorage.getItem('token');
      const response = await axios.get('http://localhost:5000/api/stats', {
        headers: { Authorization: `Bearer ${token}` }
      });
      setStats(response.data);
    };
    fetchStats();
  }, []);
  return (
    <div>
      <h2>Statistiche Personali</h2>
      Partite giocate: {stats.totalGames}
      <br />
      Punteggio medio: {stats.averageScore.toFixed(2)}
      <br />
      Punteggio massimo: {stats.maxScore}
    </div>
  );
};
export default UserProfile;

Visualizzazione della classifica generale

Aggiungiamo un nuovo componente Leaderboard per mostrare la classifica dei primi dieci giocatori:

// components/Leaderboard.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const Leaderboard = () => {
  const [users, setUsers] = useState([]);
  useEffect(() => {
    const fetchLeaderboard = async () => {
      const response = await axios.get('http://localhost:5000/api/leaderboard');
      setUsers(response.data);
    };
    fetchLeaderboard();
  }, []);
  return (
    <div>
      <h2>Classifica Generale</h2>
      <ul style={{ listStyleType: 'none' }}>
        {users.map((user, index) => (
          <li key={user.username}>
            {index + 1}. {user.username} - Punteggio massimo: {user.maxScore}
          </li>
        ))}
      </ul>
    </div>
  );
};
export default Leaderboard;

Confronto tra giocatori

Infine, creiamo un componente per confrontare le statistiche di due giocatori:

// components/ComparePlayers.js
import React, { useState } from 'react';
import axios from 'axios';
const ComparePlayers = () => {
  const [user1, setUser1] = useState('');
  const [user2, setUser2] = useState('');
  const [comparison, setComparison] = useState(null);
  const handleCompare = async () => {
    const response = await axios.get(
      `http://localhost:5000/api/compare/${user1}/${user2}`
    );
    setComparison(response.data);
  };
  return (
    <div>
      <h2>Confronto Giocatori</h2>
      <input
        type="text"
        placeholder="ID Utente 1"
        value={user1}
        onChange={(e) => setUser1(e.target.value)}
      />
      <input
        type="text"
        placeholder="ID Utente 2"
        value={user2}
        onChange={(e) => setUser2(e.target.value)}
      />
      <button onClick={handleCompare}>Confronta</button>
      {comparison && (
        <div>
          <h3>Statistiche Confronto</h3>
          <p>
            Utente 1 - Punteggio medio:{' '}
            {comparison.user1Stats.averageScore.toFixed(2)}
          </p>
          <p>
            Utente 2 - Punteggio medio:{' '}
            {comparison.user2Stats.averageScore.toFixed(2)}
          </p>
        </div>
      )}
    </div>
  );
};
export default ComparePlayers;

Conclusione

In questa lezione, abbiamo arricchito il Solitario delle 5 Carte con funzionalità avanzate di statistiche e confronto tra giocatori. Ora, ogni giocatore può visualizzare e confrontare i propri risultati con quelli degli altri, creando così un contesto competitivo e incentivante.

Nella prossima lezione, esploreremo altre opzioni per migliorare l'esperienza di gioco e la gestione di eventi speciali, come tornei e classifiche temporanee.

Se vuoi aggiornamenti su Statistiche avanzate e confronti tra giocatori inserisci la tua email nel box qui sotto:

Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.

Ti consigliamo anche