![]()
To work toward the DRY principle (Don't Repeat Yourself), the code in the previous learning Post comprised 2 almost equal blocks for two differnet conditions - one guess too high, the other too low.
A ternary operator can be used to replace those code blocks so massively decrease the code quantity, while doing the same job. This is called code refactoring.
The original similar blocks are:
} else if (guess > secretNumber) {
if (score > 1) {
document.querySelector('.message').textContent = 'Too high';
document.querySelector('.message').style.color = 'red';
score--;
document.querySelector('.score').textContent = score;
} else {
document.querySelector('.message').textContent = 'You lost the game!';
document.querySelector('.score').textContent = 0;
}
// Guess too low
} else if (guess < secretNumber) {
if (score > 1) {
document.querySelector('.message').textContent = 'Too low';
document.querySelector('.message').style.color = 'yellow';
score--;
document.querySelector('.score').textContent = score;
} else {
document.querySelector('.message').textContent = 'You lost the game!';
document.querySelector('.score').textContent = 0;
}
}
The key logic for replacement are :
if (guess > secretNumber) and if (guess < secretNumber)
with the main block differences being the screen messages "too high" and "too low"
The logic that differentiates these "if" blocks asks if the guess is either higher or lower than the secret number to be guessed, which can be replaced by the logic that the guessed number is just "different from" or not equal to the secret number to be guessed.
This original method can be replaced with an "else if" block placed above the prior two blocks and only ONE code block segment placed in it::
else if (guess !== secretNumber) {
if (score > 1) {
document.querySelector('.message').textContent =
guess > secretNumber ? 'Too high!' : 'Too low!'
score--;
document.querySelector('.score').textContent = score;
} else {
document.querySelector('.message').textContent = 'You lost the game!';
document.querySelector('.score').textContent = 0;
}
}
The ternary operator can be placed so:
'use strict';
// -----------------------------GAME------------------------------
// -----------------pre Play Again button code
let secretNumber = Math.trunc(Math.random() * 20 + 1);
// state variable - part of the state of the code - not in the DOM
let score = 20;
let highscore = 0;
document.querySelector('.check').addEventListener('click', function () {
const guess = Number(document.querySelector('.guess').value);
// When no input
if (!guess) {
document.querySelector('.message').textContent =
'No Number Entered! Try Again!';
// When player wins
} else if (guess === secretNumber) {
document.querySelector('.message').textContent = 'Correct Number! You Win!';
document.querySelector('.number').textContent = secretNumber;
// change bg on win
document.querySelector('body').style.backgroundColor = '#60b347';
// change text width
document.querySelector('.number').style.width = '30rem';
if (score > highscore) {
highscore = score;
document.querySelector('.highscore').textContent = highscore;
}
// when guess is different from secret number:
} else if (guess !== secretNumber) {
if (score > 1) {
document.querySelector('.message').textContent =
guess > secretNumber ? 'Too high!' : 'Too low!';
score--;
document.querySelector('.score').textContent = score;
} else {
document.querySelector('.message').textContent = 'You lost the game!';
document.querySelector('.score').textContent = 0;
}
}
});
// "Again" reset button - really simple method of reloading from server i window.location.reload() so cache is released - so whole page! Would incur traffic and lose highscore value. Now do long version...
document.querySelector('.again').addEventListener('click', function () {
console.log(document.querySelector('.again').value);
// window.location.reload()
score = 20;
secretNumber = Math.trunc(Math.random() * 20 + 1);
document.querySelector('.message').textContent = 'Start guessing...';
document.querySelector('.score').textContent = '20';
document.querySelector('.number').textContent = '?';
document.querySelector('.guess').value = '';
document.querySelector('body').style.backgroundColor = '#222';
document.querySelector('.number').style.width = '15rem';
});
A next refactoring step would be to replace all the duplicate code line with functions where possible. If a code block is highlighted in VS Code it shows in all the other places the same text exists, so the example of code lines for the (".message") class HTML lines shows 5 code lines the same that could be replaced with functions:

The function for this code that creates a generic displayMessage function:
// document.querySelector('.message').textContent = 'Correct Number! You Win!';
const displayMessage = function (message) {
document.querySelector('.message').textContent = message;
Once that function is created, the original code can be commented out, copied from then/or deleted, then the function can be used in all the other places with the original text of that code entered as it's message argument.
It's definition needs to be placed outside the main game container code with the other declared variables. The complete replacement code:
'use strict';
// -----------------------------GAME------------------------------
// -----------------pre Play Again button code
let secretNumber = Math.trunc(Math.random() * 20 + 1);
// state variable - part of the state of the code - not in the DOM
let score = 20;
let highscore = 0;
const displayMessage = function (message) {
document.querySelector('.message').textContent = message;
};
// Main game container {} start
document.querySelector('.check').addEventListener('click', function () {
const guess = Number(document.querySelector('.guess').value);
// When no input
if (!guess) {
// document.querySelector('.message').textContent =
// 'No Number Entered! Try Again!';
// const displayMessage = function (message) {
// document.querySelector('.message').textContent = message;
// };
displayMessage('No Number Entered!');
// When player wins
} else if (guess === secretNumber) {
displayMessage('Correct Number! You Win!');
document.querySelector('.number').textContent = secretNumber;
// change bg on win
document.querySelector('body').style.backgroundColor = '#60b347';
// change text width
document.querySelector('.number').style.width = '30rem';
if (score > highscore) {
highscore = score;
document.querySelector('.highscore').textContent = highscore;
}
// when guess is different from secret number:
} else if (guess !== secretNumber) {
if (score > 1) {
// guess > secretNumber ? 'Too high!' : 'Too low!';
// document.querySelector('.message').textContent = guess > secretNumber ? 'Too high!' : 'Too low!'
displayMessage(guess > secretNumber ? 'Too high!' : 'Too low!');
score--;
document.querySelector('.score').textContent = score;
} else {
// document.querySelector('.message').textContent = 'You lost the game!';
displayMessage('You lost the game!!');
document.querySelector('.score').textContent = 0;
}
}
});
// "Again" reset button - really simple method of reloading from server i window.location.reload() so cache is released - so whole page! Would incur traffic and lose highscore value. Now do long version...
document.querySelector('.again').addEventListener('click', function () {
console.log(document.querySelector('.again').value);
// window.location.reload()
score = 20;
secretNumber = Math.trunc(Math.random() * 20 + 1);
// document.querySelector('.message').textContent = 'Start guessing...';
displayMessage('Start guessing...');
document.querySelector('.score').textContent = '20';
document.querySelector('.number').textContent = '?';
document.querySelector('.guess').value = '';
document.querySelector('body').style.backgroundColor = '#222';
document.querySelector('.number').style.width = '15rem';
});
The same can even be done with the ternary operator :
