i'm a beginner in javascript. So I have a local multiplayer Tic Tac Toe Game and i want to get players nicknames from the two inputs and display in game by current player turn/ winner nickname.
I can access from console the values stored in p1 and p2 (p1.name, p1.val and p2.name, p2.val) but i don't know how to call them in setTurnIndicator function and check winnner.
I tried to store them in local storage and get them but it doesn't work.
// Multiplayer Options
let ps = document.getElementById('btn');
let c1 = document.getElementsByName('characP1');
let c2 = document.getElementsByName('characP2');
let msg = document.getElementById('message');
let char1;
let char2;
function Player(name, val) {
this.name = name;
this.val = val;
}
for (i = 0; i < c1.length; i++) {
c1[i].addEventListener('change', function () {
if (this.checked) {
this.value == 'X' ? c2[1].checked = true : c2[0].checked = true;
char1 = this.value;
char2 = this.value == 'X' ? 'O' : 'X';
}
});
}
for (i = 0; i < c2.length; i++) {
c2[i].addEventListener('change', function () {
if (this.checked) {
this.value == 'X' ? c1[1].checked = true : c1[0].checked = true;
char2 = this.value
char1 = this.value == 'X' ? 'O' : 'X';
}
});
}
ps.addEventListener('click', function () {
let player1 = document.getElementById('p1').value;
let player2 = document.getElementById('p2').value;
p1 = new Player(player1, char1);
p2 = new Player(player2, char2);
if (p1.name && p1.val && p2.name && p2.val) {
msg.innerHTML = p1.name + ' : ' + p1.val + '<br />' + p2.name + ' : ' + p2.val;
} else {
msg.innerHTML = 'Please fill all input fields';
}
// return playerOne, playerTwo;
// window.localStorage.setItem('nume1', p1.name);
// window.localStorage.setItem('nume2', p2.name);
});
// Hide Players Options
function hidePlayersOptions() {
let x = document.getElementById("mpOptions");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
let y = document.getElementById("game");
if (y.style.display === "none") {
y.style.display = "block";
} else {
y.style.display = "block";
}
}
// Multiplayer Game Logic
/* Tic-Tac-Toe functions */
let TicTacToe = {
/* initialize the Tic-Tac-Toe variables */
init: function() {
this.symbols = [`X`, `O`];
this.name = [window.localStorage.getItem('nume1'), window.localStorage.getItem('nume2')];
this.squares = Array.from(document.querySelectorAll(".square"));
this.turnIndicator = document.querySelector(".turnIndicator");
this.button = document.querySelector(".newGame");
this.board = document.querySelector(".board");
// square positions in which you can get 3-in-a-row
this.winningSets = [
// horizontal sets
[0,1,2], [3,4,5], [6,7,8],
// vertical sets
[0,3,6], [1,4,7], [2,5,8],
// diagonal sets
[0,4,8], [2,4,6]
];
// add click event listeners to squares and button
this.addEventListeners();
// reset the game
this.newGame();
},
// add click event listeners to squares and button
addEventListeners: function() {
let ttt = this;
// for each square, add a click listener which will call "play()"
this.squares.forEach(function(x) {
x.addEventListener("click",function() {
ttt.play(this);
}, false)
})
// when the new game button is clicked, call "newGame()"
this.button.addEventListener("click", function() {
ttt.newGame();
}, false);
},
// reset the game
newGame: function() {
// set player to first player (X)
this.activePlayer = 0;
// reset the game over variable
this.gameOver = false;
// remove all X and O classes from every square
this.squares.forEach(function (x) {
x.classList.remove(TicTacToe.symbols[0]);
x.classList.remove(TicTacToe.symbols[1]);
})
// remove gameOver class from board if it exists
this.board.classList.remove("gameOver");
// set the turn indicator (X's turn)
this.setTurnIndicator();
},
// set the turn indicator to indicate whose turn it is
setTurnIndicator: function() {
this.turnIndicator.innerText = this.symbols[this.name[this.activePlayer]] + "'s turn."
// this.turnIndicator.innerText = this.symbols["window.localStorage.getItem('nume1')"] + "'s turn."
// this.turnIndicator.innerText = this.symbols[window.localStorage.getItem('nume1')[this.activePlayer]];
},
play: function(el) {
// make sure that the square is not filled
if (!this.gameOver && el.classList.length == 1) {
// set the contents to your player's symbol
el.classList.add(this.symbols[this.activePlayer]);
// check if you won
if (this.checkWin()) {
// set the game text to display the winner
this.turnIndicator.innerText = this.symbols[this.activePlayer] + " wins!";
// call the game over function
this.endGame();
}
// check if there is a draw
else if (this.checkDraw()) {
// set the game text to say it is a draw
this.turnIndicator.innerText = "It's a draw!";
// call the game over function
this.endGame();
}
// go to the next player's turn
else {
// change the turn (0 -> 1 or 1 -> 0)
this.activePlayer = 1 - this.activePlayer;
// set the turn indicator text
this.setTurnIndicator();
}
}
},
// check if current player won
checkWin: function() {
let ttt = this;
// if for any of the winning sets,
// every square in the set is filled with
// the current player's symbol, return true
// otherwise, return false
return this.winningSets.some(function (x) {
return x.every(function(i) {
return Array.from(ttt.squares[i].classList).indexOf(ttt.symbols[ttt.activePlayer]) > -1;
})
})
},
// check if there is a draw
checkDraw: function() {
// return true if every square
// has more than 1 class (is filled)
// otherwise, return false
return this.squares.every(function (x) {
return x.classList.length > 1;
})
},
// set the game over variable and board class when the game ends
endGame: function() {
this.gameOver = true;
this.board.classList.add("gameOver");
}
}
// call the init() function of TicTacToe when the page loads
TicTacToe.init();
https://codepen.io/sebastian-mihai-ciuc/pen/LYmoMrj
Related
I need to make a coin flip 20x and display the coin, and the results x times each. I am trying to use decrement to determine the coin flip. And then need to display the flip x number of times. I am running into an issue of how to write it using this. and decrement.
const coin = {
state: 0,
flip: function () {
this.state = Math.floor(Math.random() * 2) == 0 ? "tails" : "heads";
// 0 or 1: use "this.state" to access the "state" property on this object.
},
toString: function () {
if (this.state === 0) {
sides = "heads";
} else if (this.state === 1) {
sides = "tails";
}
return sides;
},
toHTML: function () {
const image = document.createElement("img");
let h1 = document.querySelector("h1");
h1.append(image);
if (this.state === 0) {
image.src = "images/tails.png";
} else if (this.state === 1) {
image.src = "image/heads.png";
}
return image;
},
};
function display20Flips() {
const results = [];
for (let i = 0; i < 20; i++) {
coin.flip();
h3.innerHTML += coin.state;
results.push(coin.state++);
}
You can also approach it functionally. This will help you focus on one problem at a time:
// Store the coin flip state as a boolean (true or false)
function randomBoolean () {
return Boolean(Math.floor(Math.random() * 2));
}
// Convert the boolean state to a "side" string
// heads is false, tails is true
function asCoinSide (bool) {
return bool ? 'tails' : 'heads';
}
function createCoinImage (bool) {
const side = asCoinSide(bool);
const image = document.createElement('img');
image.alt = side;
// StackOverflow doesn't have access to your local images,
// so this will show an error in the code snippet demo
// when the URL is loaded, but will work if the images exist:
image.src = `images/${side}.png`;
return image;
}
function displayCoinFlips (count = 20) {
const div = document.querySelector('div.coins');
const results = [];
for (let i = 0; i < count; i += 1) {
// Get a state
const state = randomBoolean();
results.push(state);
// Use the state to create the image
const image = createCoinImage(state);
// And append it to the container div
div.appendChild(image);
}
return results;
}
function displaySummary (states) {
const div = document.querySelector('div.summary');
let headsCount = 0;
let tailsCount = 0;
// Count the heads vs. tails results
// Remember: heads is false, tails is true
for (const state of states) {
if (state) tailsCount += 1;
else headsCount += 1;
}
div.textContent = `Heads: ${headsCount}, Tails: ${tailsCount}`;
}
const states = displayCoinFlips();
displaySummary(states);
<div class="coins"></div>
<div class="summary"></div>
You had some issues with your code. I fixed them. Still, the code needs to be a little redesigned to have a class Coin and then coin = new Coin().
const coin = {
state: 0,
flip: function() {
this.state = Math.floor(Math.random() * 2) == 0 ? "tails" : "heads";
},
toString: function() {
if (this.state === 0) {
sides = "heads";
} else if (this.state === 1) {
sides = "tails";
}
return sides;
},
toHTML: function() {
let h1 = document.querySelector(".container");
const div = document.createElement("div");
if (this.state === "tails") {
div.innerText = "images/tails.png";
} else {
div.innerText = "image/heads.png";
}
h1.append(div);
return div;
},
};
function displayFlips(n) {
const results = [];
for (let i = 0; i < n; i++) {
coin.flip();
coin.toHTML();
results.push(coin.state);
}
return results;
}
console.log(displayFlips(20));
<div class="container">
</div>
I am trying to create a 2 player online Tic Tac Toe game using Firebase. I am stuck at the point where I am unable to update player 2 screen with player 1's moves. I have tried to test this in two separate tabs and when i click on a square in the grid with eg. X it does not show on the second tab which is player two. I am attaching screenshots of my code of the function which writes to firebase, reads on change, and processes the read on change. The processreadonChange() function is where I am trying to update the second screen using an array. Please have a look and advise, as I have been trying to figure this out but have not been unable to. I have attached all the necessary functions snipets below. Thanks
function fb_readOnChange(_path, _key, _data, passFunc) {
console.log('fb_ReadOnChange: ' + _path + '/' + _key);
readStatus = 'waiting...';
var ref = database.ref(_path + '/' + _key);
ref.on('value', gotData, errData);
function gotData(snapshot) {
if (snapshot.val() != null) {
var dbData = snapshot.val();
passFunc('OK', snapshot.key, dbData, _data);
//display to screen
//if (userScores.highScore > hitsCntr) {
//document.getElementById("highscore_counter").innerHTML = //userScores.highScore;
//}
} else {
console.log("db_ReadOnChange: No rec for" + _path + '/' + _key);
passFunc("n/a");
}
}
function errData(err) {
console.log(err);
readStatus = 'error';
}
} //end of db_read()
function fb_processReadOnChange(_result, _key, _dbData, _data) {
console.log("fb_processReadOnChange: result = " + _result +
" key = " + _key + "\nmarker = " + marker +
" getId = " + PLAYER[playernum].getId +
" getValue = " + PLAYER[playernum].getValue);
console.table(_dbData);//DIAG
if (_result == 'n/a') {
} else {
console.log(_dbData);
if (marker == 1){ // marker 1 means some box has been clicked else undefined
document.getElementById(PLAYER[playernum].getId).value = PLAYER[playernum].getValue;
}
}
}
function readonCreate() {
playernum = 0;
symbol = 'X';
console.log("readonCreate userDetails.uid = " + userDetails.uid);
db_write(GAMEDATA, userDetails.uid, gameData);
//fb_readOnChange(GAMEDATA, userDetails.uid, gameData.active, fb_processReadOnChange);
fb_readOnChange(GAMEDATA, userDetails.uid, gameData.p2Move, fb_processReadOnChange);
}
function readonJoin() {
playernum = 1;
symbol = '0';
console.log("readonJoin userDetails.uid = " + userDetails.uid);
db_writeUpdate(GAMEDATA, userDetails.uid, gameData);
fb_readOnChange(GAMEDATA, userDetails.uid, gameData.p1Move, fb_processReadOnChange);
}
const PLAYER = [{
getValue: 'X',
getId: ''
},
{
getValue:'0',
getId: ''
}];
function ttt_onclick(_id) { // Functions checks turn of the player
// and put accordingly value X or 0
//Then writes player moves to firebase
var elem = document.getElementById('b'+_id);
PLAYER[playernum].getId = 'b'+_id;
//PLAYER[playernum+1].getId = 'b'+_id;
//getId = 'b'+_id;
console.log(elem)
//if (flag == 1) {
if (symbol == "X") {
elem.value = "X";
getValue = "X";
elem.disabled = true;
flag = 0;
marker = 1;
}
else {
elem.value = "0";
getValue = "0";
elem.disabled = true;
flag = 1;
marker = 1;
}
if (elem.textContext != "") {
if (elem.value=="X"){
gameData.p1Move = 'b'+_id;
console.log(gameData.p1Move);
} else {
gameData.p2Move = 'b'+_id;
console.log(gameData.p2Move);
}
db_writeUpdate(GAMEDATA, userDetails.uid, gameData);
//console.log(gameData);
}
}
I am trying to trigger a modal popup from within an IIFE game controller module in JavaScript. The modal popup is situated in its own module and is returning the required function.
I have only recently learned about modules and so it is definitely plausible that I am missing something obvious, but after hours of staring at my code and attempting to scour the web, I am struggling to find the solution.
Below is the game controller module:
// Game Controller
const gameController = (() => {
// Create players
let player1 = PlayerFactory("Player 1", "images/player.png");
let player2 = PlayerFactory("Player 2", "images/computer.png");
// Initialise game variables
let round = 0;
let maxRounds = 8;
let turn = 0;
let player1Score = 0;
let player2Score = 0;
// Main game function
const play = function (e) {
if (round == maxRounds) {
// Increment both players' scores
player1Score++;
player2Score++;
// Display modal pop-up for tie
}
switch (turn) {
case 0:
if (player1.play(e)) {
e.target.dataset.player = 0;
round++;
turn = 1;
if (checkWinner() == 0) {
// Increment player 1 score
player1Score++;
// Display modal popup for player 1 win
modal.openModal();
}
}
break;
case 1:
if (player2.play(e)) {
e.target.dataset.player = 1;
round++;
turn = 0;
if (checkWinner() == 0) {
// Increment player 2 score
player2Score++;
// Display modal popup for player 2 win
}
}
break;
}
}
// Check winner function
const checkWinner = function () {
// Initialise winner variable
let gameWinner = '';
// For loop checking for horizontal wins
for (i=0; i<9; i=i+3) {
if (gameBoard.boardArray[i].dataset.player) {
if ((gameBoard.boardArray[i].dataset.player == gameBoard.boardArray[i+1].dataset.player) && (gameBoard.boardArray[i+1].dataset.player == gameBoard.boardArray[i+2].dataset.player)) {
gameWinner = gameBoard.boardArray[i].dataset.player;
return gameWinner;
}
}
}
// For loop checking for vertical wins
for (i=0; i<3; i++) {
if (gameBoard.boardArray[i].dataset.player) {
if ((gameBoard.boardArray[i].dataset.player == gameBoard.boardArray[i+3].dataset.player) && (gameBoard.boardArray[i+3].dataset.player == gameBoard.boardArray[i+6].dataset.player)) {
gameWinner = gameBoard.boardArray[i].dataset.player;
return gameWinner;
}
}
}
// For loop checking for diagonal wins
if (gameBoard.boardArray[0].dataset.player) {
if ((gameBoard.boardArray[0].dataset.player == gameBoard.boardArray[4].dataset.player) && (gameBoard.boardArray[4].dataset.player == gameBoard.boardArray[8].dataset.player)) {
gameWinner = gameBoard.boardArray[0].dataset.player;
return gameWinner;
}
}
// For loop checking for diagonal wins
if (gameBoard.boardArray[2].dataset.player) {
if ((gameBoard.boardArray[2].dataset.player == gameBoard.boardArray[4].dataset.player) && (gameBoard.boardArray[4].dataset.player == gameBoard.boardArray[6].dataset.player)) {
gameWinner = gameBoard.boardArray[2].dataset.player;
return gameWinner;
}
}
}
// Click event listener to call play function
window.addEventListener('DOMContentLoaded', (event) => {
let cells = document.querySelectorAll(".game-cell").forEach(cell => {
cell.addEventListener("click", play);
})
});
return {
};
})();
And here is the modal popup module:
// Modal Popup
const modal = (() => {
const modalPopup = document.querySelector(".modal");
const openModal = function () {
modalPopup.style.display = "block";
}
return {
openModal
}
})
Currently, when I trigger the modal popup with the following line (in the game controller):
// Display modal popup for player 1 win
modal.openModal();
I receive this error in the console:
Uncaught TypeError: modal.openModal is not a function
If anybody could provide some assitance here then it would be highly appreciated.
Thank you!
This is beacuse modal is a function, call it instead with parentheses, like this
modal().openModal()
It is simple to check if is or not defined
if (modal.openModal)
alert("is modal");
else
alert("isnt modal");
This will alert "isnt modal" because modal is a funcion
if (modal().openModal)
alert("is modal");
else
alert("isnt modal");
This will alert "is modal", this is correct.
How to change the logic of the method "kick" in the class "Team". He chooses a random target among the team with heroes (if she is alive) and deals damage to her, so the battle between the two teams ("team1" and "team2" in the class "Game") happen . It is necessary that the goal of the same type be selected first and the "kick" was used to it: "archer" from "theam1" "kick" "archer" from "theam2" then back. And if "archer" dies, then select target by accident.
Pseudo code, what I mean:
var simpletypeUnit = this.members.type[i];
if(simpletypeUnit.type == target.type && this.isAlive) {
simpletypeUnit.kick(target)
}else {
//random target selection
}
//constructor for creating a unit
function Unit(maxHealth, basicDamage,type) {
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
this.basicDamage = basicDamage;
this.type = type;
}
/*method for showing the status of life, true if the "health" is greater
than 0 and false if equal to or lower */
Unit.prototype.isAlive = function () {
return this.currentHealth > 0;
};
/* a method that
shows the level of health*/
Unit.prototype.getFormattedHealth = function () {
return this.currentHealth + "/" + this.maxHealth + " HP";
};
/*a method that returns the base damage of the hero and damage to the
weapon (if it is set)*/
Unit.prototype.getDamage = function () {
return this.basicDamage;
};
/* The method of hitting
the hero for the chosen purpose*/
Unit.prototype.kick = function (target) {
if (this.isAlive()) {
target.currentHealth = Math.max(0,
target.currentHealth - this.getDamage());
console.log(this.type + " hit " + this.type);
}
console.log(this.type + " hit " + target.type);
return this;
};
/*method for showing all the characteristics of the hero and changes
with them*/
Unit.prototype.toString = function () {
return "Type - " + this.type + ", is alive - " +
this.isAlive() + ", " + this.getFormattedHealth() +
', hero current damage - ' + this.getDamage() + ' points';
};
/*the constructors of the main types of units which we will use*/
function Archer(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "archer";
}
function Swordsman(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "swordsman";
}
function Mage(maxHealth, basicDamage) {
Unit.apply(this, arguments);
this.type = "mage";
}
Archer.prototype = Object.create(Unit.prototype);
Swordsman.prototype = Object.create(Unit.prototype);
Mage.prototype = Object.create(Unit.prototype);
/*We create units of which we will then write to the teams.
Three units per team*/
var archer = new Archer(60, 5);
var swordsman = new Swordsman(100, 10);
var mage = new Mage(40, 15);
var troll = new Archer(70, 5);
var orc = new Swordsman(150, 10);
var druid = new Mage(50, 15);
/*class for creating teams*/
function Team(name) {
this.name = name;
this.members = [];
}
/*method for adding a new unit with an arbitrary number of units*/
Team.prototype.addMember = function (...members) {
this.members.push(...members);
};
/*method of life of the team, if all participants have
"currentHealth" <0 then this method = "false"*/
Team.prototype.isAlive = function () {
return this.members.some(n => n.isAlive());
};
/*The method of random choice of the target, if the hero is alive,
then the target is randomly chosen and damage is done using
the "kick" method*/
Team.prototype.selectRandomTarget = function (targetTeam) {
var numberOfMembers = targetTeam.members.length;
var target = null;
while(target == null || !target.isAlive())
{
var randomIndex = Math.floor(Math.random() * numberOfMembers);
target = targetTeam.members[randomIndex];
}
return target;
};
/*method of damage, we go through the array of "members" and if the target
is alive, then we accidentally deal damage using the method "selectRandomTarget"*/
Team.prototype.kick = function(targetTeam) {
console.log(`\nTeam ${this.name} is attacking`);
for(var i=0; i < this.members.length; i++) {
var singleMember = this.members[i];
if(!this.isAlive()) break;
if(!singleMember.isAlive()) continue;
var target = this.selectRandomTarget(targetTeam);
singleMember.kick(target);
}
};
/*method to output information about the team*/
Team.prototype.toString = function () {
var res = "Name of team - " + this.name + '\n'
+ "life of a team : " + this.isAlive() + '\n'
+"members :\n";
for (var i=0; i<this.members.length; i++)
res += this.members[i]+"\n";
return res;
};
/*create team 1 and add units to it*/
var team1 = new Team('Alliance');
team1.addMember(archer,swordsman,mage);
/*create team 2 and add units to it*/
var team2 = new Team('Orcs');
team2.addMember(troll,orc,druid);
/*class that organizes a battle between two teams until
"currentHealth" of all units in the team will not be zero*/
function Game(team1, team2) {
this.team1 = team1;
this.team2 = team2;
}
/*the method in which the battle occurs until the
"isAlive" property of all participants of one of the commands
is equal to "false"*/
Game.prototype.battle = function() {
if (!this.team1.isAlive() || !this.team2.isAlive()) {
if (this.team1.isAlive()) {
alert("Team 1 is win");
}
if (this.team2.isAlive()) {
alert("Team 2 is win");
}
console.log(`THE BATTLE IS END :
${this.team1.toString()}
${this.team2.toString()}
${this.team1.name} - ${this.team1.members.length} -
${this.team1.members.map(n => n.currentHealth)}
${this.team2.name} - ${this.team2.members.length} -
${this.team2.members.map(n => n.currentHealth)}
`);
return;
}
team1.kick(team2);
team2.kick(team1);
requestAnimationFrame(this.battle.bind(this));
};
var game = new Game(team1, team2);
game.battle();
You can add these two little adjustments to your code. If I understand the question, this should do what you need.
Unit.prototype.SelectSameType = function(targetTeam)
{ //Iterate through all the players and look for at least one of the same type that's alive
for(let i = 0; i < targetTeam.members.length; i++)
{
let target = targetTeam.members[i];
if(target.type === this.type && target.isAlive()) return target;
}
return null;
}
Team.prototype.kick = function(targetTeam) {
console.log(`\nTeam ${this.name} is attacking`);
for(var i=0; i < this.members.length; i++) {
var singleMember = this.members[i];
if(!this.isAlive() || !targetTeam.isAlive()) break;
if(!singleMember.isAlive()) continue;
//Check for the same type first
var target = singleMember.SelectSameType(targetTeam)
if(target === null) target = this.selectRandomTarget(targetTeam);
singleMember.kick(target);
}
};
I'm working on a simon game and is doing a sequence of 3 at level 2 instead of doing just 2 at level 2. I've looked all over. and I've trying output to console, but I guess I've been staring at this for too long. If someone can find the bug, please share. thanks for the help.
here's the pen
https://codepen.io/zentech/pen/XaYygR
//variables
userSeq = [];
simonSeq = [];
const NUM_OF_LEVELS = 5;
var id, color, level = 0;
var strict = false;
var error = false;
var boardSound = [
"http://www.soundjay.com/button/sounds/button-4.mp3", //green
"http://www.soundjay.com/button/sounds/button-09.mp3", //red
"http://www.soundjay.com/button/sounds/button-10.mp3", //yellow
"http://www.soundjay.com/button/sounds/button-7.mp3" //blue
];
//1- start board sequence
$(document).ready(function() {
$(".start").click(function() {
strict = false;
error = false;
level++;
simonSeq = userSeq = [];
simonSequence();
})
//user pad listener
$(".pad").click(function() {
id = $(this).attr("id");
color = $(this).attr("class").split(" ")[1];
userSequence();
});
//strict mode listener
$(".strict").click(function() {
level = 0;
level++;
simonSeq = userSeq = [];
strict = true;
simonSequence();
})
})
//user sequence
function userSequence() {
userSeq.push(id);
console.log(id+" "+color);
addClassSound(id, color);
//check user sequence
if(!checkUserSeq()) {
//if playing strict mode reset everything lol
if(strict) {
console.log("strict");
simonSeq = [];
level = 1;
}
displayError();
userSeq = [];
error = true;
console.log("start simon error")
simonSequence();
}
//checking end of sequence
else if(userSeq.length == simonSeq.length && userSeq.length < NUM_OF_LEVELS) {
level++;
userSeq = [];
error = false;
console.log("start simon")
simonSequence();
}
//checking for winners
if(userSeq.length == NUM_OF_LEVELS) {
displayWinner();
resetGame();
}
}
/* simon sequence */
function simonSequence() {
console.log("level "+level);
$(".display").text(level);
if(!error) {
getRandomNum();
}
var i = 0;
var myInterval = setInterval(function() {
id = simonSeq[i];
color = $("#"+id).attr("class");
color = color.split(" ")[1];
console.log(id+" "+color);
addClassSound(id, color);
i++;
if(i == simonSeq.length) {
clearInterval(myInterval);
}
}, 1000);
}
//generate random number
function getRandomNum() {
var random = Math.floor(Math.random() * 4);
simonSeq.push(random);
}
/* add temporary class and sound */
function addClassSound(id, color) {
$("#"+id).addClass(color+"-active");
playSound(id)
setTimeout(function(){
$("#"+id).removeClass(color+"-active");
}, 500);
}
/* checking user seq against simon's */
function checkUserSeq() {
for(var i = 0; i < userSeq.length; i++) {
if(userSeq[i] != simonSeq[i]) {
return false;
}
}
return true;
}
/* display error */
function displayError() {
console.log("error");
var counter = 0;
var myError = setInterval(function() {
$(".display").text("Err");
counter++;
if(counter == 3) {
$(".display").text(level);
clearInterval(myError);
userSeq = [];
counter = 0;
}
}, 500);
}
//display winner
function displayWinner() {
var count = 0;
var winInterval = setInterval(function() {
count++;
$(".display").text("Win");
if(count == 5) {
clearInterval(winInterval);
$(".display").text("00");
count = 0;
}
}, 500);
}
/* play board sound */
function playSound(id) {
var sound = new Audio(boardSound[id]);
sound.play();
}
/* reset game */
function resetGame() {
userSeq = [];
simonSeq = [];
level = 0;
strict = false;
$(".display").text("00");
}
PROBLEM
You have a reference vs copy problem in your initialization code.
$(document).ready(function() {
$(".start").click(function() {
strict = false;
error = false;
level++;
simonSeq = userSeq = []; //PROBLEM !!!!
simonSequence();
})
Arrays are passed by reference, not value.
simonSeq = userSeq = [];
/* Any changes to 'userSeq' will affect 'simonSeq'.
'simonSeq' is referencing 'userSeq' */
SOLUTION
Change all instances of
simonSeq = userSeq = [];
To
simonSeq = [];
userSeq = [];
EXPLINATION
Values in JavaScript can be referred to in 2 ways; by reference and by value.
When you refer to something by value, you are copying it.
var numA = 5;
var numB = numA; //COPY numA over to numB
numA = 12; // Changes to numA will not affect numB because it was copied
console.log(numA); // 12
console.log(numB); // 5
When you refer to something by reference, your are referring/referencing it, not copying it. Any changes made to the original will affect everything that is referencing it.
var original = [1,2,3];
var ref = original; //Any changes made to 'original' will affect 'ref'
original.push('APPLES');
console.log(original); // [1,2,3,'APPLES']
console.log(ref); // [1,2,3,'APPLES']
In the above code ref does not actually contain any values. ref contains the memory location of original.
ref is referencing original.
Arrays and Objects are always passed/refereed to by reference.
Everything else is passed/refereed to by value (they are copied).