Tris game in JavaScript - javascript

I've just started to code in JS, so I'm trying some classical exercises.
Now I'm doing a simple tris game, but I have some problem with the victory check function that I posted here. Any ideas?
function controllo() {
var con = 0;
if (tab['usx'] == tab['uc'] == tab['udx'] == 'X' ||
tab['usx'] == tab['uc'] == tab['udx'] == 'O' ) //Orizzontali
con = 1;
else if (tab['csx'] == tab['cc'] == tab['cdx'] == 'X' ||
tab['csx'] == tab['cc'] == tab['cdx'] == 'O')
con = 1;
else if (tab['dsx'] == tab['dc'] == tab['ddx'] == 'X' ||
tab['dsx'] == tab['dc'] == tab['ddx'] == 'O')
con = 1;
else if (tab['usx'] == tab['cc'] == tab['ddx'] == "X" ||
tab['usx'] == tab['cc'] == tab['ddx'] == "O") //Diagonali
con = 1;
else if (tab['udx'] == tab['cc'] == tab['dsx'] == 'X' ||
tab['udx'] == tab['cc'] == tab['dsx'] == 'O')
con = 1;
else if (tab['udx'] == tab['cdx'] == tab['ddx'] == 'X' ||
tab['udx'] == tab['cdx'] == tab['ddx'] == 'O') //Verticali
con = 1;
else if (tab['uc'] == tab['cc'] == tab['dc'] == 'X' ||
tab['uc'] == tab['cc'] == tab['dc'] == 'O')
con = 1;
else if (tab['udx'] == tab['cdx'] == tab['ddx'] == 'X' ||
tab['udx'] == tab['cdx'] == tab['ddx'] == 'O')
con = 1;
return (con);
}
tab is a global array and con is a local flag. "X" and "O" mean the 2 different players. The problem is that all the conditions are always false.

See this implementation
In the first place you create a constant with the possible victories
var LINES = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
That you can use as in the implementation to count the X or O and if there are three it has won. The rest of the implementation I leave it to you. Is like this

Related

Implementation of a function to check who wins on a TicTacToe game

This is my first approach to programming and I'm trying to create a TicTacToe game.At the moment, I'm doing a function that checks if a winning play is happening, but I'm sure that there are better ways to do this that my actual code. Any suggestions?
This is what I have:
let boardGame = new Array(9)
let turn = 'x';
let winner;
let squares = document.getElementsByClassName('board') // this variable it is used in other functions that I'm not transcribing it.
let whoWins = (boardGame) =>{
if(boardGame[0] == 'x' && boardGame[1] == 'x' && boardGame[2]== 'x' || boardGame[3] == 'x' && boardGame[4] == 'x' && boardGame[5]== 'x' || boardGame[6] == 'x' && boardGame[7] == 'x' && boardGame[8]== 'x' || boardGame[0] == 'x' && boardGame[4] == 'x' && boardGame[8]== 'x' || boardGame[2] == 'x' && boardGame[4] == 'x' && boardGame[6]== 'x' || boardGame[0] == 'x' && boardGame[3] == 'x' && boardGame[6]== 'x' || boardGame[1] == 'x' && boardGame[4] == 'x' && boardGame[7]== 'x' || boardGame[2] == 'x' && boardGame[5] == 'x' && boardGame[8]== 'x'){
winner = 'x'
}
else if(boardGame[0] == 'o' && boardGame[1] == 'o' && boardGame[2]== 'o' || boardGame[3] == 'o' && boardGame[4] == 'o' && boardGame[5]== 'o' || boardGame[6] == 'o' && boardGame[7] == 'o' && boardGame[8]== 'o' || boardGame[0] == 'o' && boardGame[4] == 'o' && boardGame[8]== 'o' || boardGame[2] == 'o' && boardGame[4] == 'o' && boardGame[6]== 'o' || boardGame[0] == 'o' && boardGame[3] == 'o' && boardGame[6]== 'o' || boardGame[1] == 'o' && boardGame[4] == 'o' && boardGame[7]== 'o' || boardGame[2] == 'o' && boardGame[5] == 'o' && boardGame[8]== 'o'){
winner = 'o'
}
else{}
}
I came up with this function hoping it's not too difficult to approach with.
In case I can simplify it just let me know:)
let whoWins = (boardGame) => {
const winningConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8]
[2, 4, 6],
];
const winner = winningConditions.find(
(condition) =>
boardGame[condition[0]] === boardGame[condition[1]] &&
boardGame[condition[1]] === boardGame[condition[2]]
);
// if the game is not finished exit
if (winner === undefined) return;
winner = boardGame[winner[0]];
};
Grazie

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))
)

I am not getting any output for this js code

