diff --git a/index.html b/index.html index 9386faaf4..b610b0b08 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,8 @@ Superhero Memory Game - + +
@@ -17,7 +18,7 @@

Score

Pairs guessed: 0

- - + + diff --git a/src/index.js b/src/index.js index 37f3a672d..1209337bb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,34 +1,36 @@ const cards = [ - { name: 'aquaman', img: 'aquaman.jpg' }, - { name: 'batman', img: 'batman.jpg' }, - { name: 'captain america', img: 'captain-america.jpg' }, - { name: 'fantastic four', img: 'fantastic-four.jpg' }, - { name: 'flash', img: 'flash.jpg' }, - { name: 'green arrow', img: 'green-arrow.jpg' }, - { name: 'green lantern', img: 'green-lantern.jpg' }, - { name: 'ironman', img: 'ironman.jpg' }, - { name: 'spiderman', img: 'spiderman.jpg' }, - { name: 'superman', img: 'superman.jpg' }, - { name: 'the avengers', img: 'the-avengers.jpg' }, - { name: 'thor', img: 'thor.jpg' }, - { name: 'aquaman', img: 'aquaman.jpg' }, - { name: 'batman', img: 'batman.jpg' }, - { name: 'captain america', img: 'captain-america.jpg' }, - { name: 'fantastic four', img: 'fantastic-four.jpg' }, - { name: 'flash', img: 'flash.jpg' }, - { name: 'green arrow', img: 'green-arrow.jpg' }, - { name: 'green lantern', img: 'green-lantern.jpg' }, - { name: 'ironman', img: 'ironman.jpg' }, - { name: 'spiderman', img: 'spiderman.jpg' }, - { name: 'superman', img: 'superman.jpg' }, - { name: 'the avengers', img: 'the-avengers.jpg' }, - { name: 'thor', img: 'thor.jpg' } + { name: "aquaman", img: "aquaman.jpg" }, + { name: "batman", img: "batman.jpg" }, + { name: "captain america", img: "captain-america.jpg" }, + { name: "fantastic four", img: "fantastic-four.jpg" }, + { name: "flash", img: "flash.jpg" }, + { name: "green arrow", img: "green-arrow.jpg" }, + { name: "green lantern", img: "green-lantern.jpg" }, + { name: "ironman", img: "ironman.jpg" }, + { name: "spiderman", img: "spiderman.jpg" }, + { name: "superman", img: "superman.jpg" }, + { name: "the avengers", img: "the-avengers.jpg" }, + { name: "thor", img: "thor.jpg" }, + { name: "aquaman", img: "aquaman.jpg" }, + { name: "batman", img: "batman.jpg" }, + { name: "captain america", img: "captain-america.jpg" }, + { name: "fantastic four", img: "fantastic-four.jpg" }, + { name: "flash", img: "flash.jpg" }, + { name: "green arrow", img: "green-arrow.jpg" }, + { name: "green lantern", img: "green-lantern.jpg" }, + { name: "ironman", img: "ironman.jpg" }, + { name: "spiderman", img: "spiderman.jpg" }, + { name: "superman", img: "superman.jpg" }, + { name: "the avengers", img: "the-avengers.jpg" }, + { name: "thor", img: "thor.jpg" }, ]; const memoryGame = new MemoryGame(cards); -window.addEventListener('load', (event) => { - let html = ''; +memoryGame.shuffleCards(); + +window.addEventListener("load", (event) => { + let html = ""; memoryGame.cards.forEach((pic) => { html += `
@@ -39,13 +41,41 @@ window.addEventListener('load', (event) => { }); // Add all the divs to the HTML - document.querySelector('#memory-board').innerHTML = html; + document.querySelector("#memory-board").innerHTML = html; // Bind the click event of each element to a function - document.querySelectorAll('.card').forEach((card) => { - card.addEventListener('click', () => { - // TODO: write some code here - console.log(`Card clicked: ${card}`); + document.querySelectorAll(".card").forEach((card) => { + card.addEventListener("click", () => { + card.classList.add("turned"); + memoryGame.addPickedCard(card); + if (memoryGame.pickedCards.length < 2) { + return; + } + if ( + memoryGame.checkIfPair( + memoryGame.pickedCards[0].getAttribute("data-card-name"), + memoryGame.pickedCards[1].getAttribute("data-card-name") + ) + ) { + memoryGame.pickedCards.forEach((card) => { + card.classList.add("blocked"); + }); + memoryGame.clearPickedCards(); + if (memoryGame.checkIfFinished()) { + alert("You won!"); + } + } else { + setTimeout(() => { + memoryGame.pickedCards.forEach((card) => { + card.classList.remove("turned"); + }); + memoryGame.clearPickedCards(); + }, 1000); + } + document.querySelector("#pairs-clicked").innerText = + memoryGame.pairsClicked; + document.querySelector("#pairs-guessed").innerText = + memoryGame.pairsGuessed; }); }); }); diff --git a/src/memory.js b/src/memory.js index f6644827e..42e05ea76 100644 --- a/src/memory.js +++ b/src/memory.js @@ -1,18 +1,39 @@ class MemoryGame { constructor(cards) { - this.cards = cards; - // add the rest of the class properties here + this.cards = cards || []; + this.pickedCards = []; + this.pairsClicked = 0; + this.pairsGuessed = 0; } shuffleCards() { - // ... write your code here + if (!this.cards) { + return undefined; + } + for (let i = this.cards.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [this.cards[i], this.cards[j]] = [this.cards[j], this.cards[i]]; + } } - checkIfPair(card1, card2) { - // ... write your code here + addPickedCard(cardName) { + this.pickedCards.push(cardName); + } + + clearPickedCards() { + this.pickedCards = []; + } + + checkIfPair(card1Name, card2Name) { + this.pairsClicked++; + if (card1Name === card2Name) { + this.pairsGuessed++; + return true; + } + return false; } checkIfFinished() { - // ... write your code here + return this.pairsGuessed === this.cards.length / 2; } } diff --git a/styles/reset.css b/styles/reset.css new file mode 100644 index 000000000..1843f131a --- /dev/null +++ b/styles/reset.css @@ -0,0 +1,116 @@ +/*** + The new CSS reset - version 1.11.2 (last updated 15.11.2023) + GitHub page: https://github.com/elad2412/the-new-css-reset +***/ + +/* + Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property + - The "symbol *" part is to solve Firefox SVG sprite bug + - The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36) + */ +*:where( + :not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *) + ) { + all: unset; + display: revert; +} + +/* Preferred box-sizing value */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Fix mobile Safari increase font-size on landscape mode */ +html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; +} + +/* Reapply the pointer cursor for anchor tags */ +a, +button { + cursor: revert; +} + +/* Remove list styles (bullets/numbers) */ +ol, +ul, +menu, +summary { + list-style: none; +} + +/* For images to not be able to exceed their container */ +img { + max-inline-size: 100%; + max-block-size: 100%; +} + +/* removes spacing between cells in tables */ +table { + border-collapse: collapse; +} + +/* Safari - solving issue when using user-select:none on the text input doesn't working */ +input, +textarea { + -webkit-user-select: auto; +} + +/* revert the 'white-space' property for textarea elements on Safari */ +textarea { + white-space: revert; +} + +/* minimum style to allow to style meter element */ +meter { + -webkit-appearance: revert; + appearance: revert; +} + +/* preformatted text - use only for this feature */ +:where(pre) { + all: revert; + box-sizing: border-box; +} + +/* reset default text opacity of input placeholder */ +::placeholder { + color: unset; +} + +/* fix the feature of 'hidden' attribute. + display:revert; revert to element instead of attribute */ +:where([hidden]) { + display: none; +} + +/* revert for bug in Chromium browsers + - fix for the content editable attribute will work properly. + - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/ +:where([contenteditable]:not([contenteditable="false"])) { + -moz-user-modify: read-write; + -webkit-user-modify: read-write; + overflow-wrap: break-word; + -webkit-line-break: after-white-space; + -webkit-user-select: auto; +} + +/* apply back the draggable feature - exist only in Chromium and Safari */ +:where([draggable="true"]) { + -webkit-user-drag: element; +} + +/* Revert Modal native behavior */ +:where(dialog:modal) { + all: revert; + box-sizing: border-box; +} + +/* Remove details summary webkit styles */ +::-webkit-details-marker { + display: none; +}