/**** * Classes ****/ // Base class: represents a base in a territory var Base = Container.expand(function () { var self = Container.call(this); self.owner = null; // 0,1,2,3 self.territory = null; // index of territory occupied self.sprite = self.attachAsset('base', { anchorX: 0.5, anchorY: 0.5 }); self.setOwner = function (owner) { self.owner = owner; self.sprite.tint = COUNTRY_COLORS[owner]; }; return self; }); // Territory class: represents a territory on the map var Territory = Container.expand(function () { var self = Container.call(this); self.owner = null; // 0,1,2,3 or null self.index = -1; // index in territories array self.neighbors = []; // indices of adjacent territories self.unit = null; // reference to occupying unit, if any self.base = null; // reference to base, if any // Visual representation self.bg = self.attachAsset('territory', { anchorX: 0.5, anchorY: 0.5 }); // Set color based on owner self.setOwner = function (owner) { self.owner = owner; if (owner === null) { self.bg.tint = 0x888888; } else { self.bg.tint = COUNTRY_COLORS[owner]; } }; // Highlight for selection self.setHighlight = function (on) { self.bg.alpha = on ? 0.7 : 1.0; }; return self; }); // Unit class: represents a unit on the map var Unit = Container.expand(function () { var self = Container.call(this); self.owner = null; // 0,1,2,3 self.territory = null; // index of territory occupied self.hasMoved = false; // true if unit has moved this turn self.sprite = self.attachAsset('unit', { anchorX: 0.5, anchorY: 0.5 }); self.setOwner = function (owner) { self.owner = owner; self.sprite.tint = COUNTRY_COLORS[owner]; }; self.setSelected = function (on) { self.sprite.alpha = on ? 0.7 : 1.0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- QuadraNations: Turn-Based Conquest --- // Four countries: green, blue, red, yellow // Each country will have a base and units, and the map will be divided into territories // Define country colors var COUNTRY_COLORS = [0x2ecc40, 0x0074d9, 0xff4136, 0xffdc00]; // green, blue, red, yellow // Define country names for reference var COUNTRY_NAMES = ['Green', 'Blue', 'Red', 'Yellow']; // Track which country the player controls (set after selection) var playerCountry = null; // Track which countries are AI controlled var aiCountries = [0, 1, 2, 3]; // Track current turn (0: Green, 1: Blue, 2: Red, 3: Yellow) var currentTurn = 0; // Track number of turns elapsed var turnCount = 0; // Show country selection screen before game starts var selectionOverlay = new Container(); selectionOverlay.width = 2048; selectionOverlay.height = 2732; selectionOverlay.x = 0; selectionOverlay.y = 0; selectionOverlay.interactive = true; selectionOverlay.visible = true; game.addChild(selectionOverlay); var selectionText = new Text2('Choose Your Country', { size: 120, fill: 0xFFFFFF }); selectionText.anchor.set(0.5, 0); selectionText.x = 1024; selectionText.y = 300; selectionOverlay.addChild(selectionText); var selectionButtons = []; // Place selection buttons below the map, spaced evenly var buttonAreaY = 2100; var buttonSpacing = 400; var buttonStartX = 400; for (var i = 0; i < 4; i++) { var btn = new Container(); btn.x = buttonStartX + i * buttonSpacing; btn.y = buttonAreaY; btn.width = 250; btn.height = 250; btn.interactive = true; // Button background var btnBg = LK.getAsset('territory', { anchorX: 0.5, anchorY: 0.5 }); btnBg.width = 250; btnBg.height = 250; btnBg.tint = COUNTRY_COLORS[i]; btn.addChild(btnBg); // Button label var btnLabel = new Text2(COUNTRY_NAMES[i], { size: 60, fill: 0x000000 }); btnLabel.anchor.set(0.5, 0.5); btnLabel.x = 0; btnLabel.y = 0; btn.addChild(btnLabel); // Add event handler for selection (function (countryIndex) { btn.down = function (x, y, obj) { // Set player country and AI countries playerCountry = countryIndex; currentTurn = countryIndex; // Start the game from the selected country aiCountries = []; for (var j = 0; j < 4; j++) { if (j !== playerCountry) aiCountries.push(j); } // Visually mark the selected button as chosen (green border) for (var k = 0; k < selectionButtons.length; k++) { var border = selectionButtons[k].getChildByName && selectionButtons[k].getChildByName('border'); if (border) border.visible = false; } // Add a border to the selected button if (!btn.border) { var border = LK.getAsset('territory', { anchorX: 0.5, anchorY: 0.5 }); border.width = 270; border.height = 270; border.tint = 0x00ff00; border.alpha = 0.5; border.name = 'border'; btn.addChild(border); btn.setChildIndex(border, 0); btn.border = border; } btn.border.visible = true; // Hide overlay and start game after a short delay for feedback LK.setTimeout(function () { selectionOverlay.visible = false; selectionOverlay.destroy(); updateTurnIndicator(); }, 200); }; })(i); selectionOverlay.addChild(btn); selectionButtons.push(btn); } // Map setup: 12 territories in a 3x4 grid, each country starts in a corner var territories = []; var units = []; var bases = []; var territoryGrid = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]; // For each territory, define neighbors (adjacent up/down/left/right) function getNeighbors(row, col) { var neighbors = []; if (row > 0) neighbors.push(territoryGrid[row - 1][col]); if (row < 2) neighbors.push(territoryGrid[row + 1][col]); if (col > 0) neighbors.push(territoryGrid[row][col - 1]); if (col < 3) neighbors.push(territoryGrid[row][col + 1]); return neighbors; } // Create territory objects and add to game for (var row = 0; row < 3; row++) { for (var col = 0; col < 4; col++) { var idx = territoryGrid[row][col]; var t = new Territory(); t.index = idx; t.x = 400 + col * 400; t.y = 600 + row * 600; t.width = 350; t.height = 350; t.neighbors = getNeighbors(row, col); t.setOwner(null); game.addChild(t); territories[idx] = t; } } // Assign starting bases and units for each country (corners) var basePositions = [0, 3, 8, 11]; // top-left, top-right, bottom-left, bottom-right for (var i = 0; i < 4; i++) { // Place base var b = new Base(); b.setOwner(i); b.territory = basePositions[i]; b.x = territories[basePositions[i]].x; b.y = territories[basePositions[i]].y; game.addChild(b); bases[i] = b; territories[basePositions[i]].base = b; territories[basePositions[i]].setOwner(i); // Place unit on base var u = new Unit(); u.setOwner(i); u.territory = basePositions[i]; u.x = territories[basePositions[i]].x; u.y = territories[basePositions[i]].y; u.hasMoved = false; game.addChild(u); units.push(u); territories[basePositions[i]].unit = u; } // Add a second unit for each country in adjacent territory var secondUnitPositions = [1, 2, 9, 10]; for (var i = 0; i < 4; i++) { var u2 = new Unit(); u2.setOwner(i); u2.territory = secondUnitPositions[i]; u2.x = territories[secondUnitPositions[i]].x; u2.y = territories[secondUnitPositions[i]].y; u2.hasMoved = false; game.addChild(u2); units.push(u2); territories[secondUnitPositions[i]].unit = u2; territories[secondUnitPositions[i]].setOwner(i); } // Placeholder for selected unit/territory var selectedUnit = null; var selectedTerritory = null; // --- Score tracking variables --- var soldiersDefeated = 0; // Number of enemy soldiers defeated by player var playerSoldiers = 0; // Number of player's own soldiers alive var playerLand = 0; // Number of territories currently owned by player var landTaken = 0; // Number of territories captured from other countries by player var mothers = 0; // Number of 'mothers' (bases) currently owned by player var lastPlayerLand = 0; // For tracking land taken // Placeholder for game state var gameState = 'select'; // 'select', 'move', 'attack', etc. // Placeholder for turn indicator text var turnIndicatorText = new Text2('', { size: 90, fill: 0xFFFFFF }); turnIndicatorText.anchor.set(0.5, 0); LK.gui.top.addChild(turnIndicatorText); // Score display at top right var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); scoreText.x = 2048; // right edge scoreText.y = 0; LK.gui.top.addChild(scoreText); // Helper to update score display function updateScoreDisplay() { var score = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50; scoreText.setText('Score: ' + score); } // Function to update turn indicator function updateTurnIndicator() { turnIndicatorText.setText('Turn: ' + COUNTRY_NAMES[currentTurn]); } updateTurnIndicator(); // Helper: Deselect all units and territories function deselectAll() { for (var i = 0; i < units.length; i++) units[i].setSelected(false); for (var i = 0; i < territories.length; i++) territories[i].setHighlight(false); selectedUnit = null; selectedTerritory = null; } // Helper: Get all units for a country function getUnitsForCountry(country) { var arr = []; for (var i = 0; i < units.length; i++) { if (units[i].owner === country) arr.push(units[i]); } return arr; } // Helper: End turn and advance to next player function endTurn() { // Reset all units' hasMoved for next player for (var i = 0; i < units.length; i++) { if (units[i].owner === currentTurn) units[i].hasMoved = false; } // Update player score variables before turn changes if (playerCountry !== null) { // Count player's soldiers playerSoldiers = 0; for (var i = 0; i < units.length; i++) { if (units[i].owner === playerCountry) playerSoldiers++; } // Count player's land playerLand = 0; for (var i = 0; i < territories.length; i++) { if (territories[i].owner === playerCountry) playerLand++; } // Count player's bases (mothers) mothers = 0; for (var i = 0; i < bases.length; i++) { if (bases[i] && bases[i].owner === playerCountry) mothers++; } } lastPlayerLand = playerLand; // Next player currentTurn = (currentTurn + 1) % 4; turnCount++; updateTurnIndicator(); updateScoreDisplay(); deselectAll(); // If player has no units, skip turn if (getUnitsForCountry(currentTurn).length === 0) { endTurn(); return; } // If it's an AI country, make AI move and end turn automatically if (aiCountries.indexOf(currentTurn) !== -1) { // Simple AI: for each unit, move to a random valid neighbor (attack if possible) var aiUnits = getUnitsForCountry(currentTurn); for (var i = 0; i < aiUnits.length; i++) { var unit = aiUnits[i]; if (unit.hasMoved) continue; var t = territories[unit.territory]; // Find possible moves (empty or enemy-occupied neighbors) var possible = []; for (var j = 0; j < t.neighbors.length; j++) { var nIdx = t.neighbors[j]; var n = territories[nIdx]; if (!n.unit || n.unit && n.unit.owner !== currentTurn) { possible.push(n); } } if (possible.length > 0) { // Prefer attacking if possible var attackTargets = []; for (var k = 0; k < possible.length; k++) { if (possible[k].unit && possible[k].unit.owner !== currentTurn) { attackTargets.push(possible[k]); } } var dest = null; if (attackTargets.length > 0) { dest = attackTargets[Math.floor(Math.random() * attackTargets.length)]; } else { dest = possible[Math.floor(Math.random() * possible.length)]; } // If enemy unit, attack if (dest.unit && dest.unit.owner !== currentTurn) { var enemy = dest.unit; enemy.destroy(); for (var m = 0; m < units.length; m++) { if (units[m] === enemy) { units.splice(m, 1); break; } } dest.unit = null; } // Move unit territories[unit.territory].unit = null; unit.territory = dest.index; unit.x = dest.x; unit.y = dest.y; dest.unit = unit; dest.setOwner(currentTurn); unit.hasMoved = true; } } // Check win if (checkWin()) return; // End AI turn automatically endTurn(); return; } } // Helper: Check win condition function checkWin() { var alive = []; for (var i = 0; i < 4; i++) { if (getUnitsForCountry(i).length > 0) alive.push(i); } // If the player's country is eliminated if (playerCountry !== null && getUnitsForCountry(playerCountry).length === 0) { // Calculate score before game over var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50; LK.setScore(finalScore); LK.showGameOver(); return true; } // If only one country remains and it's the player, show win if (alive.length === 1 && playerCountry !== null && alive[0] === playerCountry) { // Calculate score before win var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50; LK.setScore(finalScore); LK.showYouWin(); return true; } // If only one country remains and it's not the player, show lose if (alive.length === 1 && playerCountry !== null && alive[0] !== playerCountry) { // Calculate score before game over var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50; LK.setScore(finalScore); LK.showGameOver(); return true; } return false; } // Handle tap on territory or unit game.down = function (x, y, obj) { // Block input if playerCountry not chosen yet if (playerCountry === null) return; // Find which territory was tapped var tappedTerritory = null; for (var i = 0; i < territories.length; i++) { var t = territories[i]; var dx = x - t.x; var dy = y - t.y; if (Math.abs(dx) < t.width / 2 && Math.abs(dy) < t.height / 2) { tappedTerritory = t; break; } } if (!tappedTerritory) return; // If selecting a unit to move if (gameState === 'select') { if (tappedTerritory.unit && tappedTerritory.unit.owner === currentTurn && !tappedTerritory.unit.hasMoved) { deselectAll(); selectedUnit = tappedTerritory.unit; selectedUnit.setSelected(true); // Highlight possible moves for (var j = 0; j < tappedTerritory.neighbors.length; j++) { var nIdx = tappedTerritory.neighbors[j]; var n = territories[nIdx]; // Can move if empty or enemy unit present if (!n.unit || n.unit && n.unit.owner !== currentTurn) { n.setHighlight(true); } } gameState = 'move'; } } else if (gameState === 'move') { // If tapped a highlighted territory, move or attack if (selectedUnit && tappedTerritory.bg.alpha === 0.7) { // If enemy unit, attack if (tappedTerritory.unit && tappedTerritory.unit.owner !== currentTurn) { // Remove enemy unit var enemy = tappedTerritory.unit; // If player is attacking, increment soldiersDefeated if (currentTurn === playerCountry) { soldiersDefeated++; } enemy.destroy(); for (var k = 0; k < units.length; k++) { if (units[k] === enemy) { units.splice(k, 1); break; } } tappedTerritory.unit = null; } // Track land taken if player captures enemy territory if (currentTurn === playerCountry && tappedTerritory.owner !== null && tappedTerritory.owner !== playerCountry) { landTaken++; } // Move unit territories[selectedUnit.territory].unit = null; selectedUnit.territory = tappedTerritory.index; selectedUnit.x = tappedTerritory.x; selectedUnit.y = tappedTerritory.y; tappedTerritory.unit = selectedUnit; tappedTerritory.setOwner(currentTurn); selectedUnit.hasMoved = true; deselectAll(); updateScoreDisplay(); // Check win if (checkWin()) return; gameState = 'select'; } else { // Tapped elsewhere, cancel move deselectAll(); gameState = 'select'; } } }; // End turn on double tap anywhere game.up = function (x, y, obj) { // Block input if playerCountry not chosen yet if (playerCountry === null) return; // If all units have moved, allow end turn var allMoved = true; var myUnits = getUnitsForCountry(currentTurn); for (var i = 0; i < myUnits.length; i++) { if (!myUnits[i].hasMoved) allMoved = false; } if (allMoved) { endTurn(); } }; // Main update loop (not much needed, but could be used for animations) game.update = function () { // Defensive: ensure units are always on top of territory for (var i = 0; i < units.length; i++) { if (units[i].parent !== game) continue; game.setChildIndex(units[i], game.children.length - 1); } };
/****
* Classes
****/
// Base class: represents a base in a territory
var Base = Container.expand(function () {
var self = Container.call(this);
self.owner = null; // 0,1,2,3
self.territory = null; // index of territory occupied
self.sprite = self.attachAsset('base', {
anchorX: 0.5,
anchorY: 0.5
});
self.setOwner = function (owner) {
self.owner = owner;
self.sprite.tint = COUNTRY_COLORS[owner];
};
return self;
});
// Territory class: represents a territory on the map
var Territory = Container.expand(function () {
var self = Container.call(this);
self.owner = null; // 0,1,2,3 or null
self.index = -1; // index in territories array
self.neighbors = []; // indices of adjacent territories
self.unit = null; // reference to occupying unit, if any
self.base = null; // reference to base, if any
// Visual representation
self.bg = self.attachAsset('territory', {
anchorX: 0.5,
anchorY: 0.5
});
// Set color based on owner
self.setOwner = function (owner) {
self.owner = owner;
if (owner === null) {
self.bg.tint = 0x888888;
} else {
self.bg.tint = COUNTRY_COLORS[owner];
}
};
// Highlight for selection
self.setHighlight = function (on) {
self.bg.alpha = on ? 0.7 : 1.0;
};
return self;
});
// Unit class: represents a unit on the map
var Unit = Container.expand(function () {
var self = Container.call(this);
self.owner = null; // 0,1,2,3
self.territory = null; // index of territory occupied
self.hasMoved = false; // true if unit has moved this turn
self.sprite = self.attachAsset('unit', {
anchorX: 0.5,
anchorY: 0.5
});
self.setOwner = function (owner) {
self.owner = owner;
self.sprite.tint = COUNTRY_COLORS[owner];
};
self.setSelected = function (on) {
self.sprite.alpha = on ? 0.7 : 1.0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// --- QuadraNations: Turn-Based Conquest ---
// Four countries: green, blue, red, yellow
// Each country will have a base and units, and the map will be divided into territories
// Define country colors
var COUNTRY_COLORS = [0x2ecc40, 0x0074d9, 0xff4136, 0xffdc00]; // green, blue, red, yellow
// Define country names for reference
var COUNTRY_NAMES = ['Green', 'Blue', 'Red', 'Yellow'];
// Track which country the player controls (set after selection)
var playerCountry = null;
// Track which countries are AI controlled
var aiCountries = [0, 1, 2, 3];
// Track current turn (0: Green, 1: Blue, 2: Red, 3: Yellow)
var currentTurn = 0;
// Track number of turns elapsed
var turnCount = 0;
// Show country selection screen before game starts
var selectionOverlay = new Container();
selectionOverlay.width = 2048;
selectionOverlay.height = 2732;
selectionOverlay.x = 0;
selectionOverlay.y = 0;
selectionOverlay.interactive = true;
selectionOverlay.visible = true;
game.addChild(selectionOverlay);
var selectionText = new Text2('Choose Your Country', {
size: 120,
fill: 0xFFFFFF
});
selectionText.anchor.set(0.5, 0);
selectionText.x = 1024;
selectionText.y = 300;
selectionOverlay.addChild(selectionText);
var selectionButtons = [];
// Place selection buttons below the map, spaced evenly
var buttonAreaY = 2100;
var buttonSpacing = 400;
var buttonStartX = 400;
for (var i = 0; i < 4; i++) {
var btn = new Container();
btn.x = buttonStartX + i * buttonSpacing;
btn.y = buttonAreaY;
btn.width = 250;
btn.height = 250;
btn.interactive = true;
// Button background
var btnBg = LK.getAsset('territory', {
anchorX: 0.5,
anchorY: 0.5
});
btnBg.width = 250;
btnBg.height = 250;
btnBg.tint = COUNTRY_COLORS[i];
btn.addChild(btnBg);
// Button label
var btnLabel = new Text2(COUNTRY_NAMES[i], {
size: 60,
fill: 0x000000
});
btnLabel.anchor.set(0.5, 0.5);
btnLabel.x = 0;
btnLabel.y = 0;
btn.addChild(btnLabel);
// Add event handler for selection
(function (countryIndex) {
btn.down = function (x, y, obj) {
// Set player country and AI countries
playerCountry = countryIndex;
currentTurn = countryIndex; // Start the game from the selected country
aiCountries = [];
for (var j = 0; j < 4; j++) {
if (j !== playerCountry) aiCountries.push(j);
}
// Visually mark the selected button as chosen (green border)
for (var k = 0; k < selectionButtons.length; k++) {
var border = selectionButtons[k].getChildByName && selectionButtons[k].getChildByName('border');
if (border) border.visible = false;
}
// Add a border to the selected button
if (!btn.border) {
var border = LK.getAsset('territory', {
anchorX: 0.5,
anchorY: 0.5
});
border.width = 270;
border.height = 270;
border.tint = 0x00ff00;
border.alpha = 0.5;
border.name = 'border';
btn.addChild(border);
btn.setChildIndex(border, 0);
btn.border = border;
}
btn.border.visible = true;
// Hide overlay and start game after a short delay for feedback
LK.setTimeout(function () {
selectionOverlay.visible = false;
selectionOverlay.destroy();
updateTurnIndicator();
}, 200);
};
})(i);
selectionOverlay.addChild(btn);
selectionButtons.push(btn);
}
// Map setup: 12 territories in a 3x4 grid, each country starts in a corner
var territories = [];
var units = [];
var bases = [];
var territoryGrid = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]];
// For each territory, define neighbors (adjacent up/down/left/right)
function getNeighbors(row, col) {
var neighbors = [];
if (row > 0) neighbors.push(territoryGrid[row - 1][col]);
if (row < 2) neighbors.push(territoryGrid[row + 1][col]);
if (col > 0) neighbors.push(territoryGrid[row][col - 1]);
if (col < 3) neighbors.push(territoryGrid[row][col + 1]);
return neighbors;
}
// Create territory objects and add to game
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 4; col++) {
var idx = territoryGrid[row][col];
var t = new Territory();
t.index = idx;
t.x = 400 + col * 400;
t.y = 600 + row * 600;
t.width = 350;
t.height = 350;
t.neighbors = getNeighbors(row, col);
t.setOwner(null);
game.addChild(t);
territories[idx] = t;
}
}
// Assign starting bases and units for each country (corners)
var basePositions = [0, 3, 8, 11]; // top-left, top-right, bottom-left, bottom-right
for (var i = 0; i < 4; i++) {
// Place base
var b = new Base();
b.setOwner(i);
b.territory = basePositions[i];
b.x = territories[basePositions[i]].x;
b.y = territories[basePositions[i]].y;
game.addChild(b);
bases[i] = b;
territories[basePositions[i]].base = b;
territories[basePositions[i]].setOwner(i);
// Place unit on base
var u = new Unit();
u.setOwner(i);
u.territory = basePositions[i];
u.x = territories[basePositions[i]].x;
u.y = territories[basePositions[i]].y;
u.hasMoved = false;
game.addChild(u);
units.push(u);
territories[basePositions[i]].unit = u;
}
// Add a second unit for each country in adjacent territory
var secondUnitPositions = [1, 2, 9, 10];
for (var i = 0; i < 4; i++) {
var u2 = new Unit();
u2.setOwner(i);
u2.territory = secondUnitPositions[i];
u2.x = territories[secondUnitPositions[i]].x;
u2.y = territories[secondUnitPositions[i]].y;
u2.hasMoved = false;
game.addChild(u2);
units.push(u2);
territories[secondUnitPositions[i]].unit = u2;
territories[secondUnitPositions[i]].setOwner(i);
}
// Placeholder for selected unit/territory
var selectedUnit = null;
var selectedTerritory = null;
// --- Score tracking variables ---
var soldiersDefeated = 0; // Number of enemy soldiers defeated by player
var playerSoldiers = 0; // Number of player's own soldiers alive
var playerLand = 0; // Number of territories currently owned by player
var landTaken = 0; // Number of territories captured from other countries by player
var mothers = 0; // Number of 'mothers' (bases) currently owned by player
var lastPlayerLand = 0; // For tracking land taken
// Placeholder for game state
var gameState = 'select'; // 'select', 'move', 'attack', etc.
// Placeholder for turn indicator text
var turnIndicatorText = new Text2('', {
size: 90,
fill: 0xFFFFFF
});
turnIndicatorText.anchor.set(0.5, 0);
LK.gui.top.addChild(turnIndicatorText);
// Score display at top right
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = 2048; // right edge
scoreText.y = 0;
LK.gui.top.addChild(scoreText);
// Helper to update score display
function updateScoreDisplay() {
var score = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50;
scoreText.setText('Score: ' + score);
}
// Function to update turn indicator
function updateTurnIndicator() {
turnIndicatorText.setText('Turn: ' + COUNTRY_NAMES[currentTurn]);
}
updateTurnIndicator();
// Helper: Deselect all units and territories
function deselectAll() {
for (var i = 0; i < units.length; i++) units[i].setSelected(false);
for (var i = 0; i < territories.length; i++) territories[i].setHighlight(false);
selectedUnit = null;
selectedTerritory = null;
}
// Helper: Get all units for a country
function getUnitsForCountry(country) {
var arr = [];
for (var i = 0; i < units.length; i++) {
if (units[i].owner === country) arr.push(units[i]);
}
return arr;
}
// Helper: End turn and advance to next player
function endTurn() {
// Reset all units' hasMoved for next player
for (var i = 0; i < units.length; i++) {
if (units[i].owner === currentTurn) units[i].hasMoved = false;
}
// Update player score variables before turn changes
if (playerCountry !== null) {
// Count player's soldiers
playerSoldiers = 0;
for (var i = 0; i < units.length; i++) {
if (units[i].owner === playerCountry) playerSoldiers++;
}
// Count player's land
playerLand = 0;
for (var i = 0; i < territories.length; i++) {
if (territories[i].owner === playerCountry) playerLand++;
}
// Count player's bases (mothers)
mothers = 0;
for (var i = 0; i < bases.length; i++) {
if (bases[i] && bases[i].owner === playerCountry) mothers++;
}
}
lastPlayerLand = playerLand;
// Next player
currentTurn = (currentTurn + 1) % 4;
turnCount++;
updateTurnIndicator();
updateScoreDisplay();
deselectAll();
// If player has no units, skip turn
if (getUnitsForCountry(currentTurn).length === 0) {
endTurn();
return;
}
// If it's an AI country, make AI move and end turn automatically
if (aiCountries.indexOf(currentTurn) !== -1) {
// Simple AI: for each unit, move to a random valid neighbor (attack if possible)
var aiUnits = getUnitsForCountry(currentTurn);
for (var i = 0; i < aiUnits.length; i++) {
var unit = aiUnits[i];
if (unit.hasMoved) continue;
var t = territories[unit.territory];
// Find possible moves (empty or enemy-occupied neighbors)
var possible = [];
for (var j = 0; j < t.neighbors.length; j++) {
var nIdx = t.neighbors[j];
var n = territories[nIdx];
if (!n.unit || n.unit && n.unit.owner !== currentTurn) {
possible.push(n);
}
}
if (possible.length > 0) {
// Prefer attacking if possible
var attackTargets = [];
for (var k = 0; k < possible.length; k++) {
if (possible[k].unit && possible[k].unit.owner !== currentTurn) {
attackTargets.push(possible[k]);
}
}
var dest = null;
if (attackTargets.length > 0) {
dest = attackTargets[Math.floor(Math.random() * attackTargets.length)];
} else {
dest = possible[Math.floor(Math.random() * possible.length)];
}
// If enemy unit, attack
if (dest.unit && dest.unit.owner !== currentTurn) {
var enemy = dest.unit;
enemy.destroy();
for (var m = 0; m < units.length; m++) {
if (units[m] === enemy) {
units.splice(m, 1);
break;
}
}
dest.unit = null;
}
// Move unit
territories[unit.territory].unit = null;
unit.territory = dest.index;
unit.x = dest.x;
unit.y = dest.y;
dest.unit = unit;
dest.setOwner(currentTurn);
unit.hasMoved = true;
}
}
// Check win
if (checkWin()) return;
// End AI turn automatically
endTurn();
return;
}
}
// Helper: Check win condition
function checkWin() {
var alive = [];
for (var i = 0; i < 4; i++) {
if (getUnitsForCountry(i).length > 0) alive.push(i);
}
// If the player's country is eliminated
if (playerCountry !== null && getUnitsForCountry(playerCountry).length === 0) {
// Calculate score before game over
var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50;
LK.setScore(finalScore);
LK.showGameOver();
return true;
}
// If only one country remains and it's the player, show win
if (alive.length === 1 && playerCountry !== null && alive[0] === playerCountry) {
// Calculate score before win
var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50;
LK.setScore(finalScore);
LK.showYouWin();
return true;
}
// If only one country remains and it's not the player, show lose
if (alive.length === 1 && playerCountry !== null && alive[0] !== playerCountry) {
// Calculate score before game over
var finalScore = soldiersDefeated * 10 + playerSoldiers * 5 + playerLand * 20 + landTaken * 15 + mothers * 50;
LK.setScore(finalScore);
LK.showGameOver();
return true;
}
return false;
}
// Handle tap on territory or unit
game.down = function (x, y, obj) {
// Block input if playerCountry not chosen yet
if (playerCountry === null) return;
// Find which territory was tapped
var tappedTerritory = null;
for (var i = 0; i < territories.length; i++) {
var t = territories[i];
var dx = x - t.x;
var dy = y - t.y;
if (Math.abs(dx) < t.width / 2 && Math.abs(dy) < t.height / 2) {
tappedTerritory = t;
break;
}
}
if (!tappedTerritory) return;
// If selecting a unit to move
if (gameState === 'select') {
if (tappedTerritory.unit && tappedTerritory.unit.owner === currentTurn && !tappedTerritory.unit.hasMoved) {
deselectAll();
selectedUnit = tappedTerritory.unit;
selectedUnit.setSelected(true);
// Highlight possible moves
for (var j = 0; j < tappedTerritory.neighbors.length; j++) {
var nIdx = tappedTerritory.neighbors[j];
var n = territories[nIdx];
// Can move if empty or enemy unit present
if (!n.unit || n.unit && n.unit.owner !== currentTurn) {
n.setHighlight(true);
}
}
gameState = 'move';
}
} else if (gameState === 'move') {
// If tapped a highlighted territory, move or attack
if (selectedUnit && tappedTerritory.bg.alpha === 0.7) {
// If enemy unit, attack
if (tappedTerritory.unit && tappedTerritory.unit.owner !== currentTurn) {
// Remove enemy unit
var enemy = tappedTerritory.unit;
// If player is attacking, increment soldiersDefeated
if (currentTurn === playerCountry) {
soldiersDefeated++;
}
enemy.destroy();
for (var k = 0; k < units.length; k++) {
if (units[k] === enemy) {
units.splice(k, 1);
break;
}
}
tappedTerritory.unit = null;
}
// Track land taken if player captures enemy territory
if (currentTurn === playerCountry && tappedTerritory.owner !== null && tappedTerritory.owner !== playerCountry) {
landTaken++;
}
// Move unit
territories[selectedUnit.territory].unit = null;
selectedUnit.territory = tappedTerritory.index;
selectedUnit.x = tappedTerritory.x;
selectedUnit.y = tappedTerritory.y;
tappedTerritory.unit = selectedUnit;
tappedTerritory.setOwner(currentTurn);
selectedUnit.hasMoved = true;
deselectAll();
updateScoreDisplay();
// Check win
if (checkWin()) return;
gameState = 'select';
} else {
// Tapped elsewhere, cancel move
deselectAll();
gameState = 'select';
}
}
};
// End turn on double tap anywhere
game.up = function (x, y, obj) {
// Block input if playerCountry not chosen yet
if (playerCountry === null) return;
// If all units have moved, allow end turn
var allMoved = true;
var myUnits = getUnitsForCountry(currentTurn);
for (var i = 0; i < myUnits.length; i++) {
if (!myUnits[i].hasMoved) allMoved = false;
}
if (allMoved) {
endTurn();
}
};
// Main update loop (not much needed, but could be used for animations)
game.update = function () {
// Defensive: ensure units are always on top of territory
for (var i = 0; i < units.length; i++) {
if (units[i].parent !== game) continue;
game.setChildIndex(units[i], game.children.length - 1);
}
};