This is the code -
<input type="text" id="field">
<input type="button" onclick="test()">
<p id="demo"></p>
<script type="text/javascript">
function test(){
var a = document.getElementById("field").value;
var b = a.split(" ");
for(var i=0; i<b.length; i++){
var x[i] = 0;
for(var j=0; j<b[i].length; j++){
if(b[i][j] == 'e' || b[i][j] == 'a' || b[i][j] == 'i' || b[i][j] == 'o' || b[i][j] == 'n' || b[i][j] == 'r' || b[i][j] == 't' || b[i][j] == 'l' || b[i][j] == 's' || b[i][j] == 'u'){
x[i]++;
}
else if(b[i][j] == 'd' || b[i][j] == 'g'){
x[i]+=2;
}
else if(b[i][j] == 'b' || b[i][j] == 'c' || b[i][j] == 'm' || b[i][j] == 'p'){
x[i]+=3;
}
else if(b[i][j] == 'f' || b[i][j] == 'h' || b[i][j] == 'w' || b[i][j] == 'y'){
x[i]+=4;
}
else if(b[i][j] == 'k'){
x[i]+=5;
}
else if(b[i][j] == 'j' || b[i][j] == 'x'){
x[i]+=8;
}
else{
x[i]+=10;
}
}
}
document.getElementById("demo").innerHTML = x[0];
/*if(x[0] > x[1]){
document.getElementById("demo").innerHTML = b[0];
}
else{
document.getElementById("demo").innerHTML = b[1];
}*/
}
</script>
</body>
I am not getting any output for this code. I am printing here x[0] but not getting anything. Please help me with this code. What's wrong in this code. I tried everything.
Please Try This
function test(){
var a = document.getElementById("field").value;
var b = a.split(" "),x;
var x =[];
for(var i=0; i<b.length; i++){
x[i] = 0;
for(var j=0; j<b[i].length; j++){
if(b[i][j] == 'e' || b[i][j] == 'a' || b[i][j] == 'i' || b[i][j] == 'o' || b[i][j] == 'n' || b[i][j] == 'r' || b[i][j] == 't' || b[i][j] == 'l' || b[i][j] == 's' || b[i][j] == 'u'){
x[i]++;
}
else if(b[i][j] == 'd' || b[i][j] == 'g'){
x[i]+=2;
}
else if(b[i][j] == 'b' || b[i][j] == 'c' || b[i][j] == 'm' || b[i][j] == 'p'){
x[i]+=3;
}
else if(b[i][j] == 'f' || b[i][j] == 'h' || b[i][j] == 'w' || b[i][j] == 'y'){
x[i]+=4;
}
else if(b[i][j] == 'k'){
x[i]+=5;
}
else if(b[i][j] == 'j' || b[i][j] == 'x'){
x[i]+=8;
}
else{
x[i]+=10;
}
}
}
document.getElementById("demo").innerHTML = x[0];
/*if(x[0] > x[1]){
document.getElementById("demo").innerHTML = b[0];
}
else{
document.getElementById("demo").innerHTML = b[1];
}*/
}
You declared the x array inside a for loop therefore it's not available outside of it. Try moving the declaration outside of the loop.
This issue is caused by your wrong array declaration var x[i] = 0;
Change it to something like this: var x = new Array();
Then access each index via x[index]
See https://www.w3schools.com/js/js_arrays.asp
Try this:
function test(){
var a = document.getElementById("field").value;
console.log(a);
var b = a.split(" ");
console.log(b);
for(var i = 0; i < b.length; i++) {
var x = [];
x[i] = 0;
for(var j=0; j<b[i].length; j++){
if(b[i][j] == 'e' || b[i][j] == 'a' || b[i][j] == 'i' || b[i][j] == 'o' || b[i][j] == 'n' || b[i][j] == 'r' || b[i][j] == 't' || b[i][j] == 'l' || b[i][j] == 's' || b[i][j] == 'u'){
x[i]++;
}
else if(b[i][j] == 'd' || b[i][j] == 'g'){
x[i]+=2;
}
else if(b[i][j] == 'b' || b[i][j] == 'c' || b[i][j] == 'm' || b[i][j] == 'p'){
x[i]+=3;
}
else if(b[i][j] == 'f' || b[i][j] == 'h' || b[i][j] == 'w' || b[i][j] == 'y'){
x[i]+=4;
}
else if(b[i][j] == 'k'){
x[i]+=5;
}
else if(b[i][j] == 'j' || b[i][j] == 'x'){
x[i]+=8;
}
else{
x[i]+=10;
}
}
document.getElementById("demo").innerHTML = x[b.length -1];
}
}
<input type="text" id="field">
<input type="button" onclick="test()">
<p id="demo"></p>
This line itself is a problem var x[i] = 0; That's not how you declare an array. Here is how you do it var x = []; but since you want to set the first element to 0 then you can do this var x = [0]; just replace this line and your code should work.
Also to check the problem your code in the future when you encounter error, on browser press F12 key to open developer tools then see the console window/tab and it'll tell you exactly what the problem in your code.
EDIT
After reading your code again I saw that #Ankul Chaudhary 's answer is probably what you wanted to achieve since in the comment in your code you intent to compare items inside array x which in his solution he declared array x outside of the loop which it won't reset its values and keep all the calculated values inside the array which allow you to access later in the code

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

