Skip to content
Related Articles

Related Articles

Pig Game Design using JavaScript
  • Difficulty Level : Hard
  • Last Updated : 22 Jan, 2021

In this article, we will be explaining the steps and various logic required in making of the famous Pig Game, which is a virtual dice game. 

About Game: In this game, User Interface (UI) contains user/player that can do three things, they are as follows:

There will be two players in this game. At the start of the game Player 1 will be the CurrentPlayer and Player 2 will be the in-active one.

  1. Roll the dice: The current player has to roll the dice and then a random number will be generated. If current player gets any number other than 1 on the dice then that number will be added to the current score (initially the current score will be 0) and then the new score will be displayed under Current Score section.  Note: If the current player gets 1 on the dice then the players will be switched i.e. the current player will become in-active and vice-versa.
  2. Hold: If the current player clicks on HOLD, then the Current Score will be added to the Total Score. When the active player clicks the Hold button then the total score is evaluated. If the Total Score >= 100 then the current player wins else the players are switched.
  3. Reset: All the scores are set to 0 and Player 1 is set as the starting player (current player).

The above flow of the game can also be understood by the below flow-chart:

FLOWCHART FOR THE PIG GAME

Making of Game: Being a game rendered by the web browser, it is built by the help of HTML, CSS (for the Front-end) and JavaScript (for the Back-end). The main logic of the game lies in the JS file whereas the appearance and the User Interface is rendered by HTML and CSS. In this project, there are basically four types of files:



  • HTML File (index.html)
  • CSS File (style.css)
  • JavaScript File (script.js file)
  • Images (dice.png file)

We will analyze all these files and thus make you understand about their working/contribution in this game. So, first let’s start with index.html file:

HTML File: Index.html file is the file which makes the web browsers understand and thus interpret what type of document we are making. It stands for Hyper Text Markup Language, our web browsers read this file and understand its component via the V8 Engine (which parses the code in a language so that the browser can understand it). Below is the HTML code for this game:

HTML

filter_none

edit
close

play_arrow

link
brightness_4
code

<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content=
        "width=device-width, initial-scale=1.0" />
  
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <title>Pig Game</title>
</head>
  
<body>
    <main>
        <section class="player player--0 player--active">
            <h2 class="name" id="name--0">Player 1</h2>
            <p class="score" id="score--0">43</p>
  
            <div class="current">
                <p class="current-label">Current</p>
  
                <p class="current-score" id="current--0">0</p>
  
            </div>
        </section>
  
        <section class="player player--1">
            <h2 class="name" id="name--1">Player 2</h2>
            <p class="score" id="score--1">24</p>
  
            <div class="current">
                <p class="current-label">Current</p>
  
                <p class="current-score" id="current--1">0</p>
  
            </div>
        </section>
  
        <img src="dice-5.png" alt="Playing dice" class="dice" />
        <button class="btn btn--new">New game</button>
        <button class="btn btn--roll">Roll dice</button>
        <button class="btn btn--hold">Hold</button>
    </main>
    <script src="script.js"></script>
</body>
  
</html>

chevron_right


In the above code, we have used various classes (for eg: btn btn–roll, rte), these will be used for the styling purpose in the CSS file, and will discuss them under the CSS files.

CSS File: In order to format and style the markup created by HTML, we need Cascading Style Sheets so that the markup (code) looks way better. Below is the CSS code for the game is given below. Before diving in the code, just have a quick look at which classes and ids are for what purpose:

  1. For overall HTML page and elements: * will affect the every element and tag in the markup. We have used 2 more tags to provide some particular styling which are html and body tag’s styling.
  2. Layout elements: Defined main tag & player class styling there. We have defined position attribute for main tag and set its property to relative.
  3. Self Made Classes: General styling needed to make the page more appealing.
  4. Absolute Positioned Classes: I have set the position attribute of btn and other classes and set its value to absolute as we have to make sure that the buttons and other elements are always at the right place in the page. Absolute position will make the arrangement of that particular element according to the element which is positioned relative (in this case, it is the main tag).

CSS

filter_none

edit
close

play_arrow

link
brightness_4
code

