13 | Welcome to the Meme Matching Game! Flip over two cards at a time and try to find all the matching pairs. Be quick and remember where you saw the cards!
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Continuous Deployment using AWS Code Pipeline and S3
2 |
3 | This repo contains the code files used in this [YouTube video](https://youtu.be/biYVW1TMYAU).
4 |
5 | ## TL;DR
6 | Code for a game is hosted in GitHub. We create an S3 bucket for static website hosting, then create a continuous deployment pipeline (using AWS Code Pipeline) to automatically deploy the code whenever changes are made.
7 |
8 | ## The Game
9 | A simple memory matching game. The user clicks two cards (images of memes) to try to match them. If there's a match, the cards disappear from the board. If there's no match, the cards are flipped back to their blank side so the user can try again.
10 |
11 | The game consists of HTML, CSS and JavaScript.
12 |
13 | Ideas for additional features:
14 | - A scoring mechanism
15 | - A timer
16 | - Add additional cards
17 | - Multi-player capabilities so you can compare scores
18 |
19 | ## The Deployment Environment
20 | The code will be deployed and hosted in S3.
21 |
22 | ## The Deployment Pipeline
23 | The pipeline is created using AWS Code Pipeline. The pipeline pulls the code from GitHub, and deploys it to S3 whenever a change is detected in the code.
24 |
25 | ## Cost
26 | All services used are eligible for the [AWS Free Tier](https://aws.amazon.com/free/). However, charges will incur at some point so it's recommended that you shut down resources after completing this tutorial.
27 |
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | background-color: #282c34;
4 | color: #ffffff;
5 | text-align: center;
6 | margin: 0;
7 | padding: 0;
8 | }
9 |
10 | .container {
11 | width: auto;
12 | margin: 40px auto;
13 | padding: 30px;
14 | background-color: #3c404d;
15 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.25);
16 | border-radius: 15px;
17 | }
18 |
19 | h1 {
20 | color: white;
21 | }
22 |
23 | .instructions {
24 | font-size: 20px;
25 | margin-bottom: 30px;
26 | color: #adbac7;
27 | }
28 |
29 | #game-board {
30 | display: grid;
31 | grid-template-columns: repeat(5, 1fr);
32 | grid-template-rows: repeat(2, 1fr);
33 | gap: 20px;
34 | justify-content: center;
35 | padding: 20px;
36 | }
37 |
38 | .card {
39 | width: 211.8px;
40 | height: 166.2px;
41 | background-color: #565c6f;
42 | border-radius: 10px;
43 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
44 | cursor: pointer;
45 | display: flex;
46 | align-items: center;
47 | justify-content: center;
48 | overflow: hidden;
49 | }
50 |
51 | .card img {
52 | width: 100%;
53 | height: auto;
54 | visibility: hidden; /* Hide images by default */
55 | display: block;
56 | }
57 |
58 | .card.show img {
59 | visibility: visible; /* Show image when card is flipped */
60 | }
61 |
62 | #start-game {
63 | background-color: #4caf50;
64 | color: white;
65 | padding: 12px 24px;
66 | border: none;
67 | border-radius: 5px;
68 | cursor: pointer;
69 | font-size: 18px;
70 | transition: background-color 0.3s, transform 0.3s;
71 | }
72 |
73 | #start-game:hover {
74 | background-color: #43a047; /* Darker on hover */
75 | transform: scale(1.05); /* Slightly enlarges on hover */
76 | }
77 |
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', () => {
2 | const grid = document.querySelector('#game-board');
3 | const startButton = document.getElementById('start-game');
4 | let cardsChosen = [];
5 | let cardsChosenId = [];
6 | let cardsWon = [];
7 |
8 | const cardArray = [
9 | { name: 'card1', img: 'images/distracted.png' },
10 | { name: 'card1', img: 'images/distracted.png' },
11 | { name: 'card2', img: 'images/drake.png' },
12 | { name: 'card2', img: 'images/drake.png' },
13 | { name: 'card3', img: 'images/fine.png' },
14 | { name: 'card3', img: 'images/fine.png' },
15 | { name: 'card4', img: 'images/rollsafe.png' },
16 | { name: 'card4', img: 'images/rollsafe.png' },
17 | { name: 'card5', img: 'images/success.png' },
18 | { name: 'card5', img: 'images/success.png' },
19 | // ...add more pairs as needed
20 | ];
21 |
22 | function shuffle(array) {
23 | array.sort(() => 0.5 - Math.random());
24 | }
25 |
26 | function createBoard() {
27 | shuffle(cardArray);
28 | grid.innerHTML = '';
29 | cardsWon = [];
30 |
31 | for (let i = 0; i < cardArray.length; i++) {
32 | const card = document.createElement('img');
33 | card.setAttribute('src', 'images/blank.png');
34 | card.setAttribute('data-id', i);
35 | card.addEventListener('click', flipCard);
36 | grid.appendChild(card);
37 | }
38 | }
39 |
40 | function flipCard() {
41 | let cardId = this.getAttribute('data-id');
42 | if (!cardsChosenId.includes(cardId)) {
43 | cardsChosen.push(cardArray[cardId].name);
44 | cardsChosenId.push(cardId);
45 | this.setAttribute('src', cardArray[cardId].img);
46 | if (cardsChosen.length === 2) {
47 | setTimeout(checkForMatch, 500);
48 | }
49 | }
50 | }
51 |
52 | function checkForMatch() {
53 | const cards = document.querySelectorAll('#game-board img');
54 | const firstCardId = cardsChosenId[0];
55 | const secondCardId = cardsChosenId[1];
56 |
57 | if (cardsChosen[0] === cardsChosen[1] && firstCardId !== secondCardId) {
58 | cards[firstCardId].style.visibility = 'hidden';
59 | cards[secondCardId].style.visibility = 'hidden';
60 | cards[firstCardId].removeEventListener('click', flipCard);
61 | cards[secondCardId].removeEventListener('click', flipCard);
62 | cardsWon.push(cardsChosen);
63 | } else {
64 | cards[firstCardId].setAttribute('src', 'images/blank.png');
65 | cards[secondCardId].setAttribute('src', 'images/blank.png');
66 | }
67 |
68 | cardsChosen = [];
69 | cardsChosenId = [];
70 |
71 | if (cardsWon.length === cardArray.length / 2) {
72 | alert('Congratulations! You found them all!');
73 | }
74 | }
75 |
76 | startButton.addEventListener('click', createBoard);
77 | });
78 |
--------------------------------------------------------------------------------