Tic Tac Toe with Javascript stuck

I am trying to make a Tic-Tac-Toe with Javascript.
I used a method to compare the current input with the winning combination.
1)How to determine player 1 and player 2 input ?
2)i can compare 3 , but i can't figure out the 4th click for each player.
Kindly Advise.
var check = [[0,0,0],[0,0,0]]; //check[0] for player 1 , check[1] for player 2 , but i can't figure out how to increase the counter for each player on each click.
function playercol(ideal) //main
{
var idname = "box"+idval;
var currentcount = (playercount%2);
if( currentcount == 0 )
{
document.getElementById(idname).innerHTML="O";
}
else
{
document.getElementById(idname).innerHTML="X";
}
document.getElementById("player").innerHTML="Player "+((playercount%2)+1);
checkwin(check,0);//to check //0 is the current player index
playercount++;
}
My Fiddle
http://jsfiddle.net/1br5LLrj/3/
I tried to modify your code as little as possible http://jsfiddle.net/rrj24ze9/1
The essential part is the win check:
You don't need to remember what the player has clicked and compare that to a winning combo. Instead, iterate through the winning combinations and check if one of them contains only fields that are taken by the player.
var winning = [
[1, 2, 3], [4, 5, 6], [7, 8, 9],
[1, 4, 7], [2, 5, 8], [3, 6, 9],
[1, 5, 9], [3, 5, 7]
];
function checkwin(player) {
for (var i = 0; i < winning.length; i++) {
var combo = true;
for (var j = 0; j < 3; j++) {
if (document.getElementById('box' + winning[i][j]).innerHTML != markers[player]) {
combo = false;
}
}
if (combo) return true;
}
return false;
}
There is a lot of potential for improvement, like not using innerHTML (separation of data from view), or even preventing two clicks on the same field, but again, I tried to leave your code intact where possible.
Just made a tic tac toe in about 20 minutes from scratch for you.
JS Bin Here
Just alternating players right now... modify it to your own needs.
all win conditions will alert who winner is:
$(document).ready( function(){
function checkwin() {
if (
$('#a1').html() == "X" && $('#b1').html() == "X" && $('#c1').html() == "X" || $('#a2').html() == "X" && $('#b2').html() == "X" && $('#c2').html() == "X" || $('#a3').html() == "X" && $('#b3').html() == "X" && $('#c3').html() == "X" || $('#a1').html() == "X" && $('#a2').html() == "X" && $('#a3').html() == "X" || $('#b1').html() == "X" && $('#b2').html() == "X" && $('#b3').html() == "X" ||
$('#c1').html() == "X" && $('#c2').html() == "X" && $('#c3').html() == "X" ||
$('#a1').html() == "X" && $('#b2').html() == "X" && $('#c3').html() == "X" ||
$('#a3').html() == "X" && $('#b2').html() == "X" && $('#c1').html() == "X"
)
{
alert("winner is: X");
}
if (
$('#a1').html() == "O" && $('#b1').html() == "O" && $('#c1').html() == "O" || $('#a2').html() == "O" && $('#b2').html() == "O" && $('#c2').html() == "O" || $('#a3').html() == "O" && $('#b3').html() == "O" && $('#c3').html() == "O" || $('#a1').html() == "O" && $('#a2').html() == "O" && $('#a3').html() == "O" || $('#b1').html() == "O" && $('#b2').html() == "O" && $('#b3').html() == "O" ||
$('#c1').html() == "O" && $('#c2').html() == "O" && $('#c3').html() == "O" ||
$('#a1').html() == "O" && $('#b2').html() == "O" && $('#c3').html() == "O" ||
$('#a3').html() == "O" && $('#b2').html() == "O" && $('#c1').html() == "O"
)
{
alert("winner is: O");
}
}
var player = 1;
$('td').click(function(){
if(player == 1){
$(this).html("X").removeClass('o').addClass('x');
checkwin();
player++;
}
else if (player == 2){
$(this).html("O").removeClass('x').addClass('o');
checkwin();
player--;
}
});
});
Dont forget to use Jquery Library!
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>

Categories

Resources