0
\$\begingroup\$

I've implemented the game of Pig in JavaScript. My implementation has the following rules:

  • Two players take turns playing in rounds.
  • In a round, the player rolls a single die as many times as they wish, with the sum of their results becoming their score for that round.
  • If the player rolls a 1, then their score for that round goes to 0 and the other player takes a turn.
  • At any point in time, the current play may choose to hold, which adds their round score to their total score, and play passes to the other player.
  • The first player whose total score reaches 100 wins the game.

For my assignment, I had to add the following additional rules:

  1. A player loses his entire score when he rolls two 6 in a row. After that, it's the next player's turn. (Hint: Always save the previous dice roll in a separate variable)
  2. Add an input field to the HTML where players can set the winning score, so that they can change the predefined score of 100. (Hint: you can read that value with the .value property in JavaScript. This is a good opportunity to use Google to figure this out :)
  3. Add another die to the game, so that there are two dice now. The player loses his current score when one of them is a 1. (Hint: you will need CSS to position the second die, so take a look at the CSS code for the first one.)

/*
YOUR 3 CHALLENGES
Change the game to follow these rules:

1. A player looses his ENTIRE score when he rolls two 6 in a row. After that, it's the next player's turn. 
(Hint: Always save the previous dice roll in a separate variable)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

2. Add an input field to the HTML where players can set the winning score, so that they can change the predefined score of 100.
 (Hint: you can read that value with the .value property in JavaScript. This is a good oportunity to use google to figure this out :)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


3. Add another dice to the game, so that there are two dices now. The player looses his current score when one of them is a 1. 
(Hint: you will need CSS to position the second dice, so take a look at the CSS code for the first one.)

*/

var scores , roundScore , activePlayer , gamePlaying , i , array , changeScore ;
init();


document.querySelector('.btn-roll').addEventListener( 'click' , function () {
        if (gamePlaying) {
            var dice = Math.floor(Math.random()*6)+1;
            var diceTwo = (Math.floor(Math.random()*6)+1);
            var diceDOM= document.querySelector('.dice');
            diceDOM.style.display = 'block';
            document.querySelector('.dice-two').style.display = 'block';
            diceDOM.src = 'dice-' + dice +'.png';
            document.querySelector('.dice-two').src = 'dice-' + diceTwo +'.png';
            if (dice !== 1 && diceTwo !== 1) {
            roundScore =roundScore + dice + diceTwo;
            document.getElementById('current-'+ activePlayer).textContent = roundScore;
            array[i]=dice;
            i = i +1 ;
            if (dice == 6 && array[i-2] ==  6 ) {
                nextPlayer();
            }
        
            } else  { 
                nextPlayer();

            }
        }
})

document.querySelector('.btn-hold').addEventListener( 'click' , function () {

        if (gamePlaying) {
            scores[activePlayer] += roundScore;
   
            document.querySelector('#score-'+ activePlayer).textContent = scores[activePlayer];
            if (scores[activePlayer] >= changeScore ) {
                document.getElementById('name-'+ activePlayer).textContent = "Winner!";
                document.querySelector('.dice').style.display = 'none';
                document.querySelector('.player-' + activePlayer +'-panel').classList.add('winner');
                document.querySelector('.player-' + activePlayer +'-panel').classList.remove('active');
                gamePlaying = false ;
        
            } else { 
                nextPlayer();
            }        
        }
})

function nextPlayer () {
    activePlayer === 1 ? activePlayer = 0 : activePlayer = 1;
    roundScore = 0;
    document.getElementById('current-0').textContent = '0';
    document.getElementById('current-1').textContent = '0';
    document.querySelector('.player-0-panel').classList.toggle('active');
    document.querySelector('.player-1-panel').classList.toggle('active');
    document.querySelector('.dice').style.display = 'none';
    document.querySelector('.dice-two').style.display = 'none';
    array = [];
}

document.querySelector('.btn-new').addEventListener( 'click' , init);

document.getElementById('changeScore-btn').addEventListener( 'click' , function(){
    changeScore = document.getElementById("changeScore-input").value;
    alert("to win you need "+changeScore+" score points ");
});



