if conditional for background color? - javascript

I've been trying to make a tic-tac-toe game but for some reason, the conditional isn't working..
I tried to target the first three elements on the first row and if they all were the same color, I wanted to browser to alert a "win" pop-up, but it doesn't happen.
Does anyone have an idea why?
Here's my code:
var one = document.getElementById("one");
var two = document.getElementById("two");
var three = document.getElementById("three");
var four = document.getElementById("four");
var five = document.getElementById("five");
var six = document.getElementById("six");
var seven = document.getElementById("seven");
var eight = document.getElementById("eight");
var nine = document.getElementById("nine");
var counter = 1;
//code that changes the box color
one.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
one.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
one.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
two.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
two.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
two.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
three.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
three.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
three.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
four.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
four.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
four.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
five.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
five.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
five.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
six.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
six.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
six.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
seven.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
seven.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
seven.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
eight.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
eight.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
eight.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
nine.addEventListener("click", function() {
if (counter < 10 && counter % 2 === 0) {
nine.style.backgroundColor = "yellow";
} else if (counter < 10 && counter % 2 != 0) {
nine.style.backgroundColor = "red";
}
counter++;
console.log(counter);
});
//logic for winning
if (one.style.backgroundColor == "red" && two.style.backgroundColor == "red" && three.style.backgroundColor == "red") {
console.log("red wins");
}
.knobs {
background-color: blue;
border: none;
padding: 50px;
margin: 10px;
}
.knobs:focus {
outline: none;
}
#total {
text-align: center;
}
<!DOCTYPE html>
<div id="total">
<button id="one" class="knobs"></button>
<button id="two" class="knobs"></button>
<button id="three" class="knobs"></button>
<br>
<button id="four" class="knobs"></button>
<button id="five" class="knobs"></button>
<button id="six" class="knobs"></button>
<br>
<button id="seven" class="knobs"></button>
<button id="eight" class="knobs"></button>
<button id="nine" class="knobs"></button>
</div>
Your help will be much appreciated!

