├── dice-1.png ├── dice-2.png ├── dice-3.png ├── dice-4.png ├── dice-5.png ├── dice-6.png ├── pig_game.gif ├── pig-game-flowchart.png ├── README.md ├── index.html ├── .gitignore ├── script.js └── style.css /dice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-1.png -------------------------------------------------------------------------------- /dice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-2.png -------------------------------------------------------------------------------- /dice-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-3.png -------------------------------------------------------------------------------- /dice-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-4.png -------------------------------------------------------------------------------- /dice-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-5.png -------------------------------------------------------------------------------- /dice-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/dice-6.png -------------------------------------------------------------------------------- /pig_game.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/pig_game.gif -------------------------------------------------------------------------------- /pig-game-flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/somekindofwallflower/pig-game/master/pig-game-flowchart.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pig game 2 | 3 | Pig is a simple dice game. 4 | 5 | Each turn, a player repeatedly rolls a dice until either a 1 is rolled or the player decides to "hold": 6 | 7 | - If the player rolls a 1, they score nothing and it becomes the next player's turn. 8 | - If the player rolls any other number, it is added to their turn total and the player's turn continues. 9 | - If a player chooses to "hold", their turn total is added to their score, and it becomes the next player's turn. 10 | > The first player to score 100 or more points wins. 11 | 12 | 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Pig Game 9 | 10 | 11 |
12 |
13 |

Player 1

14 |

43

15 |
16 |

Current

17 |

0

18 |
19 |
20 |
21 |

Player 2

22 |

24

23 |
24 |

Current

25 |

0

