123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
- <script src="/dist/alpine.js" defer></script>
- <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
- </head>
- <body>
- <!-- Memory Game -->
- <div x-data="game()" class="px-10 flex items-center justify-center min-h-screen">
- <h1 class="fixed top-0 right-0 p-10 font-bold text-3xl">
- <span x-text="points"></span>
- <span class="text-xs">pts</span>
- </h1>
- <div class="flex-1 grid grid-cols-4 gap-10">
- <template x-for="(card, index) in cards" :key="index">
- <div>
- <button x-show="! card.cleared"
- :style="'background: ' + (card.flipped ? card.color : '#999')"
- :disabled="flippedCards.length >= 2"
- class="w-full h-32"
- @click="flipCard(card)"
- >
- </button>
- </div>
- </template>
- </div>
- </div>
- <!-- Flash Message -->
- <div x-data="{ show: false, message: '' }"
- x-show.transition.opacity="show"
- x-text="message"
- @flash.window="
- message = $event.detail.message;
- show = true;
- setTimeout(() => show = false, 1000)
- "
- class="fixed bottom-0 right-0 bg-green-500 text-white p-2 mb-4 mr-4 rounded"
- >
- </div>
- <script>
- function pause(milliseconds = 1000) {
- return new Promise(resolve => setTimeout(resolve, milliseconds));
- }
- function flash(message) {
- window.dispatchEvent(new CustomEvent('flash', {
- detail: { message }
- }));
- }
- function game() {
- return {
- cards: [
- { color: 'green', flipped: false, cleared: false },
- { color: 'red', flipped: false, cleared: false },
- { color: 'blue', flipped: false, cleared: false },
- { color: 'yellow', flipped: false, cleared: false },
- { color: 'green', flipped: false, cleared: false },
- { color: 'red', flipped: false, cleared: false },
- { color: 'blue', flipped: false, cleared: false },
- { color: 'yellow', flipped: false, cleared: false },
- ].sort(() => Math.random() - .5),
- get flippedCards() {
- return this.cards.filter(card => card.flipped);
- },
- get clearedCards() {
- return this.cards.filter(card => card.cleared);
- },
- get remainingCards() {
- return this.cards.filter(card => ! card.cleared);
- },
- get points() {
- return this.clearedCards.length;
- },
- async flipCard(card) {
- card.flipped = ! card.flipped;
- if (this.flippedCards.length !== 2) return;
- if (this.hasMatch()) {
- flash('You found a match!');
- await pause();
- this.flippedCards.forEach(card => card.cleared = true);
- if (! this.remainingCards.length) {
- alert('You Won!');
- }
- } else {
- await pause();
- }
- this.flippedCards.forEach(card => card.flipped = false);
- },
- hasMatch() {
- return this.flippedCards[0]['color'] === this.flippedCards[1]['color'];
- }
- };
- }
- </script>
- </body>
- </html>
|