diff --git a/README.md b/README.md index 8c2ae1bf..97d4b2fb 100644 --- a/README.md +++ b/README.md @@ -1,251 +1,4 @@ -# 🎾 Tennis Match Prediction Application +# JavaTraining-Capg -A comprehensive Spring Boot application that provides real-time tennis match predictions using AI algorithms. The application analyzes player statistics, head-to-head records, surface performance, and live match data to predict match winners, current game winners, and current set winners. - -## 🚀 Features - -### Core Prediction Capabilities -- **Match Winner Prediction**: Predicts the overall winner of a tennis match -- **Current Game Winner Prediction**: Predicts who will win the current game -- **Current Set Winner Prediction**: Predicts who will win the current set - -### Advanced Analytics -- **Player Statistics**: Comprehensive player profiles including rankings, surface performance, and recent form -- **Head-to-Head Records**: Historical match data between players -- **Live Match Data**: Real-time statistics and score tracking -- **Surface Analysis**: Performance analysis on different court surfaces (Hard, Clay, Grass) - -### Technical Features -- **RESTful API**: Complete API for all prediction and data operations -- **Real-time Updates**: Auto-refreshing dashboard with live match data -- **Modern UI**: Beautiful, responsive web interface -- **H2 Database**: In-memory database with sample data -- **Prediction Accuracy Tracking**: Monitor prediction success rates - -## 🛠️ Technology Stack - -- **Backend**: Spring Boot 3.2.0 -- **Database**: H2 (In-memory) -- **Frontend**: Thymeleaf, Bootstrap 5, JavaScript -- **Build Tool**: Maven -- **Java Version**: 17 - -## 📋 Prerequisites - -- Java 17 or higher -- Maven 3.6 or higher -- Modern web browser - -## 🚀 Quick Start - -### 1. Clone and Navigate -```bash -cd tennis-prediction-app -``` - -### 2. Build the Application -```bash -mvn clean install -``` - -### 3. Run the Application -```bash -mvn spring-boot:run -``` - -### 4. Access the Application -Open your browser and navigate to: -- **Main Dashboard**: http://localhost:8080/tennis-prediction/ -- **H2 Database Console**: http://localhost:8080/tennis-prediction/h2-console - - JDBC URL: `jdbc:h2:mem:tennisdb` - - Username: `sa` - - Password: `password` - -## 📊 Sample Data - -The application comes pre-loaded with: - -### Top 10 ATP Players (2024 Rankings) -1. Novak Djokovic (Serbia) -2. Carlos Alcaraz (Spain) -3. Daniil Medvedev (Russia) -4. Jannik Sinner (Italy) -5. Andrey Rublev (Russia) -6. Stefanos Tsitsipas (Greece) -7. Alexander Zverev (Germany) -8. Holger Rune (Denmark) -9. Hubert Hurkacz (Poland) -10. Taylor Fritz (USA) - -### Sample Matches -- Live matches with real-time statistics -- Completed matches with full results -- Scheduled matches for future predictions - -### Head-to-Head Records -- Historical match data between all players -- Surface-specific performance records -- Recent match outcomes - -## 🔧 API Endpoints - -### Predictions -- `POST /api/predictions/match-winner/{matchId}` - Predict match winner -- `POST /api/predictions/game-winner/{matchId}` - Predict current game winner -- `POST /api/predictions/set-winner/{matchId}` - Predict current set winner -- `GET /api/predictions/match/{matchId}` - Get all predictions for a match -- `GET /api/predictions/latest/{matchId}/{predictionType}` - Get latest prediction -- `GET /api/predictions/accuracy` - Get prediction accuracy statistics - -### Matches -- `GET /api/matches` - Get all matches -- `GET /api/matches/live` - Get live matches -- `GET /api/matches/{matchId}` - Get match by ID -- `GET /api/matches/tournament/{tournamentName}` - Get matches by tournament -- `GET /api/matches/surface/{surface}` - Get matches by surface -- `POST /api/matches` - Create new match -- `PUT /api/matches/{matchId}` - Update match - -### Players -- `GET /api/players` - Get all players -- `GET /api/players/{playerId}` - Get player by ID -- `GET /api/players/name/{playerName}` - Get player by name -- `GET /api/players/top` - Get top ranked players -- `GET /api/players/country/{country}` - Get players by country -- `GET /api/players/surface/{surface}` - Get players by surface performance -- `GET /api/players/search/{namePattern}` - Search players by name -- `POST /api/players` - Create new player -- `PUT /api/players/{playerId}` - Update player - -### Head-to-Head -- `GET /api/head-to-head/{player1Id}/{player2Id}` - Get head-to-head record -- `GET /api/head-to-head/player/{playerId}` - Get player's head-to-head records - -### Statistics -- `GET /api/statistics` - Get application statistics - -## 🎯 Prediction Algorithm - -The prediction system uses a weighted algorithm that considers: - -### Factors and Weights -- **Player Rankings** (15%): Current ATP rankings -- **Head-to-Head Records** (20%): Historical performance against opponent -- **Surface Performance** (15%): Win rates on specific surfaces -- **Recent Form** (15%): Recent match performance -- **Live Statistics** (25%): Current match statistics -- **Match Momentum** (10%): Current match flow and score - -### Prediction Types -1. **Match Winner**: Overall match outcome prediction -2. **Game Winner**: Current game prediction (focuses on serving and immediate momentum) -3. **Set Winner**: Current set prediction (considers set score and match momentum) - -## 🎨 User Interface - -### Dashboard Features -- **Real-time Statistics**: Live match count, prediction accuracy, player rankings -- **Live Matches**: Current matches with real-time scores and statistics -- **Top Players**: Ranked list of top players with performance metrics -- **Recent Predictions**: Latest predictions with confidence scores and reasoning -- **Auto-refresh**: Dashboard updates every 30 seconds - -### Interactive Elements -- **Prediction Buttons**: One-click predictions for match, game, and set winners -- **Confidence Indicators**: Visual confidence levels for predictions -- **Detailed Reasoning**: Explanation of prediction factors -- **Responsive Design**: Works on desktop, tablet, and mobile devices - -## 🔍 Database Schema - -### Entities -- **Player**: Comprehensive player profiles with statistics -- **Match**: Live match data and scores -- **HeadToHead**: Historical match records between players -- **MatchPrediction**: Prediction results with confidence scores - -### Key Relationships -- Players have multiple matches (as player1 or player2) -- Matches have multiple predictions (different types) -- Players have head-to-head records with other players - -## 🚀 Deployment - -### Local Development -```bash -# Run with Maven -mvn spring-boot:run - -# Or build and run JAR -mvn clean package -java -jar target/tennis-prediction-app-1.0.0.jar -``` - -### Production Deployment -1. Build the application: `mvn clean package` -2. Deploy the JAR file to your server -3. Configure database connection (switch from H2 to production database) -4. Set up external API keys for live data feeds - -## 🔧 Configuration - -### Application Properties -```properties -# Server Configuration -server.port=8080 -server.servlet.context-path=/tennis-prediction - -# Database Configuration -spring.datasource.url=jdbc:h2:mem:tennisdb -spring.datasource.username=sa -spring.datasource.password=password - -# Prediction Settings -tennis.prediction.model.threshold=0.6 -tennis.prediction.update-interval=30000 -``` - -## 📈 Future Enhancements - -### Planned Features -- **Machine Learning Integration**: Advanced ML models for better predictions -- **External API Integration**: Real-time data from FlashScore, ATP, etc. -- **User Authentication**: User accounts and personalized predictions -- **Mobile App**: Native mobile application -- **Advanced Analytics**: Detailed statistical analysis and visualizations -- **Tournament Brackets**: Tournament prediction and bracket management - -### Technical Improvements -- **Microservices Architecture**: Split into separate services -- **Real-time WebSocket**: Live updates via WebSocket -- **Caching Layer**: Redis for improved performance -- **Containerization**: Docker support for easy deployment - -## 🤝 Contributing - -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Add tests for new functionality -5. Submit a pull request - -## 📝 License - -This project is licensed under the MIT License - see the LICENSE file for details. - -## 🆘 Support - -For support and questions: -- Create an issue in the repository -- Check the API documentation -- Review the sample data and configurations - -## 🎯 Quick Test - -1. Start the application -2. Navigate to http://localhost:8080/tennis-prediction/ -3. View the live matches -4. Click "Predict Winner" on any live match -5. See the prediction with confidence score and reasoning - -The application is ready to use immediately with sample data and working predictions! +this repo contains all practices related to basic java and advanced java. +covering spring , servlet , junit , logger,PMD etc diff --git a/pom.xml b/pom.xml deleted file mode 100644 index ff5d616c..00000000 --- a/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 3.2.0 - - - - com.tennis - tennis-prediction-app - 1.0.0 - tennis-prediction-app - Tennis Match Prediction Application - - - 17 - - - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - - org.springframework.boot - spring-boot-starter-validation - - - - - com.h2database - h2 - runtime - - - - - com.fasterxml.jackson.core - jackson-databind - - - - - org.springframework.boot - spring-boot-starter-webflux - - - - - org.projectlombok - lombok - true - - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - - \ No newline at end of file diff --git a/src/main/java/com/tennis/TennisPredictionApplication.java b/src/main/java/com/tennis/TennisPredictionApplication.java deleted file mode 100644 index e59bcfb4..00000000 --- a/src/main/java/com/tennis/TennisPredictionApplication.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.tennis; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.scheduling.annotation.EnableScheduling; - -/** - * Main Spring Boot Application class for Tennis Match Prediction - * This application provides real-time tennis match predictions including: - * - Match winner prediction - * - Current game winner prediction - * - Current set winner prediction - * - * @author Tennis Prediction Team - * @version 1.0.0 - */ -@SpringBootApplication -@EnableScheduling // Enable scheduling for periodic data updates -public class TennisPredictionApplication { - - public static void main(String[] args) { - SpringApplication.run(TennisPredictionApplication.class, args); - System.out.println("🎾 Tennis Prediction Application Started Successfully!"); - System.out.println("📊 Access the application at: http://localhost:8080/tennis-prediction"); - System.out.println("🗄️ H2 Database Console: http://localhost:8080/tennis-prediction/h2-console"); - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/controller/TennisPredictionController.java b/src/main/java/com/tennis/controller/TennisPredictionController.java deleted file mode 100644 index 3c3b73c7..00000000 --- a/src/main/java/com/tennis/controller/TennisPredictionController.java +++ /dev/null @@ -1,467 +0,0 @@ -package com.tennis.controller; - -import com.tennis.entity.*; -import com.tennis.repository.*; -import com.tennis.service.PredictionService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; -import java.util.Map; -import java.util.HashMap; - -/** - * REST Controller for Tennis Prediction Application - * Provides endpoints for predictions, matches, players, and dashboard - */ -@Controller -@RequestMapping("/api") -@RequiredArgsConstructor -@Slf4j -public class TennisPredictionController { - - private final PredictionService predictionService; - private final PlayerRepository playerRepository; - private final MatchRepository matchRepository; - private final MatchPredictionRepository predictionRepository; - private final HeadToHeadRepository headToHeadRepository; - - // ==================== DASHBOARD ENDPOINTS ==================== - - /** - * Main dashboard page - */ - @GetMapping("/") - public String dashboard(Model model) { - log.info("Loading main dashboard"); - - // Get live matches - List liveMatches = matchRepository.findByMatchStatus("Live"); - - // Get recent predictions - List recentPredictions = predictionRepository.findRecentPredictions( - LocalDateTime.now().minusHours(24)); - - // Get top players - List topPlayers = playerRepository.findTop10ByOrderByCurrentRankingAsc(); - - // Calculate prediction accuracy - Double predictionAccuracy = predictionRepository.calculatePredictionAccuracy(); - - model.addAttribute("liveMatches", liveMatches); - model.addAttribute("recentPredictions", recentPredictions); - model.addAttribute("topPlayers", topPlayers); - model.addAttribute("predictionAccuracy", predictionAccuracy != null ? predictionAccuracy : 0.0); - - return "dashboard"; - } - - // ==================== PREDICTION ENDPOINTS ==================== - - /** - * Predict match winner - */ - @PostMapping("/predictions/match-winner/{matchId}") - @ResponseBody - public ResponseEntity predictMatchWinner(@PathVariable Long matchId) { - log.info("Predicting match winner for match ID: {}", matchId); - - Optional matchOpt = matchRepository.findById(matchId); - if (matchOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - Match match = matchOpt.get(); - MatchPrediction prediction = predictionService.predictMatchWinner(match); - - return ResponseEntity.ok(prediction); - } - - /** - * Predict current game winner - */ - @PostMapping("/predictions/game-winner/{matchId}") - @ResponseBody - public ResponseEntity predictGameWinner(@PathVariable Long matchId) { - log.info("Predicting game winner for match ID: {}", matchId); - - Optional matchOpt = matchRepository.findById(matchId); - if (matchOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - Match match = matchOpt.get(); - MatchPrediction prediction = predictionService.predictCurrentGameWinner(match); - - return ResponseEntity.ok(prediction); - } - - /** - * Predict current set winner - */ - @PostMapping("/predictions/set-winner/{matchId}") - @ResponseBody - public ResponseEntity predictSetWinner(@PathVariable Long matchId) { - log.info("Predicting set winner for match ID: {}", matchId); - - Optional matchOpt = matchRepository.findById(matchId); - if (matchOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - Match match = matchOpt.get(); - MatchPrediction prediction = predictionService.predictCurrentSetWinner(match); - - return ResponseEntity.ok(prediction); - } - - /** - * Get all predictions for a match - */ - @GetMapping("/predictions/match/{matchId}") - @ResponseBody - public ResponseEntity> getMatchPredictions(@PathVariable Long matchId) { - log.info("Getting predictions for match ID: {}", matchId); - - Optional matchOpt = matchRepository.findById(matchId); - if (matchOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - List predictions = predictionRepository.findByMatchOrderByPredictionTimestampDesc(matchOpt.get()); - return ResponseEntity.ok(predictions); - } - - /** - * Get latest prediction for a match and type - */ - @GetMapping("/predictions/latest/{matchId}/{predictionType}") - @ResponseBody - public ResponseEntity getLatestPrediction( - @PathVariable Long matchId, - @PathVariable String predictionType) { - log.info("Getting latest {} prediction for match ID: {}", predictionType, matchId); - - Optional matchOpt = matchRepository.findById(matchId); - if (matchOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - Optional predictionOpt = predictionRepository - .findFirstByMatchAndPredictionTypeOrderByPredictionTimestampDesc(matchOpt.get(), predictionType); - - return predictionOpt.map(ResponseEntity::ok) - .orElse(ResponseEntity.notFound().build()); - } - - /** - * Get prediction accuracy statistics - */ - @GetMapping("/predictions/accuracy") - @ResponseBody - public ResponseEntity> getPredictionAccuracy() { - log.info("Getting prediction accuracy statistics"); - - Double overallAccuracy = predictionRepository.calculatePredictionAccuracy(); - List correctPredictions = predictionRepository.findByIsCorrectTrueOrderByPredictionTimestampDesc(); - List incorrectPredictions = predictionRepository.findByIsCorrectFalseOrderByPredictionTimestampDesc(); - - Map stats = new HashMap<>(); - stats.put("overallAccuracy", overallAccuracy != null ? overallAccuracy : 0.0); - stats.put("correctPredictions", correctPredictions.size()); - stats.put("incorrectPredictions", incorrectPredictions.size()); - stats.put("totalVerifiedPredictions", correctPredictions.size() + incorrectPredictions.size()); - - return ResponseEntity.ok(stats); - } - - // ==================== MATCH ENDPOINTS ==================== - - /** - * Get all matches - */ - @GetMapping("/matches") - @ResponseBody - public ResponseEntity> getAllMatches() { - log.info("Getting all matches"); - List matches = matchRepository.findAll(); - return ResponseEntity.ok(matches); - } - - /** - * Get live matches - */ - @GetMapping("/matches/live") - @ResponseBody - public ResponseEntity> getLiveMatches() { - log.info("Getting live matches"); - List liveMatches = matchRepository.findByMatchStatus("Live"); - return ResponseEntity.ok(liveMatches); - } - - /** - * Get match by ID - */ - @GetMapping("/matches/{matchId}") - @ResponseBody - public ResponseEntity getMatchById(@PathVariable Long matchId) { - log.info("Getting match by ID: {}", matchId); - - Optional matchOpt = matchRepository.findById(matchId); - return matchOpt.map(ResponseEntity::ok) - .orElse(ResponseEntity.notFound().build()); - } - - /** - * Get matches by tournament - */ - @GetMapping("/matches/tournament/{tournamentName}") - @ResponseBody - public ResponseEntity> getMatchesByTournament(@PathVariable String tournamentName) { - log.info("Getting matches for tournament: {}", tournamentName); - List matches = matchRepository.findByTournamentNameIgnoreCaseOrderByStartTimeDesc(tournamentName); - return ResponseEntity.ok(matches); - } - - /** - * Get matches by surface - */ - @GetMapping("/matches/surface/{surface}") - @ResponseBody - public ResponseEntity> getMatchesBySurface(@PathVariable String surface) { - log.info("Getting matches on surface: {}", surface); - List matches = matchRepository.findBySurfaceIgnoreCaseOrderByStartTimeDesc(surface); - return ResponseEntity.ok(matches); - } - - /** - * Create new match - */ - @PostMapping("/matches") - @ResponseBody - public ResponseEntity createMatch(@RequestBody Match match) { - log.info("Creating new match: {} vs {}", - match.getPlayer1().getName(), match.getPlayer2().getName()); - - Match savedMatch = matchRepository.save(match); - return ResponseEntity.ok(savedMatch); - } - - /** - * Update match - */ - @PutMapping("/matches/{matchId}") - @ResponseBody - public ResponseEntity updateMatch(@PathVariable Long matchId, @RequestBody Match match) { - log.info("Updating match ID: {}", matchId); - - if (!matchRepository.existsById(matchId)) { - return ResponseEntity.notFound().build(); - } - - match.setId(matchId); - Match updatedMatch = matchRepository.save(match); - return ResponseEntity.ok(updatedMatch); - } - - // ==================== PLAYER ENDPOINTS ==================== - - /** - * Get all players - */ - @GetMapping("/players") - @ResponseBody - public ResponseEntity> getAllPlayers() { - log.info("Getting all players"); - List players = playerRepository.findAll(); - return ResponseEntity.ok(players); - } - - /** - * Get player by ID - */ - @GetMapping("/players/{playerId}") - @ResponseBody - public ResponseEntity getPlayerById(@PathVariable Long playerId) { - log.info("Getting player by ID: {}", playerId); - - Optional playerOpt = playerRepository.findById(playerId); - return playerOpt.map(ResponseEntity::ok) - .orElse(ResponseEntity.notFound().build()); - } - - /** - * Get player by name - */ - @GetMapping("/players/name/{playerName}") - @ResponseBody - public ResponseEntity getPlayerByName(@PathVariable String playerName) { - log.info("Getting player by name: {}", playerName); - - Optional playerOpt = playerRepository.findByNameIgnoreCase(playerName); - return playerOpt.map(ResponseEntity::ok) - .orElse(ResponseEntity.notFound().build()); - } - - /** - * Get top ranked players - */ - @GetMapping("/players/top") - @ResponseBody - public ResponseEntity> getTopPlayers() { - log.info("Getting top ranked players"); - List topPlayers = playerRepository.findTop10ByOrderByCurrentRankingAsc(); - return ResponseEntity.ok(topPlayers); - } - - /** - * Get players by country - */ - @GetMapping("/players/country/{country}") - @ResponseBody - public ResponseEntity> getPlayersByCountry(@PathVariable String country) { - log.info("Getting players from country: {}", country); - List players = playerRepository.findByCountryIgnoreCase(country); - return ResponseEntity.ok(players); - } - - /** - * Get players by surface performance - */ - @GetMapping("/players/surface/{surface}") - @ResponseBody - public ResponseEntity> getPlayersBySurface(@PathVariable String surface) { - log.info("Getting players by surface performance: {}", surface); - List players = playerRepository.findPlayersBySurfacePerformance(surface, 0.6); - return ResponseEntity.ok(players); - } - - /** - * Search players by name - */ - @GetMapping("/players/search/{namePattern}") - @ResponseBody - public ResponseEntity> searchPlayers(@PathVariable String namePattern) { - log.info("Searching players with pattern: {}", namePattern); - List players = playerRepository.findByNameContainingIgnoreCase(namePattern); - return ResponseEntity.ok(players); - } - - /** - * Create new player - */ - @PostMapping("/players") - @ResponseBody - public ResponseEntity createPlayer(@RequestBody Player player) { - log.info("Creating new player: {}", player.getName()); - - Player savedPlayer = playerRepository.save(player); - return ResponseEntity.ok(savedPlayer); - } - - /** - * Update player - */ - @PutMapping("/players/{playerId}") - @ResponseBody - public ResponseEntity updatePlayer(@PathVariable Long playerId, @RequestBody Player player) { - log.info("Updating player ID: {}", playerId); - - if (!playerRepository.existsById(playerId)) { - return ResponseEntity.notFound().build(); - } - - player.setId(playerId); - Player updatedPlayer = playerRepository.save(player); - return ResponseEntity.ok(updatedPlayer); - } - - // ==================== HEAD-TO-HEAD ENDPOINTS ==================== - - /** - * Get head-to-head record between two players - */ - @GetMapping("/head-to-head/{player1Id}/{player2Id}") - @ResponseBody - public ResponseEntity getHeadToHead(@PathVariable Long player1Id, @PathVariable Long player2Id) { - log.info("Getting head-to-head record between players: {} and {}", player1Id, player2Id); - - Optional player1Opt = playerRepository.findById(player1Id); - Optional player2Opt = playerRepository.findById(player2Id); - - if (player1Opt.isEmpty() || player2Opt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - Optional h2hOpt = headToHeadRepository - .findByPlayer1AndPlayer2OrPlayer2AndPlayer1(player1Opt.get(), player2Opt.get(), - player2Opt.get(), player1Opt.get()); - - return h2hOpt.map(ResponseEntity::ok) - .orElse(ResponseEntity.notFound().build()); - } - - /** - * Get head-to-head records for a player - */ - @GetMapping("/head-to-head/player/{playerId}") - @ResponseBody - public ResponseEntity> getPlayerHeadToHead(@PathVariable Long playerId) { - log.info("Getting head-to-head records for player: {}", playerId); - - Optional playerOpt = playerRepository.findById(playerId); - if (playerOpt.isEmpty()) { - return ResponseEntity.notFound().build(); - } - - List h2hRecords = headToHeadRepository - .findByPlayer1OrPlayer2OrderByTotalMatchesDesc(playerOpt.get(), playerOpt.get()); - - return ResponseEntity.ok(h2hRecords); - } - - // ==================== STATISTICS ENDPOINTS ==================== - - /** - * Get application statistics - */ - @GetMapping("/statistics") - @ResponseBody - public ResponseEntity> getStatistics() { - log.info("Getting application statistics"); - - Map stats = new HashMap<>(); - - // Player statistics - long totalPlayers = playerRepository.count(); - List topPlayers = playerRepository.findTop10ByOrderByCurrentRankingAsc(); - - // Match statistics - long totalMatches = matchRepository.count(); - List liveMatches = matchRepository.findByMatchStatus("Live"); - List completedMatches = matchRepository.findByMatchStatus("Completed"); - - // Prediction statistics - long totalPredictions = predictionRepository.count(); - Double predictionAccuracy = predictionRepository.calculatePredictionAccuracy(); - List recentPredictions = predictionRepository.findRecentPredictions( - LocalDateTime.now().minusHours(24)); - - stats.put("totalPlayers", totalPlayers); - stats.put("topPlayers", topPlayers.size()); - stats.put("totalMatches", totalMatches); - stats.put("liveMatches", liveMatches.size()); - stats.put("completedMatches", completedMatches.size()); - stats.put("totalPredictions", totalPredictions); - stats.put("predictionAccuracy", predictionAccuracy != null ? predictionAccuracy : 0.0); - stats.put("recentPredictions", recentPredictions.size()); - - return ResponseEntity.ok(stats); - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/entity/HeadToHead.java b/src/main/java/com/tennis/entity/HeadToHead.java deleted file mode 100644 index 21f62ef4..00000000 --- a/src/main/java/com/tennis/entity/HeadToHead.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.tennis.entity; - -import jakarta.persistence.*; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.AllArgsConstructor; - -import java.time.LocalDateTime; - -/** - * HeadToHead entity representing the head-to-head record between two players - * Stores match history and statistics between specific player pairs - */ -@Entity -@Table(name = "head_to_head") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class HeadToHead { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "player1_id", nullable = false) - private Player player1; - - @ManyToOne - @JoinColumn(name = "player2_id", nullable = false) - private Player player2; - - @Column(name = "total_matches") - private Integer totalMatches; - - @Column(name = "player1_wins") - private Integer player1Wins; - - @Column(name = "player2_wins") - private Integer player2Wins; - - // Surface-specific head-to-head records - @Column(name = "hard_court_matches") - private Integer hardCourtMatches; - - @Column(name = "hard_court_player1_wins") - private Integer hardCourtPlayer1Wins; - - @Column(name = "clay_court_matches") - private Integer clayCourtMatches; - - @Column(name = "clay_court_player1_wins") - private Integer clayCourtPlayer1Wins; - - @Column(name = "grass_court_matches") - private Integer grassCourtMatches; - - @Column(name = "grass_court_player1_wins") - private Integer grassCourtPlayer1Wins; - - @Column(name = "last_match_date") - private LocalDateTime lastMatchDate; - - @Column(name = "last_match_tournament") - private String lastMatchTournament; - - @Column(name = "last_match_surface") - private String lastMatchSurface; - - @Column(name = "last_match_winner") - private String lastMatchWinner; // "player1" or "player2" - - @Column(name = "created_at") - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - /** - * Calculate player1's win rate against player2 - * @return win rate as percentage - */ - public Double getPlayer1WinRate() { - if (totalMatches == 0) return 0.0; - return (double) player1Wins / totalMatches * 100; - } - - /** - * Calculate player2's win rate against player1 - * @return win rate as percentage - */ - public Double getPlayer2WinRate() { - if (totalMatches == 0) return 0.0; - return (double) player2Wins / totalMatches * 100; - } - - /** - * Get head-to-head record for a specific surface - * @param surface the surface type - * @return win rate for player1 on that surface - */ - public Double getSurfaceWinRate(String surface) { - switch (surface.toLowerCase()) { - case "hard": - return hardCourtMatches > 0 ? (double) hardCourtPlayer1Wins / hardCourtMatches * 100 : 0.0; - case "clay": - return clayCourtMatches > 0 ? (double) clayCourtPlayer1Wins / clayCourtMatches * 100 : 0.0; - case "grass": - return grassCourtMatches > 0 ? (double) grassCourtPlayer1Wins / grassCourtMatches * 100 : 0.0; - default: - return getPlayer1WinRate(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/entity/Match.java b/src/main/java/com/tennis/entity/Match.java deleted file mode 100644 index cf7fdabf..00000000 --- a/src/main/java/com/tennis/entity/Match.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.tennis.entity; - -import jakarta.persistence.*; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.AllArgsConstructor; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * Match entity representing a tennis match - * Stores live match data, scores, and current match state - */ -@Entity -@Table(name = "matches") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class Match { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "player1_id", nullable = false) - private Player player1; - - @ManyToOne - @JoinColumn(name = "player2_id", nullable = false) - private Player player2; - - @Column(name = "tournament_name") - private String tournamentName; - - @Column(name = "match_type") - private String matchType; // "Best of 3", "Best of 5" - - @Column(name = "surface") - private String surface; // "Hard", "Clay", "Grass" - - @Column(name = "match_status") - private String matchStatus; // "Scheduled", "Live", "Completed", "Cancelled" - - @Column(name = "start_time") - private LocalDateTime startTime; - - @Column(name = "end_time") - private LocalDateTime endTime; - - // Current Score - @Column(name = "player1_sets_won") - private Integer player1SetsWon = 0; - - @Column(name = "player2_sets_won") - private Integer player2SetsWon = 0; - - @Column(name = "current_set") - private Integer currentSet = 1; - - @Column(name = "player1_games_current_set") - private Integer player1GamesCurrentSet = 0; - - @Column(name = "player2_games_current_set") - private Integer player2GamesCurrentSet = 0; - - @Column(name = "player1_points_current_game") - private Integer player1PointsCurrentGame = 0; - - @Column(name = "player2_points_current_game") - private Integer player2PointsCurrentGame = 0; - - @Column(name = "current_server") - private String currentServer; // "player1" or "player2" - - // Live Statistics - @Column(name = "player1_aces") - private Integer player1Aces = 0; - - @Column(name = "player2_aces") - private Integer player2Aces = 0; - - @Column(name = "player1_double_faults") - private Integer player1DoubleFaults = 0; - - @Column(name = "player2_double_faults") - private Integer player2DoubleFaults = 0; - - @Column(name = "player1_first_serve_percentage") - private Double player1FirstServePercentage = 0.0; - - @Column(name = "player2_first_serve_percentage") - private Double player2FirstServePercentage = 0.0; - - @Column(name = "player1_break_points_won") - private Integer player1BreakPointsWon = 0; - - @Column(name = "player2_break_points_won") - private Integer player2BreakPointsWon = 0; - - @Column(name = "player1_break_points_opportunities") - private Integer player1BreakPointsOpportunities = 0; - - @Column(name = "player2_break_points_opportunities") - private Integer player2BreakPointsOpportunities = 0; - - @Column(name = "player1_total_points_won") - private Integer player1TotalPointsWon = 0; - - @Column(name = "player2_total_points_won") - private Integer player2TotalPointsWon = 0; - - @Column(name = "total_points_played") - private Integer totalPointsPlayed = 0; - - // Set History (JSON format for simplicity) - @Column(name = "set_scores", columnDefinition = "TEXT") - private String setScores; // JSON array of set scores - - @Column(name = "created_at") - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - // Relationships - @OneToMany(mappedBy = "match", cascade = CascadeType.ALL) - private List predictions; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - /** - * Get current match score in standard tennis format - * @return formatted score string - */ - public String getCurrentScore() { - return String.format("%d-%d (%d-%d)", - player1SetsWon, player2SetsWon, - player1GamesCurrentSet, player2GamesCurrentSet); - } - - /** - * Get current game score in tennis points format - * @return game score (0, 15, 30, 40, AD) - */ - public String getCurrentGameScore() { - return String.format("%s-%s", - convertPointsToTennisScore(player1PointsCurrentGame), - convertPointsToTennisScore(player2PointsCurrentGame)); - } - - /** - * Convert points to tennis score format - * @param points number of points - * @return tennis score string - */ - private String convertPointsToTennisScore(Integer points) { - switch (points) { - case 0: return "0"; - case 1: return "15"; - case 2: return "30"; - case 3: return "40"; - default: return "AD"; - } - } - - /** - * Check if match is completed - * @return true if match is finished - */ - public boolean isCompleted() { - return "Completed".equals(matchStatus); - } - - /** - * Check if match is live - * @return true if match is currently being played - */ - public boolean isLive() { - return "Live".equals(matchStatus); - } - - /** - * Get match winner - * @return player name or null if match not completed - */ - public String getWinner() { - if (!isCompleted()) return null; - return player1SetsWon > player2SetsWon ? player1.getName() : player2.getName(); - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/entity/MatchPrediction.java b/src/main/java/com/tennis/entity/MatchPrediction.java deleted file mode 100644 index 3dc4cdf4..00000000 --- a/src/main/java/com/tennis/entity/MatchPrediction.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.tennis.entity; - -import jakarta.persistence.*; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.AllArgsConstructor; - -import java.time.LocalDateTime; - -/** - * MatchPrediction entity representing prediction results for a tennis match - * Stores various types of predictions with confidence scores - */ -@Entity -@Table(name = "match_predictions") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MatchPrediction { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "match_id", nullable = false) - private Match match; - - @Column(name = "prediction_type") - private String predictionType; // "MATCH_WINNER", "CURRENT_GAME_WINNER", "CURRENT_SET_WINNER" - - @Column(name = "predicted_winner") - private String predictedWinner; // "player1", "player2" - - @Column(name = "confidence_score") - private Double confidenceScore; // 0.0 to 1.0 - - @Column(name = "player1_win_probability") - private Double player1WinProbability; // 0.0 to 1.0 - - @Column(name = "player2_win_probability") - private Double player2WinProbability; // 0.0 to 1.0 - - // Factors that influenced the prediction - @Column(name = "ranking_factor") - private Double rankingFactor; - - @Column(name = "head_to_head_factor") - private Double headToHeadFactor; - - @Column(name = "surface_factor") - private Double surfaceFactor; - - @Column(name = "recent_form_factor") - private Double recentFormFactor; - - @Column(name = "live_stats_factor") - private Double liveStatsFactor; - - @Column(name = "momentum_factor") - private Double momentumFactor; - - @Column(name = "prediction_reasoning") - private String predictionReasoning; // Detailed explanation of the prediction - - @Column(name = "prediction_timestamp") - private LocalDateTime predictionTimestamp; - - @Column(name = "is_correct") - private Boolean isCorrect; // null if prediction not yet verified - - @Column(name = "created_at") - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - predictionTimestamp = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - /** - * Get the predicted winner's name - * @return player name - */ - public String getPredictedWinnerName() { - if ("player1".equals(predictedWinner)) { - return match.getPlayer1().getName(); - } else if ("player2".equals(predictedWinner)) { - return match.getPlayer2().getName(); - } - return "Unknown"; - } - - /** - * Get confidence level as a string - * @return confidence level description - */ - public String getConfidenceLevel() { - if (confidenceScore >= 0.8) return "Very High"; - if (confidenceScore >= 0.6) return "High"; - if (confidenceScore >= 0.4) return "Medium"; - if (confidenceScore >= 0.2) return "Low"; - return "Very Low"; - } - - /** - * Get the most influential factor - * @return factor name with highest weight - */ - public String getMostInfluentialFactor() { - Double maxFactor = Math.max(Math.max(rankingFactor, headToHeadFactor), - Math.max(surfaceFactor, recentFormFactor)); - maxFactor = Math.max(maxFactor, Math.max(liveStatsFactor, momentumFactor)); - - if (maxFactor.equals(rankingFactor)) return "Player Ranking"; - if (maxFactor.equals(headToHeadFactor)) return "Head-to-Head Record"; - if (maxFactor.equals(surfaceFactor)) return "Surface Performance"; - if (maxFactor.equals(recentFormFactor)) return "Recent Form"; - if (maxFactor.equals(liveStatsFactor)) return "Live Match Statistics"; - if (maxFactor.equals(momentumFactor)) return "Match Momentum"; - - return "Unknown"; - } - - /** - * Check if prediction is verified - * @return true if prediction has been verified - */ - public boolean isVerified() { - return isCorrect != null; - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/entity/Player.java b/src/main/java/com/tennis/entity/Player.java deleted file mode 100644 index 22cecb2a..00000000 --- a/src/main/java/com/tennis/entity/Player.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.tennis.entity; - -import jakarta.persistence.*; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.AllArgsConstructor; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * Player entity representing a tennis player - * Stores comprehensive player information including rankings, statistics, and performance data - */ -@Entity -@Table(name = "players") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class Player { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false, unique = true) - private String name; - - @Column(nullable = false) - private String country; - - @Column(name = "current_ranking") - private Integer currentRanking; - - @Column(name = "career_high_ranking") - private Integer careerHighRanking; - - @Column(name = "age") - private Integer age; - - @Column(name = "height_cm") - private Integer heightCm; - - @Column(name = "weight_kg") - private Integer weightKg; - - @Column(name = "playing_style") - private String playingStyle; // e.g., "Aggressive Baseline", "Serve and Volley" - - @Column(name = "preferred_hand") - private String preferredHand; // "Right", "Left" - - // Surface Performance Statistics (0.0 to 1.0) - @Column(name = "hard_court_win_rate") - private Double hardCourtWinRate; - - @Column(name = "clay_court_win_rate") - private Double clayCourtWinRate; - - @Column(name = "grass_court_win_rate") - private Double grassCourtWinRate; - - // Service Statistics - @Column(name = "first_serve_percentage") - private Double firstServePercentage; - - @Column(name = "first_serve_win_rate") - private Double firstServeWinRate; - - @Column(name = "second_serve_win_rate") - private Double secondServeWinRate; - - @Column(name = "aces_per_match") - private Double acesPerMatch; - - @Column(name = "double_faults_per_match") - private Double doubleFaultsPerMatch; - - // Return Statistics - @Column(name = "first_serve_return_win_rate") - private Double firstServeReturnWinRate; - - @Column(name = "second_serve_return_win_rate") - private Double secondServeReturnWinRate; - - @Column(name = "break_points_converted_percentage") - private Double breakPointsConvertedPercentage; - - // Recent Form (last 10 matches) - @Column(name = "recent_form_win_rate") - private Double recentFormWinRate; - - @Column(name = "matches_played_this_year") - private Integer matchesPlayedThisYear; - - @Column(name = "wins_this_year") - private Integer winsThisYear; - - @Column(name = "created_at") - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - // Relationships - @OneToMany(mappedBy = "player1", cascade = CascadeType.ALL) - private List headToHeadAsPlayer1; - - @OneToMany(mappedBy = "player2", cascade = CascadeType.ALL) - private List headToHeadAsPlayer2; - - @PrePersist - protected void onCreate() { - createdAt = LocalDateTime.now(); - updatedAt = LocalDateTime.now(); - } - - @PreUpdate - protected void onUpdate() { - updatedAt = LocalDateTime.now(); - } - - /** - * Calculate overall win rate for the player - * @return overall win rate as percentage - */ - public Double getOverallWinRate() { - if (matchesPlayedThisYear == 0) return 0.0; - return (double) winsThisYear / matchesPlayedThisYear * 100; - } - - /** - * Get best surface for the player - * @return surface name with highest win rate - */ - public String getBestSurface() { - if (hardCourtWinRate >= clayCourtWinRate && hardCourtWinRate >= grassCourtWinRate) { - return "Hard Court"; - } else if (clayCourtWinRate >= grassCourtWinRate) { - return "Clay Court"; - } else { - return "Grass Court"; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/repository/HeadToHeadRepository.java b/src/main/java/com/tennis/repository/HeadToHeadRepository.java deleted file mode 100644 index 41096420..00000000 --- a/src/main/java/com/tennis/repository/HeadToHeadRepository.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.tennis.repository; - -import com.tennis.entity.HeadToHead; -import com.tennis.entity.Player; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for HeadToHead entity - * Provides database operations for head-to-head records - */ -@Repository -public interface HeadToHeadRepository extends JpaRepository { - - /** - * Find head-to-head record between two players - * @param player1 first player - * @param player2 second player - * @return optional head-to-head record - */ - Optional findByPlayer1AndPlayer2OrPlayer2AndPlayer1(Player player1, Player player2, Player player2Again, Player player1Again); - - /** - * Find head-to-head records for a player - * @param player player to search for - * @return list of head-to-head records involving the player - */ - List findByPlayer1OrPlayer2OrderByTotalMatchesDesc(Player player1, Player player2); - - /** - * Find head-to-head records with minimum matches - * @param minMatches minimum number of matches - * @return list of head-to-head records with minimum matches - */ - List findByTotalMatchesGreaterThanEqualOrderByTotalMatchesDesc(Integer minMatches); - - /** - * Find head-to-head records by surface - * @param surface surface type - * @param minMatches minimum matches on surface - * @return list of head-to-head records for surface - */ - @Query("SELECT h FROM HeadToHead h WHERE " + - "(:surface = 'hard' AND h.hardCourtMatches >= :minMatches) OR " + - "(:surface = 'clay' AND h.clayCourtMatches >= :minMatches) OR " + - "(:surface = 'grass' AND h.grassCourtMatches >= :minMatches) " + - "ORDER BY " + - "CASE WHEN :surface = 'hard' THEN h.hardCourtPlayer1Wins * 1.0 / h.hardCourtMatches " + - "WHEN :surface = 'clay' THEN h.clayCourtPlayer1Wins * 1.0 / h.clayCourtMatches " + - "WHEN :surface = 'grass' THEN h.grassCourtPlayer1Wins * 1.0 / h.grassCourtMatches " + - "ELSE 0.0 END DESC") - List findBySurfaceAndMinMatches(@Param("surface") String surface, @Param("minMatches") Integer minMatches); - - /** - * Find recent head-to-head records - * @param days number of days to look back - * @return list of recent head-to-head records - */ - @Query("SELECT h FROM HeadToHead h WHERE h.lastMatchDate >= :startDate ORDER BY h.lastMatchDate DESC") - List findRecentHeadToHeadRecords(@Param("startDate") java.time.LocalDateTime startDate); - - /** - * Find head-to-head records by tournament - * @param tournamentName tournament name - * @return list of head-to-head records in tournament - */ - List findByLastMatchTournamentIgnoreCaseOrderByLastMatchDateDesc(String tournamentName); - - /** - * Find head-to-head records by winner - * @param winner winner of last match ("player1" or "player2") - * @return list of head-to-head records with that winner - */ - List findByLastMatchWinnerOrderByLastMatchDateDesc(String winner); - - /** - * Find head-to-head records with close records (similar win rates) - * @param maxWinRateDifference maximum difference in win rates - * @return list of head-to-head records with close records - */ - @Query("SELECT h FROM HeadToHead h WHERE ABS(h.player1Wins * 1.0 / h.totalMatches - h.player2Wins * 1.0 / h.totalMatches) <= :maxDifference AND h.totalMatches > 0 ORDER BY h.totalMatches DESC") - List findCloseHeadToHeadRecords(@Param("maxDifference") Double maxWinRateDifference); - - /** - * Find dominant head-to-head records (one player clearly better) - * @param minWinRateDifference minimum difference in win rates - * @return list of dominant head-to-head records - */ - @Query("SELECT h FROM HeadToHead h WHERE ABS(h.player1Wins * 1.0 / h.totalMatches - h.player2Wins * 1.0 / h.totalMatches) >= :minDifference AND h.totalMatches > 0 ORDER BY ABS(h.player1Wins * 1.0 / h.totalMatches - h.player2Wins * 1.0 / h.totalMatches) DESC") - List findDominantHeadToHeadRecords(@Param("minDifference") Double minWinRateDifference); -} \ No newline at end of file diff --git a/src/main/java/com/tennis/repository/MatchPredictionRepository.java b/src/main/java/com/tennis/repository/MatchPredictionRepository.java deleted file mode 100644 index 59989045..00000000 --- a/src/main/java/com/tennis/repository/MatchPredictionRepository.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.tennis.repository; - -import com.tennis.entity.Match; -import com.tennis.entity.MatchPrediction; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for MatchPrediction entity - * Provides database operations for prediction data - */ -@Repository -public interface MatchPredictionRepository extends JpaRepository { - - /** - * Find predictions by match - * @param match match to search for - * @return list of predictions for that match - */ - List findByMatchOrderByPredictionTimestampDesc(Match match); - - /** - * Find predictions by prediction type - * @param predictionType type of prediction - * @return list of predictions of that type - */ - List findByPredictionTypeOrderByPredictionTimestampDesc(String predictionType); - - /** - * Find predictions by match and type - * @param match match to search for - * @param predictionType type of prediction - * @return list of predictions for match and type - */ - List findByMatchAndPredictionTypeOrderByPredictionTimestampDesc(Match match, String predictionType); - - /** - * Find latest prediction for a match and type - * @param match match to search for - * @param predictionType type of prediction - * @return latest prediction - */ - Optional findFirstByMatchAndPredictionTypeOrderByPredictionTimestampDesc(Match match, String predictionType); - - /** - * Find predictions by confidence score range - * @param minConfidence minimum confidence score - * @param maxConfidence maximum confidence score - * @return list of predictions in confidence range - */ - List findByConfidenceScoreBetweenOrderByConfidenceScoreDesc(Double minConfidence, Double maxConfidence); - - /** - * Find high confidence predictions - * @param minConfidence minimum confidence threshold - * @return list of high confidence predictions - */ - List findByConfidenceScoreGreaterThanEqualOrderByConfidenceScoreDesc(Double minConfidence); - - /** - * Find predictions by date range - * @param startDate start date - * @param endDate end date - * @return list of predictions in date range - */ - List findByPredictionTimestampBetweenOrderByPredictionTimestampDesc(LocalDateTime startDate, LocalDateTime endDate); - - /** - * Find verified predictions (where isCorrect is not null) - * @return list of verified predictions - */ - List findByIsCorrectIsNotNullOrderByPredictionTimestampDesc(); - - /** - * Find correct predictions - * @return list of predictions that were correct - */ - List findByIsCorrectTrueOrderByPredictionTimestampDesc(); - - /** - * Find incorrect predictions - * @return list of predictions that were incorrect - */ - List findByIsCorrectFalseOrderByPredictionTimestampDesc(); - - /** - * Find predictions by predicted winner - * @param predictedWinner predicted winner ("player1" or "player2") - * @return list of predictions with that winner - */ - List findByPredictedWinnerOrderByPredictionTimestampDesc(String predictedWinner); - - /** - * Find predictions for live matches - * @return list of predictions for live matches - */ - @Query("SELECT mp FROM MatchPrediction mp WHERE mp.match.matchStatus = 'Live' ORDER BY mp.predictionTimestamp DESC") - List findPredictionsForLiveMatches(); - - /** - * Find predictions by match status - * @param matchStatus match status - * @return list of predictions for matches with that status - */ - @Query("SELECT mp FROM MatchPrediction mp WHERE mp.match.matchStatus = :matchStatus ORDER BY mp.predictionTimestamp DESC") - List findByMatchStatus(@Param("matchStatus") String matchStatus); - - /** - * Find predictions by surface - * @param surface surface type - * @return list of predictions for matches on that surface - */ - @Query("SELECT mp FROM MatchPrediction mp WHERE mp.match.surface = :surface ORDER BY mp.predictionTimestamp DESC") - List findBySurface(@Param("surface") String surface); - - /** - * Calculate prediction accuracy - * @return prediction accuracy percentage - */ - @Query("SELECT (COUNT(CASE WHEN mp.isCorrect = true THEN 1 END) * 100.0 / COUNT(mp)) FROM MatchPrediction mp WHERE mp.isCorrect IS NOT NULL") - Double calculatePredictionAccuracy(); - - /** - * Find predictions by tournament - * @param tournamentName tournament name - * @return list of predictions for matches in that tournament - */ - @Query("SELECT mp FROM MatchPrediction mp WHERE mp.match.tournamentName = :tournamentName ORDER BY mp.predictionTimestamp DESC") - List findByTournament(@Param("tournamentName") String tournamentName); - - /** - * Find recent predictions - * @param hours number of hours to look back - * @return list of recent predictions - */ - @Query("SELECT mp FROM MatchPrediction mp WHERE mp.predictionTimestamp >= :startTime ORDER BY mp.predictionTimestamp DESC") - List findRecentPredictions(@Param("startTime") LocalDateTime startTime); -} \ No newline at end of file diff --git a/src/main/java/com/tennis/repository/MatchRepository.java b/src/main/java/com/tennis/repository/MatchRepository.java deleted file mode 100644 index 4fa672f0..00000000 --- a/src/main/java/com/tennis/repository/MatchRepository.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.tennis.repository; - -import com.tennis.entity.Match; -import com.tennis.entity.Player; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for Match entity - * Provides database operations for match data - */ -@Repository -public interface MatchRepository extends JpaRepository { - - /** - * Find matches by status - * @param status match status - * @return list of matches with that status - */ - List findByMatchStatus(String status); - - /** - * Find live matches - * @return list of currently live matches - */ - List findByMatchStatusOrderByStartTimeDesc(String status); - - /** - * Find matches by player - * @param player player to search for - * @return list of matches involving the player - */ - List findByPlayer1OrPlayer2OrderByStartTimeDesc(Player player1, Player player2); - - /** - * Find matches by tournament - * @param tournamentName tournament name - * @return list of matches in that tournament - */ - List findByTournamentNameIgnoreCaseOrderByStartTimeDesc(String tournamentName); - - /** - * Find matches by surface - * @param surface surface type - * @return list of matches on that surface - */ - List findBySurfaceIgnoreCaseOrderByStartTimeDesc(String surface); - - /** - * Find matches between two specific players - * @param player1 first player - * @param player2 second player - * @return list of matches between these players - */ - List findByPlayer1AndPlayer2OrPlayer2AndPlayer1OrderByStartTimeDesc( - Player player1, Player player2, Player player2Again, Player player1Again); - - /** - * Find matches by date range - * @param startDate start date - * @param endDate end date - * @return list of matches in date range - */ - List findByStartTimeBetweenOrderByStartTimeDesc(LocalDateTime startDate, LocalDateTime endDate); - - /** - * Find completed matches - * @return list of completed matches - */ - List findByMatchStatusOrderByEndTimeDesc(String status); - - /** - * Find matches by player with status - * @param player player to search for - * @param status match status - * @return list of matches for player with specific status - */ - @Query("SELECT m FROM Match m WHERE (m.player1 = :player OR m.player2 = :player) AND m.matchStatus = :status ORDER BY m.startTime DESC") - List findByPlayerAndStatus(@Param("player") Player player, @Param("status") String status); - - /** - * Find matches by surface and status - * @param surface surface type - * @param status match status - * @return list of matches on surface with status - */ - List findBySurfaceIgnoreCaseAndMatchStatusOrderByStartTimeDesc(String surface, String status); - - /** - * Find recent matches - * @param days number of days to look back - * @return list of recent matches - */ - @Query("SELECT m FROM Match m WHERE m.startTime >= :startDate ORDER BY m.startTime DESC") - List findRecentMatches(@Param("startDate") LocalDateTime startDate); - - /** - * Find matches with specific score pattern - * @param player1SetsWon sets won by player1 - * @param player2SetsWon sets won by player2 - * @return list of matches with that score - */ - List findByPlayer1SetsWonAndPlayer2SetsWon(Integer player1SetsWon, Integer player2SetsWon); - - /** - * Find matches by tournament and status - * @param tournamentName tournament name - * @param status match status - * @return list of matches in tournament with status - */ - List findByTournamentNameIgnoreCaseAndMatchStatusOrderByStartTimeDesc(String tournamentName, String status); -} \ No newline at end of file diff --git a/src/main/java/com/tennis/repository/PlayerRepository.java b/src/main/java/com/tennis/repository/PlayerRepository.java deleted file mode 100644 index 53df75db..00000000 --- a/src/main/java/com/tennis/repository/PlayerRepository.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.tennis.repository; - -import com.tennis.entity.Player; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -/** - * Repository interface for Player entity - * Provides database operations for player data - */ -@Repository -public interface PlayerRepository extends JpaRepository { - - /** - * Find player by name (case-insensitive) - * @param name player name - * @return optional player - */ - Optional findByNameIgnoreCase(String name); - - /** - * Find players by country - * @param country country name - * @return list of players from that country - */ - List findByCountryIgnoreCase(String country); - - /** - * Find players by ranking range - * @param minRanking minimum ranking - * @param maxRanking maximum ranking - * @return list of players in ranking range - */ - List findByCurrentRankingBetweenOrderByCurrentRankingAsc(Integer minRanking, Integer maxRanking); - - /** - * Find top ranked players - * @param limit number of players to return - * @return list of top ranked players - */ - List findTop10ByOrderByCurrentRankingAsc(); - - /** - * Find players by surface performance - * @param surface surface type (hard, clay, grass) - * @param minWinRate minimum win rate - * @return list of players with good performance on surface - */ - @Query("SELECT p FROM Player p WHERE " + - "CASE WHEN :surface = 'hard' THEN p.hardCourtWinRate " + - "WHEN :surface = 'clay' THEN p.clayCourtWinRate " + - "WHEN :surface = 'grass' THEN p.grassCourtWinRate " + - "ELSE 0.0 END >= :minWinRate " + - "ORDER BY " + - "CASE WHEN :surface = 'hard' THEN p.hardCourtWinRate " + - "WHEN :surface = 'clay' THEN p.clayCourtWinRate " + - "WHEN :surface = 'grass' THEN p.grassCourtWinRate " + - "ELSE 0.0 END DESC") - List findPlayersBySurfacePerformance(@Param("surface") String surface, @Param("minWinRate") Double minWinRate); - - /** - * Find players by recent form - * @param minWinRate minimum recent form win rate - * @return list of players with good recent form - */ - List findByRecentFormWinRateGreaterThanEqualOrderByRecentFormWinRateDesc(Double minWinRate); - - /** - * Search players by name containing pattern - * @param namePattern name pattern to search - * @return list of matching players - */ - List findByNameContainingIgnoreCase(String namePattern); - - /** - * Find players by playing style - * @param playingStyle playing style - * @return list of players with that style - */ - List findByPlayingStyleIgnoreCase(String playingStyle); - - /** - * Find players by preferred hand - * @param preferredHand preferred hand (Right, Left) - * @return list of players with that hand preference - */ - List findByPreferredHandIgnoreCase(String preferredHand); -} \ No newline at end of file diff --git a/src/main/java/com/tennis/service/DataInitializationService.java b/src/main/java/com/tennis/service/DataInitializationService.java deleted file mode 100644 index 7a612b4a..00000000 --- a/src/main/java/com/tennis/service/DataInitializationService.java +++ /dev/null @@ -1,265 +0,0 @@ -package com.tennis.service; - -import com.tennis.entity.*; -import com.tennis.repository.*; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; - -/** - * Service to initialize the database with sample data - * Populates players, matches, and head-to-head records for testing - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class DataInitializationService implements CommandLineRunner { - - private final PlayerRepository playerRepository; - private final MatchRepository matchRepository; - private final HeadToHeadRepository headToHeadRepository; - private final MatchPredictionRepository predictionRepository; - - @Override - public void run(String... args) throws Exception { - log.info("Initializing database with sample data..."); - - // Initialize players - initializePlayers(); - - // Initialize head-to-head records - initializeHeadToHeadRecords(); - - // Initialize matches - initializeMatches(); - - log.info("Database initialization completed successfully!"); - } - - /** - * Initialize sample players - */ - private void initializePlayers() { - log.info("Creating sample players..."); - - List players = Arrays.asList( - // Top 10 ATP Players (as of 2024) - createPlayer("Novak Djokovic", "Serbia", 1, 1, 36, 188, 77, - "Aggressive Baseline", "Right", 0.85, 0.78, 0.82, - 0.68, 0.78, 0.62, 8.5, 2.1, 0.32, 0.58, 0.42, 0.88, 25, 22), - - createPlayer("Carlos Alcaraz", "Spain", 2, 1, 20, 183, 80, - "Aggressive Baseline", "Right", 0.82, 0.75, 0.79, - 0.65, 0.76, 0.60, 7.2, 2.8, 0.35, 0.62, 0.45, 0.85, 28, 24), - - createPlayer("Daniil Medvedev", "Russia", 3, 1, 27, 198, 83, - "Defensive Baseline", "Right", 0.78, 0.72, 0.75, - 0.62, 0.74, 0.58, 6.8, 2.5, 0.38, 0.65, 0.48, 0.82, 30, 25), - - createPlayer("Jannik Sinner", "Italy", 4, 3, 22, 188, 76, - "Aggressive Baseline", "Right", 0.80, 0.73, 0.77, - 0.64, 0.75, 0.59, 7.5, 2.3, 0.36, 0.61, 0.44, 0.87, 32, 28), - - createPlayer("Andrey Rublev", "Russia", 5, 5, 26, 188, 75, - "Aggressive Baseline", "Right", 0.76, 0.70, 0.73, - 0.60, 0.72, 0.56, 6.2, 2.7, 0.40, 0.68, 0.50, 0.79, 35, 30), - - createPlayer("Stefanos Tsitsipas", "Greece", 6, 3, 25, 193, 89, - "All-Court", "Right", 0.79, 0.74, 0.76, - 0.63, 0.73, 0.57, 7.0, 2.4, 0.37, 0.63, 0.46, 0.81, 38, 32), - - createPlayer("Alexander Zverev", "Germany", 7, 2, 26, 198, 90, - "Aggressive Baseline", "Right", 0.77, 0.71, 0.74, - 0.61, 0.71, 0.55, 6.5, 2.6, 0.39, 0.66, 0.49, 0.80, 40, 35), - - createPlayer("Holger Rune", "Denmark", 8, 4, 20, 188, 77, - "Aggressive Baseline", "Right", 0.81, 0.76, 0.78, - 0.66, 0.77, 0.61, 7.8, 2.2, 0.34, 0.59, 0.43, 0.84, 42, 38), - - createPlayer("Hubert Hurkacz", "Poland", 9, 9, 26, 196, 82, - "Serve and Volley", "Right", 0.74, 0.68, 0.72, - 0.58, 0.70, 0.54, 8.2, 2.0, 0.33, 0.57, 0.41, 0.78, 45, 40), - - createPlayer("Taylor Fritz", "USA", 10, 8, 25, 196, 86, - "Aggressive Baseline", "Right", 0.75, 0.69, 0.73, - 0.59, 0.71, 0.55, 6.8, 2.4, 0.38, 0.64, 0.47, 0.77, 48, 42) - ); - - playerRepository.saveAll(players); - log.info("Created {} sample players", players.size()); - } - - /** - * Create a player with all attributes - */ - private Player createPlayer(String name, String country, Integer currentRanking, Integer careerHighRanking, - Integer age, Integer heightCm, Integer weightKg, String playingStyle, String preferredHand, - Double hardCourtWinRate, Double clayCourtWinRate, Double grassCourtWinRate, - Double firstServePercentage, Double firstServeWinRate, Double secondServeWinRate, - Double acesPerMatch, Double doubleFaultsPerMatch, Double firstServeReturnWinRate, - Double secondServeReturnWinRate, Double breakPointsConvertedPercentage, - Double recentFormWinRate, Integer matchesPlayedThisYear, Integer winsThisYear) { - - Player player = new Player(); - player.setName(name); - player.setCountry(country); - player.setCurrentRanking(currentRanking); - player.setCareerHighRanking(careerHighRanking); - player.setAge(age); - player.setHeightCm(heightCm); - player.setWeightKg(weightKg); - player.setPlayingStyle(playingStyle); - player.setPreferredHand(preferredHand); - player.setHardCourtWinRate(hardCourtWinRate); - player.setClayCourtWinRate(clayCourtWinRate); - player.setGrassCourtWinRate(grassCourtWinRate); - player.setFirstServePercentage(firstServePercentage); - player.setFirstServeWinRate(firstServeWinRate); - player.setSecondServeWinRate(secondServeWinRate); - player.setAcesPerMatch(acesPerMatch); - player.setDoubleFaultsPerMatch(doubleFaultsPerMatch); - player.setFirstServeReturnWinRate(firstServeReturnWinRate); - player.setSecondServeReturnWinRate(secondServeReturnWinRate); - player.setBreakPointsConvertedPercentage(breakPointsConvertedPercentage); - player.setRecentFormWinRate(recentFormWinRate); - player.setMatchesPlayedThisYear(matchesPlayedThisYear); - player.setWinsThisYear(winsThisYear); - - return player; - } - - /** - * Initialize head-to-head records - */ - private void initializeHeadToHeadRecords() { - log.info("Creating sample head-to-head records..."); - - List players = playerRepository.findAll(); - - // Create some sample head-to-head records - for (int i = 0; i < players.size() - 1; i++) { - for (int j = i + 1; j < players.size(); j++) { - Player player1 = players.get(i); - Player player2 = players.get(j); - - HeadToHead h2h = new HeadToHead(); - h2h.setPlayer1(player1); - h2h.setPlayer2(player2); - - // Generate realistic head-to-head data - int totalMatches = (int) (Math.random() * 10) + 1; - int player1Wins = (int) (Math.random() * totalMatches); - int player2Wins = totalMatches - player1Wins; - - h2h.setTotalMatches(totalMatches); - h2h.setPlayer1Wins(player1Wins); - h2h.setPlayer2Wins(player2Wins); - - // Surface-specific records - h2h.setHardCourtMatches((int) (totalMatches * 0.4)); - h2h.setHardCourtPlayer1Wins((int) (h2h.getHardCourtMatches() * Math.random())); - h2h.setClayCourtMatches((int) (totalMatches * 0.35)); - h2h.setClayCourtPlayer1Wins((int) (h2h.getClayCourtMatches() * Math.random())); - h2h.setGrassCourtMatches((int) (totalMatches * 0.25)); - h2h.setGrassCourtPlayer1Wins((int) (h2h.getGrassCourtMatches() * Math.random())); - - h2h.setLastMatchDate(LocalDateTime.now().minusDays((int) (Math.random() * 365))); - h2h.setLastMatchTournament("Australian Open"); - h2h.setLastMatchSurface("Hard"); - h2h.setLastMatchWinner(Math.random() > 0.5 ? "player1" : "player2"); - - headToHeadRepository.save(h2h); - } - } - - log.info("Created sample head-to-head records"); - } - - /** - * Initialize sample matches - */ - private void initializeMatches() { - log.info("Creating sample matches..."); - - List players = playerRepository.findAll(); - - // Create some live and completed matches - List matches = Arrays.asList( - // Live match - createMatch(players.get(0), players.get(1), "Australian Open", "Best of 5", "Hard", "Live", - LocalDateTime.now().minusHours(2), null, 1, 0, 1, 4, 3, 30, 40, "player1", - 8, 5, 2, 1, 0.72, 0.68, 2, 1, 3, 2, 45, 42, 87), - - // Completed match - createMatch(players.get(2), players.get(3), "Wimbledon", "Best of 5", "Grass", "Completed", - LocalDateTime.now().minusDays(1), LocalDateTime.now().minusDays(1).plusHours(3), - 3, 1, 3, 6, 4, 40, 30, "player1", 12, 8, 1, 2, 0.75, 0.70, 4, 2, 6, 3, 78, 65, 143), - - // Scheduled match - createMatch(players.get(4), players.get(5), "French Open", "Best of 5", "Clay", "Scheduled", - LocalDateTime.now().plusHours(2), null, 0, 0, 1, 0, 0, 0, 0, "player1", - 0, 0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0), - - // Live match with close score - createMatch(players.get(6), players.get(7), "US Open", "Best of 5", "Hard", "Live", - LocalDateTime.now().minusHours(1), null, 1, 1, 2, 5, 5, 40, 40, "player2", - 6, 7, 1, 1, 0.68, 0.71, 1, 1, 2, 2, 52, 51, 103) - ); - - matchRepository.saveAll(matches); - log.info("Created {} sample matches", matches.size()); - } - - /** - * Create a match with all attributes - */ - private Match createMatch(Player player1, Player player2, String tournamentName, String matchType, - String surface, String matchStatus, LocalDateTime startTime, LocalDateTime endTime, - Integer player1SetsWon, Integer player2SetsWon, Integer currentSet, - Integer player1GamesCurrentSet, Integer player2GamesCurrentSet, - Integer player1PointsCurrentGame, Integer player2PointsCurrentGame, String currentServer, - Integer player1Aces, Integer player2Aces, Integer player1DoubleFaults, Integer player2DoubleFaults, - Double player1FirstServePercentage, Double player2FirstServePercentage, - Integer player1BreakPointsWon, Integer player2BreakPointsWon, - Integer player1BreakPointsOpportunities, Integer player2BreakPointsOpportunities, - Integer player1TotalPointsWon, Integer player2TotalPointsWon, Integer totalPointsPlayed) { - - Match match = new Match(); - match.setPlayer1(player1); - match.setPlayer2(player2); - match.setTournamentName(tournamentName); - match.setMatchType(matchType); - match.setSurface(surface); - match.setMatchStatus(matchStatus); - match.setStartTime(startTime); - match.setEndTime(endTime); - match.setPlayer1SetsWon(player1SetsWon); - match.setPlayer2SetsWon(player2SetsWon); - match.setCurrentSet(currentSet); - match.setPlayer1GamesCurrentSet(player1GamesCurrentSet); - match.setPlayer2GamesCurrentSet(player2GamesCurrentSet); - match.setPlayer1PointsCurrentGame(player1PointsCurrentGame); - match.setPlayer2PointsCurrentGame(player2PointsCurrentGame); - match.setCurrentServer(currentServer); - match.setPlayer1Aces(player1Aces); - match.setPlayer2Aces(player2Aces); - match.setPlayer1DoubleFaults(player1DoubleFaults); - match.setPlayer2DoubleFaults(player2DoubleFaults); - match.setPlayer1FirstServePercentage(player1FirstServePercentage); - match.setPlayer2FirstServePercentage(player2FirstServePercentage); - match.setPlayer1BreakPointsWon(player1BreakPointsWon); - match.setPlayer2BreakPointsWon(player2BreakPointsWon); - match.setPlayer1BreakPointsOpportunities(player1BreakPointsOpportunities); - match.setPlayer2BreakPointsOpportunities(player2BreakPointsOpportunities); - match.setPlayer1TotalPointsWon(player1TotalPointsWon); - match.setPlayer2TotalPointsWon(player2TotalPointsWon); - match.setTotalPointsPlayed(totalPointsPlayed); - - return match; - } -} \ No newline at end of file diff --git a/src/main/java/com/tennis/service/PredictionService.java b/src/main/java/com/tennis/service/PredictionService.java deleted file mode 100644 index 2425c8a2..00000000 --- a/src/main/java/com/tennis/service/PredictionService.java +++ /dev/null @@ -1,454 +0,0 @@ -package com.tennis.service; - -import com.tennis.entity.*; -import com.tennis.repository.*; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.HashMap; -import java.util.Map; - -/** - * Service class for tennis match predictions - * Implements algorithms for predicting match winner, current game winner, and current set winner - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class PredictionService { - - private final PlayerRepository playerRepository; - private final MatchRepository matchRepository; - private final MatchPredictionRepository predictionRepository; - private final HeadToHeadRepository headToHeadRepository; - - // Weight factors for different prediction components - private static final double RANKING_WEIGHT = 0.15; - private static final double HEAD_TO_HEAD_WEIGHT = 0.20; - private static final double SURFACE_WEIGHT = 0.15; - private static final double RECENT_FORM_WEIGHT = 0.15; - private static final double LIVE_STATS_WEIGHT = 0.25; - private static final double MOMENTUM_WEIGHT = 0.10; - - /** - * Predict match winner - * @param match the match to predict - * @return prediction result - */ - public MatchPrediction predictMatchWinner(Match match) { - log.info("Predicting match winner for match: {} vs {}", - match.getPlayer1().getName(), match.getPlayer2().getName()); - - // Calculate base probabilities - double player1Probability = calculatePlayer1WinProbability(match); - double player2Probability = 1.0 - player1Probability; - - // Determine predicted winner - String predictedWinner = player1Probability > player2Probability ? "player1" : "player2"; - double confidenceScore = Math.max(player1Probability, player2Probability); - - // Calculate factor weights - Map factors = calculatePredictionFactors(match); - - // Create prediction reasoning - String reasoning = buildPredictionReasoning(match, factors, predictedWinner, confidenceScore); - - // Create and save prediction - MatchPrediction prediction = new MatchPrediction(); - prediction.setMatch(match); - prediction.setPredictionType("MATCH_WINNER"); - prediction.setPredictedWinner(predictedWinner); - prediction.setConfidenceScore(confidenceScore); - prediction.setPlayer1WinProbability(player1Probability); - prediction.setPlayer2WinProbability(player2Probability); - prediction.setRankingFactor(factors.get("ranking")); - prediction.setHeadToHeadFactor(factors.get("headToHead")); - prediction.setSurfaceFactor(factors.get("surface")); - prediction.setRecentFormFactor(factors.get("recentForm")); - prediction.setLiveStatsFactor(factors.get("liveStats")); - prediction.setMomentumFactor(factors.get("momentum")); - prediction.setPredictionReasoning(reasoning); - - return predictionRepository.save(prediction); - } - - /** - * Predict current game winner - * @param match the match to predict - * @return prediction result - */ - public MatchPrediction predictCurrentGameWinner(Match match) { - log.info("Predicting current game winner for match: {} vs {}", - match.getPlayer1().getName(), match.getPlayer2().getName()); - - // For game prediction, focus more on serving and current momentum - double player1Probability = calculateGameWinProbability(match, true); - double player2Probability = 1.0 - player1Probability; - - String predictedWinner = player1Probability > player2Probability ? "player1" : "player2"; - double confidenceScore = Math.max(player1Probability, player2Probability); - - Map factors = calculateGamePredictionFactors(match); - String reasoning = buildGamePredictionReasoning(match, factors, predictedWinner, confidenceScore); - - MatchPrediction prediction = new MatchPrediction(); - prediction.setMatch(match); - prediction.setPredictionType("CURRENT_GAME_WINNER"); - prediction.setPredictedWinner(predictedWinner); - prediction.setConfidenceScore(confidenceScore); - prediction.setPlayer1WinProbability(player1Probability); - prediction.setPlayer2WinProbability(player2Probability); - prediction.setRankingFactor(factors.get("ranking")); - prediction.setHeadToHeadFactor(factors.get("headToHead")); - prediction.setSurfaceFactor(factors.get("surface")); - prediction.setRecentFormFactor(factors.get("recentForm")); - prediction.setLiveStatsFactor(factors.get("liveStats")); - prediction.setMomentumFactor(factors.get("momentum")); - prediction.setPredictionReasoning(reasoning); - - return predictionRepository.save(prediction); - } - - /** - * Predict current set winner - * @param match the match to predict - * @return prediction result - */ - public MatchPrediction predictCurrentSetWinner(Match match) { - log.info("Predicting current set winner for match: {} vs {}", - match.getPlayer1().getName(), match.getPlayer2().getName()); - - double player1Probability = calculateSetWinProbability(match, true); - double player2Probability = 1.0 - player1Probability; - - String predictedWinner = player1Probability > player2Probability ? "player1" : "player2"; - double confidenceScore = Math.max(player1Probability, player2Probability); - - Map factors = calculateSetPredictionFactors(match); - String reasoning = buildSetPredictionReasoning(match, factors, predictedWinner, confidenceScore); - - MatchPrediction prediction = new MatchPrediction(); - prediction.setMatch(match); - prediction.setPredictionType("CURRENT_SET_WINNER"); - prediction.setPredictedWinner(predictedWinner); - prediction.setConfidenceScore(confidenceScore); - prediction.setPlayer1WinProbability(player1Probability); - prediction.setPlayer2WinProbability(player2Probability); - prediction.setRankingFactor(factors.get("ranking")); - prediction.setHeadToHeadFactor(factors.get("headToHead")); - prediction.setSurfaceFactor(factors.get("surface")); - prediction.setRecentFormFactor(factors.get("recentForm")); - prediction.setLiveStatsFactor(factors.get("liveStats")); - prediction.setMomentumFactor(factors.get("momentum")); - prediction.setPredictionReasoning(reasoning); - - return predictionRepository.save(prediction); - } - - /** - * Calculate player1's win probability for the match - */ - private double calculatePlayer1WinProbability(Match match) { - Player player1 = match.getPlayer1(); - Player player2 = match.getPlayer2(); - - // Base probability from rankings - double rankingProb = calculateRankingProbability(player1, player2); - - // Head-to-head probability - double h2hProb = calculateHeadToHeadProbability(player1, player2, match.getSurface()); - - // Surface performance probability - double surfaceProb = calculateSurfaceProbability(player1, player2, match.getSurface()); - - // Recent form probability - double formProb = calculateRecentFormProbability(player1, player2); - - // Live stats probability - double liveStatsProb = calculateLiveStatsProbability(match); - - // Momentum probability - double momentumProb = calculateMomentumProbability(match); - - // Weighted average - double weightedProb = (rankingProb * RANKING_WEIGHT) + - (h2hProb * HEAD_TO_HEAD_WEIGHT) + - (surfaceProb * SURFACE_WEIGHT) + - (formProb * RECENT_FORM_WEIGHT) + - (liveStatsProb * LIVE_STATS_WEIGHT) + - (momentumProb * MOMENTUM_WEIGHT); - - return Math.max(0.1, Math.min(0.9, weightedProb)); // Clamp between 0.1 and 0.9 - } - - /** - * Calculate game win probability - */ - private double calculateGameWinProbability(Match match, boolean isPlayer1) { - // For game prediction, focus more on serving and current game state - double serveAdvantage = 0.6; // Server has advantage - double currentScoreFactor = calculateCurrentScoreFactor(match, isPlayer1); - double serveQualityFactor = calculateServeQualityFactor(match, isPlayer1); - - return (serveAdvantage + currentScoreFactor + serveQualityFactor) / 3.0; - } - - /** - * Calculate set win probability - */ - private double calculateSetWinProbability(Match match, boolean isPlayer1) { - // For set prediction, consider current set score and overall match momentum - double currentSetScoreFactor = calculateCurrentSetScoreFactor(match, isPlayer1); - double matchMomentumFactor = calculateMatchMomentumFactor(match, isPlayer1); - double overallMatchProbability = calculatePlayer1WinProbability(match); - - if (!isPlayer1) { - overallMatchProbability = 1.0 - overallMatchProbability; - } - - return (currentSetScoreFactor + matchMomentumFactor + overallMatchProbability) / 3.0; - } - - /** - * Calculate ranking-based probability - */ - private double calculateRankingProbability(Player player1, Player player2) { - if (player1.getCurrentRanking() == null || player2.getCurrentRanking() == null) { - return 0.5; // Neutral if rankings not available - } - - int rankDiff = player2.getCurrentRanking() - player1.getCurrentRanking(); - // Higher ranked player has advantage - return 0.5 + (rankDiff * 0.02); // Each ranking difference = 2% advantage - } - - /** - * Calculate head-to-head probability - */ - private double calculateHeadToHeadProbability(Player player1, Player player2, String surface) { - // This would typically query the HeadToHead repository - // For now, return neutral probability - return 0.5; - } - - /** - * Calculate surface performance probability - */ - private double calculateSurfaceProbability(Player player1, Player player2, String surface) { - double player1SurfaceRate = getPlayerSurfaceWinRate(player1, surface); - double player2SurfaceRate = getPlayerSurfaceWinRate(player2, surface); - - if (player1SurfaceRate + player2SurfaceRate == 0) { - return 0.5; - } - - return player1SurfaceRate / (player1SurfaceRate + player2SurfaceRate); - } - - /** - * Get player's win rate on specific surface - */ - private double getPlayerSurfaceWinRate(Player player, String surface) { - switch (surface.toLowerCase()) { - case "hard": - return player.getHardCourtWinRate() != null ? player.getHardCourtWinRate() : 0.5; - case "clay": - return player.getClayCourtWinRate() != null ? player.getClayCourtWinRate() : 0.5; - case "grass": - return player.getGrassCourtWinRate() != null ? player.getGrassCourtWinRate() : 0.5; - default: - return 0.5; - } - } - - /** - * Calculate recent form probability - */ - private double calculateRecentFormProbability(Player player1, Player player2) { - double player1Form = player1.getRecentFormWinRate() != null ? player1.getRecentFormWinRate() : 0.5; - double player2Form = player2.getRecentFormWinRate() != null ? player2.getRecentFormWinRate() : 0.5; - - if (player1Form + player2Form == 0) { - return 0.5; - } - - return player1Form / (player1Form + player2Form); - } - - /** - * Calculate live statistics probability - */ - private double calculateLiveStatsProbability(Match match) { - if (match.getTotalPointsPlayed() == 0) { - return 0.5; - } - - double player1PointRate = (double) match.getPlayer1TotalPointsWon() / match.getTotalPointsPlayed(); - return player1PointRate; - } - - /** - * Calculate momentum probability - */ - private double calculateMomentumProbability(Match match) { - // Simple momentum calculation based on recent points won - // In a real implementation, this would be more sophisticated - return 0.5; - } - - /** - * Calculate current score factor for game prediction - */ - private double calculateCurrentScoreFactor(Match match, boolean isPlayer1) { - int playerPoints = isPlayer1 ? match.getPlayer1PointsCurrentGame() : match.getPlayer2PointsCurrentGame(); - int opponentPoints = isPlayer1 ? match.getPlayer2PointsCurrentGame() : match.getPlayer1PointsCurrentGame(); - - if (playerPoints == opponentPoints) return 0.5; - if (playerPoints > opponentPoints) return 0.7; - return 0.3; - } - - /** - * Calculate serve quality factor - */ - private double calculateServeQualityFactor(Match match, boolean isPlayer1) { - if ("player1".equals(match.getCurrentServer()) && isPlayer1) { - return match.getPlayer1FirstServePercentage() != null ? match.getPlayer1FirstServePercentage() / 100.0 : 0.5; - } else if ("player2".equals(match.getCurrentServer()) && !isPlayer1) { - return match.getPlayer2FirstServePercentage() != null ? match.getPlayer2FirstServePercentage() / 100.0 : 0.5; - } - return 0.5; - } - - /** - * Calculate current set score factor - */ - private double calculateCurrentSetScoreFactor(Match match, boolean isPlayer1) { - int playerGames = isPlayer1 ? match.getPlayer1GamesCurrentSet() : match.getPlayer2GamesCurrentSet(); - int opponentGames = isPlayer1 ? match.getPlayer2GamesCurrentSet() : match.getPlayer1GamesCurrentSet(); - - if (playerGames == opponentGames) return 0.5; - if (playerGames > opponentGames) return 0.7; - return 0.3; - } - - /** - * Calculate match momentum factor - */ - private double calculateMatchMomentumFactor(Match match, boolean isPlayer1) { - int playerSets = isPlayer1 ? match.getPlayer1SetsWon() : match.getPlayer2SetsWon(); - int opponentSets = isPlayer1 ? match.getPlayer2SetsWon() : match.getPlayer1SetsWon(); - - if (playerSets == opponentSets) return 0.5; - if (playerSets > opponentSets) return 0.7; - return 0.3; - } - - /** - * Calculate prediction factors for detailed analysis - */ - private Map calculatePredictionFactors(Match match) { - Map factors = new HashMap<>(); - - Player player1 = match.getPlayer1(); - Player player2 = match.getPlayer2(); - - factors.put("ranking", calculateRankingProbability(player1, player2)); - factors.put("headToHead", calculateHeadToHeadProbability(player1, player2, match.getSurface())); - factors.put("surface", calculateSurfaceProbability(player1, player2, match.getSurface())); - factors.put("recentForm", calculateRecentFormProbability(player1, player2)); - factors.put("liveStats", calculateLiveStatsProbability(match)); - factors.put("momentum", calculateMomentumProbability(match)); - - return factors; - } - - /** - * Calculate game prediction factors - */ - private Map calculateGamePredictionFactors(Match match) { - Map factors = new HashMap<>(); - - // For game prediction, adjust weights - factors.put("ranking", 0.1); - factors.put("headToHead", 0.1); - factors.put("surface", 0.1); - factors.put("recentForm", 0.1); - factors.put("liveStats", 0.4); // Higher weight for live stats - factors.put("momentum", 0.2); // Higher weight for momentum - - return factors; - } - - /** - * Calculate set prediction factors - */ - private Map calculateSetPredictionFactors(Match match) { - Map factors = new HashMap<>(); - - // For set prediction, balance between overall match and current state - factors.put("ranking", 0.15); - factors.put("headToHead", 0.15); - factors.put("surface", 0.15); - factors.put("recentForm", 0.15); - factors.put("liveStats", 0.25); - factors.put("momentum", 0.15); - - return factors; - } - - /** - * Build prediction reasoning - */ - private String buildPredictionReasoning(Match match, Map factors, String predictedWinner, double confidence) { - StringBuilder reasoning = new StringBuilder(); - reasoning.append("Match Winner Prediction: "); - reasoning.append(predictedWinner.equals("player1") ? match.getPlayer1().getName() : match.getPlayer2().getName()); - reasoning.append(" (Confidence: ").append(String.format("%.1f%%", confidence * 100)).append(")\n\n"); - - reasoning.append("Key Factors:\n"); - reasoning.append("- Ranking Factor: ").append(String.format("%.1f%%", factors.get("ranking") * 100)).append("\n"); - reasoning.append("- Head-to-Head: ").append(String.format("%.1f%%", factors.get("headToHead") * 100)).append("\n"); - reasoning.append("- Surface Performance: ").append(String.format("%.1f%%", factors.get("surface") * 100)).append("\n"); - reasoning.append("- Recent Form: ").append(String.format("%.1f%%", factors.get("recentForm") * 100)).append("\n"); - reasoning.append("- Live Statistics: ").append(String.format("%.1f%%", factors.get("liveStats") * 100)).append("\n"); - reasoning.append("- Match Momentum: ").append(String.format("%.1f%%", factors.get("momentum") * 100)); - - return reasoning.toString(); - } - - /** - * Build game prediction reasoning - */ - private String buildGamePredictionReasoning(Match match, Map factors, String predictedWinner, double confidence) { - StringBuilder reasoning = new StringBuilder(); - reasoning.append("Current Game Winner Prediction: "); - reasoning.append(predictedWinner.equals("player1") ? match.getPlayer1().getName() : match.getPlayer2().getName()); - reasoning.append(" (Confidence: ").append(String.format("%.1f%%", confidence * 100)).append(")\n\n"); - - reasoning.append("Game-specific Factors:\n"); - reasoning.append("- Current Server: ").append("player1".equals(match.getCurrentServer()) ? match.getPlayer1().getName() : match.getPlayer2().getName()).append("\n"); - reasoning.append("- Serve Quality: ").append(String.format("%.1f%%", factors.get("liveStats") * 100)).append("\n"); - reasoning.append("- Game Momentum: ").append(String.format("%.1f%%", factors.get("momentum") * 100)); - - return reasoning.toString(); - } - - /** - * Build set prediction reasoning - */ - private String buildSetPredictionReasoning(Match match, Map factors, String predictedWinner, double confidence) { - StringBuilder reasoning = new StringBuilder(); - reasoning.append("Current Set Winner Prediction: "); - reasoning.append(predictedWinner.equals("player1") ? match.getPlayer1().getName() : match.getPlayer2().getName()); - reasoning.append(" (Confidence: ").append(String.format("%.1f%%", confidence * 100)).append(")\n\n"); - - reasoning.append("Set-specific Factors:\n"); - reasoning.append("- Current Set Score: ").append(match.getPlayer1GamesCurrentSet()).append("-").append(match.getPlayer2GamesCurrentSet()).append("\n"); - reasoning.append("- Overall Match Score: ").append(match.getPlayer1SetsWon()).append("-").append(match.getPlayer2SetsWon()).append("\n"); - reasoning.append("- Set Momentum: ").append(String.format("%.1f%%", factors.get("momentum") * 100)); - - return reasoning.toString(); - } -} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 3126208c..00000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,36 +0,0 @@ -# Server Configuration -server.port=8080 -server.servlet.context-path=/tennis-prediction - -# H2 Database Configuration -spring.datasource.url=jdbc:h2:mem:tennisdb -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect - -# H2 Console Configuration (for development) -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console - -# JPA/Hibernate Configuration -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true - -# Thymeleaf Configuration -spring.thymeleaf.cache=false -spring.thymeleaf.prefix=classpath:/templates/ -spring.thymeleaf.suffix=.html - -# Logging Configuration -logging.level.com.tennis=DEBUG -logging.level.org.springframework.web=DEBUG - -# External API Configuration (for FlashScore or similar) -tennis.api.base-url=https://api.flashscore.com -tennis.api.key=your-api-key-here - -# Application specific properties -tennis.prediction.model.threshold=0.6 -tennis.prediction.update-interval=30000 \ No newline at end of file diff --git a/src/main/resources/templates/dashboard.html b/src/main/resources/templates/dashboard.html deleted file mode 100644 index 28c72ad2..00000000 --- a/src/main/resources/templates/dashboard.html +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - Tennis Match Prediction Dashboard - - - - - - - - - - - - -
- -
-
-

