Created
November 14, 2025 15:43
-
-
Save oelna/5e9aa8975226745febff9cc443b7c2c4 to your computer and use it in GitHub Desktop.
First draft at HTML/JS memory game by @l3o_fi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="de" class="home"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Stunde 6 Demos</title> | |
| <link rel="stylesheet" href="style.css" /> | |
| <script src="script.js" defer></script> | |
| <script src="https://unpkg.com/alpinejs" defer></script> | |
| </head> | |
| <body> | |
| <div class="game" x-data="{ cards: [] }" x-init="cards = newDeck(6)"> | |
| <header>A</header> | |
| <nav>B</nav> | |
| <main> | |
| <template x-for="card in cards"> | |
| <details class="card" x-bind:data-card-suit="card.suit" @click="check($event, card)" x-data="{ open: null, solved: false }" x-bind:open="open ? '' : null"> | |
| <summary class="card-back">Card Back</summary> | |
| <div class="card-front" inert> | |
| <h2 x-text="card.title +' of '+ card.suit"></h2> | |
| </div> | |
| </details> | |
| </template> | |
| </main> | |
| <aside>C</aside> | |
| <footer>D</footer> | |
| </div> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const cards = [ | |
| ['Hearts', 'Ace', 10], | |
| ['Hearts', 'King', 10], | |
| ['Hearts', 'Queen', 10], | |
| ['Hearts', 'Jack', 10], | |
| ['Hearts', 'Ten', 10], | |
| ['Spades', 'Ace', 10], | |
| ['Spades', 'King', 10], | |
| ['Spades', 'Queen', 10], | |
| ['Spades', 'Jack', 10], | |
| ['Spades', 'Ten', 10], | |
| ['Clubs', 'Ace', 10], | |
| ['Clubs', 'King', 10], | |
| ['Clubs', 'Queen', 10], | |
| ['Clubs', 'Jack', 10], | |
| ['Clubs', 'Ten', 10], | |
| ['Diamonds', 'Ace', 10], | |
| ['Diamonds', 'King', 10], | |
| ['Diamonds', 'Queen', 10], | |
| ['Diamonds', 'Jack', 10], | |
| ['Diamonds', 'Ten', 10], | |
| ]; | |
| let previousSuit = ''; | |
| let streak = 0; | |
| const maxStreak = 4; | |
| function shuffleArray (array) { | |
| for (let i = array.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [array[i], array[j]] = [array[j], array[i]]; | |
| } | |
| } | |
| function newCard (suit, title, val) { | |
| return { | |
| 'title': title, | |
| 'val': val | |
| } | |
| } | |
| function newDeck (size=10) { | |
| const deck = cards.map((card) => { | |
| return { | |
| title: card[1], | |
| suit: card[0], | |
| val: card[2] | |
| } | |
| }); | |
| shuffleArray(deck); | |
| console.log(deck); | |
| return deck; | |
| } | |
| function hideAll () { | |
| document.querySelectorAll('main .card').forEach(function (ele, i) { | |
| ele.removeAttribute('open'); | |
| }); | |
| } | |
| function check (event, card) { | |
| // console.log(event.target.closest('details')); | |
| if (event.target.closest('details').classList.contains('cleared')) { | |
| console.log('don\'t turn'); | |
| event.target.closest('details').setAttribute('open', '') | |
| return false; | |
| } | |
| if (previousSuit.length == 0) { | |
| // first card opened | |
| previousSuit = card.suit; | |
| console.log('first card', card.suit); | |
| } else if (card.suit == previousSuit) { | |
| // suits match | |
| streak += 1; | |
| console.log('match!', card.suit); | |
| // check win condition | |
| if (streak == maxStreak) { | |
| // mark as solved | |
| document.querySelectorAll('main .card[data-card-suit="'+card.suit+'"]').forEach(function (ele, i) { | |
| console.log(ele); | |
| ele.classList.add('cleared'); | |
| }); | |
| } | |
| } else { | |
| // suits don't match | |
| streak = 0; | |
| previousSuit = card.suit; | |
| hideAll(); | |
| console.log('awwwww!', card.suit); | |
| } | |
| // console.log('is open?', ele, card.open); | |
| console.log('streak', streak); | |
| // console.log(this, card, event.target.closest('details')); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| * { | |
| box-sizing: border-box; | |
| } | |
| html { | |
| font: 150%/1.4 system-ui, sans-serif; | |
| background-color: #ccc; | |
| } | |
| html.home { | |
| } | |
| .game { | |
| background-color: #fff; | |
| width: 80%; | |
| padding: 1.5rem; | |
| margin-block: 2rem 5rem; | |
| margin-inline: auto; | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 1rem; | |
| } | |
| .game > * { | |
| outline: 1px solid red; | |
| min-height: 5rem; | |
| } | |
| .game header { | |
| grid-column-start: span 3; | |
| } | |
| .game nav { | |
| grid-column-start: span 3; | |
| } | |
| .game main { | |
| grid-column-start: span 2; | |
| padding: 0.5rem; | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 1rem; | |
| } | |
| .game main {} | |
| .game aside { | |
| grid-column-start: span 1; | |
| } | |
| .game footer { | |
| grid-column-start: span 3; | |
| } | |
| details.card { | |
| outline: 1px solid green; | |
| width: 200px; | |
| height: 200px; | |
| position: relative; | |
| cursor: pointer; | |
| } | |
| details.card summary.card-back { | |
| background: #ccc; | |
| position: absolute; | |
| z-index: 100; | |
| top: 0; | |
| width: 100%; | |
| height: 100%; | |
| user-select: none; | |
| text-indent: -9000px; | |
| } | |
| details.card .card-front { | |
| outline: 1px solid orange; | |
| position: absolute; | |
| z-index: 0; | |
| top: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| user-select: none; | |
| } | |
| details.card[open] .card-back { | |
| opacity: 0; | |
| } | |
| details.card.cleared .card-front { | |
| background: red; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment