Basic tic-tac-toe JavaScript - javascript

I am struggling to add the option of taking turns in this program I want to do. I need to add an "X" wherever the player clicks and then for the second click it will add a "O". when I run this code it only does "X" everytime I click it. How do I change this?
function X() {
this.innerHTML = "X";
}
function O() {
this.innerHTML = "O";
}
function XDO() {
for (i = 1; i <= 9; i++) {
document.getElementById("cell" + i).onclick = X;
}
}
function ODO() {
for (i = 1; i <= 9; i++) {
document.getElementById("cell" + i).onclick = O;
}
}
var turn = true;
if (turn == true) {
XDO();
turn == false;
} else if (turn == false) {
ODO();
turn == true;
}

In the below code snippet..
if(turn==true)
{
XDO();
turn==false; // assignment operator should be used turn =false
}
else if(turn ==false)
{
ODO();
turn==true; // assignment operator should be used turn =true
}
comparison operator(==) was used, it should have been assignment operator (=)

Related

Increment of global variable in google app script isn't working

How to increment my global variable 'currentstep' in Google App Script. The third if statement, I used currentstep++ but it doesn't increase as it stayed at 2. Furthermore, I had tried currentstep += 1; and currentstep = currentstep + 1; Both methods don't work as well.
function check_command(data){
var text = data.message.text;
if(text == "/start" || text == "/start"){
currentstep = 1;
return;
}
if (text == "/survey" || text == "/survey"){
currentstep = 2;
return;
}
if (text){
currentstep++;
}
return;
}
In google apps script every time you make a function call the global variable get reinitialized. So typically it's better to use PropertiesService or CacheService for global parameters that you wish to change from one execution to another.
The conditions like this:
if (text == "/start" || text == "/start") { ... }
Have little sense. They are equal with this:
if (text == "/start") { ... }
So your function can be boiled down to this:
function check_command(data) {
var text = data.message.text;
if (text == "/start") { currentstep = 1; return }
if (text == "/survey") { currentstep = 2; return }
if (text) { currentstep++ }
}
And it works fine by itself, as far as I can tell.
Here is a test:
function check_command(data) {
var text = data.message.text;
if (text == "/start") { currentstep = 1; return }
if (text == "/survey") { currentstep = 2; return }
if (text) { currentstep++ }
}
var currentstep = 0;
var data = {message: {text: ""}};
var texts = [
,
"",
false,
"/start",
"/survey",
"",
,
"aaa",
"/survey",
123,
"/start",
""
]
for (let txt of texts) {
data.message.text = txt;
check_command(data);
console.log("currentstep = " + currentstep + " for '" + txt + "'");
}
Probably #Cooper is right. You're doing something fancy that we can't know from your question. Are you running the script several times and trying to keep the global value between the runs?
Update
If you suspect that the problem is a global variable you can modify your function to avoid using the global variable within the function:
function check_command(data, counter) {
var text = data.message.text;
if (text == "/start") return = 1;
if (text == "/survey") return = 2;
if (text) counter++;
return counter;
}
And call the function this way:
currentstep = check_command(data, currentstep);

What's wrong with my Code [Iteration Structure]

I am trying to have an array that contains values of each character of a key typed and I was getting errors. Therefore, I took a very tiny snippet and did lots of tries to see what was going on:
for (var j = 0; j < code.length; j++) {
var UnitPlace = codeLength - j;
if (code[j] = "0") {
value = 0;
encryption.push(0);
}
else {
if (code[j] = "1") {
value = 1;
encryption.push(1);
}
else {
if (code[j] = "2") {
value = 2;
encryption.push(2);
}
else {
if (code[j] = "3") {
value = 3;
encryption.push(3);
}
else {
if (code[j] = "4") {
value = 4;
encryption.push(4);
}
else {
if (code[j] = "5") {
value = 5;
encryption.push(5);
}
else {
if (code[j] = "6") {
value = 6;
encryption.push(6);
}
else {
if (code[j] = "7") {
value = 7;
encryption.push(7);
}
}
}
}
}
}
}
}
}
document.write(encryption);
I was able to realize that only the first if statement is read in the iteration sequence. but the source code you see above is after i realized this and tried having it read the other parts of the sequence but it still reads only the first if statement.
Could someone tell me how to solve it and/or what the problem with my code is?
Are you looking for something like this? :
let strCode = "1234567";
let encryption = strCode.split('').map(c => parseInt(c));
document.write(encryption);

Can someone please tell me why this method did not work for finding palindromes?