- - Tennis Match Prediction Dashboard -

-

- Real-time predictions powered by AI algorithms analyzing player statistics, head-to-head records, and live match data -

-
-
- - -
-
-
-
- -

Players

-

10

- Top ranked players -
-
-
-
-
-
- -

Live Matches

-

0

- Currently playing -
-
-
-
-
-
- -

Predictions

-

0

- Last 24 hours -
-
-
-
-
-
- -

Accuracy

-

0.0%

- Prediction success rate -
-
-
-
- - -
- -
-
-
- - Live Matches -
-
-
- -

No live matches at the moment

-
- -
-
-
-
-
Player 1 vs Player 2
- LIVE -
-
1-0 (4-3)
-
- Tournament - Surface - Set 1 -
-
-
- - -
-
-
-
-
-
- - -
-
-
- - Top Players -
-
-
-
-
- 1 - Player Name -
-
-
Hard Court
- Country -
-
-
-
-
-
-
- - -
-
-
-
- - Recent Predictions -
-
-
- -

No recent predictions

-
- -
-
-
-
Predicted Winner
- Prediction Type -
-
- High -
- 85.5% -
-
- 14:30 -
- Ranking -
-
-
-
-
-
-
-
- - - - - -
-
- Loading... -
-
- - - - - - - - \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties deleted file mode 100644 index 3126208c..00000000 --- a/target/classes/application.properties +++ /dev/null @@ -1,36 +0,0 @@ -# Server Configuration -server.port=8080 -server.servlet.context-path=/tennis-prediction - -# H2 Database Configuration -spring.datasource.url=jdbc:h2:mem:tennisdb -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect - -# H2 Console Configuration (for development) -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console - -# JPA/Hibernate Configuration -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true - -# Thymeleaf Configuration -spring.thymeleaf.cache=false -spring.thymeleaf.prefix=classpath:/templates/ -spring.thymeleaf.suffix=.html - -# Logging Configuration -logging.level.com.tennis=DEBUG -logging.level.org.springframework.web=DEBUG - -# External API Configuration (for FlashScore or similar) -tennis.api.base-url=https://api.flashscore.com -tennis.api.key=your-api-key-here - -# Application specific properties -tennis.prediction.model.threshold=0.6 -tennis.prediction.update-interval=30000 \ No newline at end of file diff --git a/target/classes/com/tennis/TennisPredictionApplication.class b/target/classes/com/tennis/TennisPredictionApplication.class deleted file mode 100644 index f0ba795f..00000000 Binary files a/target/classes/com/tennis/TennisPredictionApplication.class and /dev/null differ diff --git a/target/classes/com/tennis/controller/TennisPredictionController.class b/target/classes/com/tennis/controller/TennisPredictionController.class deleted file mode 100644 index b15e7912..00000000 Binary files a/target/classes/com/tennis/controller/TennisPredictionController.class and /dev/null differ diff --git a/target/classes/com/tennis/entity/HeadToHead.class b/target/classes/com/tennis/entity/HeadToHead.class deleted file mode 100644 index 22591f8f..00000000 Binary files a/target/classes/com/tennis/entity/HeadToHead.class and /dev/null differ diff --git a/target/classes/com/tennis/entity/Match.class b/target/classes/com/tennis/entity/Match.class deleted file mode 100644 index c3c597a1..00000000 Binary files a/target/classes/com/tennis/entity/Match.class and /dev/null differ diff --git a/target/classes/com/tennis/entity/MatchPrediction.class b/target/classes/com/tennis/entity/MatchPrediction.class deleted file mode 100644 index 71afb212..00000000 Binary files a/target/classes/com/tennis/entity/MatchPrediction.class and /dev/null differ diff --git a/target/classes/com/tennis/entity/Player.class b/target/classes/com/tennis/entity/Player.class deleted file mode 100644 index 76afe65b..00000000 Binary files a/target/classes/com/tennis/entity/Player.class and /dev/null differ diff --git a/target/classes/com/tennis/repository/HeadToHeadRepository.class b/target/classes/com/tennis/repository/HeadToHeadRepository.class deleted file mode 100644 index 7e58283a..00000000 Binary files a/target/classes/com/tennis/repository/HeadToHeadRepository.class and /dev/null differ diff --git a/target/classes/com/tennis/repository/MatchPredictionRepository.class b/target/classes/com/tennis/repository/MatchPredictionRepository.class deleted file mode 100644 index 2428fe2d..00000000 Binary files a/target/classes/com/tennis/repository/MatchPredictionRepository.class and /dev/null differ diff --git a/target/classes/com/tennis/repository/MatchRepository.class b/target/classes/com/tennis/repository/MatchRepository.class deleted file mode 100644 index db252d12..00000000 Binary files a/target/classes/com/tennis/repository/MatchRepository.class and /dev/null differ diff --git a/target/classes/com/tennis/repository/PlayerRepository.class b/target/classes/com/tennis/repository/PlayerRepository.class deleted file mode 100644 index 66a306a9..00000000 Binary files a/target/classes/com/tennis/repository/PlayerRepository.class and /dev/null differ diff --git a/target/classes/com/tennis/service/DataInitializationService.class b/target/classes/com/tennis/service/DataInitializationService.class deleted file mode 100644 index 0536209c..00000000 Binary files a/target/classes/com/tennis/service/DataInitializationService.class and /dev/null differ diff --git a/target/classes/com/tennis/service/PredictionService.class b/target/classes/com/tennis/service/PredictionService.class deleted file mode 100644 index c419c50a..00000000 Binary files a/target/classes/com/tennis/service/PredictionService.class and /dev/null differ diff --git a/target/classes/templates/dashboard.html b/target/classes/templates/dashboard.html deleted file mode 100644 index 28c72ad2..00000000 --- a/target/classes/templates/dashboard.html +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - Tennis Match Prediction Dashboard - - - - - - - - - - - - -
- -
-
-