function init() {
    scores = [0,0];
    roundScore = 0;
    activePlayer = 0;
    gamePlaying = true;

    document.getElementById('score-0').textContent = '0';
    document.getElementById('score-1').textContent = '0';
    document.getElementById('current-0').textContent = '0';
    document.getElementById('current-1').textContent = '0';

    document.querySelector('.dice').style.display = 'none';
    document.querySelector('.dice-two').style.display = 'none';

    document.getElementById('name-0').textContent = "Player 1!";
    document.getElementById('name-1').textContent = "Player 2!";
    document.querySelector('.player-0-panel').classList.remove('active');
    document.querySelector('.player-1-panel').classList.remove('active');
    document.querySelector('.player-0-panel').classList.add('active');

    i = 0;
    array = [];
    changeScore = 20;
}
/**********************************************
*** GENERAL
**********************************************/

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    
}

.clearfix::after {
    content: "";
    display: table;
    clear: both;
}

body {
    background-image: linear-gradient(rgba(62, 20, 20, 0.4), rgba(62, 20, 20, 0.4)), url(back.jpg);
    background-size: cover;
    background-position: center;
    font-family: Lato;
    font-weight: 300;
    position: relative;
    height: 100vh;
    color: #555;
}

.wrapper {
    width: 1000px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fff;
    box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.3);
    overflow: hidden;
}

.player-0-panel,
.player-1-panel {
    width: 50%;
    float: left;
    height: 600px;
    padding: 100px;
}



/**********************************************
*** PLAYERS
**********************************************/

.player-name {
    font-size: 40px;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 2px;
    font-weight: 100;
    margin-top: 20px;
    margin-bottom: 10px;
    position: relative;
}

.player-score {
    text-align: center;
    font-size: 80px;
    font-weight: 100;
    color: #EB4D4D;
    margin-bottom: 130px;
}

