File size: 3,697 Bytes
bba8bcb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
document.addEventListener('DOMContentLoaded', () => {
    // DOM elements
    const canvas = document.getElementById('unscramble-canvas');
    const ctx = canvas.getContext('2d');
    const loadingMessage = document.getElementById('loading-message');

    // Prevent right-click on the canvas
    canvas.oncontextmenu = (e) => {
        e.preventDefault();
        return false;
    };

    // --- Main Unscrambling Logic ---

    async function unscramble() {
        try {
            // 1. Fetch the map data and the scrambled image simultaneously
            const [mapResponse, scrambledImage] = await Promise.all([
                fetch('assets/map.json'),
                loadImage('assets/scrambled.png')
            ]);

            if (!mapResponse.ok) {
                throw new Error(`Failed to load map.json: ${mapResponse.statusText}`);
            }

            const mapData = await mapResponse.json();
            const { gridSize, scrambleMap, width, height } = mapData;

            // Hide the loading message and set canvas dimensions
            loadingMessage.style.display = 'none';
            canvas.width = width;
            canvas.height = height;

            // 2. Calculate the tile dimensions
            const tileW = canvas.width / gridSize;
            const tileH = canvas.height / gridSize;

            // 3. Create an "inverse map" for easy unscrambling.
            // The scrambleMap tells us: new_position -> original_position
            // We need to know where the tile for an original_position is located now.
            const inverseMap = new Array(scrambleMap.length);
            for (let newIndex = 0; newIndex < scrambleMap.length; newIndex++) {
                const originalIndex = scrambleMap[newIndex];
                inverseMap[originalIndex] = newIndex;
            }

            // 4. Loop through each TILE of the FINAL image and draw it on the canvas
            for (let originalIndex = 0; originalIndex < scrambleMap.length; originalIndex++) {
                // Find where this tile is located in the SCRAMBLED image
                const scrambledIndex = inverseMap[originalIndex];

                // Calculate source (from scrambled.png) and destination (on canvas) coordinates
                const sourceX = (scrambledIndex % gridSize) * tileW;
                const sourceY = Math.floor(scrambledIndex / gridSize) * tileH;

                const destX = (originalIndex % gridSize) * tileW;
                const destY = Math.floor(originalIndex / gridSize) * tileH;

                // Copy the rectangular tile from the hidden scrambled image to the visible canvas
                ctx.drawImage(
                    scrambledImage, // The source image
                    sourceX, sourceY, // Top-left corner of the source tile
                    tileW, tileH,     // Dimensions of the source tile
                    destX, destY,     // Top-left corner of the destination on the canvas
                    tileW, tileH      // Dimensions of the destination tile
                );
            }

        } catch (error) {
            console.error("Unscrambling failed:", error);
            loadingMessage.textContent = `Error: ${error.message}`;
            loadingMessage.style.color = 'red';
        }
    }

    // Helper function to load an image and return a promise
    function loadImage(src) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.onload = () => resolve(img);
            img.onerror = (err) => reject(new Error(`Failed to load image: ${src}`));
            img.src = src;
        });
    }

    // Run the main function
    unscramble();
});