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

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

Related

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

Tris game in 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

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>

Switch statement in if else conditional, else not being reached

This is a shortened version of a conditional I've written to parse information from a vehicle VIN number. If I pass in a VIN such as JA3XXXXXXXXXXXXXX it returns and object with properties of region:'Asia';, country:'Japan'; and make:'Isuzu'; but if I pass it 2A5XXXXXXXXXXXXXX I would expect an object with properties set to region:'North America'; , country:'Canada'; and make:'Chrysler'; instead I get an object with the region property set to 'Asia' and that is it. Here is a jsFiddle with the code shown below.
var vehicle = {},
nthDigit = function (stringifiedVin, i) {
var nthChar = stringifiedVin.charAt(i);
return nthChar;
},
parseVin = function () {
var i = 0;
for (i = 0; i < 16; i += 1) {
if (i === 0) {
if (nthDigit(stringifiedVin, 0) === 'J' || 'K' || 'L' || 'M' || 'N' || 'P' || 'R') {
vehicle.region = 'Asia';
switch (nthDigit(stringifiedVin, i)) {
case 'J':
vehicle.country = 'Japan';
switch (nthDigit(stringifiedVin, 1)) {
case 'A':
if (nthDigit(stringifiedVin, 2) === 'A' || 'B' || 'C' || 'D' || 'E' || 'F' || 'G' || 'H' || 'J' || 'K' || 'L' || 'M' || 'N' || 'P' || 'R' || 'S' || 'T' || 'U' || 'V' || 'W' || 'X' || 'Y' || 'Z') {
vehicle.make = 'Isuzu';
} else if (nthDigit(stringifiedVin, 2) === '3' || '4' || '5' || '6' || '7') {
vehicle.make = 'Mitsubishi';
} else {
vehicle.make = 'Not Read';
}
break;
}
break;
}
} else if (nthDigit(stringifiedVin, 0) === '1' || '2' || '3' || '4' || '5') {
vehicle.region = 'North America';
if (nthDigit(stringifiedVin, 0) === '2') {
vehicle.country = "Canada";
switch (nthDigit(stringifiedVin, 1)) {
case 'A':
if (nthDigit(stringifiedVin, 2) === '2' || '3' || '4' || '5' || '6' || '7' || '8') {
vehicle.make = 'Chrysler';
} else {
vehicle.make = 'Not Read';
}
break;
}
break;
}
}
return vehicle;
}
}
}
I don't thing the || parts work the way you think they do. This will run the Alert() since '2' is not false:
if ('A' === '1' || '2')
alert('match')
I would use a switch or you will have to spell it out like:
var nd = nthDigit(stringifiedVin, 0);
if (nd === 'J' || nd === 'K' || nd === 'L' || ...
A shorter one:
if("JKLMNP".indexOf(nthDigit(stringifiedVin, 0)) > -1){
//....
}
#JBrooks I think you are right about how the double pipe or operator was causing trouble in the conditional statement. I think it is due to the way the operator handles falsy values as shown in this SO post. I ended up getting rid of the if statements entirely when I realized the JA3XXXXXXXXXXXXXX should have been returning Mitsubishi and not Isuzu. I found the solution here using #KennyTM answer on setting up multiple cases.

Categories

Resources