theres duplicate players when i checked. i did generate roster then transfer market then view teams. public class TeamRostersGUI extends JFrame {

private JPanel mainPanel;
private FootballTeamRostersPage teamRostersPage;
private Map<String, Integer> teamStandings; // Map to store team standings

public TeamRostersGUI() {
setTitle("Football Team Rosters Generator");
setSize(1000, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);

mainPanel = new JPanel(new CardLayout());
teamRostersPage = new FootballTeamRostersPage();

mainPanel.add(createCoverPage(), "cover");
mainPanel.add(teamRostersPage, "teamRosters");

getContentPane().add(mainPanel, BorderLayout.CENTER);
}

private JPanel createCoverPage() {
JPanel coverPanel = new JPanel(new BorderLayout());

// Set a nostalgic retro background image (replace with your image file)
ImageIcon backgroundImage = new ImageIcon("C:\Users\Vusum\OneDrive\Documents\13774adb-2bfa-4582-8253-d21f4c4b7944_clipdrop-enhance.jpg");
JLabel backgroundLabel = new JLabel(backgroundImage);
coverPanel.add(backgroundLabel, BorderLayout.CENTER);

// Create a "Start" button
JButton startButton = new JButton("Start");
startButton.setFont(new Font("Arial", Font.BOLD, 24));
startButton.setForeground(Color.RED);
startButton.setPreferredSize(new Dimension(200, 60));
startButton.addActionListener(e -> showTeamRostersPage());

JPanel buttonPanel = new JPanel();
buttonPanel.setOpaque(false);
buttonPanel.add(startButton);

coverPanel.add(buttonPanel, BorderLayout.SOUTH);

return coverPanel;
}

private void showTeamRostersPage() {
((CardLayout) mainPanel.getLayout()).show(mainPanel, "teamRosters");
teamRostersPage.loadTeamsFromFile("C:\Users\Vusum\OneDrive\Documents\teams.txt");
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}

TeamRostersGUI app = new TeamRostersGUI();
app.setVisible(true);
});
}
}

class FootballTeamRostersPage extends JPanel {

private List<Team> teams;
List<Team> updatedTeams;
private List<List<Match>> fixtures;
private List<Player> players;
private Map<String, List<Player>> teamRosters;
private JTextArea rosterTextArea;
private JTextArea unpickedPlayersTextArea;
private JButton generateButton;
private JButton transferMarketButton;
private JButton viewTeamButton;
private JTextArea transferMarketTextArea;
private JPanel managerCareerPanel = null;
private JButton managerCareerButton;
private JTextField searchField;
private JButton searchButton;

public FootballTeamRostersPage() {
setBackground(new Color(0, 102, 204));
setLayout(null);

teamStandings = new HashMap<>();
teamRosters = new HashMap<>();
players = new ArrayList<>();
rosterTextArea = new JTextArea(20, 40);
rosterTextArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(rosterTextArea);
scrollPane.setBounds(50, 50, 300, 400);

unpickedPlayersTextArea = new JTextArea(20, 40);
unpickedPlayersTextArea.setEditable(false);
JScrollPane unpickedScrollPane = new JScrollPane(unpickedPlayersTextArea);
unpickedScrollPane.setBounds(50, 530, 300, 200);

generateButton = new JButton("Generate Rosters");
generateButton.setBounds(50, 480, 200, 40);
generateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadPlayersFromFile("C:\Users\Vusum\OneDrive\Documents\Players17.txt");
generateRosters();
displayRosters();
}
});

transferMarketButton = new JButton("Transfer Market");
transferMarketButton.setBounds(270, 480, 200, 40);
transferMarketButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
openTransferMarket();
}
});

viewTeamButton = new JButton("View Team");
viewTeamButton.setBounds(490, 480, 200, 40);
viewTeamButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
openViewTeam();
}
});

transferMarketTextArea = new JTextArea(20, 40);
transferMarketTextArea.setEditable(false);
JScrollPane transferMarketScrollPane = new JScrollPane(transferMarketTextArea);
transferMarketScrollPane.setBounds(400, 50, 300, 400);

