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))
)
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
I need help on a condition logic using if statement as following:
Variables A and B contain 3 properties which is level1, level2 and level3.
level1 and level2 can be 0 or more and level3 is null or numeric.
Variables A and B can be null.
Currently I have this condition:
if (A.level1 == 0 and B.level1 == 0) {
code here
} else if (A.level2 == 0 and B.level2 == 0) {
code here
} else if (A.level3 != null and B.level3 != null) {
code here
}
The problem is that this code doesn't handle the Variables A and B can be null part. The code should handle that part like this:
When A is null, B will still go through the same condition but without A and vice versa.
However, if A and B is null then the condition will be false at once.
I have problem in how to implement the Variables A and B can be null part in my condition, any advice?
Add the A and B isNull check in your condition:
if (A == null && B == null) {
return;
} else if ((A == null || A.level1 == 0) && (B == null || B.level1 == 0)) {
// code here
} else if ((A == null || A.level2 == 0) && (B == null || B.level2 == 0)) {
// code here
} else if ((A == null || A.level3 != null) && (B == null || B.level3 != null)) {
// code here
}
Explanation,
Take A for example in this else if ((A == null || A.level1 == 0) && (B == null || B.level1 == 0)) statement:
By putting the A == null || in (A == null || A.level1 == 0) && (B == null || B.level1 == 0), if A is null, then this A.level1 == 0 check will be ignored, thus the check will be equivalent with else if (B == null || B.level1 == 0).
Since the first if already check A == null && B == null, the else if below won't have A and B both null. Therefore now else if ((A == null || A.level1 == 0) && (B == null || B.level1 == 0)) will be equivalent to else if (B.level1 == 0).
p.s. Here we are taking advantage of the || characteristic, that is if the first condition is fulfilled, the second condition will be ignored.
Seems like this is what you're looking for:
// Both A and B are null
if(A == null && B == null){
// do something
}
// Only A is null
else if(A == null){
if(B.level1 == 0){
// do something
}
else if(B.level2 == 0){
// do something
}
else if(B.level3 != null){
// do something
}
}
// Only B is null
else if(B == null){
if(A.level1 == 0){
// do something
}
else if(A.level2 == 0){
// do something
}
else if(A.level3 != null){
// do something
}
}
// Neither A or B are null
else{
if(A.level1 == 0 && B.level1 == 0){
// do something
}
else if(A.level2 == 0 && B.level1 == 0){
// do something
}
else if(A.level3 != null && B.level3 != null){
// do something
}
}
I suggest to check for falsy values of A or B first and then check the properties.
var A = null,
B = null;
if (!A && !B) {
console.log('A or B is null');
} else if (A.level1 === 0 && B.level1 === 0) {
console.log(1);
} else if (A.level2 === 0 && B.level2 === 0) {
console.log(2);
} else if (A.level3 != null && B.level3 != null) {
console.log(3);
}
Handle A and B separately,
if(!A){
if(A.level1 === 0 && A.level2 ===0){
}
else if(A.level1 === 0){
}
else if(A.level1 > 0){
}
if(A.level2 === 0){
}
else if(A.level2 > 0){
}
if(A.level3 === null){
}
else if (typeof (A.level3) === "number"){
}
}
same for B here...
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() == "") {
i have a requirement: a text box can have a max of 50 characters, to achieve this I gave preventDefault.
if (!(event.ctrlKey && (event.which == 65 || event.which == 86 || event.which == 67 || event.which == 88))
&& (!(event.shiftKey && (event.which == 35 || event.which == 36)))
&& (key != 8 && key != 37 && key != 39 && key != 46 && key != 36 && key != 35 && key != 33 && key != 34)) {
event.preventDefault();
}
But now the requirement is : when we press ctrl+a and then abc it should erace everything from the text and print abc.
to achieve this i wrote this code ->
var focusItem = $('<input type="text">');
function getSelText() {
var txt = '';
//IE
var focusItem = $('<input type="text">');
if (document.selection != undefined) {
focusItem.focus();
var sel = document.selection.createRange();
var rangeParent = sel.parentElement();
txt = sel.text;
if (!(event.ctrlKey && (event.which == 65 || event.which == 86 || event.which == 67 || event.which == 88))
&& (!(event.shiftKey && (event.which == 35 || event.which == 36)))
&& (key != 8 && key != 37 && key != 39 && key != 46 && key != 36 && key != 35 && key != 33 && key != 34)) {
//event.preventDefault();
if (txt.length > 0 && ((key >= 65 && key <= 90) || (key >= 48 && key <= 57) || (key >= 97 && key <= 122))) {
sel.text = String.fromCharCode(key).toLowerCase();
}
txt = sel.text;
}
}
return txt;
}
now things are working but.. when I press ctrl+a abc then its getting printed as bca. Whats happening is : When i press a after ctrl+a then a is getting printed on the textbox but the focus is getting set before the text, that is a.
How to deal with this.
I am using windows 7, IE9, visual studio 2010.
Thanks.
The easiest way to set the focus to the end of a textbox is to just set the text of the textbox to itself:
focusItem.val(focusItem.val());