Skip to content

Instantly share code, notes, and snippets.

@samuelhorn
Created February 18, 2026 15:16
Show Gist options
  • Select an option

  • Save samuelhorn/bca04dcecbf32899c24da438a8f7a588 to your computer and use it in GitHub Desktop.

Select an option

Save samuelhorn/bca04dcecbf32899c24da438a8f7a588 to your computer and use it in GitHub Desktop.
Lucca Faces Script

Lucca Faces Solver Improved

Original script by https://github.com/louisgeisler/LuccaFacesSolver, but improved by saving learnings to local storage and providing scripts to read

Main script

Paste this in console on the page with the GO button. When done, click replay and paste the script again.

(async (config) => {
    try {
        // Load saved learnings from localStorage
        let foundNames = new Set(JSON.parse(localStorage.getItem('lucca_foundNames') || '[]'));
        let imgId2Names = JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}');

        console.log(`🧠 Loaded ${Object.keys(imgId2Names).length} known employees`);

        function sleep(duration) {
            return new Promise((resolve) => {
                setTimeout(() => resolve(), duration);
            });
        }

        async function answer() {
            try {
                console.group("πŸ’‘ Answer Event")
                
                var img = document.querySelector('#game app-timer .image');
                if (!img) {
                    console.error("❌ Image element not found!");
                    console.groupEnd();
                    return;
                }

                let style = img.currentStyle || window.getComputedStyle(img, false);
                let url = style.backgroundImage.slice(4, -1).replace(/"/g, "");

                if (!url || url === 'none') {
                    console.error("❌ No background image!");
                    console.groupEnd();
                    return;
                }

                if (config.speedup) {
                    img.style.visibility = "hidden";
                }

                let result = await fetch(url);
                let blob = await result.blob();
                let id = [blob.type, blob.size].toString();

                let possibleAnswerElements = [];
                let attempts = 0;
                while (!possibleAnswerElements.length && attempts < 50) {
                    await sleep(100);
                    possibleAnswerElements = [...document.querySelectorAll('#game .answers .answer')];
                    attempts++;
                }

                if (!possibleAnswerElements.length) {
                    console.error("❌ Answer buttons not found!");
                    console.groupEnd();
                    return;
                }

                let known = imgId2Names[id] ?? false;
                let guessed;
                
                if (known) {
                    guessed = known;
                    console.info(`βœ… Known: ${guessed}`)
                } else {
                    console.info("❓ Unknown - learning...")
                    let bestAnswers = possibleAnswerElements.filter(e => !foundNames.has(e.innerHTML));
                    if (!bestAnswers.length) bestAnswers = possibleAnswerElements;
                    
                    guessed = bestAnswers[Math.floor(Math.random() * bestAnswers.length)].innerHTML;
                    console.info(`πŸ€” Guessing: '${guessed}'`)
                }
                
                let guessElement = possibleAnswerElements.find(e => e.innerHTML == guessed);
                if (!guessElement) {
                    console.error("❌ Could not find answer element");
                    console.groupEnd();
                    return;
                }
                
                guessElement.click();

                let rightElement;
                attempts = 0;
                while (!rightElement && attempts < 50) {
                    await sleep(100);
                    rightElement = document.querySelector('#game .answers .is-right');
                    attempts++;
                }
                
                if (!rightElement) {
                    console.error("❌ Right answer not found!");
                    console.groupEnd();
                    return;
                }
                
                let rightName = rightElement.innerHTML;
                if (!known) {
                    console.info(`🧠 Learned: '${rightName}'`)
                    imgId2Names[id] = rightName;
                    foundNames.add(rightName);
                    
                    // SAVE IMMEDIATELY
                    localStorage.setItem('lucca_imgId2Names', JSON.stringify(imgId2Names));
                    localStorage.setItem('lucca_foundNames', JSON.stringify([...foundNames]));
                    console.info(`πŸ’Ύ Saved! Total known: ${Object.keys(imgId2Names).length}`);
                }
                console.groupEnd()
            } catch (error) {
                console.error("❌ Error:", error);
                console.groupEnd();
            }
        }

        // Check if game already started
        let img = document.querySelector('#game app-timer .image');
        
        if (img) {
            console.log("βœ… Game in progress! Attaching bot...");
            
            let last_style = null;
            const observer = new MutationObserver(function(mutations) {
                if (img.style.backgroundImage != last_style && img.style.backgroundImage) {
                    answer();
                    last_style = img.style.backgroundImage;
                }
            });

            observer.observe(img, {
                attributes: true,
                attributeFilter: ['style']
            });

            // Answer current question if present
            if (img.style.backgroundImage) {
                await answer();
            }
            
            console.log("πŸ€– Bot active! Known employees:", Object.keys(imgId2Names).length);
            return;
        }

        // Otherwise wait for start
        console.log("⏳ Waiting for start button...");
        
        let start_button = document.querySelector('.rotation-loader');
        let attempts = 0;
        while (!start_button && attempts < 100) {
            await sleep(100);
            start_button = document.querySelector('.rotation-loader');
            attempts++;
        }

        if (!start_button) {
            console.error("❌ Start button not found!");
            return;
        }

        console.info("πŸš€ Starting game...");
        start_button.click();

        img = null;
        attempts = 0;
        while (!img && attempts < 100) {
            await sleep(100);
            img = document.querySelector('#game app-timer .image');
            attempts++;
        }
        
        if (!img) {
            console.error("❌ Game didn't start!");
            return;
        }

        let last_style = null;
        const observer = new MutationObserver(function(mutations) {
            if (img.style.backgroundImage != last_style && img.style.backgroundImage) {
                answer();
                last_style = img.style.backgroundImage;
            }
        });

        observer.observe(img, {
            attributes: true,
            attributeFilter: ['style']
        });

        await answer();
        
        console.log("πŸ€– Bot running! Paste script again after game ends to continue.");
        
    } catch (error) {
        console.error("πŸ’₯ Fatal error:", error);
    }
})({
    speedup: true  // Hide images for faster runs
});

console.log(`
πŸ“Š Stats: ${Object.keys(JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}')).length} employees known
πŸ”„ Re-paste this script after each game to continue!
πŸ—‘οΈ  Clear: localStorage.clear()
`);

See all learned employees

console.table(JSON.parse(localStorage.getItem('lucca_imgId2Names')))

Count

Object.keys(JSON.parse(localStorage.getItem('lucca_imgId2Names') || '{}')).length

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment