/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GridCell = Container.expand(function (letter, row, col) {
var self = Container.call(this);
self.letter = letter;
self.row = row;
self.col = col;
self.isSelected = false;
self.isFound = false;
var cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2(letter, {
size: 80,
fill: 0x333333,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
self.setSelected = function (selected) {
self.isSelected = selected;
if (self.isFound) return;
self.removeChild(cellBG);
if (selected) {
cellBG = self.attachAsset('gridCellSelected', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.addChildAt(cellBG, 0);
};
self.setFound = function () {
self.isFound = true;
self.removeChild(cellBG);
cellBG = self.attachAsset('gridCellFound', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChildAt(cellBG, 0);
};
return self;
});
var TargetWord = Container.expand(function (frenchWord, englishWord, turkishWord, level) {
var self = Container.call(this);
self.frenchWord = frenchWord;
self.englishWord = englishWord;
self.turkishWord = turkishWord;
self.level = level;
self.isFound = false;
var bg = self.attachAsset('targetWordBG', {
anchorX: 0.5,
anchorY: 0.5
});
var frenchText = new Text2(frenchWord + ' (' + level + ')', {
size: 65,
fill: 0x000000,
font: "Arial"
});
frenchText.anchor.set(0.5, 0.5);
frenchText.y = -100;
self.addChild(frenchText);
var englishText = new Text2(englishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
englishText.anchor.set(0.5, 0.5);
englishText.y = -20;
self.addChild(englishText);
var turkishText = new Text2(turkishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
turkishText.anchor.set(0.5, 0.5);
turkishText.y = 60;
self.addChild(turkishText);
self.markFound = function () {
self.isFound = true;
frenchText.tint = 0x4CAF50;
bg.tint = 0xC8E6C9;
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// French vocabulary database with CEFR levels
var vocabularyDatabase = [
// A1 Level
{
french: "CHAT",
english: "Cat",
turkish: "Kedi",
level: "A1"
}, {
french: "CHIEN",
english: "Dog",
turkish: "Köpek",
level: "A1"
}, {
french: "MAISON",
english: "House",
turkish: "Ev",
level: "A1"
}, {
french: "EAU",
english: "Water",
turkish: "Su",
level: "A1"
}, {
french: "PAIN",
english: "Bread",
turkish: "Ekmek",
level: "A1"
}, {
french: "LAIT",
english: "Milk",
turkish: "Süt",
level: "A1"
}, {
french: "ROUGE",
english: "Red",
turkish: "Kırmızı",
level: "A1"
}, {
french: "BLEU",
english: "Blue",
turkish: "Mavi",
level: "A1"
}, {
french: "VERT",
english: "Green",
turkish: "Yeşil",
level: "A1"
}, {
french: "NOIR",
english: "Black",
turkish: "Siyah",
level: "A1"
},
// A2 Level
{
french: "VOITURE",
english: "Car",
turkish: "Araba",
level: "A2"
}, {
french: "TRAVAIL",
english: "Work",
turkish: "İş",
level: "A2"
}, {
french: "ECOLE",
english: "School",
turkish: "Okul",
level: "A2"
}, {
french: "FAMILLE",
english: "Family",
turkish: "Aile",
level: "A2"
}, {
french: "TEMPS",
english: "Time",
turkish: "Zaman",
level: "A2"
}, {
french: "ARGENT",
english: "Money",
turkish: "Para",
level: "A2"
}, {
french: "VOYAGE",
english: "Travel",
turkish: "Seyahat",
level: "A2"
}, {
french: "MUSIQUE",
english: "Music",
turkish: "Müzik",
level: "A2"
}, {
french: "LIVRE",
english: "Book",
turkish: "Kitap",
level: "A2"
}, {
french: "FILM",
english: "Movie",
turkish: "Film",
level: "A2"
},
// B1 Level
{
french: "BONHEUR",
english: "Happiness",
turkish: "Mutluluk",
level: "B1"
}, {
french: "CULTURE",
english: "Culture",
turkish: "Kültür",
level: "B1"
}, {
french: "SOCIETE",
english: "Society",
turkish: "Toplum",
level: "B1"
}, {
french: "NATURE",
english: "Nature",
turkish: "Doğa",
level: "B1"
}, {
french: "SCIENCE",
english: "Science",
turkish: "Bilim",
level: "B1"
}, {
french: "HISTOIRE",
english: "History",
turkish: "Tarih",
level: "B1"
}, {
french: "OPINION",
english: "Opinion",
turkish: "Görüş",
level: "B1"
}, {
french: "ENERGIE",
english: "Energy",
turkish: "Enerji",
level: "B1"
}, {
french: "PROJECT",
english: "Project",
turkish: "Proje",
level: "B1"
}, {
french: "RESULTAT",
english: "Result",
turkish: "Sonuç",
level: "B1"
},
// B2 Level
{
french: "CONSCIENCE",
english: "Conscience",
turkish: "Vicdan",
level: "B2"
}, {
french: "PHILOSOPHIE",
english: "Philosophy",
turkish: "Felsefe",
level: "B2"
}, {
french: "TECHNOLOGIE",
english: "Technology",
turkish: "Teknoloji",
level: "B2"
}, {
french: "ECONOMIE",
english: "Economy",
turkish: "Ekonomi",
level: "B2"
}, {
french: "POLITIQUE",
english: "Politics",
turkish: "Politika",
level: "B2"
}, {
french: "ENVIRONNEMENT",
english: "Environment",
turkish: "Çevre",
level: "B2"
}, {
french: "DEMOCRATIE",
english: "Democracy",
turkish: "Demokrasi",
level: "B2"
}, {
french: "INNOVATION",
english: "Innovation",
turkish: "İnovasyon",
level: "B2"
}, {
french: "GLOBALISATION",
english: "Globalization",
turkish: "Küreselleşme",
level: "B2"
}, {
french: "COMMUNICATION",
english: "Communication",
turkish: "İletişim",
level: "B2"
},
// C1 Level
{
french: "EPISTEMOLOGIE",
english: "Epistemology",
turkish: "Epistemoloji",
level: "C1"
}, {
french: "METAPHYSIQUE",
english: "Metaphysics",
turkish: "Metafizik",
level: "C1"
}, {
french: "PHENOMENOLOGIE",
english: "Phenomenology",
turkish: "Fenomenoloji",
level: "C1"
}, {
french: "HERMENEUTIQUE",
english: "Hermeneutics",
turkish: "Hermenötik",
level: "C1"
}, {
french: "DIALECTIQUE",
english: "Dialectics",
turkish: "Diyalektik",
level: "C1"
}, {
french: "EPISODIQUE",
english: "Episodic",
turkish: "Epizodik",
level: "C1"
}, {
french: "PARADIGME",
english: "Paradigm",
turkish: "Paradigma",
level: "C1"
}, {
french: "ONTOLOGIE",
english: "Ontology",
turkish: "Ontoloji",
level: "C1"
}, {
french: "SYNTHETIQUE",
english: "Synthetic",
turkish: "Sentetik",
level: "C1"
}, {
french: "EMPIRIQUE",
english: "Empirical",
turkish: "Ampirik",
level: "C1"
}];
// Game variables
var gridSize = 10;
var cellSize = 160;
var grid = [];
var gridCells = [];
var targetWords = [];
var currentTargetWords = [];
var selectedCells = [];
var isDragging = false;
var currentSection = 1;
var wordsFoundInSection = 0;
// Score text
var scoreTxt = new Text2('Section: 1', {
size: 80,
fill: 0x333333
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Create grid container
var gridContainer = new Container();
game.addChild(gridContainer);
// Create target words container
var targetWordsContainer = new Container();
game.addChild(targetWordsContainer);
// Initialize grid
function initializeGrid() {
// Clear existing grid
for (var i = 0; i < gridCells.length; i++) {
for (var j = 0; j < gridCells[i].length; j++) {
gridContainer.removeChild(gridCells[i][j]);
}
}
grid = [];
gridCells = [];
// Create empty grid
for (var row = 0; row < gridSize; row++) {
grid[row] = [];
gridCells[row] = [];
for (var col = 0; col < gridSize; col++) {
grid[row][col] = '';
}
}
// Place target words in grid
for (var w = 0; w < currentTargetWords.length; w++) {
placeWordInGrid(currentTargetWords[w].french);
}
// Fill remaining cells with random letters
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
if (grid[row][col] === '') {
grid[row][col] = letters[Math.floor(Math.random() * letters.length)];
}
}
}
// Create visual grid cells
var startX = 1024 - gridSize * cellSize / 2 + cellSize / 2;
var startY = 400;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var cell = new GridCell(grid[row][col], row, col);
cell.x = startX + col * cellSize;
cell.y = startY + row * cellSize;
gridCells[row][col] = cell;
gridContainer.addChild(cell);
}
}
}
function placeWordInGrid(word) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 100) {
var direction = Math.floor(Math.random() * 4); // 0: horizontal, 1: vertical, 2: diagonal down-right, 3: diagonal down-left
var row, col;
if (direction === 0) {
// horizontal
row = Math.floor(Math.random() * gridSize);
col = Math.floor(Math.random() * (gridSize - word.length + 1));
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (col + i >= gridSize || grid[row][col + i] !== '' && grid[row][col + i] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (col + i < gridSize) {
grid[row][col + i] = word[i];
}
}
placed = true;
}
} else if (direction === 1) {
// vertical
row = Math.floor(Math.random() * (gridSize - word.length + 1));
col = Math.floor(Math.random() * gridSize);
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (row + i >= gridSize || grid[row + i] && grid[row + i][col] !== '' && grid[row + i][col] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (row + i < gridSize) {
grid[row + i][col] = word[i];
}
}
placed = true;
}
}
attempts++;
}
}
function selectTargetWords() {
currentTargetWords = [];
var availableWords = vocabularyDatabase.slice();
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * availableWords.length);
currentTargetWords.push(availableWords[randomIndex]);
availableWords.splice(randomIndex, 1);
}
}
function createTargetWordsDisplay() {
// Clear existing target words
while (targetWordsContainer.children.length > 0) {
targetWordsContainer.removeChild(targetWordsContainer.children[0]);
}
targetWords = [];
var startX = 1024 - 3 * 650 / 2 + 325;
var yPos = 2500;
for (var i = 0; i < currentTargetWords.length; i++) {
var targetWord = new TargetWord(currentTargetWords[i].french, currentTargetWords[i].english, currentTargetWords[i].turkish, currentTargetWords[i].level);
targetWord.x = startX + i * 650;
targetWord.y = yPos;
targetWords.push(targetWord);
targetWordsContainer.addChild(targetWord);
}
}
function getSelectedWord() {
var word = '';
for (var i = 0; i < selectedCells.length; i++) {
word += selectedCells[i].letter;
}
return word;
}
function checkForWord() {
var selectedWord = getSelectedWord();
for (var i = 0; i < currentTargetWords.length; i++) {
if (currentTargetWords[i].french === selectedWord && !targetWords[i].isFound) {
// Word found!
targetWords[i].markFound();
// Mark cells as found
for (var j = 0; j < selectedCells.length; j++) {
selectedCells[j].setFound();
}
LK.getSound('wordFound').play();
wordsFoundInSection++;
if (wordsFoundInSection >= 3) {
// Section complete
LK.setTimeout(function () {
LK.getSound('sectionComplete').play();
startNewSection();
}, 500);
}
break;
}
}
}
function startNewSection() {
currentSection++;
wordsFoundInSection = 0;
scoreTxt.setText('Section: ' + currentSection);
selectTargetWords();
createTargetWordsDisplay();
initializeGrid();
}
function clearSelection() {
for (var i = 0; i < selectedCells.length; i++) {
selectedCells[i].setSelected(false);
}
selectedCells = [];
}
function getCellAt(x, y) {
// Calculate grid position based on start position and cell size
var startX = 1024 - gridSize * cellSize / 2;
var startY = 400;
// Calculate which grid cell was touched directly from game coordinates
var col = Math.floor((x - startX) / cellSize);
var row = Math.floor((y - startY) / cellSize);
// Check bounds and return cell if valid
if (row >= 0 && row < gridSize && col >= 0 && col < gridSize) {
return gridCells[row][col];
}
return null;
}
function isValidSelection(lastCell, newCell) {
if (!lastCell) return true;
var rowDiff = Math.abs(lastCell.row - newCell.row);
var colDiff = Math.abs(lastCell.col - newCell.col);
// Allow horizontal, vertical, and diagonal connections
return rowDiff <= 1 && colDiff <= 1 && (rowDiff > 0 || colDiff > 0);
}
// Game events
game.down = function (x, y, obj) {
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
isDragging = true;
clearSelection();
selectedCells.push(cell);
cell.setSelected(true);
}
};
game.move = function (x, y, obj) {
if (!isDragging) return;
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
var lastCell = selectedCells.length > 0 ? selectedCells[selectedCells.length - 1] : null;
if (cell !== lastCell && isValidSelection(lastCell, cell)) {
// Check if cell is already in selection
var cellIndex = -1;
for (var i = 0; i < selectedCells.length; i++) {
if (selectedCells[i] === cell) {
cellIndex = i;
break;
}
}
if (cellIndex >= 0) {
// Remove cells after this one (backtracking)
for (var i = selectedCells.length - 1; i > cellIndex; i--) {
selectedCells[i].setSelected(false);
selectedCells.splice(i, 1);
}
} else {
// Add new cell to selection
selectedCells.push(cell);
cell.setSelected(true);
}
}
}
};
game.up = function (x, y, obj) {
if (isDragging) {
isDragging = false;
if (selectedCells.length > 0) {
checkForWord();
}
clearSelection();
}
};
// Initialize game
selectTargetWords();
createTargetWordsDisplay();
initializeGrid(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GridCell = Container.expand(function (letter, row, col) {
var self = Container.call(this);
self.letter = letter;
self.row = row;
self.col = col;
self.isSelected = false;
self.isFound = false;
var cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2(letter, {
size: 80,
fill: 0x333333,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
self.setSelected = function (selected) {
self.isSelected = selected;
if (self.isFound) return;
self.removeChild(cellBG);
if (selected) {
cellBG = self.attachAsset('gridCellSelected', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
cellBG = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.addChildAt(cellBG, 0);
};
self.setFound = function () {
self.isFound = true;
self.removeChild(cellBG);
cellBG = self.attachAsset('gridCellFound', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChildAt(cellBG, 0);
};
return self;
});
var TargetWord = Container.expand(function (frenchWord, englishWord, turkishWord, level) {
var self = Container.call(this);
self.frenchWord = frenchWord;
self.englishWord = englishWord;
self.turkishWord = turkishWord;
self.level = level;
self.isFound = false;
var bg = self.attachAsset('targetWordBG', {
anchorX: 0.5,
anchorY: 0.5
});
var frenchText = new Text2(frenchWord + ' (' + level + ')', {
size: 65,
fill: 0x000000,
font: "Arial"
});
frenchText.anchor.set(0.5, 0.5);
frenchText.y = -100;
self.addChild(frenchText);
var englishText = new Text2(englishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
englishText.anchor.set(0.5, 0.5);
englishText.y = -20;
self.addChild(englishText);
var turkishText = new Text2(turkishWord, {
size: 65,
fill: 0x000000,
font: "Arial"
});
turkishText.anchor.set(0.5, 0.5);
turkishText.y = 60;
self.addChild(turkishText);
self.markFound = function () {
self.isFound = true;
frenchText.tint = 0x4CAF50;
bg.tint = 0xC8E6C9;
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// French vocabulary database with CEFR levels
var vocabularyDatabase = [
// A1 Level
{
french: "CHAT",
english: "Cat",
turkish: "Kedi",
level: "A1"
}, {
french: "CHIEN",
english: "Dog",
turkish: "Köpek",
level: "A1"
}, {
french: "MAISON",
english: "House",
turkish: "Ev",
level: "A1"
}, {
french: "EAU",
english: "Water",
turkish: "Su",
level: "A1"
}, {
french: "PAIN",
english: "Bread",
turkish: "Ekmek",
level: "A1"
}, {
french: "LAIT",
english: "Milk",
turkish: "Süt",
level: "A1"
}, {
french: "ROUGE",
english: "Red",
turkish: "Kırmızı",
level: "A1"
}, {
french: "BLEU",
english: "Blue",
turkish: "Mavi",
level: "A1"
}, {
french: "VERT",
english: "Green",
turkish: "Yeşil",
level: "A1"
}, {
french: "NOIR",
english: "Black",
turkish: "Siyah",
level: "A1"
},
// A2 Level
{
french: "VOITURE",
english: "Car",
turkish: "Araba",
level: "A2"
}, {
french: "TRAVAIL",
english: "Work",
turkish: "İş",
level: "A2"
}, {
french: "ECOLE",
english: "School",
turkish: "Okul",
level: "A2"
}, {
french: "FAMILLE",
english: "Family",
turkish: "Aile",
level: "A2"
}, {
french: "TEMPS",
english: "Time",
turkish: "Zaman",
level: "A2"
}, {
french: "ARGENT",
english: "Money",
turkish: "Para",
level: "A2"
}, {
french: "VOYAGE",
english: "Travel",
turkish: "Seyahat",
level: "A2"
}, {
french: "MUSIQUE",
english: "Music",
turkish: "Müzik",
level: "A2"
}, {
french: "LIVRE",
english: "Book",
turkish: "Kitap",
level: "A2"
}, {
french: "FILM",
english: "Movie",
turkish: "Film",
level: "A2"
},
// B1 Level
{
french: "BONHEUR",
english: "Happiness",
turkish: "Mutluluk",
level: "B1"
}, {
french: "CULTURE",
english: "Culture",
turkish: "Kültür",
level: "B1"
}, {
french: "SOCIETE",
english: "Society",
turkish: "Toplum",
level: "B1"
}, {
french: "NATURE",
english: "Nature",
turkish: "Doğa",
level: "B1"
}, {
french: "SCIENCE",
english: "Science",
turkish: "Bilim",
level: "B1"
}, {
french: "HISTOIRE",
english: "History",
turkish: "Tarih",
level: "B1"
}, {
french: "OPINION",
english: "Opinion",
turkish: "Görüş",
level: "B1"
}, {
french: "ENERGIE",
english: "Energy",
turkish: "Enerji",
level: "B1"
}, {
french: "PROJECT",
english: "Project",
turkish: "Proje",
level: "B1"
}, {
french: "RESULTAT",
english: "Result",
turkish: "Sonuç",
level: "B1"
},
// B2 Level
{
french: "CONSCIENCE",
english: "Conscience",
turkish: "Vicdan",
level: "B2"
}, {
french: "PHILOSOPHIE",
english: "Philosophy",
turkish: "Felsefe",
level: "B2"
}, {
french: "TECHNOLOGIE",
english: "Technology",
turkish: "Teknoloji",
level: "B2"
}, {
french: "ECONOMIE",
english: "Economy",
turkish: "Ekonomi",
level: "B2"
}, {
french: "POLITIQUE",
english: "Politics",
turkish: "Politika",
level: "B2"
}, {
french: "ENVIRONNEMENT",
english: "Environment",
turkish: "Çevre",
level: "B2"
}, {
french: "DEMOCRATIE",
english: "Democracy",
turkish: "Demokrasi",
level: "B2"
}, {
french: "INNOVATION",
english: "Innovation",
turkish: "İnovasyon",
level: "B2"
}, {
french: "GLOBALISATION",
english: "Globalization",
turkish: "Küreselleşme",
level: "B2"
}, {
french: "COMMUNICATION",
english: "Communication",
turkish: "İletişim",
level: "B2"
},
// C1 Level
{
french: "EPISTEMOLOGIE",
english: "Epistemology",
turkish: "Epistemoloji",
level: "C1"
}, {
french: "METAPHYSIQUE",
english: "Metaphysics",
turkish: "Metafizik",
level: "C1"
}, {
french: "PHENOMENOLOGIE",
english: "Phenomenology",
turkish: "Fenomenoloji",
level: "C1"
}, {
french: "HERMENEUTIQUE",
english: "Hermeneutics",
turkish: "Hermenötik",
level: "C1"
}, {
french: "DIALECTIQUE",
english: "Dialectics",
turkish: "Diyalektik",
level: "C1"
}, {
french: "EPISODIQUE",
english: "Episodic",
turkish: "Epizodik",
level: "C1"
}, {
french: "PARADIGME",
english: "Paradigm",
turkish: "Paradigma",
level: "C1"
}, {
french: "ONTOLOGIE",
english: "Ontology",
turkish: "Ontoloji",
level: "C1"
}, {
french: "SYNTHETIQUE",
english: "Synthetic",
turkish: "Sentetik",
level: "C1"
}, {
french: "EMPIRIQUE",
english: "Empirical",
turkish: "Ampirik",
level: "C1"
}];
// Game variables
var gridSize = 10;
var cellSize = 160;
var grid = [];
var gridCells = [];
var targetWords = [];
var currentTargetWords = [];
var selectedCells = [];
var isDragging = false;
var currentSection = 1;
var wordsFoundInSection = 0;
// Score text
var scoreTxt = new Text2('Section: 1', {
size: 80,
fill: 0x333333
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Create grid container
var gridContainer = new Container();
game.addChild(gridContainer);
// Create target words container
var targetWordsContainer = new Container();
game.addChild(targetWordsContainer);
// Initialize grid
function initializeGrid() {
// Clear existing grid
for (var i = 0; i < gridCells.length; i++) {
for (var j = 0; j < gridCells[i].length; j++) {
gridContainer.removeChild(gridCells[i][j]);
}
}
grid = [];
gridCells = [];
// Create empty grid
for (var row = 0; row < gridSize; row++) {
grid[row] = [];
gridCells[row] = [];
for (var col = 0; col < gridSize; col++) {
grid[row][col] = '';
}
}
// Place target words in grid
for (var w = 0; w < currentTargetWords.length; w++) {
placeWordInGrid(currentTargetWords[w].french);
}
// Fill remaining cells with random letters
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
if (grid[row][col] === '') {
grid[row][col] = letters[Math.floor(Math.random() * letters.length)];
}
}
}
// Create visual grid cells
var startX = 1024 - gridSize * cellSize / 2 + cellSize / 2;
var startY = 400;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var cell = new GridCell(grid[row][col], row, col);
cell.x = startX + col * cellSize;
cell.y = startY + row * cellSize;
gridCells[row][col] = cell;
gridContainer.addChild(cell);
}
}
}
function placeWordInGrid(word) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 100) {
var direction = Math.floor(Math.random() * 4); // 0: horizontal, 1: vertical, 2: diagonal down-right, 3: diagonal down-left
var row, col;
if (direction === 0) {
// horizontal
row = Math.floor(Math.random() * gridSize);
col = Math.floor(Math.random() * (gridSize - word.length + 1));
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (col + i >= gridSize || grid[row][col + i] !== '' && grid[row][col + i] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (col + i < gridSize) {
grid[row][col + i] = word[i];
}
}
placed = true;
}
} else if (direction === 1) {
// vertical
row = Math.floor(Math.random() * (gridSize - word.length + 1));
col = Math.floor(Math.random() * gridSize);
var canPlace = true;
for (var i = 0; i < word.length; i++) {
if (row + i >= gridSize || grid[row + i] && grid[row + i][col] !== '' && grid[row + i][col] !== word[i]) {
canPlace = false;
break;
}
}
if (canPlace) {
for (var i = 0; i < word.length; i++) {
if (row + i < gridSize) {
grid[row + i][col] = word[i];
}
}
placed = true;
}
}
attempts++;
}
}
function selectTargetWords() {
currentTargetWords = [];
var availableWords = vocabularyDatabase.slice();
for (var i = 0; i < 3; i++) {
var randomIndex = Math.floor(Math.random() * availableWords.length);
currentTargetWords.push(availableWords[randomIndex]);
availableWords.splice(randomIndex, 1);
}
}
function createTargetWordsDisplay() {
// Clear existing target words
while (targetWordsContainer.children.length > 0) {
targetWordsContainer.removeChild(targetWordsContainer.children[0]);
}
targetWords = [];
var startX = 1024 - 3 * 650 / 2 + 325;
var yPos = 2500;
for (var i = 0; i < currentTargetWords.length; i++) {
var targetWord = new TargetWord(currentTargetWords[i].french, currentTargetWords[i].english, currentTargetWords[i].turkish, currentTargetWords[i].level);
targetWord.x = startX + i * 650;
targetWord.y = yPos;
targetWords.push(targetWord);
targetWordsContainer.addChild(targetWord);
}
}
function getSelectedWord() {
var word = '';
for (var i = 0; i < selectedCells.length; i++) {
word += selectedCells[i].letter;
}
return word;
}
function checkForWord() {
var selectedWord = getSelectedWord();
for (var i = 0; i < currentTargetWords.length; i++) {
if (currentTargetWords[i].french === selectedWord && !targetWords[i].isFound) {
// Word found!
targetWords[i].markFound();
// Mark cells as found
for (var j = 0; j < selectedCells.length; j++) {
selectedCells[j].setFound();
}
LK.getSound('wordFound').play();
wordsFoundInSection++;
if (wordsFoundInSection >= 3) {
// Section complete
LK.setTimeout(function () {
LK.getSound('sectionComplete').play();
startNewSection();
}, 500);
}
break;
}
}
}
function startNewSection() {
currentSection++;
wordsFoundInSection = 0;
scoreTxt.setText('Section: ' + currentSection);
selectTargetWords();
createTargetWordsDisplay();
initializeGrid();
}
function clearSelection() {
for (var i = 0; i < selectedCells.length; i++) {
selectedCells[i].setSelected(false);
}
selectedCells = [];
}
function getCellAt(x, y) {
// Calculate grid position based on start position and cell size
var startX = 1024 - gridSize * cellSize / 2;
var startY = 400;
// Calculate which grid cell was touched directly from game coordinates
var col = Math.floor((x - startX) / cellSize);
var row = Math.floor((y - startY) / cellSize);
// Check bounds and return cell if valid
if (row >= 0 && row < gridSize && col >= 0 && col < gridSize) {
return gridCells[row][col];
}
return null;
}
function isValidSelection(lastCell, newCell) {
if (!lastCell) return true;
var rowDiff = Math.abs(lastCell.row - newCell.row);
var colDiff = Math.abs(lastCell.col - newCell.col);
// Allow horizontal, vertical, and diagonal connections
return rowDiff <= 1 && colDiff <= 1 && (rowDiff > 0 || colDiff > 0);
}
// Game events
game.down = function (x, y, obj) {
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
isDragging = true;
clearSelection();
selectedCells.push(cell);
cell.setSelected(true);
}
};
game.move = function (x, y, obj) {
if (!isDragging) return;
var cell = getCellAt(x, y);
if (cell && !cell.isFound) {
var lastCell = selectedCells.length > 0 ? selectedCells[selectedCells.length - 1] : null;
if (cell !== lastCell && isValidSelection(lastCell, cell)) {
// Check if cell is already in selection
var cellIndex = -1;
for (var i = 0; i < selectedCells.length; i++) {
if (selectedCells[i] === cell) {
cellIndex = i;
break;
}
}
if (cellIndex >= 0) {
// Remove cells after this one (backtracking)
for (var i = selectedCells.length - 1; i > cellIndex; i--) {
selectedCells[i].setSelected(false);
selectedCells.splice(i, 1);
}
} else {
// Add new cell to selection
selectedCells.push(cell);
cell.setSelected(true);
}
}
}
};
game.up = function (x, y, obj) {
if (isDragging) {
isDragging = false;
if (selectedCells.length > 0) {
checkForWord();
}
clearSelection();
}
};
// Initialize game
selectTargetWords();
createTargetWordsDisplay();
initializeGrid();