I am writing a memory card game. Each time when I refresh the page, the cards are supposed to place in a random position but it turns out that they remain in the same position.
here is the code :
var cardsArray = [{
'name': 'ball',
'img': '../img/ball.png',
},
{
'name': 'building',
'img': '../img/building.png',
},
{
'name': 'fan',
'img': '../img/fan.png',
},
{
'name': 'fish',
'img': '../img/fish.png',
},
{
'name': 'fishball',
'img': '../img/fishball.png',
},
{
'name': 'flower',
'img': '../img/flower.png',
},
{
'name': 'hill',
'img': '../img/hill.png',
},
{
'name': 'orange',
'img': '../img/orange.png',
},
{
'name': 'boo',
'img': '../img/boo.png',
},
{
'name': 'shoe',
'img': '../img/shoe.png',
},
];
var firstGuess = '';
var secondGuess = '';
var count = 0;
var previousTarget = null;
var delay = 1200;
var moves;
var matched;
var score;
var game = document.getElementById('game');
var grid = document.createElement('section');
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
0.5 - Math.random()
});
function startGame() {
grid.setAttribute('class', 'grid');
game.appendChild(grid);
moves = 0;
score = 0;
matched = 0;
document.getElementById("moves").innerHTML = moves;
document.getElementById("score").innerHTML = score;
gameGrid.forEach(function(item) {
const {
name,
img
} = item;
const card = document.createElement('div');
card.classList.add('card');
card.dataset.name = name;
const front = document.createElement('div');
front.classList.add('front');
const back = document.createElement('div');
back.classList.add('back');
back.style.backgroundImage = `url(${img})`;
grid.appendChild(card);
card.appendChild(front);
card.appendChild(back);
});
}
Sorry, I know it might be a bit long, but I guess the problem might be here:
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
0.5 - Math.random()
});
Did I do something wrong here? How can i fix it?
You're not actually returning the random value to sort on.
const gameGrid = cardsArray
.concat(cardsArray)
.sort(function() {
return 0.5 - Math.random()
});
Related
I'm trying to do this:
var array = [];
array[1] = {
'name': 'Raul'
};
array[5] = {
'name': 'Ilidio'
};
array[20] = {
'name': 'Ferreira'
};
array[1001] = {
'name': 'Reis'
};
console.log(array);
When I run console.log() this appears:
I want only the keys that I defined to appear. Am I doing something wrong to give me all the keys up to 1001?
That is what an array is - it sounds like you want an object:
var obj = {};
obj[1] = {
'name': 'Raul'
};
obj[5] = {
'name': 'Ilidio'
};
obj[20] = {
'name': 'Ferreira'
};
obj[1001] = {
'name': 'Reis'
};
console.log(obj);
I am trying to create a roll dice button for my code but I'm not quite sure how I can do this, since if I do create one then either it does not work how I want it too or my button does not function right.
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" title="Default Styles"/>
<script>
var r_text = new Array ();
r_text[0] = "All leave are brown";
r_text[1] = "fafwfaf";
r_text[2] = "fakfjwkfkajwkfawjf";
r_text[3] = "cornflakes";
r_text[4] = "bannana";
r_text[5] = "Choclate";
r_text[6] = "lol";
var i = Math.floor(7*Math.random())
var videos = [
{
id: 1,
url: "https://www.youtube.com/embed/ngUMyF9D9SQ?autoplay=1",
text: r_text[i]
},
{
id: 2,
url: "https://www.youtube.com/embed/v=r-l_gVPVylM?autoplay=1",
text: r_text[i]
},
{
id: 3,
url: "https://www.youtube.com/embed/6ukTzRjXcR0?autoplay=1",
text: r_text[i]
},
{
id: 4,
url: "https://www.youtube.com/embed/n5BXMNCTu8I?autoplay=1",
text: r_text[i]
},
{
id: 5,
url: "https://www.youtube.com/embed/JtwVmnMNaEY?autoplay=1",
text: r_text[i]
},
{
id: 6,
url: "https://www.youtube.com/embed/lAMgRaHP8Q4?autoplay=1",
text: r_text[i]
}
];
window.onload = function() {
var playerDiv = document.getElementById("random_player");
var player = document.createElement("IFRAME");
var previousId = localStorage.getItem("previousId");
if (previousId) {
var previousIndex = videos.findIndex(v => v.id === parseInt(previousId));
videos.splice(previousIndex, 1);
}
var current = Math.floor(Math.random() * videos.length);
localStorage.setItem("previousId", videos[current].id);
localStorage.getItem("previousId");
var randomVideoUrl = videos[current].url;
player.setAttribute("width", "640");
player.setAttribute("height", "390");
player.setAttribute("src", randomVideoUrl);
playerDiv.appendChild(player);
var textContainer = document.getElementById("r_text");
setTimeout(() => {
textContainer.innerHTML = videos[current].text;
}, 3000)
};
</script>
</head>
<div id="random_player">
<div id="r_text">
</div>
</div>
</html>
I am expecting it to have nothing at first apart from the button and once the button is clicked then the video starts playing and then everything else starts to happen.
Try this https://codepen.io/dsb/pen/XWrQbxR
Explanation:
1) Add button to HTML
<button id="btn-roll">Roll</button>
2) Modify JS code
var r_text = [];
r_text[0] = "All leave are brown";
r_text[1] = "fafwfaf";
r_text[2] = "fakfjwkfkajwkfawjf";
r_text[3] = "cornflakes";
r_text[4] = "bannana";
r_text[5] = "Choclate";
r_text[6] = "lol";
var i = Math.floor(6 * Math.random())
var videos = [{
id: 1,
url: "https://www.youtube.com/embed/ngUMyF9D9SQ?autoplay=1",
text: r_text[1]
},
{
id: 2,
url: "https://www.youtube.com/embed/v=r-l_gVPVylM?autoplay=1",
text: r_text[2]
},
{
id: 3,
url: "https://www.youtube.com/embed/6ukTzRjXcR0?autoplay=1",
text: r_text[3]
},
{
id: 4,
url: "https://www.youtube.com/embed/n5BXMNCTu8I?autoplay=1",
text: r_text[4]
},
{
id: 5,
url: "https://www.youtube.com/embed/JtwVmnMNaEY?autoplay=1",
text: r_text[5]
},
{
id: 6,
url: "https://www.youtube.com/embed/lAMgRaHP8Q4?autoplay=1",
text: r_text[6]
}
];
window.onload = function() {
function rollVideo(numberRand) {
let playerDiv = document.getElementById("random_player");
if (document.querySelector("iframe") !== null) {
document.querySelector("iframe").remove();
}
let player = document.createElement("IFRAME");
let randomVideoUrl = videos[numberRand].url;
player.setAttribute("width", "640");
player.setAttribute("height", "390");
player.setAttribute("src", randomVideoUrl);
playerDiv.appendChild(player);
document.getElementById("r_text").innerHTML = "";
document.getElementById("r_text").innerHTML = videos[numberRand].text;
}
startRoll(i);
document.getElementById("btn-roll").addEventListener("click", startRoll);
function startRoll() {
let currentNumber = Math.floor(Math.random() * videos.length);
rollVideo(currentNumber);
}
};
There is no conditions about text variables and id of previous video so i minified the example.
As you can see i have added your code but nothing happens.
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" title="Default Styles"/>
<script>
var r_text = new Array ();
r_text[0] = "All leave are brown";
r_text[1] = "fafwfaf";
r_text[2] = "fakfjwkfkajwkfawjf";
r_text[3] = "cornflakes";
r_text[4] = "bannana";
r_text[5] = "Choclate";
r_text[6] = "lol";
var i = Math.floor(7*Math.random())
var videos = [
{
id: 1,
url: "https://www.youtube.com/embed/ngUMyF9D9SQ?autoplay=1",
text: r_text[i]
},
{
id: 2,
url: "https://www.youtube.com/embed/v=r-l_gVPVylM?autoplay=1",
text: r_text[i]
},
{
id: 3,
url: "https://www.youtube.com/embed/6ukTzRjXcR0?autoplay=1",
text: r_text[i]
},
{
id: 4,
url: "https://www.youtube.com/embed/n5BXMNCTu8I?autoplay=1",
text: r_text[i]
},
{
id: 5,
url: "https://www.youtube.com/embed/JtwVmnMNaEY?autoplay=1",
text: r_text[i]
},
{
id: 6,
url: "https://www.youtube.com/embed/lAMgRaHP8Q4?autoplay=1",
text: r_text[i]
}
];
window.onload = function() {
function rollVideo(numberRand) {
var playerDiv = document.getElementById("random_player");
var player = document.createElement("IFRAME");
var previousId = localStorage.getItem("previousId");
if (previousId) {
var previousIndex = videos.findIndex(v => v.id === parseInt(previousId));
videos.splice(previousIndex, 1);
}}
var current = Math.floor(Math.random() * videos.length);
localStorage.setItem("previousId", videos[current].id);
localStorage.getItem("previousId");
var randomVideoUrl = videos[current].url;
player.setAttribute("width", "640");
player.setAttribute("height", "390");
player.setAttribute("src", randomVideoUrl);
playerDiv.appendChild(player);
var textContainer = document.getElementById("r_text");
setTimeout(() => {
textContainer.innerHTML = videos[current].text;
}, 3000)
};
document.getElementById("btn-roll").addEventListener("click", startRoll);
function startRoll() {
let currentNumber = Math.floor(Math.random() * videos.length);
rollVideo(currentNumber);
}
</script>
</head>
<div id="random_player">
<div id="r_text">
</div>
</div>
<button id="btn-roll">Roll</button>
</html>
I found this matching game on codepen.io that I am using in corporation with a trivia spinner - thanks #Malky.kid - The idea is once they get to the matching game they have 10 clicks to match as many as they can but the cards MUST stay flipped over.
This is for a project and the odds of winning has to do with chance not skill.
(function(){
var Memory = {
init: function(cards){
this.$game = $(".game");
this.$modal = $(".modal");
this.$overlay = $(".modal-overlay");
this.$restartButton = $("button.restart");
this.cardsArray = $.merge(cards, cards);
this.shuffleCards(this.cardsArray);
this.setup();
},
shuffleCards: function(cardsArray){
this.$cards = $(this.shuffle(this.cardsArray));
},
setup: function(){
this.html = this.buildHTML();
this.$game.html(this.html);
this.$memoryCards = $(".card");
this.binding();
this.paused = false;
this.guess = null;
},
binding: function(){
this.$memoryCards.on("click", this.cardClicked);
this.$restartButton.on("click", $.proxy(this.reset, this));
},
// kinda messy but hey
cardClicked: function(){
var _ = Memory;
var $card = $(this);
if(!_.paused && !$card.find(".inside").hasClass("matched") && !$card.find(".inside").hasClass("picked")){
$card.find(".inside").addClass("picked");
if(!_.guess){
_.guess = $(this).attr("data-id");
} else if(_.guess == $(this).attr("data-id") && !$(this).hasClass("picked")){
$(".picked").addClass("matched");
_.guess = null;
} else {
_.guess = null;
_.paused = true;
setTimeout(function(){
$(".picked").removeClass("picked");
Memory.paused = false;
}, 600);
}
if($(".matched").length == $(".card").length){
_.win();
}
}
},
win: function(){
this.paused = true;
setTimeout(function(){
Memory.showModal();
Memory.$game.fadeOut();
}, 1000);
},
showModal: function(){
this.$overlay.show();
this.$modal.fadeIn("slow");
},
hideModal: function(){
this.$overlay.hide();
this.$modal.hide();
},
reset: function(){
this.hideModal();
this.shuffleCards(this.cardsArray);
this.setup();
this.$game.show("slow");
},
// Fisher--Yates Algorithm -- https://bost.ocks.org/mike/shuffle/
shuffle: function(array){
var counter = array.length, temp, index;
// While there are elements in the array
while (counter > 0) {
// Pick a random index
index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
},
buildHTML: function(){
var frag = '';
this.$cards.each(function(k, v){
frag += '<div class="card" data-id="'+ v.id +'"><div class="inside">\
<div class="front"><img src="'+ v.img +'"\
alt="'+ v.name +'" /></div>\
<div class="back"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/codepen-logo.png"\
alt="Codepen" /></div></div>\
</div>';
});
return frag;
}
};
var cards = [
{
name: "php",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/php-logo_1.png",
id: 1,
},
{
name: "css3",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/css3-logo.png",
id: 2
},
{
name: "html5",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/html5-logo.png",
id: 3
},
{
name: "jquery",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/jquery-logo.png",
id: 4
},
{
name: "javascript",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/js-logo.png",
id: 5
},
{
name: "node",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/nodejs-logo.png",
id: 6
},
{
name: "photoshop",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/photoshop-logo.png",
id: 7
},
{
name: "python",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/python-logo.png",
id: 8
},
{
name: "rails",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/rails-logo.png",
id: 9
},
{
name: "sass",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sass-logo.png",
id: 10
},
{
name: "sublime",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/sublime-logo.png",
id: 11
},
{
name: "wordpress",
img: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/74196/wordpress-logo.png",
id: 12
},
];
Memory.init(cards);
})();
see game here
The only difference to this is that the cards stay flipped over - if they match cards they should still show that they are matched - it highlights green for a second. The cards flip back over after you select two cards ONLY if they do not match. If they do match they stay facing up but I need it always facing up. Thanks
Am having a problem to return match array between two array element, please any help is important
here is my code
$scope.MacA = [
{
name: '24:fd:52:c3:d8:35',
sector: 'A23'
},
{
name: '56:db:30:4b:57:45',
sector: 'It support'
},
{
name: 'b6:b6:76:6b:e9:00',
sector: 'A24'
},
{
name: 'e8:74:e6:a1:14:16',
sector: 'Vodafone Guest'
},
{
name: 'dc:4a:3e:b7:32:0e',
sector: 'Direct HP officejet'
}
,
{
name: '7c:4c:a5:32:13:29',
sector: 'skyb7'
}
]
and array 2 is
scope.match = ['dc:4a:3e:b7:32:0e','7c:4c:a5:32:13:29' ];
and here is the function that returns the match if found
$scope.getList = function(){
// $scope.wifiList = WifiService.list();
var c = $scope.MacA;
var m = WifiService.list();
for(var i = 0;i < c.length;i++) {
for(var j = i;j < m.length;j++) { // Notice the j = i;
if (c[i].name === m[j]) {
$scope.result = c[i].sector;
// $scope.result = 'Its working';
break;
} else {
$scope.result = "Sorry!";
}
};
};
return $scope.result;
}
You didn't specify what exactly you want as the result, but here is a possible version that looks for matches.
var result = [];
match.forEach(m => result.push(MacA.find(macA => macA.name === m)));
MacA = [
{
name: '24:fd:52:c3:d8:35',
sector: 'A23'
},
{
name: '56:db:30:4b:57:45',
sector: 'It support'
},
{
name: 'b6:b6:76:6b:e9:00',
sector: 'A24'
},
{
name: 'e8:74:e6:a1:14:16',
sector: 'Vodafone Guest'
},
{
name: 'dc:4a:3e:b7:32:0e',
sector: 'Direct HP officejet'
},
{
name: '7c:4c:a5:32:13:29',
sector: 'skyb7'
}
]
Match = ['dc:4a:3e:b7:32:0e','7c:4c:a5:32:13:29' ];
MacA.filter(({name}) => Match.includes(name)).map(({sector}) => sector)
// RETURNS // ["Direct HP officejet", "skyb7"]
SO, given your code above, something like this:
$scope.getList = function(){
return $scope.result = $scope.MacA.filter(({name}) => $scope.match.includes(name)).map(({sector}) => sector)
}
I've refactored some of your code.
$scope.getList = function(){
var devices = $scope.MacA;
var macList = WifiService.list();
var results = devices.reduce((acc, device) => acc.concat(macList.find(current.name)? [current.sector]:[]), []);
return results.length? $scope.results = results : $scope.results = 'Sorry!';
}
Here is my code
var dataGroupByParentCategory = function(data){
return _.groupBy(data, function(entry){
return entry.category.parent;
});
};
var parentCategorySum = function(data) {
var result = {};
_.forEach(_.keys(this.dataGroupByParentCategory(data)), function(parentCategory){
var that = this;
console.log(parentCategory);
var s = _.reduce(that.dataGroupByParentCategory[parentCategory], function(s, entry){
console.log('>' + entry); // Can not see entry here
return s + parseFloat(entry.amount);
}, 0);
result[parentCategory] = s;
});
return result;
};
and data looks like
'data': [
{
'category': {
'uri': '/categories/0b092e7c-4d2c-4eba-8c4e-80937c9e483d',
'parent': 'Food',
'name': 'Costco'
},
'amount': '15.0',
'debit': true
},
{
'category': {
'uri': '/categories/d6c10cd2-e285-4829-ad8d-c1dc1fdeea2e',
'parent': 'Food',
'name': 'India Bazaar'
},
'amount': '10.0',
'debit': true
},
{
'category': {
'uri': '/categories/d6c10cd2-e285-4829-ad8d-c1dc1fdeea2e',
'parent': 'Food',
'name': 'Sprouts'
},
'amount': '11.1',
'debit': true
}, ...
Problem?
I can not see value of entry as seen in code above
console.log('>' + entry); // Can not see entry here
I am learning JavaScript and not very well versed with concept of scopes, is that is causing issue here?
It seems your dataGroupByParentCategory function is global, so you don't need use this or that to access it. Also it seems you make a typo in dataGroupByParentCategory[parentCategory]. It must be dataGroupByParentCategory(parentCategory)
After spending sometime with code, I realized I was doing it incorrectly, the actual code now is
var parentCategorySum = function(data) {
var result = {};
var dataGroupByParent = dataGroupByParentCategory(data);
_.forEach(_.keys(dataGroupByParent), function(parentCategory){
var s = _.reduce(dataGroupByParent[parentCategory], function(s, entry){
return s + parseFloat(entry.amount);
}, 0);
result[parentCategory] = s;
});
return result;
};