-
Notifications
You must be signed in to change notification settings - Fork 903
/
Copy pathscript.js
278 lines (261 loc) · 10.2 KB
/
script.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
// Card trick by Stian Martinsen - 2021
// button to toggle if the start button should be a reset-button instead.
let buttonIsStart = true;
// arrays to be used for each pile
let pile1 = [];
let pile2 = [];
let pile3 = [];
// Variable to keep track of the number of selections. (correct card is found at min 3)
let pileSelectionCounter = 0;
// store the cards from the API in this array:
let cards;
// HTML-elements to use.
const correctCardHTML =
document.documentElement.querySelector(".correctCardArea");
const mainheaderHTML = document.documentElement.querySelector(".mainheader");
const allCardsHTML = document.documentElement.querySelector(".allcards");
const startButton = document.documentElement.querySelector(".startButton");
const changeCardsButton =
document.documentElement.querySelector(".changeCardsButton");
const continueButton =
document.documentElement.querySelector(".continueButton");
const pile1placement = document.documentElement.querySelector(".pile1cards");
const pile2placement = document.documentElement.querySelector(".pile2cards");
const pile3placement = document.documentElement.querySelector(".pile3cards");
const pileSelectionButtons =
document.documentElement.querySelectorAll(".pileselection");
// getNewCards() fetches a new deck, and retrieves 21 cards from the deck.
const getNewCards = async function () {
// empties the array to avoid adding more to previously fetched decks.
cards = [];
// Get the deck_id
let response = await fetch(
"https://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=1"
);
let post = await response.json();
// use the deck_id fetched in the previous call and get the cards in the deck.
let cardResponse = await fetch(
`https://deckofcardsapi.com/api/deck/${post.deck_id}/draw/?count=21`
);
//stores the result in a temp variable because it needs further processing.
let tempCards = await cardResponse.json();
//reassigning cards to only store the cards info.
tempCards = tempCards.cards;
// iterating through tempCards to create a new Array to store only the image-urls.
tempCards.forEach((card) => {
cards.push(card.image);
});
};
// Runs the getNewCards on page load, so the initial deck is already loaded when the Start-button is clicked.
getNewCards();
// User needs to click the start-button to start.
startButton.onclick = async function () {
// makes the change cards button visible.
if (buttonIsStart === true) {
// toggles the function of this button.
buttonIsStart = false;
// changes the Text of the button.
startButton.innerHTML = "Reset Game";
// makes the ChangeCards-button visible. (already loaded in the HTML, but hidden by CSS)
changeCardsButton.style.setProperty(`display`, "inline-flex");
// presents the deck.
presentDeck();
} else {
// When the button is a ResetButton, the following happens.
// Text on the button is changed back.
startButton.innerHTML = "Start Game";
// Hides buttons and html-sections
changeCardsButton.style.setProperty(`display`, `none`);
mainheaderHTML.innerHTML = ``;
continueButton.style.setProperty(`display`, `none`);
correctCardHTML.innerHTML = ``;
allCardsHTML.innerHTML = ``;
// toggles the function of this button.
buttonIsStart = true;
// Resets the pileSelectionCounter which might have been increased before reset.
pileSelectionCounter = 0;
// Clears the piles.
ClearPiles();
// Hides the PileButtons.
showPileButtons(0);
// Grabs a ned deck of cards.
await getNewCards();
}
};
// The ChangeCards-button simply calls the API for new cards and presents them in the current view.
changeCardsButton.onclick = async function () {
await getNewCards();
presentDeck();
};
// The presentDeck() displays the deck loaded from the API for verification by the user.
function presentDeck() {
// Makes the mainheader-element visible and sets the H2.
mainheaderHTML.innerHTML = `Remember one of these cards before you click "Continue".`;
// Empties the "allCards". Without this the cards presented will accumulate when changing cards.
allCardsHTML.innerHTML = ``;
// Create the HTML-element for each card.
for (i = 0; i < cards.length; i++) {
allCardsHTML.innerHTML += `<img src="${cards[i]}" class="card">`;
}
// Makes the ContinueButton-visible.
continueButton.style.setProperty(`display`, `flex`);
}
// The onClick-function for the Continue-button.
continueButton.onclick = function () {
// Hides the buttons which are now obsolete.
changeCardsButton.style.setProperty(`display`, `none`);
continueButton.style.setProperty(`display`, `none`);
allCardsHTML.innerHTML = ``;
//Present the piles...
presentPiles(cards);
};
// presentPiles() takes the current deck of 21 cards and simulates the dealing of cards in 3 piles.
function presentPiles(CardDeck) {
// change the instructions
mainheaderHTML.innerHTML = `2. Click the pile-button below the pile where you see your card, round: ${
pileSelectionCounter + 1
}`;
// resetting a variable to identify where the card in each pile is. Currently used for styling.
let cardPileIndex1 = 0,
cardPileIndex2 = 0,
cardPileIndex3 = 0;
// ordering each card in each pile like a human would deal the cards.
pile1 = [
CardDeck[0],
CardDeck[3],
CardDeck[6],
CardDeck[9],
CardDeck[12],
CardDeck[15],
CardDeck[18],
];
pile2 = [
CardDeck[1],
CardDeck[4],
CardDeck[7],
CardDeck[10],
CardDeck[13],
CardDeck[16],
CardDeck[19],
];
pile3 = [
CardDeck[2],
CardDeck[5],
CardDeck[8],
CardDeck[11],
CardDeck[14],
CardDeck[17],
CardDeck[20],
];
// adding the HTML requires for each card in each pile.
pile1.forEach((card) => {
// setting the pileIndex for each card.
cardPileIndex1++;
// addubg the card.
pile1placement.innerHTML += `<img src="${card}" class="cardpiles">`;
// adding a lineshift-component. Only used for styling.
if (cardPileIndex1 === 2 || cardPileIndex1 === 5) {
pile1placement.innerHTML += `<br class="newCardLine">`;
}
});
pile2.forEach((card) => {
cardPileIndex2++;
pile2placement.innerHTML += `<img src="${card}" class="cardpiles">`;
if (cardPileIndex2 === 2 || cardPileIndex2 === 5) {
pile2placement.innerHTML += `<br class="newCardLine">`;
}
});
pile3.forEach((card) => {
cardPileIndex3++;
pile3placement.innerHTML += `<img src="${card}" class="cardpiles">`;
if (cardPileIndex3 === 2 || cardPileIndex3 === 5) {
pile3placement.innerHTML += `<br class="newCardLine">`;
}
});
// Display the pileSelection-buttons.
showPileButtons(1);
}
// onClick-functions for all the 3 pileSelection-buttons.
pileSelectionButtons.forEach(function (button) {
button.addEventListener("click", () => {
// increase the pileSelectionCounter to identify which round we are in.
pileSelectionCounter++;
// If we are not ready to present the correct card, we do the following;
if (pileSelectionCounter < 3) {
//buttonClass is defined to identify which of the 3 buttons that are clicked.
let buttonClass = button.parentElement.className;
// if pile 1 is clicked:
if (buttonClass === "pile1") {
//clear the piles.
ClearPiles();
//Retrieve the next array of cards, buy providing getNextCardArray with the selected pile (1), and then presents it using presentPiles().
presentPiles(getNextCardArray(1));
} else if (buttonClass === "pile2") {
ClearPiles();
presentPiles(getNextCardArray(2));
} else if (buttonClass === "pile3") {
ClearPiles();
presentPiles(getNextCardArray(3));
}
} else {
// When we are ready to present the correct card:
// Extracts the pile number from the button-name selected.
let CorrectPile = getNextCardArray(
button.parentElement.className.replace("pile", "")
);
// Calls the function to present the card and provdes the 11th. card (index 10), which is the right one.
presentCorrectCard(CorrectPile[10]);
}
});
});
// Created this ClearPiles-function to just empty the piles, because it`s needed more than one place.
// I concidered to add more functionality to the visual "undealing" of cards, which could improve the user experience.
function ClearPiles() {
pile1placement.innerHTML = ``;
pile2placement.innerHTML = ``;
pile3placement.innerHTML = ``;
}
// showPileButtons just shows or hides the 3 PileSelectionButtons.
function showPileButtons(boolean) {
if (boolean === 1) {
pileSelectionButtons.forEach(function (button) {
button.style.setProperty(`display`, `inline-block`);
});
} else {
pileSelectionButtons.forEach(function (button) {
button.style.setProperty(`display`, `none`);
});
}
}
// getNextCardArray takes the selectedPile, puts it in the middle of the next cardDeck to deal.
function getNextCardArray(selectedPile) {
// Defines 3 piles.
let piles = [1, 2, 3];
// removes the selectedPile from the pileArray.
piles.splice(selectedPile - 1, 1);
// The below "if" was concidered to be used as a visual "trick" to randomize which order the stacks are undealt.
// if (Math.round(Math.random()) === 1) {
// piles.reverse();
// }
// Adds the selectedPile to the middle of the array.
piles.splice(1, 0, selectedPile);
// Reassigns the pilenames to be used in the next function. (these results are already defines variables)
firstPile = "pile" + piles[0];
selectedPile = "pile" + piles[1];
LastPile = "pile" + piles[2];
// creates the variable to be returned by this function. It contains the values of 3 existing variables, which is why I use the eval().
let nextDeck = eval(firstPile).concat(eval(selectedPile), eval(LastPile));
// Returns the variable with the new order of cardPiles.
return nextDeck;
}
// presentCorrectCards is triggered when we are ready to present the card.
function presentCorrectCard(correctCard) {
// remove the card piles.
ClearPiles();
// Hides the pilebuttons.
showPileButtons(0);
// Reveals the card along with the text presented.
mainheaderHTML.innerHTML = `According to my intelligence this is your card...`;
mainheaderHTML.style.setProperty(`display`, `flex`);
correctCardHTML.innerHTML += `<img src="${correctCard}" class="correctCard">`;
}