Attempting to complete the algorithms on freeCodeCamp. I eventually found an approach that works, but i still don't understand why this method did not work for all cases.
function palindrome(str) {
var alphaNumericStr = str.replace(/\W/g,"");
var lowerCaseAlphaNumericString = alphaNumericStr.toLowerCase();
var arr = lowerCaseAlphaNumericString.split("");
arr.reverse();
var reversedString = arr.join("");
if(str === reversedString){
return true;
}
return false;
}
palindrome("race car");
You're comparing a string which has been stripped of spaces and converted to lowercase to the original string. Replace your conditional with:
if(lowerCaseAlphaNumericString == reversedString){
rethrn true;
}
return false;
Here's a little refactor if you're interested:
// ...
var reversedString = arr.join('');
return lowerCaseAlphaNumericString == reversedString;
demo
This is where you are going wrong if(str === reversedString)
Try this:
if(lowerCaseAlphaNumericString === reversedString) {
return true;
}
return false;
}
There could be another approach. In this approach, the corner cases are handled separately.
function check_Palindrome(input_str){
var astr = input_str.toLowerCase().replace(/\W/g,'');
var acount = 0;
if(astr==="") {
console.log("Not Palindrome.");
return false;
}
if ((astr.length) % 2 === 0) {
acount = (astr.length) / 2;
} else {
if (astr.length === 1) {
console.log("Palindrome.");
return true;
} else {
acount = (astr.length - 1) / 2;
}
}
for (var x = 0; x < acount; x++) {
if (astr[x] != astr.slice(-1-x)[0]) {
console.log("Not Palindrome.");
return false;
}
}
console.log("Palindrome.");
return true;
}

Input button never appears when javascript detects form completed

I'm making a register page using HTML, CSS and JS and Java servlet etc. I have a monitorer() function which checks if the user has finished inputting everything before making the register button visible. But now everything works, but somewhere am getting screwed over and the button never comes back..
my button in reg.html :
<input type="submit" value="Register" class="btnSub" id="btnReg" style="visibility:hidden;"/>
javascript function monitorer()
function monitorer() {
var btnReg = document.getElementById("btnReg");
btnReg.style.visibility = "hidden";
var flag = true;
if (document.getElementById("fname").value.length >= 3) {
if (document.getElementById("lname").value.length >= 3) {
if (valiDate(document.getElementById("dob"))) {
if (document.getElementById("USN").value.length == 10) {
if (document.getElementById("passw").value.length > 5) {
var ticks = document.getElementsByClassName("checker"), i = 0;
for (i = 0; i < ticks.length; i++) {
if (ticks.item(i).innerHTML == "✔") {
alert("i val = " + i);
continue;
} else {
flag = false;
break;
}
}
}
} else {
flag = false;
document.getElementById("USN").focus();
}
} else {
flag = false;
document.getElementById("dob").focus();
}
} else {
flag = false;
document.getElementById("lname").focus();
}
} else {
flag = false;
document.getElementById("fname").focus();
}
if (flag == true) {
btnReg.style.visibility = "visible";
} else if(flag == false) {
btnReg.style.visibility = "hidden";
}}
And to help you get as good a picture as you can, a screenshot
See - all the ticks are there, the first name, last name etc are having value.length >=3 but still the register button doesn't show..
Also, I have put the monitorer() method in every input's "onBlur", "onChange" events.
Here is a link to my html file >>> reg.html
and please let me know if i can improve anything?

Boolean's value is acting as true but is listed as false?

I'm creating a simple tic-tac-toe game and I have a boolean called winAlert that if it is true it should alert the player that they have won. This works correctly for the most part, but there is one instance where it does not. If the game is won and all of the cells are filled, the console logs that winAlert's value is false, but it still alerts the player that they have won, as if it were true. Could someone look over this code and see why this is behaving in this way? http://jsfiddle.net/Z5c9P/3/
This function is where I think the problem lies, but I don't know for sure.
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
for (var j = 0; j < winConditions[i].length; j++) {
winAlert = false;
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
winAlert = true;
break;
}
}
if (!winAlert) break;
}
if (winAlert) {
alert(currentPlayer + " wins!");
break;
}
}
};
Here's the code that calls this function:
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
This is happening because your code does the following:
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
So if X ever wins the game, determineWin(xMoves) will set the variable to true, and determinWin(oMoves) will set it back to false, all before the console.log()
One way to solve this would be to only check for a win for the current player's moves:
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : yMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
You have called determineWin on each player. so if x wins, determineWin(oMoves); will make winAlert false. Is this the problem?
Maybe you should create a new determineWin which only called once to determine who is the winner.
this code will just skip another user(so winAlert is still true) when his cell is less than 3, so this problem doesn't need fill all cells but just each player has more than 3 cells.
if (winConditions[i].length > pMoves.length) {
continue;
}
i change a little your code Fiddle
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
winAlert = false;
matches = 0;
for (var j = 0; j < winConditions[i].length; j++) {
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
matches++;
}
}
}
if (matches == 3) return true;
}
return false;
};
and then
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
if (determineWin(xMoves)){ // this is changed
alert("X Win")
return;
};
if (determineWin(oMoves)){
alert("O Win")
return;
};
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
** Updated to clarify

Categories