├── LICENSE ├── README.md ├── css ├── responsive.css └── style.css ├── images ├── bg-pentagon.svg ├── bg-triangle.svg ├── demo.jpg ├── favicon-32x32.png ├── icon-close.svg ├── icon-lizard.svg ├── icon-paper.svg ├── icon-rock.svg ├── icon-scissors.svg ├── icon-spock.svg ├── image-rules-bonus.svg ├── image-rules.svg ├── logo-bonus.svg └── logo.svg ├── index.html └── js └── app.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 amirhossein allami 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rock, Paper, Scissors Game 2 | 3 | ![demo](images/demo.jpg) 4 | 5 | [![MIT License](https://img.shields.io/badge/License-MIT-blue)](https://opensource.org/licenses/MIT) 6 | ![Last Update](https://img.shields.io/github/last-commit/amirallami-code/rock-paper-scissors-game?style=flat&color=blue) 7 | [![Stars](https://img.shields.io/github/stars/amirallami-code/rock-paper-scissors-game?style=flat&color=yellow)](https://github.com/amirallami-code/binary-search-algorithm/) 8 | ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen) 9 | ![Contributions Welcome](https://img.shields.io/badge/Contributions-welcome-brightgreen) 10 | 11 | 12 | 13 | ## Table of Contents 14 | - [Introduction](#introduction) 15 | - [How to Play](#how-to-play) 16 | - [Features](#features) 17 | - [Technologies Used](#technologies-used) 18 | - [Live Demo](#live-demo) 19 | - [Usage](#usage) 20 | - [Contributing](#contributing) 21 | - [License](#license) 22 | - [Contact Information](#contact-information) 23 | 24 | ## Introduction 25 | 26 | **Rock, Paper, Scissors** is a classic hand game that has entertained generations. This project brings the timeless game to the digital world, allowing you to play against a computer opponent anytime, anywhere. 27 | 28 | ## How to Play 29 | 30 | 1. **Players**: You vs. the Computer 31 | 2. **Rules**: 32 | - Choose your move: Rock (👊), Paper (✋), or Scissors (✌️) 33 | - The winner is determined as follows: 34 | - Rock crushes Scissors 35 | - Scissors cut Paper 36 | - Paper covers Rock 37 | - If both players choose the same shape, it's a tie 38 | 3. **Gameplay**: 39 | - Click on your chosen move 40 | - The computer's choice is generated randomly 41 | - The winner of the round is displayed 42 | - Score is updated after each round 43 | - Play as many rounds as you like! 44 | 45 | ## Features 46 | 47 | - Intuitive user interface 48 | - Real-time score tracking 49 | - Responsive design for desktop and mobile 50 | 51 | ## Technologies Used 52 | 53 | - **HTML5**: Structure of the game interface 54 | - **CSS3**: Styling and animations 55 | - **JavaScript (ES6+)**: Game logic and DOM manipulation 56 | - **LocalStorage**: For saving game progress 57 | 58 | ## Live Demo 59 | 60 | Experience the game live: [Rock, Paper, Scissors Game](https://rpsgame-amirallami.vercel.app) 61 | 62 | ## Installation 63 | 64 | To run this project locally: 65 | 66 | 1. Clone the repository: 67 | 68 | ```bash 69 | git clone https://github.com/amirallami-code/rock-paper-scissors-game.git 70 | ``` 71 | 72 | 2. Navigate to the project directory: 73 | 74 | ```bash 75 | cd rock-paper-scissors-game 76 | ``` 77 | 78 | 3. Open `index.html` in your preferred web browser 79 | 80 | ## Usage 81 | 82 | 1. Open the game in your web browser. 83 | 2. Click on your choice of Rock, Paper, or Scissors. 84 | 3. View the computer's choice and the round result. 85 | 4. Check the updated score. 86 | 5. Play again! 87 | 88 | ## Contributing 89 | 90 | We welcome contributions! If you'd like to contribute: 91 | 92 | 1. Fork the repository 93 | 2. Create a new branch (`git checkout -b feature/AmazingFeature`) 94 | 3. Make your changes 95 | 4. Commit your changes (`git commit -m 'Add some AmazingFeature'`) 96 | 5. Push to the branch (`git push origin feature/AmazingFeature`) 97 | 6. Open a Pull Request 98 | 99 | ## License 100 | 101 | This project is open source and available under the [MIT License](LICENSE). 102 | 103 | ## Contact Information 104 | 105 | For questions or feedback about this project, please contact: 106 | 107 | Amirhossein Allami - amirallami.dev@gmail.com 108 | 109 | Project Link: [https://github.com/amirallami-code/rock-paper-scissors-game](https://github.com/amirallami-code/rock-paper-scissors-game) 110 | 111 | --- 112 | 113 | We appreciate your interest in this project. If you find it helpful, consider starring the repository. 114 | -------------------------------------------------------------------------------- /css/responsive.css: -------------------------------------------------------------------------------- 1 | /* tablet */ 2 | @media only screen and (max-width: 600px) { 3 | header { 4 | width: 90%; 5 | margin: 40px 40px 0px 40px; 6 | padding: 12.5px 15px; 7 | } 8 | header img { 9 | width: 135px; 10 | } 11 | .scores { 12 | width: 100px; 13 | } 14 | .objects { 15 | height: 290px; 16 | } 17 | .circle img { 18 | max-width: 55px; 19 | height: 60px; 20 | } 21 | .circle { 22 | padding: 15px; 23 | } 24 | .guide { 25 | font-size: 20px; 26 | } 27 | .white-bg { 28 | padding: 25px; 29 | } 30 | .background-triangle { 31 | position: absolute; 32 | width: 250px; 33 | margin-top: 120px; 34 | } 35 | footer { 36 | justify-content: center; 37 | } 38 | .level-two { 39 | align-items: start; 40 | height: 320px; 41 | width: 320px; 42 | grid-template-columns: auto auto; 43 | } 44 | .result { 45 | grid-area: 2 / 2 / 2 / 2; 46 | grid-column: 1 / span 2; 47 | align-self: end; 48 | margin: 0px -100px; 49 | } 50 | .resultText { 51 | font-size: 30px; 52 | } 53 | .userPicked { 54 | width: 150px; 55 | flex-direction: column-reverse; 56 | } 57 | .botPicked { 58 | width: 150px; 59 | flex-direction: column-reverse; 60 | } 61 | .notSelected { 62 | width: 135px; 63 | height: 140px; 64 | } 65 | .userPicked .guide { 66 | font-size: 17px; 67 | } 68 | .botPicked .guide { 69 | font-size: 17px; 70 | } 71 | } 72 | /* mobile */ 73 | @media only screen and (max-width: 375px) { 74 | header { 75 | width: 90%; 76 | height: 100px; 77 | margin: 25px 25px 0px 25px; 78 | padding: 10px; 79 | border-radius: 7px; 80 | -webkit-border-radius: 7px; 81 | -moz-border-radius: 7px; 82 | -ms-border-radius: 7px; 83 | -o-border-radius: 7px; 84 | } 85 | header img { 86 | width: 100px; 87 | } 88 | .scores { 89 | width: 80px; 90 | padding: 10px; 91 | border-radius: 7px; 92 | -webkit-border-radius: 7px; 93 | -moz-border-radius: 7px; 94 | -ms-border-radius: 7px; 95 | -o-border-radius: 7px; 96 | } 97 | .scores p { 98 | font-size: 12.5px; 99 | } 100 | .user-score { 101 | font-size: 40px; 102 | } 103 | .objects { 104 | height: 240px; 105 | } 106 | .circle { 107 | padding: 10px; 108 | } 109 | .circle img { 110 | max-width: 45px; 111 | height: 50px; 112 | } 113 | .level-one .guide { 114 | width: 250px; 115 | } 116 | .background-triangle { 117 | width: 200px; 118 | } 119 | .level-two { 120 | height: 280px; 121 | width: 280px; 122 | } 123 | .notSelected { 124 | width: 115px; 125 | height: 120px; 126 | } 127 | .userPicked { 128 | width: 140px; 129 | } 130 | .botPicked { 131 | width: 140px; 132 | } 133 | .userPicked .guide { 134 | font-size: 12.5px; 135 | } 136 | .botPicked .guide { 137 | font-size: 12.5px; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | * { 8 | margin: 0; 9 | padding: 0; 10 | border: 0 solid transparent; 11 | } 12 | 13 | body { 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: space-between; 18 | height: 100vh; 19 | user-select: none; 20 | -moz-user-select: none; 21 | -webkit-user-select: none; 22 | -ms-user-select: none; 23 | line-height: 1; 24 | font-family: "Barlow Semi Condensed", sans-serif; 25 | text-rendering: optimizeSpeed; 26 | background: radial-gradient( 27 | circle at top, 28 | hsl(214, 47%, 23%), 29 | hsl(237, 49%, 15%) 30 | ); 31 | } 32 | 33 | img, 34 | svg, 35 | video, 36 | canvas, 37 | audio, 38 | iframe, 39 | embed, 40 | object { 41 | display: block; 42 | max-width: 100%; 43 | } 44 | 45 | input, 46 | button, 47 | textarea, 48 | select { 49 | font: inherit; 50 | line-height: inherit; 51 | color: inherit; 52 | } 53 | 54 | table { 55 | border-collapse: collapse; 56 | border-spacing: 0; 57 | } 58 | 59 | button, 60 | [role="button"] { 61 | cursor: pointer; 62 | background-color: transparent; 63 | -webkit-tap-highlight-color: transparent; 64 | &:focus { 65 | outline: 0; 66 | } 67 | } 68 | 69 | a { 70 | cursor: pointer; 71 | color: inherit; 72 | text-decoration: inherit; 73 | -webkit-tap-highlight-color: transparent; 74 | } 75 | 76 | h1, 77 | h2, 78 | h3, 79 | h4, 80 | h5, 81 | h6 { 82 | font-size: inherit; 83 | font-weight: inherit; 84 | } 85 | 86 | ol, 87 | ul { 88 | list-style: none; 89 | } 90 | 91 | [type="date"], 92 | [type="datetime"], 93 | [type="datetime-local"], 94 | [type="email"], 95 | [type="month"], 96 | [type="number"], 97 | [type="password"], 98 | [type="search"], 99 | [type="tel"], 100 | [type="text"], 101 | [type="time"], 102 | [type="url"], 103 | [type="week"], 104 | textarea, 105 | select { 106 | -webkit-appearance: none; 107 | -moz-appearance: none; 108 | appearance: none; 109 | width: 100%; 110 | &:focus { 111 | outline: 0; 112 | } 113 | } 114 | 115 | ::-moz-placeholder { 116 | opacity: 1; 117 | } 118 | 119 | textarea { 120 | vertical-align: top; 121 | 122 | overflow: auto; 123 | } 124 | 125 | [type="checkbox"], 126 | [type="radio"] { 127 | -webkit-appearance: none; 128 | -moz-appearance: none; 129 | appearance: none; 130 | &:focus { 131 | outline: 0; 132 | } 133 | } 134 | 135 | @media (prefers-reduced-motion: reduce) { 136 | html:focus-within { 137 | scroll-behavior: auto; 138 | } 139 | 140 | *, 141 | *::before, 142 | *::after { 143 | animation-duration: 0.01ms !important; 144 | animation-iteration-count: 1 !important; 145 | transition-duration: 0.01ms !important; 146 | scroll-behavior: auto !important; 147 | } 148 | } 149 | 150 | /* styles */ 151 | .preloader { 152 | display: flex; 153 | justify-content: center; 154 | align-items: center; 155 | position: fixed; 156 | top: 0; 157 | left: 0; 158 | height: 100%; 159 | width: 100%; 160 | color: #fff; 161 | font-size: 45px; 162 | font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 163 | Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; 164 | background: radial-gradient( 165 | circle at top, 166 | hsl(214, 47%, 23%), 167 | hsl(237, 49%, 15%) 168 | ); 169 | z-index: 9999999; 170 | overflow: hidden; 171 | transition: all 1s; 172 | -webkit-transition: all 1s; 173 | -moz-transition: all 1s; 174 | -ms-transition: all 1s; 175 | -o-transition: all 1s; 176 | } 177 | header { 178 | width: 550px; 179 | height: 130px; 180 | display: flex; 181 | align-items: center; 182 | justify-content: space-between; 183 | margin: 20px 30px 0px 30px; 184 | padding: 12.5px 20px; 185 | border: 3px solid hsl(217, 16%, 45%); 186 | border-radius: 10px; 187 | -webkit-border-radius: 10px; 188 | -moz-border-radius: 10px; 189 | -ms-border-radius: 10px; 190 | -o-border-radius: 10px; 191 | } 192 | header img { 193 | width: 150px; 194 | } 195 | .scores { 196 | display: flex; 197 | flex-direction: column; 198 | justify-content: space-between; 199 | padding: 15px 0px; 200 | align-items: center; 201 | height: 100%; 202 | width: 120px; 203 | background-color: #fff; 204 | border-radius: 10px; 205 | -webkit-border-radius: 10px; 206 | -moz-border-radius: 10px; 207 | -ms-border-radius: 10px; 208 | -o-border-radius: 10px; 209 | } 210 | .scores p { 211 | letter-spacing: 1px; 212 | color: hsl(229, 64%, 46%); 213 | } 214 | .user-score { 215 | font-weight: 700; 216 | font-size: 50px; 217 | color: hsl(229, 25%, 31%); 218 | } 219 | main div { 220 | display: flex; 221 | align-items: center; 222 | justify-content: center; 223 | } 224 | .level-one { 225 | display: flex; 226 | flex-direction: column; 227 | transition: all 0.2s; 228 | -webkit-transition: all 0.2s; 229 | -moz-transition: all 0.2s; 230 | -ms-transition: all 0.2s; 231 | -o-transition: all 0.2s; 232 | } 233 | .guide { 234 | color: #fff; 235 | font-size: 25px; 236 | padding: 25px 10px; 237 | letter-spacing: 0.5px; 238 | text-align: center; 239 | transition: all 0.2s; 240 | -webkit-transition: all 0.2s; 241 | -moz-transition: all 0.2s; 242 | -ms-transition: all 0.2s; 243 | -o-transition: all 0.2s; 244 | user-select: none; 245 | -moz-user-select: none; 246 | -webkit-user-select: none; 247 | -ms-user-select: none; 248 | } 249 | .guide { 250 | cursor: default; 251 | } 252 | .objects { 253 | height: 370px; 254 | display: flex; 255 | align-items: flex-start; 256 | } 257 | .circle { 258 | align-self: auto; 259 | padding: 20px; 260 | clip-path: circle(); 261 | border-radius: 50%; 262 | -webkit-border-radius: 50%; 263 | -moz-border-radius: 50%; 264 | -ms-border-radius: 50%; 265 | -o-border-radius: 50%; 266 | } 267 | .circle:hover { 268 | cursor: pointer; 269 | } 270 | .white-bg { 271 | padding: 35px; 272 | clip-path: circle(); 273 | background-color: #fff; 274 | box-shadow: inset 0px 7.5px 2px rgb(209, 209, 209); 275 | border-radius: 50%; 276 | -webkit-border-radius: 50%; 277 | -moz-border-radius: 50%; 278 | -ms-border-radius: 50%; 279 | -o-border-radius: 50%; 280 | } 281 | .white-bg img { 282 | max-width: 65px; 283 | height: 70px; 284 | } 285 | .objects .paper { 286 | margin-right: -50px; 287 | } 288 | .objects .scissors { 289 | margin-left: -50px; 290 | } 291 | .white-bg img { 292 | width: 70px; 293 | } 294 | .rock { 295 | align-self: end; 296 | background: linear-gradient(260deg, hsl(349, 71%, 52%), hsl(349, 70%, 56%)); 297 | box-shadow: inset 0px -9px 2px hsl(349, 56%, 46%); 298 | } 299 | .paper { 300 | background: linear-gradient(260deg, hsl(230, 89%, 62%), hsl(230, 89%, 65%)); 301 | box-shadow: inset 0px -9px 2px hsl(230, 51%, 47%); 302 | } 303 | .scissors { 304 | background: linear-gradient(260deg, hsl(39, 89%, 49%), hsl(40, 84%, 53%)); 305 | box-shadow: inset 0px -9px 2px hsl(40, 74%, 43%); 306 | } 307 | .background-triangle { 308 | position: absolute; 309 | width: 500px; 310 | margin-top: 100px; 311 | } 312 | footer { 313 | width: 100%; 314 | display: flex; 315 | align-items: end; 316 | justify-content: end; 317 | } 318 | 319 | .rules { 320 | color: #fff; 321 | border: 2px solid #fff; 322 | padding: 10px 25px; 323 | margin: 30px 50px; 324 | border-radius: 5px; 325 | } 326 | .modal { 327 | display: none; 328 | opacity: 0; 329 | align-items: center; 330 | justify-content: center; 331 | position: fixed; 332 | z-index: 1; 333 | left: 0; 334 | width: 100%; 335 | height: 100vh; 336 | background-color: transparent; 337 | padding: 0px 5%; 338 | transition: all 0.2s; 339 | -webkit-transition: all 0.2s; 340 | -moz-transition: all 0.2s; 341 | -ms-transition: all 0.2s; 342 | -o-transition: all 0.2s; 343 | } 344 | .modal-content { 345 | padding: 20px; 346 | background-color: #fff; 347 | border-radius: 5px; 348 | -webkit-border-radius: 5px; 349 | -moz-border-radius: 5px; 350 | -ms-border-radius: 5px; 351 | -o-border-radius: 5px; 352 | } 353 | .modal-content__details { 354 | display: flex; 355 | align-items: center; 356 | justify-content: space-between; 357 | padding-bottom: 25px; 358 | } 359 | .modal-content__details span { 360 | font-size: 25px; 361 | font-weight: 700; 362 | color: hsl(229, 25%, 31%); 363 | } 364 | .modal-content__details img { 365 | width: 25px; 366 | padding: 5px; 367 | } 368 | .modal-content__details img:hover { 369 | cursor: pointer; 370 | } 371 | .modal-content__image img { 372 | padding: 10px; 373 | } 374 | 375 | .level-two { 376 | display: none; 377 | grid-template-columns: auto auto auto; 378 | column-gap: 5px; 379 | opacity: 0; 380 | flex-direction: column; 381 | align-items: center; 382 | justify-content: center; 383 | width: auto; 384 | transition: all 0.7s ease-in-out; 385 | } 386 | .level-two .guide { 387 | font-size: 17px; 388 | } 389 | .userPicked { 390 | display: flex; 391 | flex-direction: column; 392 | transition: all 0.3s; 393 | -webkit-transition: all 0.3s; 394 | -moz-transition: all 0.3s; 395 | -ms-transition: all 0.3s; 396 | -o-transition: all 0.3s; 397 | } 398 | .botPicked { 399 | display: flex; 400 | flex-direction: column; 401 | } 402 | .notSelected { 403 | display: flex; 404 | width: 175px; 405 | height: 180px; 406 | background-color: hsl(237, 49%, 15%); 407 | clip-path: circle(); 408 | border-radius: 50%; 409 | -webkit-border-radius: 50%; 410 | -moz-border-radius: 50%; 411 | -ms-border-radius: 50%; 412 | -o-border-radius: 50%; 413 | } 414 | .Selected { 415 | display: none; 416 | opacity: 0; 417 | transition: all 0.3s; 418 | -webkit-transition: all 0.3s; 419 | -moz-transition: all 0.3s; 420 | -ms-transition: all 0.3s; 421 | -o-transition: all 0.3s; 422 | } 423 | .result { 424 | display: flex; 425 | opacity: 0; 426 | overflow: hidden; 427 | width: 0; 428 | height: max-content; 429 | justify-self: center; 430 | 431 | align-items: center; 432 | justify-content: space-evenly; 433 | flex-direction: column; 434 | width: auto; 435 | transition: all 0.5s ease-in-out; 436 | } 437 | .resultText { 438 | color: #fff; 439 | font-size: 35px; 440 | padding: 20px; 441 | } 442 | .resultButton, 443 | .resetScoreBtn { 444 | color: hsl(229, 25%, 31%); 445 | background-color: #fff; 446 | padding: 10px 40px; 447 | margin: 5px; 448 | transition: all 0.2s; 449 | border-radius: 5px; 450 | -webkit-border-radius: 5px; 451 | -moz-border-radius: 5px; 452 | -ms-border-radius: 5px; 453 | -o-border-radius: 5px; 454 | -webkit-transition: all 0.2s; 455 | -moz-transition: all 0.2s; 456 | -ms-transition: all 0.2s; 457 | -o-transition: all 0.2s; 458 | } 459 | .resultButton:hover, 460 | .resetScoreBtn:hover { 461 | color: hsl(349, 71%, 52%); 462 | } 463 | -------------------------------------------------------------------------------- /images/bg-pentagon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/bg-triangle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amirallami-code/rock-paper-scissors-game/b54b6b5848b824af0452d4e36ea359b212d73ff3/images/demo.jpg -------------------------------------------------------------------------------- /images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amirallami-code/rock-paper-scissors-game/b54b6b5848b824af0452d4e36ea359b212d73ff3/images/favicon-32x32.png -------------------------------------------------------------------------------- /images/icon-close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon-lizard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon-paper.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon-rock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon-scissors.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icon-spock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/image-rules-bonus.svg: -------------------------------------------------------------------------------- 1 | BEATSBEATSBEATSBEATSBEATSBEATSBEATSBEATSBEATSBEATS -------------------------------------------------------------------------------- /images/image-rules.svg: -------------------------------------------------------------------------------- 1 | BEATSBEATSBEATS -------------------------------------------------------------------------------- /images/logo-bonus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Rock, Paper, Scissors game 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 |
loading...
22 | 23 |
24 | logo 25 |
26 |

score

27 | 0 28 |
29 |
30 |
31 |
32 |

Choose one of the following items to start...

33 |
34 | triangle 35 |
36 |
37 |
38 |
39 | paper 40 |
41 |
42 |
43 |
44 | rock 45 |
46 |
47 |
48 |
49 | scissors 50 |
51 |
52 |
53 |
54 |
55 |
56 |

YOU PICKED

57 | 58 |
59 |
60 |

61 | 62 | 63 |
64 |
65 |

THE HOUSE PICKED

66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | let $ = document 2 | 3 | const preloaderElement = $.querySelector('.preloader') 4 | 5 | const rulesBtn = $.querySelector('.rules') 6 | const modalElem = $.querySelector('.modal') 7 | const closeBtn = $.querySelector('.close-button') 8 | 9 | const userScoreElem = $.querySelector('.user-score') 10 | 11 | const levelOneWrapper = $.querySelector('.level-one') 12 | const guideElem = $.querySelector('.guide') 13 | const rockElem = $.querySelector('.rock') 14 | const paperElem = $.querySelector('.paper') 15 | const scissorsElem = $.querySelector('.scissors') 16 | 17 | const userPickedElem = $.querySelector('.userPicked') 18 | const levelTwoWrapper = $.querySelector('.level-two') 19 | const notSelectedElem = $.querySelector('.notSelected') 20 | const SelectedElem = $.querySelector('.Selected') 21 | 22 | const resultElem = $.querySelector('.result') 23 | const resultTextElem = $.querySelector('.resultText') 24 | const resultButtonElem = $.querySelector('.resultButton') 25 | const resetScoreBtn = $.querySelector(".resetScoreBtn"); 26 | 27 | let userLevel = 1 28 | let userScore = 0 29 | let userSelectedObject = null 30 | let randomNumber = null 31 | 32 | let objects = ['rock', 'paper', 'scissors'] 33 | 34 | if (localStorage.getItem('score') === null) { 35 | localStorage.setItem('score', userScore) 36 | } 37 | userScore = localStorage.getItem('score') 38 | 39 | userScoreElem.innerHTML = userScore 40 | 41 | window.addEventListener('load', function () { 42 | preloaderElement.style.opacity = 0; 43 | this.setTimeout(function () { 44 | preloaderElement.style.display = "none"; 45 | }, 1050) 46 | }) 47 | 48 | // find user clicked object 49 | if (userLevel == 1) { 50 | levelOneWrapper.addEventListener('click', event => { 51 | let userObjectClass = event.target.getAttribute("class") 52 | let userObjectAlt = event.target.getAttribute("alt") 53 | 54 | if (userObjectClass == 'circle scissors' && userObjectAlt == null || userObjectClass == null && userObjectAlt == 'scissors') { 55 | 56 | userSelectedObject = 'scissors' 57 | 58 | } else if (userObjectClass == 'circle paper' && userObjectAlt == null || userObjectClass == null && userObjectAlt == 'paper') { 59 | 60 | userSelectedObject = 'paper' 61 | 62 | } else if (userObjectClass == 'circle rock' && userObjectAlt == null || userObjectClass == null && userObjectAlt == 'rock') { 63 | 64 | userSelectedObject = 'rock' 65 | } else if (userObjectAlt == 'holder') { 66 | userSelectedObject = event.target.children[0].alt 67 | } 68 | 69 | if (userSelectedObject != null) { 70 | // hide transition 71 | setTimeout(() => { 72 | levelOneWrapper.style.display = 'none' 73 | }, 200) 74 | levelOneWrapper.style.opacity = '0' 75 | guideElem.style.opacity = '0' 76 | 77 | userLevel = 2 78 | setTimeout(() => { 79 | objectGenerator(userSelectedObject) 80 | }, 500); 81 | } 82 | }) 83 | } 84 | 85 | // functions 86 | const changeScore = () => { 87 | localStorage.setItem('score', userScore) 88 | preloaderElement.style.opacity = 100; 89 | preloaderElement.style.display = "flex"; 90 | setTimeout(() => { 91 | window.location.reload() 92 | }, 500) 93 | levelTwoWrapper.style.opacity = '0' 94 | } 95 | 96 | const objectGenerator = objectName => { 97 | 98 | // unhide transition 99 | setTimeout(() => { 100 | levelTwoWrapper.style.opacity = '1' 101 | }, 500) 102 | levelTwoWrapper.style.display = 'grid' 103 | 104 | let objectTemplate = ` 105 |
106 |
107 | ${objectName} 108 |
109 |
` 110 | 111 | userPickedElem.insertAdjacentHTML('beforeend', objectTemplate) 112 | generateRandomNumber(randomNumber) 113 | } 114 | 115 | const generateRandomNumber = randomNumber => { 116 | let createRandomNum = Math.floor(Math.random() * 2.5) 117 | randomNumber = createRandomNum 118 | insertObjectToDom(randomNumber) 119 | } 120 | 121 | const insertObjectToDom = randomNum => { 122 | let findRandomObjectName = objects[randomNum] 123 | 124 | if (findRandomObjectName != undefined) { 125 | setTimeout(() => { 126 | notSelectedElem.style.display = 'none' 127 | SelectedElem.style.display = 'flex' 128 | }, 1900) 129 | setTimeout(() => { 130 | SelectedElem.style.opacity = '1' 131 | definitionLastResult() 132 | }, 2000) 133 | 134 | // insert random object in DOM 135 | let randomObjectTemplate = ` 136 |
137 |
138 | ${findRandomObjectName} 139 |
140 |
` 141 | 142 | SelectedElem.insertAdjacentHTML('beforeend', randomObjectTemplate) 143 | } 144 | } 145 | 146 | const definitionLastResult = () => { 147 | 148 | let definitionResult = null 149 | let botObjectWrapper = SelectedElem.querySelector('div').getAttribute('id') 150 | let userObjectWrapper = userPickedElem.querySelector('div').getAttribute('id') 151 | 152 | if (userObjectWrapper === 'rock' && botObjectWrapper === 'paper' || 153 | userObjectWrapper === 'scissors' && botObjectWrapper === 'rock' || 154 | userObjectWrapper === 'paper' && botObjectWrapper === 'scissors') { 155 | definitionResult = 'lose' 156 | userScore-- 157 | } else if ( 158 | userObjectWrapper === 'rock' && botObjectWrapper === 'scissors' || 159 | userObjectWrapper === 'scissors' && botObjectWrapper === 'paper' || 160 | userObjectWrapper === 'paper' && botObjectWrapper === 'rock' 161 | ) { 162 | definitionResult = 'win' 163 | userScore++ 164 | } else if (userObjectWrapper === botObjectWrapper) { 165 | definitionResult = 'draw' 166 | } 167 | generatLastResult(definitionResult, userScore) 168 | } 169 | 170 | const generatLastResult = (result, userScore) => { 171 | userScoreElem.innerHTML = userScore 172 | setTimeout(() => { 173 | resultElem.style.width = 'max-content'; 174 | resultElem.style.opacity = '1' 175 | }, 650) 176 | 177 | if (result === 'lose') { 178 | resultTextElem.style.color = "#dc2e4e"; 179 | resultTextElem.innerHTML = 'YOU LOSE' 180 | setTimeout(() => { 181 | userPickedElem.style.filter = 'grayscale(1)' 182 | userPickedElem.style.opacity = '0.6' 183 | }, 400) 184 | } else if (result === 'win') { 185 | resultTextElem.style.color = "#31dc2e"; 186 | resultTextElem.innerHTML = 'YOU WIN' 187 | setTimeout(() => { 188 | SelectedElem.style.filter = 'grayscale(1)' 189 | SelectedElem.style.opacity = '0.6' 190 | }, 400) 191 | } else if (result === 'draw') { 192 | resultTextElem.innerHTML = 'DRAW' 193 | } 194 | } 195 | 196 | // rules button logic 197 | rulesBtn.addEventListener('click', () => { 198 | modalElem.style.display = 'flex' 199 | setTimeout(() => { 200 | modalElem.style.opacity = '1' 201 | modalElem.style.backgroundColor = 'rgba(0, 0, 0, 0.4)' 202 | }, 0) 203 | }) 204 | closeBtn.addEventListener('click', () => { 205 | modalElem.style.display = 'none' 206 | modalElem.style.opacity = '0' 207 | modalElem.style.backgroundColor = 'transparent' 208 | }) 209 | resultButtonElem.addEventListener('click', () => { 210 | changeScore(); 211 | }) 212 | resetScoreBtn.addEventListener("click", () => { 213 | userScore = 0; 214 | changeScore(); 215 | }) --------------------------------------------------------------------------------