.active { background-color: #f7f7f7; }
.active .player-name { font-weight: 300; }

.active .player-name::after {
    content: "\2022";
    font-size: 47px;
    position: absolute;
    color: #EB4D4D;
    top: -7px;
    right: 10px;
    
}

.player-current-box {
    background-color: #EB4D4D;
    color: #fff;
    width: 40%;
    margin: 0 auto;
    padding: 12px;
    text-align: center;
}

.player-current-label {
    text-transform: uppercase;
    margin-bottom: 10px;
    font-size: 12px;
    color: #222;
}

.player-current-score {
    font-size: 30px;
}

button {
    position: absolute;
    width: 200px;
    left: 50%;
    transform: translateX(-50%);
    color: #555;
    background: none;
    border: none;
    font-family: Lato;
    font-size: 20px;
    text-transform: uppercase;
    cursor: pointer;
    font-weight: 300;
    transition: background-color 0.3s, color 0.3s;
}

button:hover { font-weight: 600; }
button:hover i { margin-right: 20px; }

button:focus {
    outline: none;
}

i {
    color: #EB4D4D;
    display: inline-block;
    margin-right: 15px;
    font-size: 32px;
    line-height: 1;
    vertical-align: text-top;
    margin-top: -4px;
    transition: margin 0.3s;
}

.btn-new { top: 45px;}
.btn-roll { top: 403px;}
.btn-hold { top: 467px;}

.dice {
    position: absolute;
    left: 50%;
    top: 178px;
    transform: translateX(-50%);
    height: 100px;
    box-shadow: 0px 10px 60px rgba(0, 0, 0, 0.10);
}
.dice-two {
    position: absolute;
    left: 50%;
    top: 287px;
    transform: translateX(-50%);
    height: 100px;
    box-shadow: 0px 10px 60px rgba(0, 0, 0, 0.10);
}
.winner { background-color: #f7f7f7; }
.winner .player-name { font-weight: 300; color: #EB4D4D; }
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <link href="https://fonts.googleapis.com/css?family=Lato:100,300,600" rel="stylesheet" type="text/css">
        <link href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css">
        <link type="text/css" rel="stylesheet" href="style.css">
        
        <title>Pig Game</title>
    </head>

    <body>
        <div class="wrapper clearfix">
            <div class="player-0-panel active">
                <div class="player-name" id="name-0">Player 1</div>
                <div class="player-score" id="score-0">43</div>
                <div class="player-current-box">
                    <div class="player-current-label">Current</div>
                    <div class="player-current-score" id="current-0">11</div>
                </div>
            </div>
            
            <div class="player-1-panel">
                <div class="player-name" id="name-1">Player 2</div>
                <div class="player-score" id="score-1">72</div>
                <div class="player-current-box">
                    <div class="player-current-label">Current</div>
                    <div class="player-current-score" id="current-1">0</div>
                </div>
            </div>
            
            <button class="btn-new"><i class="ion-ios-plus-outline"></i>New game</button>
            <button class="btn-roll"><i class="ion-ios-loop"></i>Roll dice</button>
            <button class="btn-hold"><i class="ion-ios-download-outline"></i>Hold</button>
            
            <img src="dice-5.png" alt="Dice" class="dice">
            <img src="dice-5.png" alt="Dice" class="dice-two">
        </div>
        <input type="text" id="changeScore-input" >
        <button id="changeScore-btn">change score</button>

        <script src="app.js"></script>
    </body>
</html>

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Review! From your question, it seems like you are unsure of whether or not your code is functioning correctly - "Who can evaluate the completion of tasks". Code Review is only for reviewing complete and functional code; we don't help you meet the task, but we may suggest better ways to complete the task. Can you please edit[codereview.stackexchange.com/posts/227564/edit] your question to clarify whether or not the code is complete and correct to the best of your knowledge? \$\endgroup\$ Sep 6, 2019 at 14:09
  • \$\begingroup\$ Additionally, your code doesn't seem to run correctly as a snippet. Is it not working correctly at all, or is it an issue with how it transformed into a snippet? Can you update it to function correctly in the snippet or provide a link to see it working correctly? \$\endgroup\$ Sep 6, 2019 at 14:15

1 Answer 1

1
\$\begingroup\$

Whenever possible put the styling in the CSS. Avoid doing it in the JavaScript like this. For example, you could add it to your .dice style. (Note: same goes for other parts of your code)

diceDOM.style.display = 'block';

Use shorthand +=. (Note: same goes for other parts of your code)

roundScore =roundScore + dice + diceTwo;

'array' is a bad name for a variable. It's not descriptive. It's also a keyword in a lot of languages, so you should avoid it anyway

array[i]=dice;

No need for an if statement here, both paths do the same thing

if (dice == 6 && array[i-2] ==  6 ) {
    nextPlayer();
}

} else  { 
    nextPlayer();
}

Change your ternary from this:

activePlayer === 1 ? activePlayer = 0 : activePlayer = 1;

to this:

activePlayer = activePlayer === 1 ? 0 : 1;

Hopefully your 'challenges' were posted by a mistake, as a result of copying & pasting the instructions. It wouldn't be right to do any part of your assignment for you. Code reviewing it is already crossing a line, probably.

However I will say the challenge should definitely get you thinking about ways to refactor your code. In real life changes happen all the time. The customer suddenly wants this or that feature added. You should always write you code in such a way it can be changed easily.

For example what if you want to erase the score on a '6' roll? You'd need to scroll through your code looking for the area that handles dice rolls. But if you had a method it's blanetly obvious (As an added bonus, easier to read the code):

function shouldScoreBeErased(dice1, dice2)
{
    return dice1 == 1 || dice2 == 1;
}

You should also have a method for erasing the score etc. To add the dice being 6 twice in a row feature, you'd need to keep track of previous rolls as well. (Tbh you should be anyways, showing the history of the game at the end could be a nice feature!)

You should also have a method for writing the score, dice etc to the DOM. Again making it easier for maintanability.

Instead of 'dice1' and 'dice2' I strongly recommend using an array of dice. Again for maintanability (adding new dice or removing one). It also gets rid of the grammer awkwardness ('1 Dice' is actually called a 'die')

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.