├── 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 |
19 |
20 |
21 | Player 2
22 | 24
23 |
27 |
28 |
29 |
30 | 🔄 New game
31 | 🎲 Roll dice
32 | 📥 Hold
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 |
--------------------------------------------------------------------------------