@import url(
* {
    margin: 0;
    padding: 0;
    box-sizing: inherit;
}
  
html {
    font-size: 62.5%;
    box-sizing: border-box;
}
  
body {
    font-family: 'Nunito', sans-serif;
    font-weight: 400;
    height: 100vh;
    color: #333;
    background-image: linear-gradient(to top left,
        #753682 0%, #bf2e34 100%);
    display: flex;
    align-items: center;
    justify-content: center;
}
  
  
/* LAYOUT */
main {
    position: relative;
    width: 100rem;
    height: 60rem;
    background-color: rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(200px);
    filter: blur();
    box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25);
    border-radius: 9px;
    overflow: hidden;
    display: flex;
}
  
.player {
    flex: 50%;
    padding: 9rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: all 0.75s;
}
  
  
/* ELEMENTS */
.name {
    position: relative;
    font-size: 4rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    word-spacing: 2px;
    font-weight: 300;
    margin-bottom: 1rem;
}
  
.score {
    font-size: 8rem;
    font-weight: 300;
    color: #c7365f;
    margin-bottom: auto;
}
  
.player--active {
    background-color: rgba(255, 255, 255, 0.4);
}
  
.player--active .name {
    font-weight: 700;
}
  
.player--active .score {
    font-weight: 400;
}
  
.player--active .current {
    opacity: 1;
}
  
.current {
    background-color: #c7365f;
    opacity: 0.8;
    border-radius: 9px;
    color: #fff;
    width: 65%;
    padding: 2rem;
    text-align: center;
    transition: all 0.75s;
}
  
.current-label {
    text-transform: uppercase;
    margin-bottom: 1rem;
    font-size: 1.7rem;
    color: #ddd;
}
  
.current-score {
    font-size: 3.5rem;
}
  
  
/* ABSOLUTE POSITIONED ELEMENTS */
.btn {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    color: #444;
    background: none;
    border: none;
    font-family: inherit;
    font-size: 1.8rem;
    text-transform: uppercase;
    cursor: pointer;
    font-weight: 400;
    transition: all 0.2s;
    background-color: white;
    background-color: rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(10px);
    padding: 0.7rem 2.5rem;
    border-radius: 50rem;
    box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1);
}
  
.btn::first-letter {
    font-size: 2.4rem;
    display: inline-block;
    margin-right: 0.7rem;
}
  
.btn--new {
    top: 4rem;
}
  
.btn--roll {
    top: 39.3rem;
}
  
.btn--hold {
    top: 46.1rem;
}
  
.btn:active {
    transform: translate(-50%, 3px);
    box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15);
}
  
.btn:focus {
    outline: none;
}
  
.dice {
    position: absolute;
    left: 50%;
    top: 16.5rem;
    transform: translateX(-50%);
    height: 10rem;
    box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2);
}
  
.player--winner {
    background-color: #2f2f2f;
}
  
.player--winner .name {
    font-weight: 700;
    color: #c7365f;
}
  
.hidden {
    display: none;
}

chevron_right


We have used Google fonts rather than the default browser’s font. That’s why we have imported the font from the Google fonts website:

