Why aren’t my two values comparing correctly? - javascript

I have objects that I am trying to compare their values and make a function happen if one value is greater than the other. But My code seems to be wrong because even though the value is greater than the other, it still console logs "false" instead of true. I even console logged the value to check if it was greater and it was. Here's my code.
var clicks1 = 0;
function onClick() {
clicks1 += 1;
document.getElementById("clicks1").innerHTML = clicks1;
document.getElementById("clicks1").value = clicks1;
var clicks2 = 0;
function onClick() {
clicks2 += 1;
document.getElementById("clicks2").innerHTML = clicks2;
document.getElementById("clicks2").value = clicks2;
playbutton.onclick = function () {
const click1var = document.getElementById("clicks1").value
const click2var = document.getElementById("clicks2").value
console.log(click1var)    //Console shows 3
console.log(click2var)    //Console shows 1
if (click1var < click2var) {
console.log('true')
} else {
console.log('false')  //Console shows false.  
}
}

click1var is 3
click2var is 1
if (click1var < click2var){ // are you asking if 3 is lower than 1 (FALSE)
then it will go to the else.

Related

Connect Four game in Javascript - how do I detect a horizontal win?

I try to code a Connect Four game and define a winner when 4 pieces are aligned horizontally. I haven't moved to the diagonal part yet, want to get this one first.
What I try to achieve - check if the current location (i) and i+6, meaning the next column, same row, have the same player's class.
Problem - "Count" never adds up for horizontal victory.
The problematic part starts from checkForHorizontalVictory.
Pay attention that I switched for loop to go through allSlots.length, not slots.length, as I want all 42 slots. You'll see the rest.
Anyway, how do I write a code to understand where the player's button is, get the index, and check if index+6 (and later -6) has the same class?
var currentPlayer = "player1";
var column = $(".column");
var allSlots = $(column.children());
function switchPlayer() {
if (currentPlayer === "player1") {
currentPlayer = "player2";
} else {
currentPlayer = "player1";
}
}
$(".column").on("click", function (e) {
var col = $(e.currentTarget);
var slots = col.children();
for (var i = slots.length - 1; i >= 0; i--) {
var currentSlot = slots.eq(i);
var hole = currentSlot.children();
if (!hole.hasClass("player1") && !hole.hasClass("player2")) {
hole.addClass(currentPlayer);
var verticalVictory = checkForVerticalVictory(slots);
var horizontalVictory = checkForHorizontalVictory(slots);
if (verticalVictory) {
}
if (horizontalVictory) {
}
switchPlayer();
break;
}
}
});
function checkForVerticalVictory(slots) {
var count = 0;
for (var i = 0; i < slots.length; i++) {
console.log(slots.length, "this is slots length in vertical");
var currentSlot = slots.eq(i);
var hole = currentSlot.children();
if (hole.hasClass(currentPlayer)) {
count++;
} else {
count = 0;
}
console.log(count, "this is count!");
if (count == 4) {
alert("you won! 🎉");
return true;
}
}
console.log("no wins yet ❌");
return false;
}
function checkForHorizontalVictory(slots) {
var count = 0;
for (var i = 0; i < allSlots.length; i++) {
var thisSlot = allSlots.eq(i);
var thisHole = thisSlot.children(i);
if (
thisHole.hasClass(currentPlayer) && allSlots.eq(i + 6).hasClass(currentPlayer)
) {
count++;
console.log("this is count", count);
} else {
count = 0;
}
console.log("this is count", count);
if (count == 4) {
// 3. If the counter reaches 4 - we have a win
alert("you won! 🎉");
return true;
}
}
console.log("no wins yet ❌");
return false;
}
I can't be sure, since I can't reproduce your issue. But here is what I think:
In the for loop, when it reaches the indexes of the last column and checks for i + 6 it makes allSlots.eq(42) to allSlots.eq(47)... And that ends up in a false. So count gets resetted to zero.
So change the loop too:
for (var i = 0; i < allSlots.length - 6; i++) {
I also would move that after the loop. Notice the condition change.
if (count <= 4) {
// 3. If the counter reaches 4 - we have a win
alert("you won! 🎉");
return true;
}
In short, column #7 was already checked while checking column #6... ;)
EDIT
Using the full code from your gitHub, I changed the way you are checking the holes of a particular row.
First, pass the slot index to checkForHorizontalVictory
So in that function, you know exactly which slot is the starting point of your logic.
You can now get all the slots on the same row by filtering allSlots.
I used Arra.from() to be able to use JS .filter with a modulo of the deducted rowNum.
Then, recreate a jQuery object from that filtered element list.
function checkForHorizontalVictory(currentSlotIndex) {
var count = 0;
let rowNum = currentSlotIndex % 6; // rows from 0 to 5, top to bottom
console.log("rowNum", rowNum);
// Get a JS array from the jQuery collection
var thisrow = Array.from(allSlots).filter((s, i) => i % 6 == rowNum);
console.log("thisrow", thisrow);
console.log("thisrow length", thisrow.length);
// Create a jQuery collection from the filtered above
var $thisrow = $(thisrow)
for (var i = 0; i < thisrow.length; i++) {
// var thisrow = allSlots.eq(currentRow);
console.log(thisrow[i]);
// Tests to confirm you are checking the right row
// thisHole.addClass("test");
// thisHole.text(i)
if (
// jQuery object for the specific row
$thisrow
.eq(i + 1)
.children()
.hasClass(currentPlayer)
) {
count++;
}
console.log("this is count", count);
if (count == 4) {
console.log("you won! 🎉");
return true;
}
}
console.log("no wins yet ❌");
return false;
}
CodePen with your modified code
For fun, uncomment the Tests to confirm you are checking the right row.

I can't make setTimeout() work in my script

I'm making a memory game. It already sort of works, but when I choose two cards that aren't the same picture, they flip back instantly, without showing the user what is on the second card. I think I should use setTimeout(), but for now it only made my flipBack() function not work at all. Maybe, I am using it incorrectly or in the wrong place.
I tried putting both the flipBack() and setTimeout(flipBack, 5000) inside "else if", outside of it, outside of my revealCard() function.
I'm only getting "Uncaught TypeError: Cannot read properties of undefined (reading 'style')
at flipBack (memory game.js:61:35)" in the console. It seems that setTimeout cannot execute flipBack() or something like that.
let board = document.getElementById("board");
let score = document.getElementById("score");
let fails = document.getElementById("fails");
let cards = document.querySelectorAll(".card");
// add eventListener to every card
for (let i = 0; i < 6; i++) {
cards[i].addEventListener("click", revealCard);
}
let revealCounter = 2;
let imgAltArray = [];
let latestTwoRevealedCards = [];
let points = 0;
let wrongGuesses = 0;
function revealCard(event) {
if (revealCounter > 0) {
let cardImg = event.target.firstChild;
// make card "flip", so you can see the picture
cardImg.style.visibility = "visible";
imgAltArray.push(cardImg.alt);
latestTwoRevealedCards.push(cardImg);
console.log(imgAltArray);
revealCounter--;
// check if both cards have the same picture on them by comparing alt parameters
if (revealCounter == 0 && imgAltArray[0] === imgAltArray[1]) {
imgAltArray = [];
latestTwoRevealedCards = [];
points++
score.textContent = `Score: ${points}`;
revealCounter = 2;
}
else if (revealCounter == 0 && imgAltArray[0] !== imgAltArray[1]) {
wrongGuesses++;
fails.textContent = `Failed attempts: ${wrongGuesses}`
imgAltArray = [];
// make cards flip back
setTimeout(flipBack, 5000);
latestTwoRevealedCards = [];
revealCounter = 2;
}
}
}
// TIMEOUT DOESN"T WORK
function flipBack() {
for (let i = 1; i >= 0; i--) {
latestTwoRevealedCards[i].style.visibility = "hidden";
}
}
latestTwoRevealedCards[i] This element may be undefined

How can I get my result logged horizontally rather than vertically?

Hello you beautiful coders!
Today I've been working on a little quiz called "Chessboard" but ran into a weird situation.
but my code is spitting out results vertically but I need to make it horizontally so that I can repeat this process a few more times to make a board out of it. Here's my code:
let value = 8;
for (i = 1; i <= value ; i++) {
if ( i % 2 == 0 ) {
let x = i;
console.log(x);
} else {
let y = " ";
console.log(y);
}
}
this above code outputs
2
4
6
8
How can I make these results show horizontally like so:
2 4 6 8
So that I can repeat this process in a new line afterward?
I've been thinking about this for awhile but.... I might just be too dumb to figure this out?
I THINK I have to nest this if function again in this function to achieve this but not sure how...
Thanks in advance!!
Add an empty string at the beginning of the code, append the results to it, and log it to console, as illustrated below:
var res = "";
let value = 8;
for (i = 1; i <= value ; i++) {
if ( i % 2 == 0 ) {
let x = i;
res += x + ' ';
} else {
let y = " ";
res += y;
}
}
console.log(res);
A console.log will always show on a new line in the console. I would add each result to an array and then convert the array into a string. Then console log it once.
let value = 8;
// create empty array
const results = [];
for (let i = 1; i <= value; i++) {
if ( i % 2 == 0 ) {
let x = i;
// rather than console logging, add to empty array
results.push(x);
} else {
let y = " ";
results.push(y);
}
}
// convert array to string, seperated by spaces
const str = results.join(" ");
console.log(str)

why is comparing two values isn't working?

I'm trying to make a winning algorithm for a simple connect four game, this code is for checking if there is 4 same values in a horizontal line:
function win(clicked) {
var cellco = clicked.className.match(/[a-zA-Z]+|[0-9]+/g); // example output:["col", "3", "row", "7"]
var playervalue = document.getElementById('tbl').rows[cellco[3]].cells[cellco[1]].children[0];
var count = 0;
for (var i = 0; i < GRID_SIZE; i++) {
var slot = document.getElementById('tbl').rows[cellco[3]].cells[i].children[0];
if (slot == playervalue) {
count++;console.log(count)//it only shows 1 even after having 4 objects
if (count >=4) {
return true;
} else {
count = 0;
}
}
}
return false;
}
var count = 0;
The count starts at zero.
count++;console.log(count)
You increment it and log it. It is now 1.
if (count >=4) {
It is not. 1 is less than 4.
count = 0;
You set it to zero.
(Then you go back to the step where you increment it to 1 and log it).

Why does the second array remain empty?

The goal of this "counter" is to see how many different words are inside the "ToCount"string. To do that it makes ToCount an array and then iterates over the elements, checking if they already are there and if not, adding them there.
The ToCountArr2 remains empty after the loop and a length of 0 is being displayed. Why does that happen and what can I do about it?
I ran a debugger and saw that no elements are added to the second list, as if nothing appenned inside the "if" control if the i-th element of the first array already is inside the second array.
function counter(){
var ToCount = document.getElementById("demo").value; //the contents of a textbox
var ToCountArr1 = ToCount.split(" ");
var ToCountArr2 = new Array;
var i = 0;
var lengthToCountArr1 = ToCountArr1.length;
var wordToPush;
while (i < lengthToCountArr1){
if(ToCountArr2.includes(ToCountArr1[i] === false)) {
wordToPush = ToCountArr1[i];
ToCountArr2.push(wordToPush);
}
i = i + 1;
}
alert(ToCountArr2.length);
}
The issue is with this line if(ToCountArr2.includes(ToCountArr1[i] === false)). Here the braces need to be after ToCountArr1[i], where as this line ToCountArr1[i] === false) is checking whether that value in ToCountArr1 is true or false.
This line
if(ToCountArr2.includes(ToCountArr1[i] === false)) will be evaluated as
if(ToCountArr2.includes(true/false))
depending on result of ToCountArr1[i] === false)
function counter() {
var ToCount = document.getElementById("demo").value; //the contents of a textbox
var ToCountArr1 = ToCount.split(" ");
var ToCountArr2 = new Array;
var i = 0;
var lengthToCountArr1 = ToCountArr1.length;
var wordToPush;
while (i < lengthToCountArr1) {
if (ToCountArr2.includes(ToCountArr1[i]) === false) {
wordToPush = ToCountArr1[i];
ToCountArr2.push(wordToPush);
}
i = i + 1;
}
console.log(ToCountArr2.length);
}
counter()
<input type='text' id='demo' value='Test Values'>
You can minimize if (ToCountArr2.includes(ToCountArr1[i]) === false) { by replacing it with
if (!ToCountArr2.includes(ToCountArr1[i])) {
Your wordcount function should use a parameter so you can pass a string in. This means you can use the wordcount function on an any string, not just the "demo" element. Also, this is a good time to learn about Map -
const wordcount = (str = "") =>
{ const result =
new Map
for (const s of str.split(/ /))
if (s === "")
continue
else if (result.has(s))
result.set(s, result.get(s) + 1)
else
result.set(s, 1)
return Array.from(result.entries())
}
const prettyPrint = (value) =>
console.log(JSON.stringify(value))
<!-- pass this.value as the string for wordcount
-- wordcount returns a value that we could use elsewhere
-- prettyPrint displays the value to the console
-->
<input onkeyup="prettyPrint(wordcount(this.value))">
Run the code snippet and copy/paste the following line into the field -
this is the captain speaking. is this the commander?
You will see this output -
[["this",2],["is",2],["the",2],["captain",1],["speaking.",1],["commander?",1]]
Here is an working example. I think it will help you right way. Here I use indexOf to check the value exist on a array.
function counter(){
var ToCount = "I am string just for text.";//document.getElementById("demo").value; //the contents of a textbox
var ToCountArr1 = ToCount.split(" ");
var ToCountArr2 = new Array;
var i = 0;
var lengthToCountArr1 = ToCountArr1.length;
var wordToPush;
while (i < lengthToCountArr1){
if( ToCountArr2.indexOf(ToCountArr1[i]) == -1 ) {
wordToPush = ToCountArr1[i];
ToCountArr2.push(wordToPush);
}
i = i + 1;
}
alert(ToCountArr2.length);
}
counter();

Categories

Resources