26 |
27 |
28 | 29 | Playing dice 30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // Selecting elements 4 | const player0El = document.querySelector(".player--0"); 5 | const player1El = document.querySelector(".player--1"); 6 | const score0El = document.querySelector("#score--0"); 7 | // Note: getElementById works a bit faster than querySelector 8 | const score1El = document.getElementById("score--1"); 9 | const current0El = document.getElementById("current--0"); 10 | const current1El = document.getElementById("current--1"); 11 | const diceEl = document.querySelector(".dice"); 12 | const btnNew = document.querySelector(".btn--new"); 13 | const btnRoll = document.querySelector(".btn--roll"); 14 | const btnHold = document.querySelector(".btn--hold"); 15 | 16 | //Starting conditions 17 | score0El.textContent = 0; 18 | score1El.textContent = 0; 19 | diceEl.classList.add("hidden"); 20 | 21 | let scores, currentScore, activePlayer, playing; 22 | 23 | const init = function() { 24 | scores = [0, 0]; 25 | currentScore = 0; 26 | activePlayer = 0; 27 | playing = true; 28 | 29 | score0El.textContent = 0; 30 | score1El.textContent = 0; 31 | current0El.textContent = 0; 32 | current1El.textContent = 0; 33 | 34 | player0El.classList.remove("player--winner"); 35 | player1El.classList.remove("player--winner"); 36 | player1El.classList.remove("player--active"); 37 | player0El.classList.add("player--active"); 38 | }; 39 | 40 | init(); 41 | 42 | const switchPlayer = () => { 43 | document.getElementById(`current--${activePlayer}`).textContent = 0; 44 | activePlayer = activePlayer === 0 ? 1 : 0; 45 | currentScore = 0; 46 | player0El.classList.toggle("player--active"); 47 | player1El.classList.toggle("player--active"); 48 | }; 49 | 50 | // Roll button clicked 51 | btnRoll.addEventListener("click", function() { 52 | if (playing) { 53 | // 1. Generate a random dice roll 54 | const dice = Math.trunc(Math.random() * 6) + 1; 55 | // 2. Display the dice 56 | diceEl.classList.remove("hidden"); 57 | diceEl.src = `dice-${dice}.png`; 58 | // 3. Check for rolled 1: if true, switch to next player 59 | if (dice != 1) { 60 | // Add dice to current score 61 | currentScore += dice; 62 | document.getElementById(`current--${activePlayer}`).textContent = currentScore; 63 | } else { 64 | // Switch to next player 65 | switchPlayer(); 66 | } 67 | } 68 | }); 69 | 70 | // Hold button clicked 71 | btnHold.addEventListener("click", function(e) { 72 | if (playing) { 73 | // 1.Add current score to active player's score 74 | scores[activePlayer] += currentScore; 75 | // 2.Check if player's score is > =100 76 | document.getElementById(`score--${activePlayer}`).textContent = scores[activePlayer]; 77 | // Finish game 78 | if (scores[activePlayer] >= 100) { 79 | document.querySelector(`.player--${activePlayer}`).classList.add("player--winner"); 80 | document.querySelector(`.player--${activePlayer}`).classList.remove("player--active"); 81 | diceEl.classList.add("hidden"); 82 | playing = false; 83 | } 84 | // Switch to the next player 85 | switchPlayer(); 86 | } 87 | 88 | }); 89 | 90 | // Resetting the game using new button 91 | btnNew.addEventListener("click", init); 92 | 93 | 94 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap'); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: inherit; 7 | } 8 | 9 | html { 10 | font-size: 62.5%; 11 | box-sizing: border-box; 12 | } 13 | 14 | body { 15 | font-family: 'Nunito', sans-serif; 16 | font-weight: 400; 17 | height: 100vh; 18 | color: #333; 19 | background-image: linear-gradient(to top left, rgba(217, 159, 159, 0.6) 0%, rgba(81, 88, 133, 0.9) 100%); 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | 25 | /* LAYOUT */ 26 | main { 27 | position: relative; 28 | width: 100rem; 29 | height: 60rem; 30 | background-color: rgba(255, 255, 255, 0.35); 31 | backdrop-filter: blur(200px); 32 | filter: blur(); 33 | box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25); 34 | border-radius: 9px; 35 | overflow: hidden; 36 | display: flex; 37 | } 38 | 39 | .player { 40 | flex: 50%; 41 | padding: 9rem; 42 | display: flex; 43 | flex-direction: column; 44 | align-items: center; 45 | transition: all 0.75s; 46 | } 47 | 48 | /* ELEMENTS */ 49 | .name { 50 | position: relative; 51 | font-size: 4rem; 52 | text-transform: uppercase; 53 | letter-spacing: 1px; 54 | word-spacing: 2px; 55 | font-weight: 300; 56 | margin-bottom: 1rem; 57 | } 58 | 59 | .score { 60 | font-size: 8rem; 61 | font-weight: 300; 62 | color: #c7365f; 63 | margin-bottom: auto; 64 | } 65 | 66 | .player--active { 67 | background-color: rgba(255, 255, 255, 0.4); 68 | } 69 | .player--active .name { 70 | font-weight: 700; 71 | } 72 | .player--active .score { 73 | font-weight: 400; 74 | } 75 | 76 | .player--active .current { 77 | opacity: 1; 78 | } 79 | 80 | .current { 81 | background-color: #c7365f; 82 | opacity: 0.8; 83 | border-radius: 9px; 84 | color: #fff; 85 | width: 65%; 86 | padding: 2rem; 87 | text-align: center; 88 | transition: all 0.75s; 89 | } 90 | 91 | .current-label { 92 | text-transform: uppercase; 93 | margin-bottom: 1rem; 94 | font-size: 1.7rem; 95 | color: #ddd; 96 | } 97 | 98 | .current-score { 99 | font-size: 3.5rem; 100 | } 101 | 102 | /* ABSOLUTE POSITIONED ELEMENTS */ 103 | .btn { 104 | position: absolute; 105 | left: 50%; 106 | transform: translateX(-50%); 107 | color: #444; 108 | background: none; 109 | border: none; 110 | font-family: inherit; 111 | font-size: 1.8rem; 112 | text-transform: uppercase; 113 | cursor: pointer; 114 | font-weight: 400; 115 | transition: all 0.2s; 116 | 117 | background-color: white; 118 | background-color: rgba(255, 255, 255, 0.6); 119 | backdrop-filter: blur(10px); 120 | 121 | padding: 0.7rem 2.5rem; 122 | border-radius: 50rem; 123 | box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1); 124 | } 125 | 126 | .btn::first-letter { 127 | font-size: 2.4rem; 128 | display: inline-block; 129 | margin-right: 0.7rem; 130 | } 131 | 132 | .btn--new { 133 | top: 4rem; 134 | } 135 | .btn--roll { 136 | top: 39.3rem; 137 | } 138 | .btn--hold { 139 | top: 46.1rem; 140 | } 141 | 142 | .btn:active { 143 | transform: translate(-50%, 3px); 144 | box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15); 145 | } 146 | 147 | .btn:focus { 148 | outline: none; 149 | } 150 | 151 | .dice { 152 | position: absolute; 153 | left: 50%; 154 | top: 16.5rem; 155 | transform: translateX(-50%); 156 | height: 10rem; 157 | box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2); 158 | } 159 | 160 | .player--winner { 161 | background-color: #181D31; 162 | } 163 | 164 | .player--winner .name { 165 | font-weight: 700; 166 | color: #c7365f; 167 | } 168 | 169 | 170 | .hidden { 171 | display: none; 172 | } 173 | --------------------------------------------------------------------------------