add(scrollPane);
add(unpickedScrollPane);
add(generateButton);
add(transferMarketButton);
add(viewTeamButton);
add(transferMarketScrollPane);

JButton simulateButton = new JButton("Simulate Season");
simulateButton.addActionListener(e -> simulateSeason());

add(simulateButton);
simulateButton.setBounds(50, 450, 200, 40);
revalidate();
repaint();

}

public Map<String, Integer> teamStandings;

private void showTeamRosters() {
// Switch back to the team rosters page
((CardLayout) getParent().getLayout()).show(getParent(), "teamRosters");
}

public void loadTeamsFromFile(String filename) {
teams = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
String[] parts = line.split(":");
if (parts.length == 3) {
String teamName = parts[0].trim();
double transferBudget = Double.parseDouble(parts[1].trim().replace("m", ""));
String formation = parts[2].trim();
Team team = new Team(teamName, transferBudget, formation);
teams.add(team);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void loadPlayersFromFile(String filename) {
players.clear();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
// Split using tab as the delimiter
String[] parts = line.split("\t");
if (parts.length == 4) {
String playerName = parts[0].trim();
String playerPosition = parts[1].trim();
// Assuming transfer price is in millions
int transferPrice = (int) Double.parseDouble(parts[3].trim().replace("m", ""));
int rating = Integer.parseInt(parts[2].trim());
Player player = new Player(playerName, playerPosition, transferPrice, rating, null);
player.setFreeAgent(true); // Mark as free agent initially

players.add(player);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void generateRosters() {
// Clear previous roster information
teamRosters.clear();
List<Player> unpickedPlayers = new ArrayList<>(players);

for (Team team : teams) {
List<Player> roster = new ArrayList<>();
boolean hasGK = false; // Flag to track if the team already has a goalkeeper

// Fill the roster with random players, ensuring only one goalkeeper
for (int i = 0; i < 17; i++) { // Maximum 17 players per team (16 outfield + 1 GK)
if (!unpickedPlayers.isEmpty()) {
int index = new Random().nextInt(unpickedPlayers.size());
Player player = unpickedPlayers.get(index);

if (player.getPosition().equalsIgnoreCase("GK") && hasGK) {
// Skip adding another goalkeeper
continue;
}

if (player.getPosition().equalsIgnoreCase("GK")) {
hasGK = true;
}

// Track the previous club for transferred players
if (!team.getName().equals(player.getPreviousClub())) {
player.setPreviousClub(team.getName());
player.setTransferStatus("Transferred");
} else {
player.setTransferStatus("Free Agent");
}

roster.add(player);
player.setFreeAgent(false); // No longer a free agent
unpickedPlayers.remove(player);

} else {
break; // No more players to pick from
}
}

teamRosters.put(team.getName(), roster);
}
for (Team team : teams) {
List<Player> roster = teamRosters.get(team.getName());
if (roster != null) {
for (Player player : roster) {
player.setPicked(true);
}
}
}

// Display unpicked players
displayUnpickedPlayers(unpickedPlayers);
}

public void displayRosters() {
JPanel rosterPanel = new JPanel(new GridLayout(teams.size(), 1, 10, 10)); // Rows for each team
rosterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

for (Map.Entry<String, List<Player>> entry : teamRosters.entrySet()) {
String teamName = entry.getKey();
List<Player> roster = entry.getValue();

JPanel teamRosterPanel = new JPanel(new GridLayout(6, 5)); // 6 rows x 5 columns for player info
teamRosterPanel.setBorder(BorderFactory.createTitledBorder(teamName));

for (Player player : roster) {
JPanel playerPanel = new JPanel(new GridLayout(3, 1)); // 3 rows for name, position, and rating
playerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

JLabel nameLabel = new JLabel(player.getName());
nameLabel.setHorizontalAlignment(SwingConstants.CENTER);

JLabel positionLabel = new JLabel("Position: " + player.getPosition());
positionLabel.setHorizontalAlignment(SwingConstants.CENTER);

JLabel ratingLabel = new JLabel("Rating: " + player.getRating());
ratingLabel.setHorizontalAlignment(SwingConstants.CENTER);

playerPanel.add(nameLabel);
playerPanel.add(positionLabel);
playerPanel.add(ratingLabel);

teamRosterPanel.add(playerPanel);
}

rosterPanel.add(teamRosterPanel);
}

JScrollPane rosterScrollPane = new JScrollPane(rosterPanel);
rosterTextArea.setText(""); // Clear the old text
rosterTextArea.setLayout(new BorderLayout());
rosterTextArea.add(rosterScrollPane, BorderLayout.CENTER);
}

public void displayUnpickedPlayers(List<Player> unpickedPlayers) {
StringBuilder unpickedPlayersBuilder = new StringBuilder("Unpicked Players:\n");

for (Player player : unpickedPlayers) {
if (!player.isPicked()) {
unpickedPlayersBuilder.append(player.getName()).append(" (")
.append(player.getPosition()).append("), Rating: ").append(player.getRating());
}
// Display transfer status and previous club for realism
String transferStatus = player.getTransferStatus();
String previousClub = player.getPreviousClub();
if (transferStatus != null) {
unpickedPlayersBuilder.append(", Transfer Status: ").append(transferStatus);
if (transferStatus.equals("Transferred") && previousClub != null) {
unpickedPlayersBuilder.append(", Previous Club: ").append(previousClub);
}
}

unpickedPlayersBuilder.append("\n");
}

unpickedPlayersTextArea.setText(unpickedPlayersBuilder.toString());
}

public void openTransferMarket() {
JFrame transferMarketFrame = new JFrame("Transfer Market");
transferMarketFrame.setSize(800, 600);
transferMarketFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
transferMarketFrame.setLocationRelativeTo(this);

JPanel transferMarketPanel = new JPanel();
transferMarketPanel.setLayout(new BorderLayout());

JTextArea transferMarketTextArea = new JTextArea(20, 40);
transferMarketTextArea.setEditable(false);
JScrollPane transferMarketScrollPane = new JScrollPane(transferMarketTextArea);
transferMarketPanel.add(transferMarketScrollPane, BorderLayout.CENTER);

// Add a "Simulate Transfer Window" button
JButton simulateButton = new JButton("Simulate Transfer Window");
simulateButton.setBounds(50, 480, 200, 40);
simulateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
simulateTransferWindow(transferMarketTextArea);
}
});
transferMarketPanel.add(simulateButton, BorderLayout.SOUTH);

transferMarketFrame.add(transferMarketPanel);
transferMarketFrame.setVisible(true);
}

public void simulateTransferWindow(JTextArea transferMarketTextArea) {

List<Player> availablePlayers = new ArrayList<>(players);
// Define transfer window parameters
int transferWindowHours = 20; // Total transfer window duration (hours)
int maxTransfersPerHour = 8; // Maximum transfers per hour
int transferDeadlineHour = 20; // Hour at which the transfer window closes

// Track transferred players and their destinations
Map<Player, Team> transferHistory = new HashMap<>();
Map<Player, Team> freeAgentTransfers = new HashMap<>();
Map<Team, List<Player>> playersBought = new HashMap<>();
Map<Team, Double> moneySpent = new HashMap<>();

for (int hour = 1; hour <= transferWindowHours; hour++) {
if (hour <= transferDeadlineHour) {
// Simulate negotiations and transfers within the transfer window
int negotiationsThisHour = new Random().nextInt(maxTransfersPerHour + 1); // Randomize negotiations per hour

for (int i = 0; i < negotiationsThisHour; i++) {
if (!players.isEmpty() && !teams.isEmpty()) {
int randomPlayerIndex = new Random().nextInt(availablePlayers.size());
Player playerToTransfer = availablePlayers.get(randomPlayerIndex);
availablePlayers.remove(randomPlayerIndex);

int randomTeamIndex = new Random().nextInt(teams.size());
Team destinationTeam = teams.get(randomTeamIndex);

if (playerToTransfer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
// Simulate negotiation for transfer fee
int negotiatedFee = simulateNegotiation(playerToTransfer.getTransferPrice());

if (negotiatedFee > 0) {
// Transfer fee paid from the destination team's budget
destinationTeam.deductTransferBudget(negotiatedFee);

// Track transfer history
transferHistory.put(playerToTransfer, destinationTeam);

// Track money spent by the destination team
moneySpent.put(destinationTeam, moneySpent.getOrDefault(destinationTeam, 0.0) + negotiatedFee);

// Add the player to the destination team's roster
destinationTeam.addPlayer(playerToTransfer);

// Add the player to the playersBought map
playersBought.computeIfAbsent(destinationTeam, k -> new ArrayList<>()).add(playerToTransfer);

// Display the transfer in the log
transferMarketTextArea.append("Hour " + hour + ": ");
transferMarketTextArea.append(playerToTransfer.getName() + " has transferred to " + destinationTeam.getName()
+ " for $" + negotiatedFee + "m\n");
playerToTransfer.setFreeAgent(false);
} else {
// Transfer negotiation failed
transferMarketTextArea.append("Hour " + hour + ": ");
transferMarketTextArea.append(playerToTransfer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

}
} else {

if (playerToTransfer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
// Simulate negotiation for transfer fee
int negotiatedFee = simulateNegotiation(playerToTransfer.getTransferPrice());

if (negotiatedFee > 0) {
// Transfer fee paid from the destination team's budget
destinationTeam.deductTransferBudget(negotiatedFee);

// Track transfer history
transferHistory.put(playerToTransfer, destinationTeam);

//...
} else {
// Transfer negotiation failed
transferMarketTextArea.append("Hour " + hour + ": ");
transferMarketTextArea.append(playerToTransfer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

}
} else {
// Player's transfer fee is too high for the destination team, so they opt for another player
transferMarketTextArea.append("Hour " + hour + ": ");
transferMarketTextArea.append(destinationTeam.getName() + " cannot afford " + playerToTransfer.getName() + ". Opting for another player.\n");

// Put the original player back into the available players pool
availablePlayers.add(playerToTransfer);

// Get another player from the available players pool
int anotherPlayerIndex = new Random().nextInt(availablePlayers.size());
Player anotherPlayer = availablePlayers.get(anotherPlayerIndex);
availablePlayers.remove(anotherPlayerIndex);

// Simulate negotiation for the new player
int negotiatedFee = simulateNegotiation(anotherPlayer.getTransferPrice());

if (negotiatedFee > 0 && anotherPlayer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
// Transfer fee paid from the destination team's budget
destinationTeam.deductTransferBudget(negotiatedFee);

// Track transfer history
transferHistory.put(anotherPlayer, destinationTeam);

//...
} else {
// Transfer negotiation failed or the team still cannot afford the new player
transferMarketTextArea.append("Hour " + hour + ": ");
transferMarketTextArea.append(anotherPlayer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

}
}

}
}
}
} else {
// Transfer window is closed
transferMarketTextArea.append("Transfer window is closed.\n");

// End the transfer window when the deadline is reached
break;
}

// Update the transfer market display every hour
try {
Thread.sleep(1000); // Sleep for 1 second to simulate the passing of time
} catch (InterruptedException e) {
e.printStackTrace();
}
}

// Display free agent transfers
transferMarketTextArea.append("\nFree Agent Transfers:\n");
for (Map.Entry<Player, Team> entry : freeAgentTransfers.entrySet()) {
Player player = entry.getKey();
Team destinationTeam = entry.getValue();
transferMarketTextArea.append(player.getName() + " transferred as a free agent to " + destinationTeam.getName() + "\n");
}

// Display money spent by each team
transferMarketTextArea.append("\nMoney Spent by Teams:\n");
for (Map.Entry<Team, Double> entry : moneySpent.entrySet()) {
Team team = entry.getKey();
double spentAmount = entry.getValue();
transferMarketTextArea.append(team.getName() + ": $" + spentAmount + "m\n");
}

// Display players bought by each team
transferMarketTextArea.append("\nPlayers Bought by Teams:\n");
for (Map.Entry<Team, List<Player>> entry : playersBought.entrySet()) {
Team team = entry.getKey();
List<Player> boughtPlayers = entry.getValue();
transferMarketTextArea.append(team.getName() + ":\n");
for (Player player : boughtPlayers) {
transferMarketTextArea.append(" " + player.getName() + " (" + player.getPosition() + ") - $" + player.getTransferPrice() + "m\n");
}
}

// At the end of the transfer window, assign remaining players to teams
for (Player player : availablePlayers) {
int randomTeamIndex = new Random().nextInt(teams.size());
Team destinationTeam = teams.get(randomTeamIndex);
destinationTeam.addPlayer(player);
}

// Update the team list and transfer market display
updateTeamRosters();
displayTransferMarket();
}

public void updateTeamRosters() {
for (Team team : teams) {
// Get the existing roster for the team
List<Player> existingRoster = teamRosters.getOrDefault(team.getName(), new ArrayList<>());

// Get the current players in the team object (including transferred players)
List<Player> currentPlayers = team.getPlayers();

// Add new players to the existing roster (checking for duplicates by name)
for (Player player : currentPlayers) {
boolean playerExists = false;
for (Player existingPlayer : existingRoster) {
if (existingPlayer.getName().equals(player.getName())) {
playerExists = true;
break;
}
}
if (!playerExists) {
existingRoster.add(player);
}
}

// Update the teamRosters map
teamRosters.put(team.getName(), existingRoster);
}
}

private int simulateNegotiation(int initialFee) {
int currentFee = initialFee;
double minFee = initialFee * 0.75; // Selling club won't accept less than 75% of initial fee
int maxRounds = 5;
Random random = new Random();

for (int round = 1; round <= maxRounds; round++) {
// Buyer's new offer
int offer = (int) (currentFee * (0.95 - random.nextDouble() * 0.1)); // Reduce 5-15%

// Simulate selling club's acceptance based on offer
double acceptanceProbability = (double) offer / initialFee; // Higher offer, higher chance
double randomValue = random.nextDouble();

if (offer >= minFee && randomValue <= acceptanceProbability) {
// Selling club accepts the offer
return offer;
} else {
// Selling club rejects, adjust current fee for next round
currentFee = offer;
}
}
// Negotiation failed
return 0;
}

public void openViewTeam() {
// Create a dialog to select a team to view
String[] teamNames = new String[teams.size()];
for (int i = 0; i < teams.size(); i++) {
teamNames[i] = teams.get(i).getName();
}

String selectedTeam = (String) JOptionPane.showInputDialog(this, "Select a team to view:", "View Team",
JOptionPane.QUESTION_MESSAGE, null, teamNames, teamNames[0]);

if (selectedTeam != null) {
// Find the selected team and display its information
for (Team team : teams) {
if (team.getName().equals(selectedTeam)) {
showTeamInfo(team);
break;
}
}
}
}

public void showTeamInfo(Team team) {
JFrame teamInfoFrame = new JFrame(team.getName() + " Formation");
teamInfoFrame.setSize(600, 600);
teamInfoFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
teamInfoFrame.setLocationRelativeTo(this);

JPanel teamInfoPanel = new JPanel(new BorderLayout());
teamInfoFrame.add(teamInfoPanel);

JLabel formationLabel = new JLabel("Formation: " + team.getFormation());
formationLabel.setFont(new Font("Arial", Font.BOLD, 20));
formationLabel.setHorizontalAlignment(SwingConstants.CENTER);
teamInfoPanel.add(formationLabel, BorderLayout.NORTH);

JPanel playerInfoPanel = new JPanel(new GridLayout(0, 2, 10, 10)); // 2 columns for player name and rating
teamInfoPanel.add(playerInfoPanel, BorderLayout.CENTER);

List<Player> teamRoster = teamRosters.get(team.getName());

if (teamRoster != null) {
for (Player player : teamRoster) {
JLabel playerNameLabel = new JLabel(player.getName());
playerNameLabel.setFont(new Font("Arial", Font.PLAIN, 16));
playerNameLabel.setHorizontalAlignment(SwingConstants.LEFT);

JLabel playerRatingLabel = new JLabel("Rating: " + player.getRating());
playerRatingLabel.setFont(new Font("Arial", Font.PLAIN, 16));
playerRatingLabel.setHorizontalAlignment(SwingConstants.RIGHT);

playerInfoPanel.add(playerNameLabel);
playerInfoPanel.add(playerRatingLabel);
}
}

teamInfoFrame.setVisible(true);
}

public void updateTeamList() {
StringBuilder transferMarketStringBuilder = new StringBuilder();

for (Team team : teams) {
transferMarketStringBuilder.append(team.getName()).append(" - Budget: $")
.append(team.getTransferBudget()).append("m\n");

List<Player> teamRoster = teamRosters.get(team.getName());
if (teamRoster != null) {
for (Player player : teamRoster) {
transferMarketStringBuilder.append(" ").append(player.getName()).append(" (")
.append(player.getPosition()).append(")\n");
}
}

transferMarketStringBuilder.append("\n");
}

transferMarketTextArea.setText(transferMarketStringBuilder.toString());
}

public void displayTransferMarket() {
updateTeamList();
repaint();
}

class Match {
private Team homeTeam;
private Team awayTeam;
private int homeGoals;
private int awayGoals;

public Match(Team homeTeam, Team awayTeam) {
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
homeGoals = 0;
awayGoals = 0;
}

public Team getHomeTeam() {
return homeTeam;
}

public Team getAwayTeam() {
return awayTeam;
}

public int getHomeGoals() {
return homeGoals;
}

public int getAwayGoals() {
return awayGoals;
}

public void setResult(int homeGoals, int awayGoals) {
this.homeGoals = homeGoals;
this.awayGoals = awayGoals;
}
}

public void simulateSeason() {
// Generate fixtures
fixtures = generateFixtures(teams);

int matchDayNumber = 1;

for (List<Match> matchDay : fixtures) {
simulateMatchDay(matchDay, matchDayNumber);
matchDayNumber++;
// Update team standings after each match day if needed
updateTeamStandings();
}

displaySeasonSummary();
}

private List<List<Match>> generateFixtures(List<Team> teams) {
int numTeams = teams.size();

List<List<Match>> fixtures = new ArrayList<>();

List<Team> teamsCopy = new ArrayList<>(teams); // Make a copy to avoid modifying the original list

if (numTeams % 2 != 0) {
// If the number of teams is odd, add a dummy team which will get a bye
teamsCopy.add(null);
numTeams++;
}

int totalRounds = numTeams - 1;
int matchesPerRound = numTeams / 2;

for (int round = 0; round < totalRounds; round++) {
List<Match> roundMatches = new ArrayList<>();

for (int match = 0; match < matchesPerRound; match++) {
int home = (round + match) % (numTeams - 1);
int away = (numTeams - 1 - match + round) % (numTeams - 1);

if (match == 0) {
away = numTeams - 1;
}

Team homeTeam = teamsCopy.get(home);
Team awayTeam = teamsCopy.get(away);

if (homeTeam != null && awayTeam != null) {
Match fixture = new Match(homeTeam, awayTeam);
roundMatches.add(fixture);
}
}

fixtures.add(roundMatches);
}

// Now create return matches (second half of the season)
List<List<Match>> returnFixtures = new ArrayList<>();

for (List<Match> roundMatches : fixtures) {
List<Match> returnRound = new ArrayList<>();
for (Match match : roundMatches) {
// Swap home and away teams
Match returnMatch = new Match(match.getAwayTeam(), match.getHomeTeam());
returnRound.add(returnMatch);
}
returnFixtures.add(returnRound);
}

// Combine the fixtures into the full season
fixtures.addAll(returnFixtures);

return fixtures;
}

private void simulateMatchDay(List<Match> matchDay, int matchDayNumber) {
for (Match match : matchDay) {
simulateMatch(match);
}

// Optionally, print match day results
displayMatchDayResults(matchDay, matchDayNumber);
}

private void simulateMatch(Match match) {
Team homeTeam = match.getHomeTeam();
Team awayTeam = match.getAwayTeam();

double homeTeamRating = getTeamRating(homeTeam);
double awayTeamRating = getTeamRating(awayTeam);

// Apply home advantage
homeTeamRating *= 1.1; // Increase home team rating by 10%

// Expected goals calculation
double homeExpectedGoals = (homeTeamRating / (homeTeamRating + awayTeamRating)) * 2.0;
double awayExpectedGoals = (awayTeamRating / (homeTeamRating + awayTeamRating)) * 1.5;

// Simulate goals using a Poisson distribution approximation
int homeGoals = simulateGoals(homeExpectedGoals);
int awayGoals = simulateGoals(awayExpectedGoals);

// Set the match result
match.setResult(homeGoals, awayGoals);

// Update team statistics
homeTeam.updateStatistics(homeGoals, awayGoals);
awayTeam.updateStatistics(awayGoals, homeGoals); // Swap for the away team

// Update wins, draws, losses
if (homeGoals > awayGoals) {
homeTeam.incrementWins();
awayTeam.incrementLosses();
} else if (homeGoals < awayGoals) {
awayTeam.incrementWins();
homeTeam.incrementLosses();
} else {
homeTeam.incrementDraws();
awayTeam.incrementDraws();
}
}

private double getTeamRating(Team team) {
int sumRatings = 0;
for (Player player : team.getPlayers()) {
sumRatings += player.getRating();
}
if (team.getPlayers().size() > 0) {
return (double) sumRatings / team.getPlayers().size();
} else {
return 1.0; // Assign minimal rating if no players
}
}

private int simulateGoals(double lambda) {
// Simulate goals using a Poisson distribution approximation
double L = Math.exp(-lambda);
double p = 1.0;
int k = 0;

do {
k++;
p *= Math.random();
} while (p > L);

return k - 1;
}

private void displayMatchDayResults(List<Match> matchDay, int matchDayNumber) {
StringBuilder resultsBuilder = new StringBuilder();
resultsBuilder.append("Match Day ").append(matchDayNumber).append(" Results:\n");

for (Match match : matchDay) {
resultsBuilder.append(match.getHomeTeam().getName())
.append(" ")
.append(match.getHomeGoals())
.append(" - ")
.append(match.getAwayGoals())
.append(" ")
.append(match.getAwayTeam().getName())
.append("\n");
}

// Optionally, display the results in the GUI, or print to console
// For now, let's print to console
System.out.println(resultsBuilder.toString());
}

private void updateTeamStandings() {
// Calculate team standings based on points and goal difference
List<Team> sortedTeams = new ArrayList<>(teams);
sortedTeams.sort(Comparator
.comparingInt((Team team) -> calculateTeamPoints(team))
.thenComparingInt(Team::getGoalDifference)
.reversed());

// Update team standings map
teamStandings.clear();
for (int i = 0; i < sortedTeams.size(); i++) {
teamStandings.put(sortedTeams.get(i).getName(), i + 1);
}
}

private int calculateTeamPoints(Team team) {
// Calculate team points based on wins, draws, and losses
int wins = team.getWins();
int draws = team.getDraws();
return (wins * 3) + draws;
}

private void displaySeasonSummary() {
// Display season summary including final standings
List<Team> sortedTeams = new ArrayList<>(teams);
sortedTeams.sort(Comparator
.comparingInt((Team team) -> calculateTeamPoints(team))
.thenComparingInt(Team::getGoalDifference)
.reversed());

StringBuilder summaryBuilder = new StringBuilder();
summaryBuilder.append("\n\nFinal Standings:\n\n");

summaryBuilder.append(String.format("%-20s %-10s %-5s %-5s %-5s %-5s %-5s %-10s%n",
"Team", "Points", "W", "D", "L", "GF", "GA", "GD"));
summaryBuilder.append(String.format("%-20s %-10s %-5s %-5s %-5s %-5s %-5s %-10s%n",
"--------------------", "------", "-", "-", "-", "--", "--", "----"));

for (Team team : sortedTeams) {
summaryBuilder.append(String.format("%-20s %-10d %-5d %-5d %-5d %-5d %-5d %-10d%n",
team.getName(), calculateTeamPoints(team), team.getWins(), team.getDraws(),
team.getLosses(), team.getGoalsScored(), team.getGoalsConceded(), team.getGoalDifference()));
}
System.out.println(summaryBuilder.toString());

// Display team statistics and player performances
for (Team team : teams) {
summaryBuilder.append("\n").append("Team: ").append(team.getName()).append("\n");
summaryBuilder.append("Points: ").append(calculateTeamPoints(team)).append("\n");
summaryBuilder.append("Goals Scored: ").append(team.getGoalsScored()).append("\n");
summaryBuilder.append("Goals Conceded: ").append(team.getGoalsConceded()).append("\n");

// Display player performances
summaryBuilder.append("\nPlayer Performances:\n");
List<Player> teamRoster = team.getPlayers();
for (Player player : teamRoster) {
summaryBuilder.append(player.getName()).append(" - Rating: ").append(player.simulatePlayerPerformance()).append("\n");
}
}

JTextArea seasonSummaryTextArea = new JTextArea(summaryBuilder.toString());
seasonSummaryTextArea.setFont(new Font("Consolas", Font.PLAIN, 16));

JScrollPane seasonSummaryScrollPane = new JScrollPane(seasonSummaryTextArea);
seasonSummaryScrollPane.setBounds(800, 50, 400, 600);
add(seasonSummaryScrollPane);

repaint();
}

private Team getTeamByName(String name) {
for (Team team : teams) {
if (team.getName().equals(name)) {
return team;
}
}
return null;
}
}

class Team {

private String name;
private double transferBudget;
private String formation;
private List<Player> players;
private int wins;
private int draws;
private int losses;
private int goalsScored;
private int goalsConceded;

public Team(String name, double transferBudget, String formation) {
this.name = name;
this.transferBudget = transferBudget;
this.formation = formation;
this.players = new ArrayList<>();
this.wins = 0;
this.draws = 0;
this.losses = 0;
this.goalsScored = 0;
this.goalsConceded = 0;
}

public String getName() {
return name;
}

public double getTransferBudget() {
return transferBudget;
}

public String getFormation() {
return formation;
}

public List<Player> getPlayers() {
return players;
}

public void addPlayer(Player player) {
if (!players.contains(player)) {
players.add(player);
}
}

public void deductTransferBudget(double amount) {
transferBudget -= amount;
}

public int getGoalsScored() {
return goalsScored;
}

public int getGoalsConceded() {
return goalsConceded;
}

public int getGoalDifference() {
return goalsScored - goalsConceded;
}

public void incrementWins() {
wins++;
}

public void incrementDraws() {
draws++;
}

public void incrementLosses() {
losses++;
}

public void updateStatistics(int goalsScored, int goalsConceded) {
this.goalsScored += goalsScored;
this.goalsConceded += goalsConceded;
}

public int getWins() {
return wins;
}

public int getDraws() {
return draws;
}

public int getLosses() {
return losses;
}
}

class Player {

private String name;
private String position;
private int transferPrice;
private int rating;
private String previousClub;
private String transferStatus;
private boolean isFreeAgent;
private boolean isPicked;

public Player(String name, String position, int transferPrice, int rating, String previousClub) {
this.name = name;
this.position = position;
this.transferPrice = transferPrice;
this.rating = rating;
this.previousClub = previousClub;
this.transferStatus = "Unassigned";
}

public String getName() {
return name;
}

public String getPosition() {
return position;
}

public int getTransferPrice() {
return transferPrice;
}

public int getRating() {
return rating;
}

public String getPreviousClub() {
return previousClub;
}

public void setPreviousClub(String previousClub) {
this.previousClub = previousClub;
}

public String getTransferStatus() {
return transferStatus;
}

public void setTransferStatus(String transferStatus) {
this.transferStatus = transferStatus;
}

public boolean isFreeAgent() {
return isFreeAgent;
}

public void setFreeAgent(boolean freeAgent) {
isFreeAgent = freeAgent;
}

public boolean isPicked() {
return isPicked;
}

public void setPicked(boolean picked) {
isPicked = picked;
}

public int simulatePlayerPerformance() {
Random random = new Random();
int performanceVariation = random.nextInt(5) - 2; // Variation between -2 and +2
int performance = this.rating + performanceVariation;
performance = Math.max(1, performance); // Ensure minimum performance
return performance;
}

}