-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpuzzle.js
128 lines (103 loc) · 3.91 KB
/
puzzle.js
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
window.onload = function() {
var images = ['teacher2.jpg', 'teacher3.jpg', 'hoangnamtien.png', ];
$('.answer,.tile').css({
'background-image': 'url(' + images[Math.floor(Math.random() * images.length)] + ')'
});
$('.tile--empty').css({
'background': 'transparent'
});
};
// Initiate CSS Grid animation tool
const grid = document.querySelector(".grid");
const { forceGridAnimation } = animateCSSGrid.wrapGrid(grid);
// Get all the tiles and the empty tile
const tiles = Array.from(document.querySelectorAll(".tile"));
const emptyTile = document.querySelector(".tile--empty");
// Get congratulations heading
const heading = document.querySelector(".heading");
// A key / value store of what areas to "unlock"
const areaKeys = {
A: ["B", "D"],
B: ["A", "C", "E"],
C: ["B", "F"],
D: ["A", "E", "G"],
E: ["B", "D", "F", "H"],
F: ["C", "E", "I"],
G: ["D", "H"],
H: ["E", "G", "I"],
I: ["F", "H"]
};
// Add click listener to all tiles
tiles.map(tile => {
tile.addEventListener("click", event => {
// Grab the grid area set on the clicked tile and empty tile
const tileArea = tile.style.getPropertyValue("--area");
const emptyTileArea = emptyTile.style.getPropertyValue("--area");
// Swap the empty tile with the clicked tile
emptyTile.style.setProperty("--area", tileArea);
tile.style.setProperty("--area", emptyTileArea);
// Animate the tiles
forceGridAnimation();
// Unlock and lock tiles
unlockTiles(tileArea);
});
});
// Unlock or lock tiles based on empty tile position
const unlockTiles = currentTileArea => {
// Cycle through all the tiles and check which should be disabled and enabled
tiles.map(tile => {
const tileArea = tile.style.getPropertyValue("--area");
// Check if that areaKey has the tiles area in it's values
// .trim() is needed because the animation lib formats the styles attribute
if (areaKeys[currentTileArea.trim()].includes(tileArea.trim())) {
tile.disabled = false;
} else {
tile.disabled = true;
}
});
// Check if the tiles are in the right order
isComplete(tiles);
};
const isComplete = tiles => {
// Get all the current tile area values
const currentTilesString = tiles
.map(tile => tile.style.getPropertyValue("--area").trim())
.toString();
// Compare the current tiles with the areaKeys keys
if (currentTilesString == Object.keys(areaKeys).toString()) {
$(':button').prop('disabled', true);
heading.children[1].innerHTML = "You win!";
heading.style = `
animation: popIn .3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
`;
}
};
// Inversion calculator
const getInvCount = arr => {
let inv_count = 0;
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) inv_count++;
}
}
return inv_count;
};
// Randomise tiles
const shuffledKeys = keys => Object.keys(keys).sort(() => .5 - Math.random());
setTimeout(() => {
// Begin with our in order area keys
let startingAreas = Object.keys(areaKeys);
// Use the inversion function to check if the keys will be solveable or not shuffled
// Shuffle the keys until they are solvable
while (getInvCount(startingAreas) % 2 == 1 || getInvCount(startingAreas) == 0) {
console.log(getInvCount(startingAreas) % 2 + "----" + getInvCount(startingAreas));
startingAreas = shuffledKeys(areaKeys);
}
// Apply shuffled areas
tiles.map((tile, index) => {
tile.style.setProperty("--area", startingAreas[index]);
});
forceGridAnimation();
// Unlock and lock tiles
unlockTiles(emptyTile.style.getPropertyValue("--area"));
}, 1000);