I am building a Tic Tac Toe game and I am wondering if this syntax could be valid. It seems the program sometimes is running correctly and sometimes not so i would like your opinion.
If ( (spacesArray[0] &&
spacesArray[1] &&
spacesArray[2] == (userDraw || compDraw))){
}
So basically i am checcking positions 0,1,2 in an Array if they have the same value ("x" OR "o"). Is this syntax correct?
**Edit
For anyone that want to see the full project here it is.
https://codepen.io/Ispaxan/pen/ZaRjZW?editors=0001
You mean the same value. So the first thing you need to check is 3 item was equally.
When 3 values was equally, you just need to check one of them equal userDraw or compDraw and done.
By this way. You can make your if statement run faster because when first or second condition was fail, javascript engine will not do a check for remain conditions.
if (spacesArray[0] === spacesArray[1] &&
spacesArray[0] === spacesArray[2] &&
(spacesArray[0] === userDraw || spacesArray[0] === compDraw) )
Edited: I was checking the Codepen and noticed that. This is gonna a bug if you check spacesArray[0] === (userDraw || compDraw). because (userDraw || compDraw) will always return userDraw.
I would have a separate check for if userDraw or compDraw so you can tell who wins. Also, use === instead of == for javascript quirky equality reasons.
// destructure array
const [a, b, c] = spacesArray;
// check if a is not null or undefined
// check if a and b are equal
// check if a and c are equal
if (a && a === b && a === c) {
// all 3 are the same value
// check if userDraw wins
if (a === userDraw) {
console.log(`${userDraw} wins`;
}
// check if compDraw wins
if (a === compDraw) {
console.log(`${compDraw} wins`;
}
}
** Elaborating on why the || won't work in this case. **
Setup:
const userDraw = 'x';
const compDraw = 'y';
const spacesArray = ['y', 'y', 'y'];
// (userDraw || compDraw) will be 'x'
Case:
if (spacesArray[0] &&
spacesArray[1] &&
spacesArray[2] == (userDraw || compDraw)
Here's where it fails:
if ('y' && // -> true
'y' && // -> true
'y' === 'x') // -> false
Case:
if (spacesArray[0] === spacesArray[1] &&
spacesArray[0] === spacesArray[2] &&
spacesArray[0] === (userDraw || compDraw))
Here's where it fails:
spacesArray[0] === spacesArray[1] // 'y' === 'y' -> true
spacesArray[0] === spacesArray[2] // 'y' === 'y' -> true
spacesArray[0] === (userDraw || compDraw) // 'y' === 'x' -> false
I think when you put just spacesArray[0] by itself then it checks if it is true or false.
you might want to try:
if ( (spacesArray[0] == (userDraw || compDraw) &&
spacesArray[1] == (userDraw || compDraw) &&
spacesArray[2] == (userDraw || compDraw))){
}
First verify the equality between answers, and finally if its O or X
if ( spacesArray[0] == spacesArray[1] &&
spacesArray[0] == spacesArray[2] &&
spacesArray[0] == (userDraw || compDraw))
First, it's if, not If and second, no, that's not the right syntax. Each test must be complete and independent of the others, as in:
if (spacesArray[0] == (userDraw || compDraw) &&
spacesArray[1] == (userDraw || compDraw) &&
spacesArray[2] == (userDraw || compDraw)){
}
But, in your case, none of that is necessary because you are performing the wrong test in the first place. You should be checking to see if all 3 elements in the spacesArray are the same value, that would mean that they are all "X's" or all "O's" and that can be most efficiently done with the Array.prototype.every() method.
function allX(currentValue) {
return currentValue === "X";
}
function allO(currentValue) {
return currentValue === "O";
}
var spacesArray1 = ["X", "O", "O"];
var spacesArray2 = ["X", "X", "O"];
var spacesArray3 = ["X", "X", "X"];
var spacesArray4 = ["O", "O", "O"];
console.log(spacesArray1.every(allX), spacesArray1.every(allO));
console.log(spacesArray2.every(allX), spacesArray2.every(allO));
console.log(spacesArray3.every(allX), spacesArray3.every(allO));
console.log(spacesArray4.every(allX), spacesArray4.every(allO));
// So, to test for tic-tac-toe:
function test(player){
if(spacesArray3.every(allX) || spacesArray3.every(allO)){
console.log(player + " wins!");
} else {
console.log("Not yet!");
}
}
test("Scott");
Related
function checkWin(){
if (arro[0] === arro[1] === arro[2] === 1 || arro[3] === arro[4] === arro[5] === 1 || arro[6] === arro[7] === arro[8] === 1 || arro[0] === arro[4] === arro[8] === 1 || arro[2] === arro[4] === arro[6] === 1 || arro[0] === arro[3] === arro[6] === 1 || arro[1] === arro[4] === arro[7] === 1 || arro[2] === arro[5] === arro[8] === 1) {
console.log("O Won");
return "O";
}
else if (arrx[0] === arrx[1] === arrx[2] === 1 || arrx[3] === arrx[4] === arrx[5] === 1 || arrx[6] === arrx[7] === arrx[8] === 1 || arrx[0] === arrx[4] === arrx[8] === 1 || arrx[2] === arrx[4] === arrx[6] === 1 || arrx[0] === arrx[3] === arrx[6] === 1 || arrx[1] === arrx[4] === arrx[7] === 1 || arrx[2] === arrx[5] === arrx[8] === 1){
console.log("X Won");
return "X";
}
else
return "notwin"; }
Here, the arro is the matrix for O and the arrx is the array for X.
Running this in the console returns notwin everytime. Some help would be great. Thanks.
You can't combine condition checks like that. When you do a === b === c, what you're doing is comparing the result value of the a === b expression (which will be true [if they're the same] or false [if not]) with the value of c.
Instead, you need to combine them with &&, e.g. a === b && b === c.
E.g.:
function checkWin() {
if ((arro[0] === arro[1] && arro[1] === arro[2]) ||
(arro[3] === arro[4] && arro[4] === arro[5]) ||
/*...and so on...*/
) {
console.log("O Won");
return "O";
}
// ...
Side note: If you return from the block attached to the if, there's no need for the else prior to the next if. It's harmless, but pointless.
the result I want is second if else statement if code not in the list then alert, I don't get why the first if else statement fail, I thought that just reverse second if else statement ?? do I misunderstand some thing??
https://jsfiddle.net/e6qohvhc/
var code = '500';
if (code != '400' || code != '401' || code != '500') {
console.log('true'); // I don't want it alert here
}
if (code == '400' || code == '401' || code == '500') {
// I have to always leave this empty line ...
} else {
console.log('second true');
}
This has to do with De Morgan's laws:
If you want to invert a statement you have to invert every operator.
!a becomes a, b becomes !b, ||becomes &&, && becomes ||.
So the inversion of your second if would be something like
(code != '400' && code != '401' && code != '500')
You may need to review the Morgan's laws.
Basically, if you want to negate (a || b || c) you need to use (!a && !b && !c)
Hope it helps,
if(code != '400' || code != '401' || code != '500'){}
always will be true because a variable cant be equal to multiple values
The problem is ||
First if statement for 500 is always true, that's why you are having problem/
Do it in this way and it should work the way you wanted it (check it out in your fiddle);
var code = 500;
alert(code);
console.log(code);
if (((code !== 400) || (code !== 401)) && (code !== 500)) {
console.log('true');
alert("123");
}
else if ((code == 400) || (code == 401) || (code == 500)) {
alert("456");
} else {
console.log("second true");
alert("else");
}
I have 20 divs, each one with a speficif class, so I select it and check if is 1 of the 4 'special ones'.
The main issue is that the following code is supposed to work...
$('.cbp-ig-grid li, .cbp-ig-grid li a span object').on('click', function () {
/* Variables Definition */
var item = $(this).find('span').attr('class').split(' ')[1]
}
if((item != 'item1') || (item != 'item2') || (item != 'item3') || (item != 'item4')){
// Always enters here!
}else{
// Never enters here :( (I need to enter here for the 4 cases in the if statement)
}
but when I do for just one ... it works!
if(item != 'item1'){
// do stuff
}else{
// do other stuff
}
I don't know what I'm doing wrong, please any help will be useful
Consider your if statement:
if((item != 'item1') || (item != 'item2') || (item != 'item3') || (item != 'item4')){
}
What that is saying is that if ANY of these conditions are true, the if condition is met and it will execute the if block.
Let's say the item is "item2" now the first expression of your if statement is met as it's not item1 so that part is true. thus it executes the block.
What you want is: &&
if((item != 'item1') && (item != 'item2') && (item != 'item3') && (item != 'item4')){
//when it's not the special case.
}
else
{
//the 4 special cases.
}
if((item != 'item1') || (item != 'item2') || (item != 'item3') || (item != 'item4')){
No chance to go into the else here... item is always different from one or the other.
.hasClass() is your best friend. https://api.jquery.com/hasclass/
$('.cbp-ig-grid li, .cbp-ig-grid li a span object').on('click', function () {
/* Variables Definition */
var item = $(this).find('span');
switch(true) {
case item.hasClass('item1'):
// item 1
break;
case item.hasClass('item2'):
// item 2
break;
case item.hasClass('item3'):
// item 3
break;
case item.hasClass('item4'):
// item 4
break;
default:
// other stuff
}
});
Let's make it simple
if((item != 'item1') || (item != 'item2') || (item != 'item3') || (item != 'item4'))
Let's test it:
1:
item = 'item1':
false || true || true || true
that equals to true; because false || true = true
2:
item = 'theGreatOldOnes'
true || true || true || true - that equal to true
Both are true! That means that your expression is flawed - it doesn't make difference between 'special class' and any 'nonspecial class'
To make it understand difference between 'special' and 'not special' you need to use:
if((item != 'item1') && (item != 'item2') && (item != 'item3') && (item != 'item4'))
Or
if((item === 'item1') || (item === 'item2') || (item === 'item3') || (item === 'item4'))
You can do testing with 'item1' and 'theGreatOldOnes' to get a better grip on those things ^ ^
Help me please, I'm trying to make a rule for the little game and there is the problem.
I'm creating winning combination and say if the cell && cell+1 && cell+2 == to 'X' then you win, but when between two "X"s presents "o" it also says that "X" wins. Why? Please see my code and the game example on link a the bottom.
this.rezult = function(){
this.arr2.forEach(function(arr, i, innerArr){
arr.forEach(function(val, j){
var wincomb = innerArr[i][j] && innerArr[i][j+1] && innerArr[i][j+2];
var wincomb2 = innerArr[i][j] && innerArr[i+1][j] && innerArr[i+2][j];
var wincomb3 = innerArr[i][j] && innerArr[i+1][j+1] && innerArr[i+2][j+2];
console.log(wincomb == "X" && innerArr[i][j] !== "o");
// console.log(innerArr);
// THE RULE
if(wincomb == "X"){
alert(' X wins!');
}
});
});
};
Link to JSFiddle
In JavaScript, the && operator has interesting behavior with non-boolean values.
If the left-side of && is "truthy", the result is the right-side.
If the left-side of && is "falsey", the result is the left-side.
All non-empty strings are "truthy".
So, consider these examples:
("A" && "B" && "C") === "C"
("" && "B" && "C") === ""
(0 && "B" && "C") === 0
("X" && "X" && "O") === "O"
("O" && "O" && "X") === "X"
By the looks of it, you're trying to check if all 3 values are equal. You shouldn't use && for that, you should use === for that.
At the risk of doing your homework for you ;) here's a good way to do this:
function areTheSame(a,b,c) {
return a === b && b === c;
}
var down = areTheSame(innerArr[i][j], innerArr[i][j+1], innerArr[i][j+2]);
var across = areTheSame(innerArr[i][j], innerArr[i+1][j], innerArr[i+2][j]);
var diagonal = areTheSame(innerArr[i][j], innerArr[i+1][j+1], innerArr[i+2][j+2]);
if (down || across || diagonal) {
var winner = innerArr[i][j];
alert( winner + " wins!");
}
I put everything in parentheses but code below still throws error in jslint:
Problem at line 5 character 104: The '&&' subexpression should be wrapped in parens.
if ((typeof (c1) === 'string') && (typeof (c2) === 'string') && (c1 !== n...
How to fix ?
"use strict";
function t() {
var c1, c2;
if (((typeof (c1)) === 'string') && ((typeof (c2)) === 'string') && (c1 !== null) && (c2 !== null) && ((c1.trim()) === '') || ((c2.trim()) !== '')) {
return;
}
}
It's complaining about the form if(a && b && c || d) because (I suppose) it's not immediately obvious whether && or || will take precedence. Fix it to look like if(a && b && (c || d)) and it will stop complaining.
I think it wants this:
if (((typeof (c1) === 'string') && (typeof (c2) === 'string') && (c1 !== null) && (c2 !== null)) && ((c1.trim()) === '') || ((c2.trim()) !== '')) {
wrap the 4 anded expressions on the left of the && at 100.
I'm fairly certain you want the following:
function t() {
var c1, c2;
if (typeof c1 === 'string' && typeof c2 === 'string' && c1 !== null && c2 !== null && (c1.trim() === '' || c2.trim() !== '')) {
return;
}
}
Not everyone knows the precedence for boolean logic, so they want you to wrap the c1.trim() || c2.trim() statements in parenthesis so it's clear how they get operated.
As a side note, I think it's ridiculous that jslint wants spaces between my operators and my operands. I think it's much more clear when there is NOT a space.