The problem is that your if statement only runs once in the beginning. You need to turn it into a function and then call it after each event. Something like
function check() {
if (one.style.backgroundColor == "red" && two.style.backgroundColor == "red" && three.style.backgroundColor == "red"){
console.log("red wins");
}
}
At the end of the event listener you would call it like so:
check();
(Like Xufox said above, you should really look into delegation so that this is more manageable and you don't have to repeat everything.)

In your code:
var one = document.getElementById("one");
var two = document.getElementById("two");
var three = document.getElementById("three");
var four = document.getElementById("four");
var five = document.getElementById("five");
var six = document.getElementById("six");
var seven = document.getElementById("seven");
var eight = document.getElementById("eight");
var nine = document.getElementById("nine");
You don't need to declare each of your buttons like this. You can optimize it using an array and a loop like for or forEach. Like this:
var knobs = [
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine'
];
knobs.forEach(function(id) {
var element = document.getElementById(id);
element.addEventListener('click', function() {
...
}
}
You are adding a listener to each button with addEventListener. This can be optimized as I mention in my point number 1. You get the button element with var element = document.getElementById(id); and the you cand add the listener in the same forEach.
I also used the same forEach to initialize my board array with -1 for each element. This mean it is empty.
Now you need to add a method to verify is there is a winner after each click. In this code sample I used verifyWinner(index); and I passed the index of the button;
Also, in this line one.style.backgroundColor == 'red' only == is not enough so I suggest you to use === for compare strings.
The problem to use this method based on CSS is that what happens if you click two or more times in the same knob? The counter will increase and the knob will change the color from red to yellow for example. That is why I recommend you to use a board array to map the "game status".
Finally, I created a board as an array and I put 1 if is red and 2 if is yellow. This will help you to simplify the verification process.
Here is the code sample. Happy coding.
Note: I reduced the knob size for better visualization in the snippet runner.
var knobs = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var board = [];
var isRed = true;
var isEndGame = false;
var counter = 0;
knobs.forEach(function(id) {
var element = document.getElementById(id);
board.push(-1);
element.addEventListener('click', function() {
var index = knobs.indexOf(id);
if (!isEndGame && board[index] == -1) {
if (isRed) {
element.style.backgroundColor = 'red';
board[index] = 1;
} else {
element.style.backgroundColor = 'yellow';
board[index] = 2;
}
verifyWinner(index);
isRed = !isRed;
counter++;
//console.log(counter)
}
if (counter == 9) {
isEndGame = true;
console.log('End of game.');
}
});
});
function verifyWinner(index) {
//logic for winning
var player = isRed ? 1 : 2;
switch (index) {
case 0:
case 2:
case 6:
case 8:
case 4:
verifyVertial(index);
verifyHorizontal(index);
verifyDiagonal(index);
break;
case 1:
case 3:
case 5:
case 7:
verifyVertial(index);
verifyHorizontal(index);
break;
}
if (isEndGame) {
console.log((isRed ? 'Red' : 'Yellow') + ' has won.');
console.log('End of game.');
}
}
function verifyVertial(index) {
//logic for winning
if (!isEndGame) {
var player = isRed ? 1 : 2;
switch (index) {
case 0:
case 3:
case 6:
if (board[0] == player && board[3] == player && board[6] == player) {
isEndGame = true;
}
break;
case 1:
case 4:
case 7:
if (board[1] == player && board[4] == player && board[7] == player) {
isEndGame = true;
}
break;
case 2:
case 5:
case 8: // edges
if (board[2] == player && board[5] == player && board[8] == player) {
isEndGame = true;
}
break;
}
}
}
function verifyHorizontal(index) {
//logic for winning
if (!isEndGame) {
var player = isRed ? 1 : 2;
switch (index) {
case 0:
case 1:
case 2: // edges
if (board[0] == player && board[1] == player && board[2] == player) {
isEndGame = true;
}
break;
case 3:
case 4:
case 5:
if (board[3] == player && board[4] == player && board[5] == player) {
isEndGame = true;
}
break;
case 6:
case 7:
case 8: // edges
if (board[6] == player && board[7] == player && board[8] == player) {
isEndGame = true;
}
break;
}
}
}
function verifyDiagonal(index) {
//logic for winning
if (!isEndGame) {
var player = isRed ? 1 : 2;
switch (index) {
case 0:
case 4:
case 8: // edges
if (board[0] == player && board[4] == player && board[8] == player) {
isEndGame = true;
}
break;
case 2:
case 4:
case 6: // edges
if (board[2] == player && board[4] == player && board[6] == player) {
isEndGame = true;
}
break;
}
}
}
.knobs {
background-color: blue;
border: none;
padding: 25px;
margin: 3px;
}
.knobs:focus .clear:focus {
outline: none;
}
#total {
text-align: center;
}
.clear {
clear: both;
}
<!DOCTYPE html>
<div id="total">
<button id="one" class="knobs"></button>
<button id="two" class="knobs"></button>
<button id="three" class="knobs"></button>
<div class="clearfix"></div>
<button id="four" class="knobs"></button>
<button id="five" class="knobs"></button>
<button id="six" class="knobs"></button>
<div class="clearfix"></div>
<button id="seven" class="knobs"></button>
<button id="eight" class="knobs"></button>
<button id="nine" class="knobs"></button>
</div>

Related

How to fix js code on if then statement with number Input

I wanted the user to input a number and if the number is a multiple of 3 or 5, I want a word/paragraph that says, "You are a witch"
created a function but I cannot seem to make it work
var x;
function pop() {
for (x = 1; x <= 100; x++)
if (x % 3 == 0) {
document.getElementById('onClick').innerHTML = 'You are a Warrior';
} else if (x % 5 == 0) {
document.getElementById('onClick').innerHTML = 'You are a wizard';
} else if (x % 3 == 0 && x % 5 == 0) {
document.getElementById('onClick').innerHTML = 'You are a Sage';
} else {
document.getElementById('onClick').innerHTML = 'invalid';
}
}
<input type="number" id="x">
<br>
<br>
<center><button onclick="pop()">Click Me</button> </center>
<br>
<br>
<p id="onClick"></p>
You never read the user input. You have a loop where there should not be one. You need to change the order of the comparisons.
function pop(){
var x = document.getElementById("x").value;
if (x % 3 == 0 && x % 5 == 0) {
document.getElementById('onClick').innerHTML = "You are a Sage";
}
else if (x % 3 == 0 ) {
document.getElementById('onClick').innerHTML = "You are a Warrior";
}
else if (x % 5 == 0){
document.getElementById('onClick').innerHTML = "You are a wizard";
}
else {
document.getElementById('onClick').innerHTML = "invalid";
}
}
<input type="number" id="x">
<br>
<br>
<center><button onclick="pop()">Click Me</button> </center>
<br>
<br>
<p id="onClick"></p>

Javascript - div innerHTML does not change

var score = 0, time = 1, heart = 3;
window.onload = function() {
var input = document.getElementById("wordTyped");
var timeLeft = document.getElementById("time");
var life = document.getElementById("life");
input.addEventListener("click", timer, false);
function timer() {
var id = setInterval(countdown, 10);
function countdown() {
input.removeEventListener("click", timer, false);
timeLeft.innerHTML = "Time left: " + (time - 0.01).toFixed(2) + "s";
time = 1 * (time - 0.01).toFixed(2);
if (time == 0 && life.innerHTML == "") {
clearInterval(id);
} else if (time == 0) {
--heart;
time = 1;
life(heart);
}
}
function life(heart) {
heart *= 1; // To make sure it is a number type
console.log(heart);
switch (heart) {
case 2:
life.innerHTML = "❤️❤️";
console.log(life.innerHTML);
break;
case 1:
life.innerHTML = "❤️";
console.log(life.innerHTML);
break;
case 0:
default:
life.innerHTML = "";
console.log(life.innerHTML);
break;
}
/*if(heart === 2) {
life.innerHTML = "❤️❤️";
}
else if(heart == 1) {
life.innerHTML = "❤️";
}
else {
life.innerHTML = "";
}*/
}
}
}
<div id="wordGenerated">illustration</div>
<input id="wordTyped" type="text" />
<div id="time">Time left: 1.00s</div>
<div id="score">Score: 0</div>
<div id="life">❤️❤️❤️</div>
I'm not sure what is wrong within the function life(heart).
I'm trying to decrease the amount of '❤️' by one as the time hit 0 and reset back to its original value, repeating until heart equals to 0.
If I use life.innerHTML = " example " outside the function timer() scope, it will work.
Using console.log(), it shows that life.innerHTML has changed, however, the display of HTML document stays the same and I don't understand why.
I've tried .nodeValue, .innerText, and .textContent, and all still gave the same result
There is a conflict usage with life variable and life() function. Change life() function name to something else like updateLife() and your code works,
Note: You can't have the same name for variable or function or Objects within the scopes.
Demo
var score = 0, time = 1, heart = 3;
window.onload = function() {
var input = document.getElementById("wordTyped");
var timeLeft = document.getElementById("time");
var life = document.getElementById("life");
input.addEventListener("click", timer, false);
function timer() {
var id = setInterval(countdown, 10);
function countdown() {
input.removeEventListener("click", timer, false);
timeLeft.innerHTML = "Time left: " + (time - 0.01).toFixed(2) + "s";
time = 1 * (time - 0.01).toFixed(2);
if (time == 0 && life.innerHTML == "") {
clearInterval(id);
} else if (time == 0) {
--heart;
time = 1;
updateLife(heart);
}
}
function updateLife(heart) {
heart *= 1; // To make sure it is a number type
console.log(heart);
switch (heart) {
case 2:
life.innerHTML = "❤️❤️";
console.log(life.innerHTML);
break;
case 1:
life.innerHTML = "❤️";
console.log(life.innerHTML);
break;
case 0:
default:
life.innerHTML = "";
console.log(life.innerHTML);
break;
}
/*if(heart === 2) {
life.innerHTML = "❤️❤️";
}
else if(heart == 1) {
life.innerHTML = "❤️";
}
else {
life.innerHTML = "";
}*/
}
}
}
<div id="wordGenerated">illustration</div>
<input id="wordTyped" type="text" />
<div id="time">Time left: 1.00s</div>
<div id="score">Score: 0</div>
<div id="life">❤️❤️❤️</div>
there is a conflict between life and life function so you can go like $("#life").innerHTML="" or any thing else

I need a button NOT to disapear

I am making a javascript code that has a button and when I click on it, it displays one of 5 symbols but when I click the button, it shows the random symbol but the button disapears. I'm new to javascript so can I please get some help?
<script>
function slots()
{
var slot1 = Math.floor(Math.random()*5);
if (slot1 == 0) {
document.write("\u2663");
}
if (slot1 == 1) {
document.write("\u2665");
}
if (slot1 == 2) {
document.write("\u2666");
}
if (slot1 == 3) {
document.write("\u2660");
}
if (slot1 == 4) {
document.write("7");
}
}
</script>
<button type="button" value="Spin" name="SPIN"onClick="slots(); return false;"></button>
When you write document.write() the screen refreshes, so I guess you could do something like this:
<script>
function slots()
{
var slot1 = Math.floor(Math.random()*5);
if (slot1 == 0) {
document.getElementById('value').innerHTML = "\u2663";
}
if (slot1 == 1) {
document.getElementById('value').innerHTML = "\u2665";
}
if (slot1 == 2) {
document.getElementById('value').innerHTML = "\u2666";
}
if (slot1 == 3) {
document.getElementById('value').innerHTML = "\u2660";
}
if (slot1 == 4) {
document.getElementById('value').innerHTML = "7";
}
}
</script>
<button type="button" value="Spin" name="SPIN" onClick="slots();">Click</button>
<span id="value"></span>
Slightly optimized version of otrebla's code, see it in action:
function slots() {
var slot1 = Math.floor(Math.random() * 5);
var value = document.getElementById('value');
switch (slot1) {
case 0:
value.innerHTML = "\u2663";
break;
case 1:
value.innerHTML = "\u2665";
break;
case 2:
value.innerHTML = "\u2666";
break;
case 3:
value.innerHTML = "\u2660";
break;
case 4:
value.innerHTML = "7";
break;
}
}
<button type="button" value="Spin" name="SPIN" onClick="slots();">Click</button>
<span id="value"></span>

How to move an element in javascript automatically with while loop?

I am making a Snake game so I'm trying to move my snake. It is moving with keys but it should move automatically on the screen. I tried doing that with while loops like in the code below but because of break; I have to press a key every time I want it to move. How can I make it move automatically? I tried removing break; an using an if statement but I didn't succeed.
Any other solutions or something else?
I'm new to programming so any advices would be helpful.
var main = function() {
var i = 0;
var j = 0;
$(document).keyup(function(event) {
var e = event.which;
while(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
while(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
while(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
while(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
//Which key is preesed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
});
};
$(document).ready(main);
I think you just have to organize a little bit your code.
First. You must put your code inside a function. You really don't need a while. You can use a simple if.
function move(i) {
if(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
if(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
if(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
if(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
}
Now you have to change the event, using keydown instead of keyup
function main() {
var interval;
$(document).keydown(function(event) {
if(interval) clearInterval(interval); // Clear the previous interval
var e = event.which;
var i;
//Which key is pressed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
interval = setInterval(function() {
move(i)
},1000); // repeat every 1 second
});
}
$(document).ready(main);

Javascript Check variable.Then gain ++ per second

I have a problem i want to check a variable.If its 0 then gain ++ after 1.5s.If its 10 then gain ++ after .4s.Its complicated.It doesnt really work.My code so far:
if(road == 1){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1400);}
else if(road == 2){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1300);}
else if(road == 3){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1200);}
else if(road == 4){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1100);}
else if(road == 5){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1000);}
else if(road == 6){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},900);}
else if(road == 7){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},800);}
else if(road == 8){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},600);}
else if(road == 9){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},400);}
else if(road == 10){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},200);}
else{setInterval(function(){stamina++;document.getElementById("stamina").innerHTML = stamina;},1500);}
And the code to build a road is this:
function build_road() {
if ((wood + tavern) >= 29 && stone > 4 && road < 10) {
road++;
document.getElementById("road_count").innerHTML = road;
wood = (wood + tavern) - 20;
stone = stone - 5;
document.getElementById("wood").innerHTML = wood;
document.getElementById("stone").innerHTML = stone;
exp = exp + 20;
var x = document.getElementById("PROGRESS");
x.setAttribute("value", exp);
x.setAttribute("max", max);
if (exp == 100) {
exp = 0;
level++;
document.getElementById("level").innerHTML = level;
}
alert("Congratulations,You've create a Road,Now you gain stamina slightly faster.");
}
else {
alert("You need: 30Wood,5Stone .Maximum 10 Roads.")
}
}
Make reusable functions (it's often a good practice, when you a difficulties with a piece of code, to break it into small functions):
var staminaIncreaseTimer = null;
function configureStaminaIncrease(delay) {
if (staminaIncreaseTimer !== null)
clearInterval(staminaIncreaseTimer);
staminaIncreaseTimer = setInterval(function () {
increaseStamina();
}, delay);
}
function increaseStamina() {
stamina += 1;
document.getElementById("stamina").innerHTML = stamina;
}
Solution with an array (suggested by Jay Harris)
var roadIndex = road-1;
var ROAD_DELAYS = [1400, 1300, 1200, /*...*/];
var DEFAULT_DELAY = 1500;
if (roadIndex < ROAD_DELAYS.length) {
configureStaminaIncrease(ROAD_DELAYS[roadIndex]);
} else {
configureStaminaIncrease(DEFAULT_DELAY);
}
Solution with a switch instead of you if-elseif mess:
switch (road) {
case 1:
configureStaminaIncrease(1400);
break;
case 2:
configureStaminaIncrease(1300);
break;
case 3:
configureStaminaIncrease(1200);
break;
//and so on...
default:
configureStaminaIncrease(1500);
}

Categories

Resources