Code edit (1 edits merged)
Please save this source code
User prompt
Turkish Super League: Soccer Simulations
Initial prompt
Let's play a football game, let's have all the teams of the Turkish Super League in it, let the teams' squad be in the game, let the scores be realistic, let the market value, OVR and potential of the players be determined according to their age, out of 100.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { selectedTeam: 0, season: 1, matchDay: 1, teamData: undefined }); /**** * Classes ****/ var Button = Container.expand(function (label, callback, width, height) { var self = Container.call(this); width = width || 300; height = height || 120; var button = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: width, height: height }); var labelText = new Text2(label, { size: 40, fill: 0xFFFFFF }); labelText.anchor.set(0.5, 0.5); self.addChild(labelText); self.setLabel = function (newLabel) { labelText.setText(newLabel); }; self.down = function (x, y, obj) { // Visual feedback button.tint = 0x3742fa; if (callback) { callback(); } }; self.up = function (x, y, obj) { button.tint = 0xffffff; }; return self; }); var Match = Container.expand(function (homeTeam, awayTeam) { var self = Container.call(this); self.homeTeam = homeTeam; self.awayTeam = awayTeam; self.homeGoals = 0; self.awayGoals = 0; self.isPlayed = false; self.matchTime = 0; self.events = []; var matchCard = self.attachAsset('matchCard', { anchorX: 0.5, anchorY: 0.5 }); var homeText = new Text2(homeTeam.name, { size: 50, fill: 0xFFFFFF }); homeText.anchor.set(1, 0.5); homeText.x = -100; self.addChild(homeText); var scoreText = new Text2("vs", { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0.5); self.addChild(scoreText); var awayText = new Text2(awayTeam.name, { size: 50, fill: 0xFFFFFF }); awayText.anchor.set(0, 0.5); awayText.x = 100; self.addChild(awayText); self.simulateMatch = function () { if (self.isPlayed) { return; } LK.getSound('whistle').play(); var homeStrength = self.homeTeam.strength; var awayStrength = self.awayTeam.strength; // Calculate home advantage (about 10% boost) homeStrength = Math.floor(homeStrength * 1.1); // Calculate expected goals based on team strength var homeExpectedGoals = homeStrength / 20 + Math.random() * 1.5; var awayExpectedGoals = awayStrength / 25 + Math.random() * 1.2; // Generate actual goals with Poisson-like distribution self.homeGoals = Math.floor(getPoissonRandom(homeExpectedGoals)); self.awayGoals = Math.floor(getPoissonRandom(awayExpectedGoals)); // Update team statistics self.homeTeam.goalsFor += self.homeGoals; self.homeTeam.goalsAgainst += self.awayGoals; self.awayTeam.goalsFor += self.awayGoals; self.awayTeam.goalsAgainst += self.homeGoals; if (self.homeGoals > self.awayGoals) { self.homeTeam.points += 3; self.homeTeam.wins += 1; self.awayTeam.losses += 1; } else if (self.homeGoals < self.awayGoals) { self.awayTeam.points += 3; self.awayTeam.wins += 1; self.homeTeam.losses += 1; } else { self.homeTeam.points += 1; self.awayTeam.points += 1; self.homeTeam.draws += 1; self.awayTeam.draws += 1; } // Generate match events self.generateEvents(); // Update the score display scoreText.setText(self.homeGoals + " - " + self.awayGoals); self.isPlayed = true; }; self.generateEvents = function () { // Generate goal events for (var i = 0; i < self.homeGoals; i++) { var minute = Math.floor(Math.random() * 90) + 1; var scorerIndex = Math.floor(Math.random() * self.homeTeam.players.length); var scorer = self.homeTeam.players[scorerIndex]; self.events.push({ type: "goal", team: self.homeTeam.name, player: scorer.name, minute: minute }); } for (var i = 0; i < self.awayGoals; i++) { var minute = Math.floor(Math.random() * 90) + 1; var scorerIndex = Math.floor(Math.random() * self.awayTeam.players.length); var scorer = self.awayTeam.players[scorerIndex]; self.events.push({ type: "goal", team: self.awayTeam.name, player: scorer.name, minute: minute }); } // Sort events by minute self.events.sort(function (a, b) { return a.minute - b.minute; }); }; self.getEventText = function () { var text = ""; for (var i = 0; i < self.events.length; i++) { var event = self.events[i]; if (event.type === "goal") { text += event.minute + "' GOAL! " + event.player + " (" + event.team + ")\n"; } } return text; }; self.down = function (x, y, obj) { if (!self.isPlayed && currentScreen === "fixtures") { self.simulateMatch(); // Check if this was the selected team's match var isUserTeam = self.homeTeam.name === teams[userTeamIndex].name || self.awayTeam.name === teams[userTeamIndex].name; if (isUserTeam) { showMatchDetails(self); } // Check if all matches for current matchday are played var allPlayed = true; for (var i = 0; i < currentFixtures.length; i++) { if (!currentFixtures[i].isPlayed) { allPlayed = false; break; } } if (allPlayed) { showNextMatchdayButton(); } } }; return self; }); var MatchDetailView = Container.expand(function (match) { var self = Container.call(this); var background = self.attachAsset('field', { anchorX: 0.5, anchorY: 0.5, width: 1800, height: 2400 }); background.alpha = 0.7; var titleText = new Text2(match.homeTeam.name + " vs " + match.awayTeam.name, { size: 60, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.y = -1000; self.addChild(titleText); var scoreText = new Text2(match.homeGoals + " - " + match.awayGoals, { size: 100, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.y = -900; self.addChild(scoreText); var eventsText = new Text2(match.getEventText(), { size: 40, fill: 0xFFFFFF }); eventsText.anchor.set(0.5, 0); eventsText.y = -750; self.addChild(eventsText); var closeButton = new Button("CONTINUE", function () { game.removeChild(self); }); closeButton.y = 900; self.addChild(closeButton); return self; }); var Player = Container.expand(function (playerData) { var self = Container.call(this); self.name = playerData.name; self.position = playerData.position; self.age = playerData.age; self.ovr = playerData.ovr; self.potential = playerData.potential; self.value = playerData.value; self.updateSkills = function () { // Adjust player skills based on age and potential if (self.age < 30 && self.ovr < self.potential) { self.ovr += Math.floor(Math.random() * 3); if (self.ovr > self.potential) { self.ovr = self.potential; } } else if (self.age > 30) { self.ovr -= Math.floor(Math.random() * 2); } // Update player value based on OVR and age var ageModifier = 1; if (self.age > 30) { ageModifier = 0.8; } else if (self.age < 23) { ageModifier = 1.2; } self.value = Math.floor(self.ovr * 100000 * ageModifier); }; return self; }); var Team = Container.expand(function (teamData) { var self = Container.call(this); self.data = teamData; self.name = teamData.name; self.players = teamData.players; self.points = 0; self.wins = 0; self.draws = 0; self.losses = 0; self.goalsFor = 0; self.goalsAgainst = 0; self.calculateTeamStrength = function () { var totalStrength = 0; for (var i = 0; i < self.players.length; i++) { totalStrength += self.players[i].ovr; } return Math.floor(totalStrength / self.players.length); }; self.strength = self.calculateTeamStrength(); return self; }); var TeamCard = Container.expand(function (team, index) { var self = Container.call(this); var isSelected = index === userTeamIndex; var card = self.attachAsset('teamCard', { anchorX: 0.5, anchorY: 0.5 }); if (isSelected) { card.tint = 0x3742fa; } var nameText = new Text2(team.name, { size: 40, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0); nameText.y = -80; self.addChild(nameText); var strengthText = new Text2("Team Rating: " + team.strength, { size: 30, fill: 0xFFFFFF }); strengthText.anchor.set(0.5, 0.5); strengthText.y = 0; self.addChild(strengthText); var positionText = new Text2("", { size: 30, fill: 0xFFFFFF }); positionText.anchor.set(0.5, 1); positionText.y = 70; self.addChild(positionText); self.updatePosition = function (position) { positionText.setText(position + ordinalSuffix(position)); }; self.down = function (x, y, obj) { if (currentScreen === "teamSelection") { userTeamIndex = index; storage.selectedTeam = index; showScreen("mainMenu"); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x005e30 }); /**** * Game Code ****/ // Global Variables var teams = []; var fixtures = []; var userTeamIndex = storage.selectedTeam || 0; var currentScreen = "loading"; var currentFixtures = []; var currentMatchday = storage.matchDay || 1; var season = storage.season || 1; // UI Elements var title = new Text2("Turkish Super League", { size: 90, fill: 0xFFFFFF }); title.anchor.set(0.5, 0); title.y = 150; LK.gui.top.addChild(title); var subtitle = new Text2("Manager Simulation", { size: 60, fill: 0xFFFFFF }); subtitle.anchor.set(0.5, 0); subtitle.y = 250; LK.gui.top.addChild(subtitle); var seasonText = new Text2("Season " + season, { size: 50, fill: 0xFFFFFF }); seasonText.anchor.set(0.5, 0); seasonText.y = 320; LK.gui.top.addChild(seasonText); var matchdayText = new Text2("Matchday " + currentMatchday, { size: 40, fill: 0xFFFFFF }); matchdayText.anchor.set(0.5, 0); matchdayText.y = 380; LK.gui.top.addChild(matchdayText); var statusText = new Text2("", { size: 40, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0); statusText.y = 440; LK.gui.top.addChild(statusText); // Helper Functions function getPoissonRandom(mean) { var L = Math.exp(-mean); var p = 1.0; var k = 0; do { k++; p *= Math.random(); } while (p > L); return k - 1; } function ordinalSuffix(i) { var j = i % 10, k = i % 100; if (j == 1 && k != 11) { return "st"; } if (j == 2 && k != 12) { return "nd"; } if (j == 3 && k != 13) { return "rd"; } return "th"; } function createTeams() { // Initialize with sample Turkish Super League teams // In a real game, this would be loaded from a data file var teamData = [{ name: "Galatasaray", players: generatePlayers(85, 75, 12) }, { name: "Fenerbahçe", players: generatePlayers(84, 76, 12) }, { name: "Beşiktaş", players: generatePlayers(83, 74, 12) }, { name: "Trabzonspor", players: generatePlayers(80, 72, 11) }, { name: "Başakşehir", players: generatePlayers(79, 73, 11) }, { name: "Adana Demirspor", players: generatePlayers(78, 70, 10) }, { name: "Konyaspor", players: generatePlayers(77, 69, 10) }, { name: "Alanyaspor", players: generatePlayers(76, 70, 9) }, { name: "Antalyaspor", players: generatePlayers(75, 69, 9) }, { name: "Kayserispor", players: generatePlayers(74, 68, 8) }, { name: "Gaziantep FK", players: generatePlayers(73, 67, 8) }, { name: "Kasımpaşa", players: generatePlayers(72, 66, 7) }, { name: "Sivasspor", players: generatePlayers(71, 65, 7) }, { name: "Hatayspor", players: generatePlayers(70, 64, 6) }, { name: "Giresunspor", players: generatePlayers(69, 62, 6) }, { name: "Ümraniyespor", players: generatePlayers(68, 60, 5) }, { name: "Ankaragücü", players: generatePlayers(67, 61, 5) }, { name: "İstanbulspor", players: generatePlayers(66, 60, 4) }]; for (var i = 0; i < teamData.length; i++) { var team = new Team(teamData[i]); teams.push(team); } // Save team data to storage if (!storage.teamData) { storage.teamData = teamData; } } function generatePlayers(maxRating, avgRating, stars) { var players = []; var positions = ["GK", "DEF", "MID", "FWD"]; var numPlayers = 24; // Create 3 star players for (var i = 0; i < stars; i++) { var rating = Math.floor(Math.random() * 5) + maxRating - 5; var age = Math.floor(Math.random() * 8) + 25; var position = positions[Math.floor(Math.random() * 3) + 1]; // Don't make star GKs var potential = rating + Math.floor(Math.random() * 5); players.push(new Player({ name: "Star Player " + (i + 1), position: position, age: age, ovr: rating, potential: potential, value: rating * 100000 })); } // Fill the rest with regular players for (var i = stars; i < numPlayers; i++) { var rating = Math.floor(Math.random() * 10) + avgRating - 5; var age = Math.floor(Math.random() * 15) + 18; var position = positions[Math.floor(Math.random() * positions.length)]; var potential = rating; if (age < 25) { potential += Math.floor(Math.random() * 10); } players.push(new Player({ name: "Player " + (i + 1), position: position, age: age, ovr: rating, potential: potential, value: rating * 50000 })); } return players; } function createFixtures() { fixtures = []; // Generate fixtures for a round-robin tournament // Each team plays against every other team twice (home and away) var matchdays = (teams.length - 1) * 2; for (var matchday = 1; matchday <= matchdays; matchday++) { fixtures[matchday] = []; for (var i = 0; i < teams.length / 2; i++) { var home, away; if (matchday <= teams.length - 1) { // First half of the season home = (matchday + i) % (teams.length - 1); away = (teams.length - 1 - i + matchday) % (teams.length - 1); // Last team stays fixed if (i === 0) { away = teams.length - 1; } } else { // Second half of the season - reverse home/away var firstHalfMatchday = matchday - (teams.length - 1); away = (firstHalfMatchday + i) % (teams.length - 1); home = (teams.length - 1 - i + firstHalfMatchday) % (teams.length - 1); // Last team stays fixed if (i === 0) { home = teams.length - 1; } } var match = new Match(teams[home], teams[away]); fixtures[matchday].push(match); } } } function showScreen(screenName) { currentScreen = screenName; // Clear the game container first while (game.children.length > 0) { game.removeChild(game.children[0]); } // Update UI elements title.visible = true; subtitle.visible = true; if (screenName === "loading") { statusText.setText("Loading game data..."); LK.setTimeout(function () { if (!storage.teamData) { showScreen("teamSelection"); } else { showScreen("mainMenu"); } }, 1000); } else if (screenName === "teamSelection") { subtitle.setText("Select Your Team"); statusText.setText(""); var xPos = -700; var yPos = 600; var counter = 0; for (var i = 0; i < teams.length; i++) { var teamCard = new TeamCard(teams[i], i); teamCard.x = xPos + counter % 4 * 450; teamCard.y = yPos + Math.floor(counter / 4) * 250; game.addChild(teamCard); counter++; } } else if (screenName === "mainMenu") { subtitle.setText("Main Menu"); statusText.setText("Managing " + teams[userTeamIndex].name); var viewTableButton = new Button("LEAGUE TABLE", function () { showScreen("table"); }); viewTableButton.y = 700; game.addChild(viewTableButton); var viewFixturesButton = new Button("FIXTURES", function () { showScreen("fixtures"); }); viewFixturesButton.y = 850; game.addChild(viewFixturesButton); var viewSquadButton = new Button("SQUAD", function () { showScreen("squad"); }); viewSquadButton.y = 1000; game.addChild(viewSquadButton); // Add a field background var field = LK.getAsset('field', { anchorX: 0.5, anchorY: 0.5 }); field.alpha = 0.3; game.addChildAt(field, 0); field.x = 2048 / 2; field.y = 2732 / 2; // Start ambient sound LK.playMusic('stadiumAmbience'); } else if (screenName === "table") { subtitle.setText("League Table"); // Sort teams by points, goal difference, goals scored var sortedTeams = teams.slice(); sortedTeams.sort(function (a, b) { if (a.points !== b.points) { return b.points - a.points; } var aGD = a.goalsFor - a.goalsAgainst; var bGD = b.goalsFor - b.goalsAgainst; if (aGD !== bGD) { return bGD - aGD; } return b.goalsFor - a.goalsFor; }); var tableY = 500; var headerText = new Text2("Pos Team P W D L GF GA GD Pts", { size: 30, fill: 0xFFFFFF }); headerText.anchor.set(0, 0.5); headerText.x = 200; headerText.y = tableY; game.addChild(headerText); for (var i = 0; i < sortedTeams.length; i++) { var team = sortedTeams[i]; var played = team.wins + team.draws + team.losses; var gd = team.goalsFor - team.goalsAgainst; var gdSign = gd > 0 ? "+" : ""; var highlight = team === teams[userTeamIndex]; var rowText = new Text2((i + 1).toString().padEnd(3) + team.name.padEnd(20) + played.toString().padEnd(5) + team.wins.toString().padEnd(5) + team.draws.toString().padEnd(5) + team.losses.toString().padEnd(5) + team.goalsFor.toString().padEnd(5) + team.goalsAgainst.toString().padEnd(5) + (gdSign + gd).toString().padEnd(5) + team.points.toString(), { size: 28, fill: highlight ? "#ffff00" : "#ffffff" }); rowText.anchor.set(0, 0.5); rowText.x = 200; rowText.y = tableY + (i + 1) * 50; game.addChild(rowText); // Update TeamCard position information for (var j = 0; j < game.children.length; j++) { if (game.children[j] instanceof TeamCard && game.children[j].data === team) { game.children[j].updatePosition(i + 1); } } } var backButton = new Button("BACK", function () { showScreen("mainMenu"); }); backButton.y = 2400; game.addChild(backButton); } else if (screenName === "fixtures") { subtitle.setText("Fixtures - Matchday " + currentMatchday); // Display current matchday fixtures currentFixtures = fixtures[currentMatchday]; var startY = 600; for (var i = 0; i < currentFixtures.length; i++) { var match = currentFixtures[i]; match.x = 2048 / 2; match.y = startY + i * 250; game.addChild(match); } var backButton = new Button("BACK", function () { showScreen("mainMenu"); }); backButton.y = 2400; game.addChild(backButton); // Show "Next Matchday" button if all matches are played var allPlayed = true; for (var i = 0; i < currentFixtures.length; i++) { if (!currentFixtures[i].isPlayed) { allPlayed = false; break; } } if (allPlayed) { showNextMatchdayButton(); } } else if (screenName === "squad") { subtitle.setText("Squad - " + teams[userTeamIndex].name); var team = teams[userTeamIndex]; var startY = 600; var headerText = new Text2("Name Pos Age OVR POT Value", { size: 30, fill: 0xFFFFFF }); headerText.anchor.set(0, 0.5); headerText.x = 200; headerText.y = startY - 60; game.addChild(headerText); // Sort players by overall rating var sortedPlayers = team.players.slice(); sortedPlayers.sort(function (a, b) { return b.ovr - a.ovr; }); for (var i = 0; i < sortedPlayers.length; i++) { var player = sortedPlayers[i]; var valueFormatted = (player.value / 1000000).toFixed(1) + "M"; var rowText = new Text2(player.name.padEnd(18) + player.position.padEnd(6) + player.age.toString().padEnd(6) + player.ovr.toString().padEnd(6) + player.potential.toString().padEnd(6) + valueFormatted, { size: 28, fill: 0xFFFFFF }); rowText.anchor.set(0, 0.5); rowText.x = 200; rowText.y = startY + i * 50; game.addChild(rowText); } var backButton = new Button("BACK", function () { showScreen("mainMenu"); }); backButton.y = 2400; game.addChild(backButton); } } function showNextMatchdayButton() { var nextButton = new Button("NEXT MATCHDAY", function () { currentMatchday++; if (currentMatchday > (teams.length - 1) * 2) { // End of season endSeason(); } else { storage.matchDay = currentMatchday; matchdayText.setText("Matchday " + currentMatchday); showScreen("fixtures"); } }); nextButton.y = 2250; game.addChild(nextButton); } function showMatchDetails(match) { var detailView = new MatchDetailView(match); detailView.x = 2048 / 2; detailView.y = 2732 / 2; game.addChild(detailView); if (match.homeGoals > 0 || match.awayGoals > 0) { LK.getSound('goal').play(); } } function endSeason() { season++; currentMatchday = 1; storage.season = season; storage.matchDay = currentMatchday; // Reset team stats but keep player development for (var i = 0; i < teams.length; i++) { teams[i].points = 0; teams[i].wins = 0; teams[i].draws = 0; teams[i].losses = 0; teams[i].goalsFor = 0; teams[i].goalsAgainst = 0; // Age players and develop them for (var j = 0; j < teams[i].players.length; j++) { var player = teams[i].players[j]; player.age++; player.updateSkills(); } } // Regenerate fixtures for the new season createFixtures(); // Update UI seasonText.setText("Season " + season); matchdayText.setText("Matchday " + currentMatchday); // Show season summary var summaryView = new Container(); var background = LK.getAsset('field', { anchorX: 0.5, anchorY: 0.5 }); background.alpha = 0.7; summaryView.addChild(background); var titleText = new Text2("Season " + (season - 1) + " Complete!", { size: 70, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.y = -1000; summaryView.addChild(titleText); // Sort teams by points to find champion var sortedTeams = teams.slice(); sortedTeams.sort(function (a, b) { if (a.points !== b.points) { return b.points - a.points; } var aGD = a.goalsFor - a.goalsAgainst; var bGD = b.goalsFor - b.goalsAgainst; if (aGD !== bGD) { return bGD - aGD; } return b.goalsFor - a.goalsFor; }); var championText = new Text2("Champion: " + sortedTeams[0].name, { size: 60, fill: 0xFFFF00 }); championText.anchor.set(0.5, 0); championText.y = -900; summaryView.addChild(championText); var userTeamPos = sortedTeams.indexOf(teams[userTeamIndex]) + 1; var userTeamText = new Text2("Your Team: " + teams[userTeamIndex].name + " (" + userTeamPos + ordinalSuffix(userTeamPos) + " place)", { size: 50, fill: 0xFFFFFF }); userTeamText.anchor.set(0.5, 0); userTeamText.y = -800; summaryView.addChild(userTeamText); var continueButton = new Button("CONTINUE TO SEASON " + season, function () { game.removeChild(summaryView); showScreen("fixtures"); }); continueButton.y = 900; summaryView.addChild(continueButton); summaryView.x = 2048 / 2; summaryView.y = 2732 / 2; game.addChild(summaryView); } // Initialize Game function initGame() { // Create teams and fixtures createTeams(); createFixtures(); // Start with team selection or main menu showScreen("loading"); } // Game update game.update = function () { // Nothing to do in the update loop for now // This simulation game is mostly event-driven }; // Start the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
selectedTeam: 0,
season: 1,
matchDay: 1,
teamData: undefined
});
/****
* Classes
****/
var Button = Container.expand(function (label, callback, width, height) {
var self = Container.call(this);
width = width || 300;
height = height || 120;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: width,
height: height
});
var labelText = new Text2(label, {
size: 40,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
self.setLabel = function (newLabel) {
labelText.setText(newLabel);
};
self.down = function (x, y, obj) {
// Visual feedback
button.tint = 0x3742fa;
if (callback) {
callback();
}
};
self.up = function (x, y, obj) {
button.tint = 0xffffff;
};
return self;
});
var Match = Container.expand(function (homeTeam, awayTeam) {
var self = Container.call(this);
self.homeTeam = homeTeam;
self.awayTeam = awayTeam;
self.homeGoals = 0;
self.awayGoals = 0;
self.isPlayed = false;
self.matchTime = 0;
self.events = [];
var matchCard = self.attachAsset('matchCard', {
anchorX: 0.5,
anchorY: 0.5
});
var homeText = new Text2(homeTeam.name, {
size: 50,
fill: 0xFFFFFF
});
homeText.anchor.set(1, 0.5);
homeText.x = -100;
self.addChild(homeText);
var scoreText = new Text2("vs", {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0.5);
self.addChild(scoreText);
var awayText = new Text2(awayTeam.name, {
size: 50,
fill: 0xFFFFFF
});
awayText.anchor.set(0, 0.5);
awayText.x = 100;
self.addChild(awayText);
self.simulateMatch = function () {
if (self.isPlayed) {
return;
}
LK.getSound('whistle').play();
var homeStrength = self.homeTeam.strength;
var awayStrength = self.awayTeam.strength;
// Calculate home advantage (about 10% boost)
homeStrength = Math.floor(homeStrength * 1.1);
// Calculate expected goals based on team strength
var homeExpectedGoals = homeStrength / 20 + Math.random() * 1.5;
var awayExpectedGoals = awayStrength / 25 + Math.random() * 1.2;
// Generate actual goals with Poisson-like distribution
self.homeGoals = Math.floor(getPoissonRandom(homeExpectedGoals));
self.awayGoals = Math.floor(getPoissonRandom(awayExpectedGoals));
// Update team statistics
self.homeTeam.goalsFor += self.homeGoals;
self.homeTeam.goalsAgainst += self.awayGoals;
self.awayTeam.goalsFor += self.awayGoals;
self.awayTeam.goalsAgainst += self.homeGoals;
if (self.homeGoals > self.awayGoals) {
self.homeTeam.points += 3;
self.homeTeam.wins += 1;
self.awayTeam.losses += 1;
} else if (self.homeGoals < self.awayGoals) {
self.awayTeam.points += 3;
self.awayTeam.wins += 1;
self.homeTeam.losses += 1;
} else {
self.homeTeam.points += 1;
self.awayTeam.points += 1;
self.homeTeam.draws += 1;
self.awayTeam.draws += 1;
}
// Generate match events
self.generateEvents();
// Update the score display
scoreText.setText(self.homeGoals + " - " + self.awayGoals);
self.isPlayed = true;
};
self.generateEvents = function () {
// Generate goal events
for (var i = 0; i < self.homeGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.homeTeam.players.length);
var scorer = self.homeTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.homeTeam.name,
player: scorer.name,
minute: minute
});
}
for (var i = 0; i < self.awayGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.awayTeam.players.length);
var scorer = self.awayTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.awayTeam.name,
player: scorer.name,
minute: minute
});
}
// Sort events by minute
self.events.sort(function (a, b) {
return a.minute - b.minute;
});
};
self.getEventText = function () {
var text = "";
for (var i = 0; i < self.events.length; i++) {
var event = self.events[i];
if (event.type === "goal") {
text += event.minute + "' GOAL! " + event.player + " (" + event.team + ")\n";
}
}
return text;
};
self.down = function (x, y, obj) {
if (!self.isPlayed && currentScreen === "fixtures") {
self.simulateMatch();
// Check if this was the selected team's match
var isUserTeam = self.homeTeam.name === teams[userTeamIndex].name || self.awayTeam.name === teams[userTeamIndex].name;
if (isUserTeam) {
showMatchDetails(self);
}
// Check if all matches for current matchday are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
}
};
return self;
});
var MatchDetailView = Container.expand(function (match) {
var self = Container.call(this);
var background = self.attachAsset('field', {
anchorX: 0.5,
anchorY: 0.5,
width: 1800,
height: 2400
});
background.alpha = 0.7;
var titleText = new Text2(match.homeTeam.name + " vs " + match.awayTeam.name, {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
self.addChild(titleText);
var scoreText = new Text2(match.homeGoals + " - " + match.awayGoals, {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = -900;
self.addChild(scoreText);
var eventsText = new Text2(match.getEventText(), {
size: 40,
fill: 0xFFFFFF
});
eventsText.anchor.set(0.5, 0);
eventsText.y = -750;
self.addChild(eventsText);
var closeButton = new Button("CONTINUE", function () {
game.removeChild(self);
});
closeButton.y = 900;
self.addChild(closeButton);
return self;
});
var Player = Container.expand(function (playerData) {
var self = Container.call(this);
self.name = playerData.name;
self.position = playerData.position;
self.age = playerData.age;
self.ovr = playerData.ovr;
self.potential = playerData.potential;
self.value = playerData.value;
self.updateSkills = function () {
// Adjust player skills based on age and potential
if (self.age < 30 && self.ovr < self.potential) {
self.ovr += Math.floor(Math.random() * 3);
if (self.ovr > self.potential) {
self.ovr = self.potential;
}
} else if (self.age > 30) {
self.ovr -= Math.floor(Math.random() * 2);
}
// Update player value based on OVR and age
var ageModifier = 1;
if (self.age > 30) {
ageModifier = 0.8;
} else if (self.age < 23) {
ageModifier = 1.2;
}
self.value = Math.floor(self.ovr * 100000 * ageModifier);
};
return self;
});
var Team = Container.expand(function (teamData) {
var self = Container.call(this);
self.data = teamData;
self.name = teamData.name;
self.players = teamData.players;
self.points = 0;
self.wins = 0;
self.draws = 0;
self.losses = 0;
self.goalsFor = 0;
self.goalsAgainst = 0;
self.calculateTeamStrength = function () {
var totalStrength = 0;
for (var i = 0; i < self.players.length; i++) {
totalStrength += self.players[i].ovr;
}
return Math.floor(totalStrength / self.players.length);
};
self.strength = self.calculateTeamStrength();
return self;
});
var TeamCard = Container.expand(function (team, index) {
var self = Container.call(this);
var isSelected = index === userTeamIndex;
var card = self.attachAsset('teamCard', {
anchorX: 0.5,
anchorY: 0.5
});
if (isSelected) {
card.tint = 0x3742fa;
}
var nameText = new Text2(team.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = -80;
self.addChild(nameText);
var strengthText = new Text2("Team Rating: " + team.strength, {
size: 30,
fill: 0xFFFFFF
});
strengthText.anchor.set(0.5, 0.5);
strengthText.y = 0;
self.addChild(strengthText);
var positionText = new Text2("", {
size: 30,
fill: 0xFFFFFF
});
positionText.anchor.set(0.5, 1);
positionText.y = 70;
self.addChild(positionText);
self.updatePosition = function (position) {
positionText.setText(position + ordinalSuffix(position));
};
self.down = function (x, y, obj) {
if (currentScreen === "teamSelection") {
userTeamIndex = index;
storage.selectedTeam = index;
showScreen("mainMenu");
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x005e30
});
/****
* Game Code
****/
// Global Variables
var teams = [];
var fixtures = [];
var userTeamIndex = storage.selectedTeam || 0;
var currentScreen = "loading";
var currentFixtures = [];
var currentMatchday = storage.matchDay || 1;
var season = storage.season || 1;
// UI Elements
var title = new Text2("Turkish Super League", {
size: 90,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.y = 150;
LK.gui.top.addChild(title);
var subtitle = new Text2("Manager Simulation", {
size: 60,
fill: 0xFFFFFF
});
subtitle.anchor.set(0.5, 0);
subtitle.y = 250;
LK.gui.top.addChild(subtitle);
var seasonText = new Text2("Season " + season, {
size: 50,
fill: 0xFFFFFF
});
seasonText.anchor.set(0.5, 0);
seasonText.y = 320;
LK.gui.top.addChild(seasonText);
var matchdayText = new Text2("Matchday " + currentMatchday, {
size: 40,
fill: 0xFFFFFF
});
matchdayText.anchor.set(0.5, 0);
matchdayText.y = 380;
LK.gui.top.addChild(matchdayText);
var statusText = new Text2("", {
size: 40,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
statusText.y = 440;
LK.gui.top.addChild(statusText);
// Helper Functions
function getPoissonRandom(mean) {
var L = Math.exp(-mean);
var p = 1.0;
var k = 0;
do {
k++;
p *= Math.random();
} while (p > L);
return k - 1;
}
function ordinalSuffix(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return "st";
}
if (j == 2 && k != 12) {
return "nd";
}
if (j == 3 && k != 13) {
return "rd";
}
return "th";
}
function createTeams() {
// Initialize with sample Turkish Super League teams
// In a real game, this would be loaded from a data file
var teamData = [{
name: "Galatasaray",
players: generatePlayers(85, 75, 12)
}, {
name: "Fenerbahçe",
players: generatePlayers(84, 76, 12)
}, {
name: "Beşiktaş",
players: generatePlayers(83, 74, 12)
}, {
name: "Trabzonspor",
players: generatePlayers(80, 72, 11)
}, {
name: "Başakşehir",
players: generatePlayers(79, 73, 11)
}, {
name: "Adana Demirspor",
players: generatePlayers(78, 70, 10)
}, {
name: "Konyaspor",
players: generatePlayers(77, 69, 10)
}, {
name: "Alanyaspor",
players: generatePlayers(76, 70, 9)
}, {
name: "Antalyaspor",
players: generatePlayers(75, 69, 9)
}, {
name: "Kayserispor",
players: generatePlayers(74, 68, 8)
}, {
name: "Gaziantep FK",
players: generatePlayers(73, 67, 8)
}, {
name: "Kasımpaşa",
players: generatePlayers(72, 66, 7)
}, {
name: "Sivasspor",
players: generatePlayers(71, 65, 7)
}, {
name: "Hatayspor",
players: generatePlayers(70, 64, 6)
}, {
name: "Giresunspor",
players: generatePlayers(69, 62, 6)
}, {
name: "Ümraniyespor",
players: generatePlayers(68, 60, 5)
}, {
name: "Ankaragücü",
players: generatePlayers(67, 61, 5)
}, {
name: "İstanbulspor",
players: generatePlayers(66, 60, 4)
}];
for (var i = 0; i < teamData.length; i++) {
var team = new Team(teamData[i]);
teams.push(team);
}
// Save team data to storage
if (!storage.teamData) {
storage.teamData = teamData;
}
}
function generatePlayers(maxRating, avgRating, stars) {
var players = [];
var positions = ["GK", "DEF", "MID", "FWD"];
var numPlayers = 24;
// Create 3 star players
for (var i = 0; i < stars; i++) {
var rating = Math.floor(Math.random() * 5) + maxRating - 5;
var age = Math.floor(Math.random() * 8) + 25;
var position = positions[Math.floor(Math.random() * 3) + 1]; // Don't make star GKs
var potential = rating + Math.floor(Math.random() * 5);
players.push(new Player({
name: "Star Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 100000
}));
}
// Fill the rest with regular players
for (var i = stars; i < numPlayers; i++) {
var rating = Math.floor(Math.random() * 10) + avgRating - 5;
var age = Math.floor(Math.random() * 15) + 18;
var position = positions[Math.floor(Math.random() * positions.length)];
var potential = rating;
if (age < 25) {
potential += Math.floor(Math.random() * 10);
}
players.push(new Player({
name: "Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 50000
}));
}
return players;
}
function createFixtures() {
fixtures = [];
// Generate fixtures for a round-robin tournament
// Each team plays against every other team twice (home and away)
var matchdays = (teams.length - 1) * 2;
for (var matchday = 1; matchday <= matchdays; matchday++) {
fixtures[matchday] = [];
for (var i = 0; i < teams.length / 2; i++) {
var home, away;
if (matchday <= teams.length - 1) {
// First half of the season
home = (matchday + i) % (teams.length - 1);
away = (teams.length - 1 - i + matchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
away = teams.length - 1;
}
} else {
// Second half of the season - reverse home/away
var firstHalfMatchday = matchday - (teams.length - 1);
away = (firstHalfMatchday + i) % (teams.length - 1);
home = (teams.length - 1 - i + firstHalfMatchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
home = teams.length - 1;
}
}
var match = new Match(teams[home], teams[away]);
fixtures[matchday].push(match);
}
}
}
function showScreen(screenName) {
currentScreen = screenName;
// Clear the game container first
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
// Update UI elements
title.visible = true;
subtitle.visible = true;
if (screenName === "loading") {
statusText.setText("Loading game data...");
LK.setTimeout(function () {
if (!storage.teamData) {
showScreen("teamSelection");
} else {
showScreen("mainMenu");
}
}, 1000);
} else if (screenName === "teamSelection") {
subtitle.setText("Select Your Team");
statusText.setText("");
var xPos = -700;
var yPos = 600;
var counter = 0;
for (var i = 0; i < teams.length; i++) {
var teamCard = new TeamCard(teams[i], i);
teamCard.x = xPos + counter % 4 * 450;
teamCard.y = yPos + Math.floor(counter / 4) * 250;
game.addChild(teamCard);
counter++;
}
} else if (screenName === "mainMenu") {
subtitle.setText("Main Menu");
statusText.setText("Managing " + teams[userTeamIndex].name);
var viewTableButton = new Button("LEAGUE TABLE", function () {
showScreen("table");
});
viewTableButton.y = 700;
game.addChild(viewTableButton);
var viewFixturesButton = new Button("FIXTURES", function () {
showScreen("fixtures");
});
viewFixturesButton.y = 850;
game.addChild(viewFixturesButton);
var viewSquadButton = new Button("SQUAD", function () {
showScreen("squad");
});
viewSquadButton.y = 1000;
game.addChild(viewSquadButton);
// Add a field background
var field = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
field.alpha = 0.3;
game.addChildAt(field, 0);
field.x = 2048 / 2;
field.y = 2732 / 2;
// Start ambient sound
LK.playMusic('stadiumAmbience');
} else if (screenName === "table") {
subtitle.setText("League Table");
// Sort teams by points, goal difference, goals scored
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var tableY = 500;
var headerText = new Text2("Pos Team P W D L GF GA GD Pts", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = tableY;
game.addChild(headerText);
for (var i = 0; i < sortedTeams.length; i++) {
var team = sortedTeams[i];
var played = team.wins + team.draws + team.losses;
var gd = team.goalsFor - team.goalsAgainst;
var gdSign = gd > 0 ? "+" : "";
var highlight = team === teams[userTeamIndex];
var rowText = new Text2((i + 1).toString().padEnd(3) + team.name.padEnd(20) + played.toString().padEnd(5) + team.wins.toString().padEnd(5) + team.draws.toString().padEnd(5) + team.losses.toString().padEnd(5) + team.goalsFor.toString().padEnd(5) + team.goalsAgainst.toString().padEnd(5) + (gdSign + gd).toString().padEnd(5) + team.points.toString(), {
size: 28,
fill: highlight ? "#ffff00" : "#ffffff"
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = tableY + (i + 1) * 50;
game.addChild(rowText);
// Update TeamCard position information
for (var j = 0; j < game.children.length; j++) {
if (game.children[j] instanceof TeamCard && game.children[j].data === team) {
game.children[j].updatePosition(i + 1);
}
}
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
} else if (screenName === "fixtures") {
subtitle.setText("Fixtures - Matchday " + currentMatchday);
// Display current matchday fixtures
currentFixtures = fixtures[currentMatchday];
var startY = 600;
for (var i = 0; i < currentFixtures.length; i++) {
var match = currentFixtures[i];
match.x = 2048 / 2;
match.y = startY + i * 250;
game.addChild(match);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
// Show "Next Matchday" button if all matches are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
} else if (screenName === "squad") {
subtitle.setText("Squad - " + teams[userTeamIndex].name);
var team = teams[userTeamIndex];
var startY = 600;
var headerText = new Text2("Name Pos Age OVR POT Value", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = startY - 60;
game.addChild(headerText);
// Sort players by overall rating
var sortedPlayers = team.players.slice();
sortedPlayers.sort(function (a, b) {
return b.ovr - a.ovr;
});
for (var i = 0; i < sortedPlayers.length; i++) {
var player = sortedPlayers[i];
var valueFormatted = (player.value / 1000000).toFixed(1) + "M";
var rowText = new Text2(player.name.padEnd(18) + player.position.padEnd(6) + player.age.toString().padEnd(6) + player.ovr.toString().padEnd(6) + player.potential.toString().padEnd(6) + valueFormatted, {
size: 28,
fill: 0xFFFFFF
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = startY + i * 50;
game.addChild(rowText);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
}
}
function showNextMatchdayButton() {
var nextButton = new Button("NEXT MATCHDAY", function () {
currentMatchday++;
if (currentMatchday > (teams.length - 1) * 2) {
// End of season
endSeason();
} else {
storage.matchDay = currentMatchday;
matchdayText.setText("Matchday " + currentMatchday);
showScreen("fixtures");
}
});
nextButton.y = 2250;
game.addChild(nextButton);
}
function showMatchDetails(match) {
var detailView = new MatchDetailView(match);
detailView.x = 2048 / 2;
detailView.y = 2732 / 2;
game.addChild(detailView);
if (match.homeGoals > 0 || match.awayGoals > 0) {
LK.getSound('goal').play();
}
}
function endSeason() {
season++;
currentMatchday = 1;
storage.season = season;
storage.matchDay = currentMatchday;
// Reset team stats but keep player development
for (var i = 0; i < teams.length; i++) {
teams[i].points = 0;
teams[i].wins = 0;
teams[i].draws = 0;
teams[i].losses = 0;
teams[i].goalsFor = 0;
teams[i].goalsAgainst = 0;
// Age players and develop them
for (var j = 0; j < teams[i].players.length; j++) {
var player = teams[i].players[j];
player.age++;
player.updateSkills();
}
}
// Regenerate fixtures for the new season
createFixtures();
// Update UI
seasonText.setText("Season " + season);
matchdayText.setText("Matchday " + currentMatchday);
// Show season summary
var summaryView = new Container();
var background = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
background.alpha = 0.7;
summaryView.addChild(background);
var titleText = new Text2("Season " + (season - 1) + " Complete!", {
size: 70,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
summaryView.addChild(titleText);
// Sort teams by points to find champion
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var championText = new Text2("Champion: " + sortedTeams[0].name, {
size: 60,
fill: 0xFFFF00
});
championText.anchor.set(0.5, 0);
championText.y = -900;
summaryView.addChild(championText);
var userTeamPos = sortedTeams.indexOf(teams[userTeamIndex]) + 1;
var userTeamText = new Text2("Your Team: " + teams[userTeamIndex].name + " (" + userTeamPos + ordinalSuffix(userTeamPos) + " place)", {
size: 50,
fill: 0xFFFFFF
});
userTeamText.anchor.set(0.5, 0);
userTeamText.y = -800;
summaryView.addChild(userTeamText);
var continueButton = new Button("CONTINUE TO SEASON " + season, function () {
game.removeChild(summaryView);
showScreen("fixtures");
});
continueButton.y = 900;
summaryView.addChild(continueButton);
summaryView.x = 2048 / 2;
summaryView.y = 2732 / 2;
game.addChild(summaryView);
}
// Initialize Game
function initGame() {
// Create teams and fixtures
createTeams();
createFixtures();
// Start with team selection or main menu
showScreen("loading");
}
// Game update
game.update = function () {
// Nothing to do in the update loop for now
// This simulation game is mostly event-driven
};
// Start the game
initGame();