X's Replaces O's - javascript

i'm making the tic tac toe game and im trying to fix a bug that i have now.
When i play the game and i click on the O's it changes to X how can i fix this?
I thought it would be something like: If (turn == 0 && ('td') == "") {
But that doesn't work
var newGame = function () {
$('td').one('click', function (event) {
if (turn == 0) {
$(this).text(human);
boardCheck();
checkWin();
turn == 1;
compMove();
boardCheck();
checkWin();
}
});
};
// VARIABLES
var human = 'x'; // turn = 0
var computer = 'o'; // turn = 1
var compMove;
var turn = 0; // toggles btw 0 and 1 for switching turns
var boardCheck; // function to check value in each cell
var a1; // value within each cell
var a2;
var a3;
var b1;
var b2;
var b3;
var c1;
var c2;
var c3;
var checkWin; // function that checks the board for winning combo
var xWin = false; // true if X wins
var oWin = false; // true if O wins
var winAlert; // function that declares winner and restarts game
var newGame;
var clearBoard;
// PLACES AN X OR O IN THE BOX WHEN CLICKED. TOGGLES.
var newGame = function () {
$('td').one('click', function (event) {
if (turn == 0) {
$(this).text(human);
boardCheck();
checkWin();
turn == 1;
compMove();
boardCheck();
checkWin();
}
});
};
// INITIALIZES GAME - keep after var newGame
$(document).ready(function () {
newGame();
});
// COMP MOVE AI DETECTS IF THERE ARE TWO IN A ROW NEXT TO AN EMPTY CELL AND PLACES MOVE THERE
var compMove = function () {
if (a1 == "" && ((a3 == "x" && a2 == "x") || (c3 == "x" && b2 == "x") || (c1 == "x" && b1 == "x"))) {
$('#a1').text("o");
turn = 0;
} else {
if (a2 == "" && ((a1 == "x" && a3 == "x") || (c2 == "x" && b2 == "x"))) {
$('#a2').text("o");
turn = 0;
}
else{
if (a3 == "" && ((a1 == "x" && a2 == "x") || (c1 == "x" && b2 == "x") || (c3 == "x" && b3 == "x"))) {
$('#a3').text("o");
turn = 0;
}
else{
if (c3 == "" && ((c1 == "x" && c2 == "x") || (a1 == "x" && b2 == "x") || (a3 == "x" && b3 == "x"))) {
$('#c3').text("o");
turn = 0;
}
else{
if (c1 == "" && ((c3 == "x" && c2 == "x") || (a3 == "x" && b2 == "x") || (a1 == "x" && b1 == "x"))) {
$('#c1').text("o");
turn = 0;
}
else{
if (c2 == "" && ((c3 == "x" && c1 == "x") || (a2 == "x" && b2 == "x"))) {
$('#c2').text("o");
turn = 0;
}
else{
if (b1 == "" && ((b3 == "x" && b2 == "x") || (a1 == "x" && c1 == "x"))) {
$('#b1').text("o");
turn = 0;
}
else{
if (b3 == "" && ((a3 == "x" && c3 == "x") || (b2 == "x" && b1 == "x"))) {
$('#b3').text("o");
turn = 0;
}
else{
if (b2 == "" && ((a3 == "x" && c1 == "x") || (c3 == "x" && a1 == "x") || (b3 == "x" && b1 == "x") || (c2 == "x" && a2 == "x"))) {
$('#b2').text("o");
turn = 0;
}
else{ // IF NO OPP TO BLOCK A WIN, THEN PLAY IN ONE OF THESE SQUARES
if (b2 == "") {
$('#b2').text("o");
turn = 0;
}
else{
if (a1 == "") {
$('#a1').text("o");
turn = 0;
}
else{
if (c3 == "") {
$('#c3').text("o");
turn = 0;
}
else {
if (c2 == "") {
$('#c2').text("o");
turn = 0;
}
else{
if (b1 == "") {
$('#b1').text("o");
turn = 0;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
};
// CREATES A FUNCTION TO DETECT WHAT IS IN EACH BOX AFTER EACH MOVE
boardCheck = function () {
a1 = $('#a1').html();
a2 = $('#a2').html();
a3 = $('#a3').html();
b1 = $('#b1').html();
b2 = $('#b2').html();
b3 = $('#b3').html();
c1 = $('#c1').html();
c2 = $('#c2').html();
c3 = $('#c3').html();
};
// CREATES A FUNCTION TO DETECT A WIN OR A TIE
checkWin = function () { // CHECKS IF X WON
if ((a1 == a2 && a1 == a3 && (a1 == "x")) || //first row
(b1 == b2 && b1 == b3 && (b1 == "x")) || //second row
(c1 == c2 && c1 == c3 && (c1 == "x")) || //third row
(a1 == b1 && a1 == c1 && (a1 == "x")) || //first column
(a2 == b2 && a2 == c2 && (a2 == "x")) || //second column
(a3 == b3 && a3 == c3 && (a3 == "x")) || //third column
(a1 == b2 && a1 == c3 && (a1 == "x")) || //diagonal 1
(a3 == b2 && a3 == c1 && (a3 == "x")) //diagonal 2
) {
xWin = true;
winAlert();
} else { // CHECKS IF O WON
if ((a1 == a2 && a1 == a3 && (a1 == "o")) || //first row
(b1 == b2 && b1 == b3 && (b1 == "o")) || //second row
(c1 == c2 && c1 == c3 && (c1 == "o")) || //third row
(a1 == b1 && a1 == c1 && (a1 == "o")) || //first column
(a2 == b2 && a2 == c2 && (a2 == "o")) || //second column
(a3 == b3 && a3 == c3 && (a3 == "o")) || //third column
(a1 == b2 && a1 == c3 && (a1 == "o")) || //diagonal 1
(a3 == b2 && a3 == c1 && (a3 == "o")) //diagonal 2
) {
oWin = true;
winAlert();
} else { // CHECKS FOR TIE GAME IF ALL CELLS ARE FILLED
if (((a1 == "x") || (a1 == "o")) && ((b1 == "x") || (b1 == "o")) && ((c1 == "x") || (c1 == "o")) && ((a2 == "x") || (a2 == "o")) && ((b2 == "x") || (b2 == "o")) && ((c2 == "x") || (c2 == "o")) && ((a3 == "x") || (a3 == "o")) && ((b3 == "x") || (b3 == "o")) && ((c3 == "x") || (c3 == "o"))) {
alert("It's a tie!");
clearBoard();
}
}
}
};
// DECLARES WHO WON
var winAlert = function () {
if (xWin == true) {
alert("You won!");
clearBoard(); // THIS DOESN'T WORK
} else {
if (oWin == true) {
alert("Sorry, you lose!");
clearBoard(); // THIS DOESN'T WORK
}
}
};
// NEWGAME BUTTON CLEARS THE BOARD, RESTARTS GAME, AND RESETS THE WINS
var clearBoard = $('#restart').click(function (event) {
a1 = $('#a1').text("");
b1 = $('#b1').text("");
c1 = $('#c1').text("");
a2 = $('#a2').text("");
b2 = $('#b2').text("");
c2 = $('#c2').text("");
a3 = $('#a3').text("");
b3 = $('#b3').text("");
c3 = $('#c3').text("");
xWin = false;
oWin = false;
newGame();
window.location.reload(true); // WITHOUT THIS, THERE'S A BUG WHICH PLACES MULTIPLE 0'S ON ALL GAMES AFTER THE FIRST
});
// STILL NEED TO FIX:
// * Alert for tie game or xWin appears twice
// * X's can replace O's
// * Missed opportunities for O to win
// * Almost never let's human win
// * Clean up logic for compMove'

if (turn == 0 && $(this).text() == "") {

Related

Why won't the text show up with this code?

This is all of the code for an app I've been making for class thats meant to tell you what game to buy depending on the genre, length, and amount of players but I cant figure out why it wont display the text.
It may be obvious whats wrong but this class is my first time coding except so ill miss some obvious things
var Genre = getText("genreSelector");
var Length = getNumber("lengthSelector");
var Mode = getText("modeSelector");
onEvent("genreSelector", "change", function( ) {
updateScreen();
});
onEvent("modeSelector", "change", function( ) {
updateScreen();
});
onEvent("lengthSelector", "change", function( ) {
updateScreen();
});
function updateScreen() {
if (Genre == "RPG" && Mode == "Multiplayer" && Length == 80 || Length == 70 || Length == 60 || Length == 50) {
setText("selectedGameText", "Baldur's Gate");
}
if (Genre == "RPG" && Mode == "Multiplayer" && Length == 40 || Length == 30) {
setText("selectedGameText", "Diablo");
}
if(Genre == "RPG" && Mode == "Multiplayer" && Length == 20 || Length == 10) {
setText("selectedGameText", "Child of light");
}
if (Genre == "RPG" && Mode == "Singleplayer" && Length == 80 || Length == 70 || Length == 60 || Length == 50) {
setText("selectedGameText", "Final Fantasy");
}
if (Genre == "RPG" && Mode == "Singleplayer" && Length == 30 || Length == 20 || Length == 10) {
setText("selectedGameText", "NieR");
}
if (Genre == "Sci-Fi" && Mode == "Multiplayer" && Length == 80 || Length == 70 || Length == 60 || Length == 50) {
setText("selectedGameText", "Astroneer");
}
if (Genre == "Sci-Fi" && Mode == "Multiplayer" && Length == 40 || Length == 30 || Length == 20) {
setText("selectedGameText", "Destiny 2");
}
if (Genre == "Sci-fi" && Mode == "Multiplayer" && Length == 10) {
setText("selectedGameText", "Halo");
}
if (Genre == "Sci-Fi" && Mode == "Singleplayer" && Length == 80 || Length == 70 || Length == 60) {
setText("selectedGameText", "Mass Effect Legendary Edition");
}
if (Genre == "Sci-Fi" && Mode == "Singleplayer" && Length == 40 || Length == 30 ) {
setText("selectedGameText", "Xcom");
}
if (Genre == "Sci-Fi" && Mode == "Singleplayer" && Length == 20 || Length == 10) {
setText("selectedGameText", "Deadspace");
}
}

Code keeps looping into max call stack error

I am trying to make tic tac toe on a website using javascript. That worked and now I'm trying to make a bot that, then you have 2 area's in a row. It needs to block you. But everytime it does block me, it won't do anything else afterwards, because it keeps looping into the error.
The t-numbers are the tile names, 0 means unoccupied,1 means for player 1, and 2 for player 2.
The t-numbers with a 1 behind it are just the tiles but they mustn't interfere with the functions (they are t-numbers too).
How do I fix this?
function tbot(){
while (turn == "player 2") {
if (t41 == 0 &&
(t01 == 1 && t81 == 1) ||
(t11 == 1 && t71 == 1) ||
(t21 == 1 && t61 == 1) ||
(t31 == 1 && t51 == 1)
) {t4()}
else {
var tiles = ['0', '1', '2', '3', '4', '5', '6', '7', '8'];
var tile = tiles[Math.floor(Math.random()*tiles.length)];
if (tile == '0' && t01 == 0) {t0()}
else if (tile == '1' && t11 == 0) {t1()}
else if (tile == '2' && t21 == 0) {t2()}
else if (tile == '3' && t31 == 0) {t3()}
else if (tile == '4' && t41 == 0) {t4()}
else if (tile == '5' && t51 == 0) {t5()}
else if (tile == '6' && t61 == 0) {t6()}
else if (tile == '7' && t71 == 0) {t7()}
else if (tile == '8' && t81 == 0) {t8()}
}
}
}
function update() {
if (t01 == 1 &&
((t11 == 1 && t21 == 1)||(t31 == 1 && t61 == 1))
||t41 == 1 &&
((t31 == 1 && t51 == 1)||(t11 == 1 && t71 == 1)||
(t01 == 1 && t81 == 1)||(t21 == 1 && t61 == 1))
||t81 == 1 &&
((t61 == 1 && t71 == 1)||(t21 == 1 && t51 == 1))
) {
twin = 1;
document.getElementById('turnshow').innerHTML = "Player 1 is the winner!";
document.getElementById('treset').style.backgroundColor = '#888';
} else if (t01 == 2 &&
((t11 == 2 && t21 == 2)||(t31 == 2 && t61 == 2))
||t41 == 2 &&
((t31 == 2 && t51 == 2)||(t11 == 2 && t71 == 2)||
(t01 == 2 && t81 == 2)||(t21 == 2 && t61 == 2))
||t81 == 2 &&
((t61 == 2 && t71 == 2)||(t21 == 2 && t51 == 2))
) {
twin = 1;
document.getElementById('turnshow').innerHTML = "Player 2 is the winner!";
document.getElementById('treset').style.backgroundColor = '#888';
} else {
if (bot == 1) {tbot();}
document.getElementById('turnshow').innerHTML = "It is " + turn + "'s turn!";
}
}
function t4() {
if (t41 == 0 && twin == 0) {
if (turn == "player 1") {
document.getElementById('t4').style.backgroundColor = p1;
turn = "player 2";
t41 = 1;
} else {
document.getElementById('t4').style.backgroundColor = p2;
turn = "player 1";
t41 = 2;
}
}
update();
}
The program never exit the while loop because condition (turn == "player 2") is always true.
If you're expecting t4() to change turn then I guess it doesn't do the job right. Check for (t41 == 0 && twin == 0), turn will never change if this condition is never been true.
I found what i did wrong. When I was checking if there are two area's selected in a row my code was:
if (t41 == 0 &&
(t01 == 1 && t81 == 1) ||
(t11 == 1 && t71 == 1) ||
(t21 == 1 && t61 == 1) ||
(t31 == 1 && t51 == 1)
)
But what that did: t41 and t01 and t81 or t11 and t71 or etc.
I just needed to add "()" around the options :/
if (t41 == 0 &&
((t01 == 1 && t81 == 1) ||
(t11 == 1 && t71 == 1) ||
(t21 == 1 && t61 == 1) ||
(t31 == 1 && t51 == 1))
)

Find condition by included words in JS string

I'm new with JS, I'm trying to figure out, what causes this result in condition:
if ((y1 == true || y2 == true || y3 == true || y4 == true || y5 ==true || y6 == true || y7 == true || y8 == true) && (n1 == false || n2 == false || n3 == false)) {
document.getElementById("demo1").innerHTML = "YES";
} else if ((y1 == false || y2 == false || y3 == false || y4 == false || y5 ==false || y6 == false || y7 == false || y8 == false) && (n1 == true || n2 == true || n3 == true)) {
document.getElementById("demo1").innerHTML = "NO" ;
} else if ((y1 == true || y2 == true || y3 == true || y4 == true || y5 ==true || y6 == true || y7 == true || y8 == true) && (n1 == true || n2 == true || n3 == true)){
document.getElementById("demo1").innerHTML = "BOTH TRUE";
} else if ((y1 == false || y2 == false || y3 == false || y4 == false || y5 ==false || y6 == false || y7 == false || y8 == false) && (n1 == false || n2 == false || n3 == false)){
document.getElementById("demo2").innerHTML = "BOTH FALSE";
}
if I have number of different words to find specific words in string by content with bool value:
var input = "hello, yes and no"; // "hello, yes"; "hello no"; "hello"
var i = input.trim().toLocaleLowerCase();
var y1 = i.includes("yes");
var y2 = i.includes("sure");
var y3 = i.includes("i want");
var y4 = i.includes("yes i want");
var y5 = i.includes("ok");
var y6 = i.includes("oks");
var y7 = i.includes("okay");
var y8 = i.includes("okey");
var n1 = i.includes("no");
var n2 = i.includes("nope");
var n3 = i.includes("not now");
this way result looks correct:
if (y1 == true && n1 == false) {
document.getElementById("demo2").innerHTML = "YES";
} else if (y1 == false && n1 == true) {
document.getElementById("demo2").innerHTML = "NO" ;
} else if (y1 == true && n1 == true){
document.getElementById("demo2").innerHTML = "BOTH TRUE";
} else if (y1 == false && n1 == false){
document.getElementById("demo2").innerHTML = "BOTH FALSE";
}
if input "hello, yes" result is YES
if input "hello, no" result is NO
if input "hello, yes and no" result is BOTH TRUE
if input "hello" result is BOTH FALSE
but if I want this result with number of values, in this case listed directly in condition with logical statement result is incorrect:
if input "hello, yes" result is YES
if input "hello, no" result is NO
if input "hello, yes and no" result is YES (Incorrect)
if input "hello" result is BOTH FALSE
I'm not sure if it is logical error or I've missed something, looks like includes also accepts "ko" as content of "ok", so maybe this method is not the correct way to get desired result. Maybe it is easier just to split string and check each value. Anyway, I'm looking for the proper solution to find specific words in string, so any basic advice would be very helpful
(n1 == false || n2 == false || n3 == false) will be true as long as at least one of no, nope or not now is not present in your string. (See: DeMorgan's Law.)
You can try to create a function that validates and return the string.
Idea:
Create list of words for yes and no.
Now loop over these words and check for availability. You can use modern function like Array.some for this.
Now you have 2 flags which needs to be validated. As binary permutation, you just have 4 combination,
0 0 (both false)
0 1 (no yes word but no word exists)
1 0 (yes word exists but no no exists)
1 1 (both words exists)
Based on this, return necessary string.
Few suggestions:
Most expensive part of a code is the part where human interacts with it. So keep it as simple/ readable. Having so many || conditions will confuse developer that takes charge after you go.
Use meaningful names. y1... does not specify its purpose and anyone debugging will have to read the code to understand what is going on.
If you notice your code, y1 == false/true ... or n1 == false... is repeated multiple times in same function. Its better to create a variable and store its value. Its simpler and you are not being redundant.
Try to break your code in smaller parts. In your case, you can have following parts:
Interact with DOM. Accept value and set processed result.
Process accepted input and perform logic.
This way, your code will be more modular and scalable.
Sample code
function processInput(input) {
const yesWords = ["yes", "sure", "i want", "yes i want", "ok", "oks", "okay", "okey"];
const noWords = ["no", "nope", "not now"];
input = input.trim().toLocaleLowerCase();
const containsYesWord = yesWords.some((word) => input.includes(word));
const containsNoWord = noWords.some((word) => input.includes(word));
if (containsYesWord && !containsNoWord) {
return "YES";
} else if (!containsYesWord && containsNoWord) {
return "NO";
} else if (containsYesWord && containsNoWord) {
return "BOTH TRUE";
} else if (!containsYesWord && !containsNoWord) {
return "BOTH FALSE";
}
}
const sampleInput = [
"hello, yes",
"hello, no",
"hello, yes and no",
"hello"
];
sampleInput.forEach((input) => console.log(input, processInput(input)))
As Scott Hunter stated, while checking the absence of the string in your way, you're always getting true.
The right version of your condition is:
if ((y1 == true || y2 == true || y3 == true || y4 == true || y5 ==true || y6 == true || y7 == true || y8 == true) && (n1 == false && n2 == false && n3 == false)) {
document.getElementById("demo1").innerHTML = "YES";
} else if ((y1 == false && y2 == false && y3 == false && y4 == false && y5 ==false && y6 == false && y7 == false && y8 == false) && (n1 == true || n2 == true || n3 == true)) {
document.getElementById("demo1").innerHTML = "NO" ;
} else if ((y1 == true || y2 == true || y3 == true || y4 == true || y5 ==true || y6 == true || y7 == true || y8 == true) && (n1 == true || n2 == true || n3 == true)){
document.getElementById("demo1").innerHTML = "BOTH TRUE";
} else if ((y1 == false && y2 == false && y3 == false && y4 == false && y5 ==false && y6 == false && y7 == false && y8 == false) && (n1 == false && n2 == false && n3 == false)){
document.getElementById("demo2").innerHTML = "BOTH FALSE";
}
Notice that now there are ANDs instead of ORs between the false checks, and that's because none of them should be present.
I think you want to have a look at this
var input = "hello, yes and no"; // "hello, yes"; "hello no"; "hello"
var inp = input.trim().toLocaleLowerCase().split(/[^\w]/);
console.log(inp)
const y = ["yes",
"sure",
"i want",
"yes i want",
"ok",
"oks",
"okay",
"okey"]
const n = ["no","nope","not now"];
var found = {y:0,n:0}
for (let i=0;i < inp.length;i++) {
found["y"] += inp[i] && y.indexOf(inp[i]) !=-1 ? 1 : 0;
found["n"] += inp[i] && n.indexOf(inp[i]) !=-1 ? 1 : 0;
}
console.log(found)
if (found.y > 0 && found.n === 0) {
text = "YES";
} else if (found.y === 0 && found.n > 0) {
text = "NO";
} else if (found.y > 0 && found.n > 0) {
text = "BOTH TRUE";
} else if (found.y === 0 && found.n === 0) {
text = "BOTH FALSE";
}
document.getElementById("demo2").innerHTML = text;
<span id="demo2"></span>

Can a Javascript condition be between numbers?

I'm looking to identify a category based on this table:
I have an if statement that seems to work for some conditions, but not others. R, P, and Q are working, but conditions that go between numbers aren't returning the right category.
If statement:
function getCategory(featureFunctionalScore, featureDysfunctionalScore) {
if (featureFunctionalScore == 4 && featureDysfunctionalScore == -2) {
return "Performance";
} else if (featureFunctionalScore == 4 && featureDysfunctionalScore <= -1 && featureDysfunctionalScore > 4) {
return "Attractive"
} else if (featureFunctionalScore <= -1 && featureFunctionalScore > 4 && featureDysfunctionalScore == 4) {
return "Expected"
} else if ((featureFunctionalScore >= -2 && featureFunctionalScore <= 2 && featureDysfunctionalScore == -2) || (featureFunctionalScore == -2 && featureDysfunctionalScore >= -2 && featureDysfunctionalScore <= 2)) {
return "Reverse"
} else if ((featureFunctionalScore == 4 && featureDysfunctionalScore == -2) || (featureFunctionalScore == 2 && featureDysfunctionalScore == -1) || (featureFunctionalScore == -1 && featureDysfunctionalScore == 2) || (featureFunctionalScore == -2 && featureDysfunctionalScore == 4)) {
return "Questionable"
} else {
return "Indifferent"
};
};
Am I missing something important?
Update
This statement works in Excel, but I'm struggling to get it to work in JS:
=IF(OR(AND(C3 <= 2, B3 <= -1), AND(C3 <= -1, B3 <= 2)), "R", IF(AND(C3 <= 2, C3 >= -1, B3 <= 2, B3 >= -1), "I", IF(AND(C3 >= 2,B3 >= -1, B3 <= 2),"A", IF(AND(C3 <= 2, B3 <= 4, B3 >= 2), "M", IF(AND(C3 >= 2, B3 >= 2), "P", "Q")))))
This should be what you're looking for. I'm sure it could be optimized, but it works. JSFiddle: https://jsfiddle.net/yxb7tr9n/
function getCategory(x,y){
var answer = -999;
if (x == 4 && y == 4){
answer = "p";
}else if([-1,0,2].indexOf(x) >= 0 && y == 4){
answer = "A";
}else if((x == -2 && y == 4) || (x == -1 && y == 2) || (x == 4, y == -2)){
answer = "Q";
}else if(x == 4 && [-1,0,2].indexOf(y) >= 0) {
answer = "M";
}else if((x == -1 && [-1,0].indexOf(y) >= 0) || (x == 0 && [-1,0,2].indexOf(y) >= 0) || (x == 2 && [0,2].indexOf(y) >= 0)){
answer = "I";
}else if ((x == -2 && [-2,-1,0,2].indexOf(y) >= 0) || (y == -2 && [-2,-1,0,2].indexOf(x) >= 0)) {
answer = "R";
}else{
answer = "??";
}
return answer;
}
UPDATE: Alternate version using a coordinate mapping system. JSFiddle: https://jsfiddle.net/g2d6p4rL/4/
function indexOfCustom (parentArray, searchElement) {
for ( var i = 0; i < parentArray.length; i++ ) {
if ( parentArray[i][0] == searchElement[0] && parentArray[i][1] == searchElement[1] ) {
return i;
}
}
return -1;
}
function getCategory2(x,y){
var p = [[4,4]];
var q = [[-2,4],[-1,2],[2,-1],[4,-2]];
var a = [[-1,4],[0,4],[2,4]];
var m = [[4,2],[4,0],[4,-1]];
var i = [[0,2],[2,2],[-1,0],[0,0],[2,0],[-1,-1],[0,-1]];
var r = [[-2,2],[-2,0],[-2,-1],[-2,-2],[-1,-2],[0,-2],[2,-2]];
coord = [x,y];
if (indexOfCustom(p,coord) >= 0){
return "p";
} else if (indexOfCustom(q,coord) >= 0){
return "Q";
} else if (indexOfCustom(a,coord) >= 0){
return "A";
} else if (indexOfCustom(m,coord) >= 0){
return "M";
} else if (indexOfCustom(i,coord) >= 0){
return "I";
} else if (indexOfCustom(r,coord) >= 0){
return "R";
}else{
return "??";
}
}
Output of all answers:
[-2,-2] = R
[-2,-1] = R
[-2,0] = R
[-2,2] = R
[-2,4] = Q
[-1,-2] = R
[-1,-1] = I
[-1,0] = I
[-1,2] = Q
[-1,4] = A
[0,-2] = R
[0,-1] = I
[0,0] = I
[0,2] = I
[0,4] = A
[2,-2] = R
[2,-1] = Q
[2,0] = I
[2,2] = I
[2,4] = A
[4,-2] = Q
[4,-1] = M
[4,0] = M
[4,2] = M
[4,4] = p

Comparing numbers with JavaScript

How can I loop through an array of numbers and compare them to multiple sets of numbers. I am trying to program the game logic for a Tic Tac Toe project. When the players click a square the number of the square that was clicked is stored in p1Taken or p2Taken. I am trying to loop through those arrays and compare the numbers to the numbers for the squares needed to win. Only the first if statement works and I don’t think it’s bc of the number of squares but because there is 3 numbers in the array. Here is the code that I have so far:
const turnTaken = {
X: [],
O: []
}
var whosTurn = 'X';
let p1Taken = turnTaken.X;
let p2Taken = turnTaken.O;
const gameGrid = document.getElementsByClassName("grid");
const message = document.getElementById("message");
for(i=0, l=gameGrid.length; i < l; i++){
const boardNum = gameGrid[i].getAttribute("value");
gameGrid[i].addEventListener('click', function(e) {
if(whosTurn == 'X') {
message.innerHTML = "O's Turn";
player1Turn(e);
} else {
message.innerHTML = "X's Turn";
player2Turn(e);
}
});
}
function player1Turn(e){
const clickedValue = e.target.getAttribute("value");
const clicked = e.target;
const xIcon = document.createElement("IMG");
const srcX = "img/x-icon.png";
xIcon.setAttribute("src", srcX);
clicked.appendChild(xIcon);
p1Taken.push(clickedValue);
whosTurn = 'O';
player1CheckWin(p1Taken);
}
function player2Turn(e){
const clickedValue = e.target.getAttribute("value");
const clicked = e.target;
const oIcon = document.createElement("IMG");
const srcO = "img/o-icon.png";
oIcon.setAttribute("src", srcO);
clicked.appendChild(oIcon);
p2Taken.push(clickedValue);
whosTurn = 'X';
player2CheckWin(p2Taken);
}
function player1CheckWin(p1Taken){
for(var i=0; i < p1Taken.length; i++) {
if(p1Taken.length > 2) {
if(p1Taken[i] == 1 || p1Taken[i] == 2 || p1Taken[i] == 3) {
console.log("first");
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 4 || p1Taken[i] == 5 || p1Taken[i] == 6) {
console.log("second");
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 7 || p1Taken[i] == 8 || p1Taken[i] == 9) {
console.log("third");
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 1 || p1Taken[i] == 4 || p1Taken[i] == 7) {
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 2 || p1Taken[i] == 5 || p1Taken[i] == 8) {
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 3 || p1Taken[i] == 6 || p1Taken[i] == 9) {
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 1 || p1Taken[i] == 5 || p1Taken[i] == 9){
message.innerHTML = "X Won!";
} else if(p1Taken[i] == 3 || p1Taken[i] == 5 || p1Taken[i] == 7) {
message.innerHTML = "X Won!";
} else {
break;
}
} else {
break;
}
}
}
function player2CheckWin(p2Taken){
for(var j=0; j < p2Taken.length; j++) {
if(p2Taken.length > 2) {
if(p2Taken[j] == 1 || p2Taken[j] == 2 || p2Taken[j] == 3) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 4 || p2Taken[j] == 5 || p2Taken[j] == 6) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 7 || p2Taken[j] == 8 || p2Taken[j] == 9) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 1 || p2Taken[j] == 4 || p2Taken[j] == 7) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 2 || p2Taken[j] == 5 || p2Taken[j] == 8) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 3 || p2Taken[j] == 6 || p2Taken[j] == 9) {
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 1 || p2Taken[j] == 5 || p2Taken[j] == 9){
message.innerHTML = "O Won!";
} else if(p2Taken[j] == 3 || p2Taken[j] == 5 || p2Taken[j] == 7) {
message.innerHTML = "O Won!";
} else {
break;
}
} else {
break;
}
}
}
I'll just pick one of your predicates:
p1Taken[i] == 1 && 2 && 3
This is true iff all of the following are true:
p1Taken[i] is similar to 1 (after necessary casting)
2 is true (after necessary casting)
3 is true (after necessary casting)
So I know that the numbers 2 and 3 are truthy and thus casting to boolean will both be true. If you meant to compare p1Taken[i] to the 3 numbers you need to do 3 comparisons:
p1Taken[i] == 1 || p1Taken[i] == 2 || p1Taken[i] == 3
If the number always are integers you can use ranges:
p1Taken[i] >= 1 && p1Taken[i] <= 3
EDIT
The key to making something easy rather than hard is to have a though out data structure that supports the operations you want to do. I would imagine that a board with the indexes representing the positions would be just as easy to update and it will be easy to check if one won. Here is how I would have modelled it:
function getWinner(b) {
if (b[4] && (
b[3] == b[4] && b[4] == b[5] ||
b[0] == b[4] && b[4] == b[8] ||
b[2] == b[4] && b[4] == b[6] ||
b[1] == b[4] && b[4] == b[7])) {
return b[4];
}
if (b[0] && (
b[1] == b[0] && b[0] == b[2] ||
b[3] == b[0] && b[0] == b[6])) {
return b[0];
}
if (b[8] && (
b[6] == b[8] && b[8] == b[7] ||
b[2] == b[8] && b[8] == b[5])) {
return b[8];
}
return false;
}
// tests
const o = 'o';
const x = 'x';
const n = undefined;
const test1 = [
o, o, x,
x, o, x,
o, n, x
];
const test2 = [
o, x, x,
x, o, o,
o, n, x
];
const test3 = [
o, x, x,
o, o, o,
x, n, x
];
console.log(getWinner(test1)); // prints x
console.log(getWinner(test2)); // prints false
console.log(getWinner(test3)); // prints o
you need to correct your logic of comparison
change this
p1Taken[i] == 1 && 2 && 3
to
p1Taken[i] == 1 && p1Taken[i] == 2 && p1Taken[i] == 3
similarly for others
&& operator expects expressions to be compared, in your case you gave first expression as p1Taken[i] == 1 which is correct but second & third expression given were '2' & '3' which are truthy values
Now about your logic part, the above code still wont give correct result as you expecting same thing p1Taken[i] to be equal to multiple values at same time.
so just a hint, p1Taken keep it as array of taken tile nos & use condition as
p1Taken.includes(1) && p1Taken.includes(2) && p1Taken.includes(3)
TicTacToe game

Categories

Resources