@import url(‘https://fonts.googleapis.com/css2?family=Nunito&display=swap’);



In the HTML code, we have provided names of various classes. In this file, we have provided their different functionalities.  The CSS file plays an important role in making a webpage or a game look good (only in case of web browsers). Below is the effect of CSS on the game. 

First one is the UI with HTML + CSS while the Second UI is with HTML only

Till now, we have made the UI of the game perfectly, now comes the trickier part. So let’s dive into the Game Logic…

JavaScript File: There are some JavaScript variables, we can use two type of variables i.e. let and constant. One can modify the variables declared with let, while the variables declared with constant can’t be changed. In the JavaScript file, we are basically doing the DOM Manipulations (everything in JavaScript is a type of Object, so we term the UI as the Document Object Model). So document.querySelector() is a way of selecting elements from the DOM. 

In order to understand the work-flow of the logic, we have to first understand the concept of Event Listeners. Event Listeners are the functions that performs an action based on certain events. They wait for the specific event to happen. We have a total of 03 event listeners for this game:  btnRoll, btnHold, btnNew.  We will understand functionalities of all these event listeners:

Note: Before heading to the event handlers section, we must declare some variables in the file so that we can use them later in our game logic.

Javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

'use strict';
  
// Selecting elements
const player0El = document.querySelector('.player--0');
const player1El = document.querySelector('.player--1');
const score0El = document.querySelector('#score--0');
const score1El = document.getElementById('score--1');
const current0El = document.getElementById('current--0');
const current1El = document.getElementById('current--1');
  
const diceEl = document.querySelector('.dice');
const btnNew = document.querySelector('.btn--new');
const btnRoll = document.querySelector('.btn--roll');
const btnHold = document.querySelector('.btn--hold');
  
let scores, currentScore, activePlayer, playing;

chevron_right


At the very beginning of the JavaScript File, there is a line ‘use strict’. The purpose of “use strict” is to indicate that the code should be executed in “strict mode”.  All modern browsers support “use strict” except Internet Explorer 9 and lower. 

Now lets start to see the code for each of the 3 event handlers.

1. btnRoll Event Handler:

Javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

// Rolling dice functionality
btnRoll.addEventListener('click', function () {
  if (playing) {
    
    // 1. Generating a random dice roll
    const dice = Math.trunc(Math.random() * 6) + 1;
  
    // 2. Display dice
    diceEl.classList.remove('hidden');
    diceEl.src = `dice-${dice}.png`;
  
    // 3. Check for rolled 1
    if (dice !== 1) {
      
      // Add dice to current score
      currentScore += dice;
      document.getElementById(
        `current--${activePlayer}`
      ).textContent = currentScore;
    } else {
      
      // Switch to next player
      switchPlayer();
    }
  }
});

chevron_right


This event handler is in action whenever the player clicks on Roll button (that is why we have used the click event there). Then there is a callback function which starts with an if-else block. As we have declared the variable playing = true, so the if block of this event handler will be true and thus the code of if block will be executed. Following are the steps ahead:

  1. Step1: After the player hits the roll dice button, this event handler produces a random number using the Math.trunc() function. We have used Math.trunc() function because this function returns the integer portion of the randomly generated function and have added a 1 to it because the random() function can generate any number starting from 0 to 1 but in our case, we only need numbers from 1 to 6. <br>Understanding the dice variable: The dice variable will store the random generated number. Say the Math.random() function generates number 0.02. According to the code, first 0.02 will be multiplied by 6. So variable dice will now have a value of 0.12. Then the Math.trunc() function will come into play and will make the dice variable 0. Now 1 will be addded to the variable which will make the dice = 1 (That is what we need as a number for our dice)
  2. Step2: Now we have got the score for the dice, we have to display the dice corresponding to the number of dice. (In the CSS file, we have made a class named as hidden which will make the dice hidden initially at the start of the game) But as now we have a dice number to be displayed in the form of dice image, we have to remove the hidden class. This is achieved by the line diceE1.classList.remove(‘hidden’) and then the correct image of dice is rendered to the UI. 
  3. Step3. Now as per the game rules, we have to check the number on the dice. So, if the dice number is not 1 then current score is updated. If the dice number is 1, then switchPlayer() gets invoked. 

Javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

const switchPlayer = function () {
  document.getElementById(`current--${activePlayer}`).textContent = 0;
  currentScore = 0;
  activePlayer = activePlayer === 0 ? 1 : 0;
  player0El.classList.toggle('player--active');
  player1El.classList.toggle('player--active');
};

chevron_right


According to the rules: “If the player rolls out a 1, then he losts all of his current score”. The same functionality is being achieved by this function.

activePlayer =  activePlayer === 0 ? 1 : 0 {This is a ternary operator in which we are saying that if the activeplayer is 0 then make it 1 and if it is make then turn it to 0.

2. btnHold Event Handler

Javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

btnHold.addEventListener('click', function () {
  if (playing) {
    
    // 1. Add current score to active player's score
    scores[activePlayer] += currentScore;
    // scores[1] = scores[1] + currentScore
  
    document.getElementById(`score--${activePlayer}`)
      .textContent = scores[activePlayer];
  
    // 2. Check if player's score is >= 100
    if (scores[activePlayer] >= 100) {
      
      // Finish the game
      playing = false;
      diceEl.classList.add('hidden');
  
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.add('player--winner');
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.remove('player--active');
    } else {
      
      // Switch to the next player
      switchPlayer();
    }
  }
});

chevron_right


This event handler fires off whenever a player hits the HOLD button. Following are the steps involved in this handler:

  1. Step1: As soon as the player hits hold, the current score gets added to the overall score of that player.
  2. Step2: Evaluation of the overall scores is done after that step. If overall score is found to be greater than 100, then the game finishes and then the class of player-winner (which make the background-color: black and changes the color and font-weight) and removes the class of active-player.

3. btnNew Event Handler:

btnNew.addEventListener(‘click’,init): Whenever a new game is initialized, this event handler fires off. It only does initialize the Init() function. Init() kinds of reset the game to the start, that is it does the following things:

  • Makes the scores of both players 0.
  • Makes the Player 1 as the active/current player.
  • Hides the dice by the hidden class.
  • Removes the player–winner class from both players
  • Adds the player–active class to Player 1

Javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

// Starting conditions
const init = function () {
  scores = [0, 0];
  currentScore = 0;
  activePlayer = 0;
  playing = true;
  
  score0El.textContent = 0;
  score1El.textContent = 0;
  current0El.textContent = 0;
  current1El.textContent = 0;
  
  diceEl.classList.add('hidden');
  player0El.classList.remove('player--winner');
  player1El.classList.remove('player--winner');
  player0El.classList.add('player--active');
  player1El.classList.remove('player--active');
};
init();

chevron_right


Note: init() function is initialized at the time of loading the game also. 

Output:

Finally, we are done with this game.

You can check Github repository from my Github Account: https://github.com/VersatileVats/Pig-Game Check out the following steps to deploy your project to Github Using Visual Studio Code OR window’s command prompt.

Step 1: First log in to your Github account, if you don’t have one then create new one by visiting their website.

Step 2: Click on Create New Repository Sign and then you have to fill out the basic details for the new repository. We have made a sample repository for making you guys understand.

Details About Newly Created Repository

Click on Create Repository button and then you will be re-directed to other page which will tell you some details. For example: In my case :-

Page after creating a new repository

Step 3: Now open Visual Studio Code in your local machine and open the folder which you want to upload/push on Github. For example purposes we have made folder named Demo.  Then open the terminal in the VS Code or simply open Windows Command Prompt. Say we have made the Demo folder on desktop. So in order to push that folder in Github you must make sure that your CWD (current working directory should be that folder itself). In Window’s Command Prompt use the command cd Desktop\Name_Of_The_Folder so we have to write cd Desktop\Demo. For VS Code it is very easy, open the folder via VS Code and then hit New Terminal inside the Terminal Button in the Toolbar (or you can just hit Ctrl+Shift+`).

Further steps are same for both VS Code terminal and Windows Command Terminal

Step 4: In the terminals, write git init and click enter. (Make sure you have installed Git on you local machines as it is a pre-requisite)

Step 5: Then write git add. (here . Means all because there are many cases in which you don’t want to push all contents of the file so in that case rather than . you can specify the name of that file only)

Step 6: Write git commit -m “Any message you want to write” (there are various flags in here, so -m is a message flag which has message ahead of that). This command only puts a message which will be displayed in the repository post successful deployment of folder on Github

Step 7: Git remote add origin https://github.com/UserName/Description. This will vary as per repository’s details. You will get this from the page.

Step 8: Finally you have to push the folder on github using the command: git push -u origin master (the last word i.e. master tell you that you are pushing the folder at which branch of the repository, master is the main one)

All Steps To Push Files On Github

After successfully completing all these steps, go to the repository on Github, if still the repository is not showing any files then reload the page once and then you can see that finally the folder has been successfully uploaded to Github πŸ™‚

full-stack-img

My Personal Notes arrow_drop_up
Recommended Articles
Page :