- - Tennis Match Prediction Dashboard -

-

- Real-time predictions powered by AI algorithms analyzing player statistics, head-to-head records, and live match data -

-
-
- - -
-
-
-
- -

Players

-

10

- Top ranked players -
-
-
-
-
-
- -

Live Matches

-

0

- Currently playing -
-
-
-
-
-
- -

Predictions

-

0

- Last 24 hours -
-
-
-
-
-
- -

Accuracy

-

0.0%

- Prediction success rate -
-
-
-
- - -
- -
-
-
- - Live Matches -
-
-
- -

No live matches at the moment

-
- -
-
-
-
-
Player 1 vs Player 2
- LIVE -
-
1-0 (4-3)
-
- Tournament - Surface - Set 1 -
-
-
- - -
-
-
-
-
-
- - -
-
-
- - Top Players -
-
-
-
-
- 1 - Player Name -
-
-
Hard Court
- Country -
-
-
-
-
-
-
- - -
-
-
-
- - Recent Predictions -
-
-
- -

No recent predictions

-
- -
-
-
-
Predicted Winner
- Prediction Type -
-
- High -
- 85.5% -
-
- 14:30 -
- Ranking -
-
-
-
-
-
-
-
- - - - - -
-
- Loading... -
-
- - - - - - - - \ No newline at end of file diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index ac8dd12f..00000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,12 +0,0 @@ -com/tennis/entity/MatchPrediction.class -com/tennis/controller/TennisPredictionController.class -com/tennis/TennisPredictionApplication.class -com/tennis/repository/MatchRepository.class -com/tennis/entity/HeadToHead.class -com/tennis/service/DataInitializationService.class -com/tennis/entity/Player.class -com/tennis/entity/Match.class -com/tennis/repository/HeadToHeadRepository.class -com/tennis/service/PredictionService.class -com/tennis/repository/PlayerRepository.class -com/tennis/repository/MatchPredictionRepository.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 5a232d9a..00000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,12 +0,0 @@ -/workspace/src/main/java/com/tennis/repository/PlayerRepository.java -/workspace/src/main/java/com/tennis/repository/MatchRepository.java -/workspace/src/main/java/com/tennis/entity/HeadToHead.java -/workspace/src/main/java/com/tennis/controller/TennisPredictionController.java -/workspace/src/main/java/com/tennis/service/PredictionService.java -/workspace/src/main/java/com/tennis/repository/MatchPredictionRepository.java -/workspace/src/main/java/com/tennis/entity/MatchPrediction.java -/workspace/src/main/java/com/tennis/repository/HeadToHeadRepository.java -/workspace/src/main/java/com/tennis/service/DataInitializationService.java -/workspace/src/main/java/com/tennis/TennisPredictionApplication.java -/workspace/src/main/java/com/tennis/entity/Match.java -/workspace/src/main/java/com/tennis/entity/Player.java