I need to create a lottery game. I have an idea of how the whole code should be and it's mostly done, but I have a problem:
I have a button with an onclick called generar(), and this function, needs to draw 3 numbers from 1 to 999 and create along with the three numbers, another button which after pressing it, draws another number and then (the new button) checks the new number number with the ones who are already created to see if I won, or not.
Okay, I've managed to do the whole code, but the comparison of the three first numbers with the fourth number, doesn't work correctly. Always, the comprobation which says if I won or not, writes "¡Perdedor!" (looser!).
This is my code:
<html>
<head>
<title>Práctica 3</title>
<style>
#contenedor { border: 1px black solid;
width: 250px;
height: 250px;
float: left;
margin-right: 5px;
text-align: center;
margin-bottom: 5px; }
</style>
</head>
<body>
<div id="contenedor"> <p id="primerNumero"/> </div>
<div id="contenedor"> <p id="segundoNumero"/> </div>
<div id="contenedor"> <p id="tercerNumero"/> </div>
<button id="generar" onclick="generar()">Genera dècims</button>
<div id="contenedor"> <p id="resultado"/> </div>
<p id="t"/>
<script>
function generar() {
var primerNumero = Math.floor(Math.random() * 10);
var segundoNumero = Math.floor(Math.random() * 10);
var tercerNumero = Math.floor(Math.random() * 10);
var botones = document.getElementsByTagName("BUTTON").length;
if (botones < 2) {
generarBotones();
}
document.getElementById("primerNumero").innerHTML = primerNumero;
document.getElementById("primerNumero").style.fontSize = "72px";
document.getElementById("segundoNumero").innerHTML = segundoNumero;
document.getElementById("segundoNumero").style.fontSize = "72px";
document.getElementById("tercerNumero").innerHTML = tercerNumero;
document.getElementById("tercerNumero").style.fontSize = "72px";
}
function generarBotones() {
var boton = document.createElement("BUTTON");
var t = document.createTextNode("Realizar sorteig");
boton.onclick = function(){
var numeroGanador = Math.floor(Math.random() * 10);
document.getElementById("resultado").innerHTML = numeroGanador;
document.getElementById("resultado").style.fontSize = "72px";
if(primerNumero == numeroGanador || segundoNumero == numeroGanador || tercerNumero == numeroGanador) {
document.getElementById("t").innerHTML = "¡Ganador!";
} else {
document.getElementById("t").innerHTML = "¡Perdedor!";
}
};
boton.appendChild(t);
document.body.appendChild(boton);
}
</script>
</body>
</html>
If somebody can tell me why and where I fail and a possible solution, it will be great. I will very grateful if an explanation is given too
primerNumero
segundoNumero
tercerNumero
Are html elements, not value, to get the value is necessary to use innerText OR innerHTML.
if(primerNumero.innerText == numeroGanador || segundoNumero.innerText == numeroGanador || tercerNumero.innerText == numeroGanador) {
document.getElementById("t").innerHTML = "¡Ganador!";
} else {
document.getElementById("t").innerHTML = "¡Perdedor!";
}
Or you can rename the variables to a different name of the element, because your problem is that the variables that contain the generated numbers are the same name as the id of the html element. If rename will work according to your first code.
Related
How do I make reference to the specific dashes I created, and add a
specific letter to them. Read the comments and code to get a better
context. Thanks for any help in advance!!
<!Doctype html>
<html lang="en">
<head>
<style>
ul {
display: inline;
list-style-type: none;
}
.boxes {
font-size:1.6em;
text-align:center;
width: 10px;
border-bottom: 3px solid black;
margin: 5px;
padding: 10px;
display: inline;
}
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
</style>
</head>
<body>
<script>
var possibleWord = ["COW", "BETTER", "HARDER", "JUSTIFY", "CONDEMN",
"CONTROL", "HELLO", "UNDERSTAND", "LIFE", "INSIGHT","DATE",
"RIGHTEOUSNESS"];
var hangmanWord = possibleWord[Math.floor(Math.random() *
possibleWord.length)];
var underlineHelp;
var space;
var guess;
var guesses = [];
var placement;
var underscores = [];
var character = [];
var textNodes = [];
window.onload = function () {
placement = document.getElementById('hold');
underlineHelp = document.createElement('ul');
placement.appendChild(underlineHelp);
for (i = 0; i < hangmanWord.length; i++) {
underscores = document.createElement('li');
underscores.setAttribute('class', 'boxes');
guesses.push(underscores);
underlineHelp.appendChild(underscores);
character = document.createElement('span');
character.appendChild(document.createTextNode(hangmanWord[i]));
character.classList.add('hidden');
underscores.appendChild(character);
}
This is the area I want to refer to later.
for(x=1;x<=26;x++){
document.getElementById("test").innerHTML = hangmanWord;
var btn = document.createElement("BUTTON");
var myP = document.createElement("br");
var letter = String.fromCharCode(x+64);
var t = document.createTextNode(letter);
btn.appendChild(t);
btn.id = letter;
Just creating buttons. This is important when I say 'this.id' down below.
btn.addEventListener("click", checkLetter);
document.body.appendChild(btn);
//add a line break 'myP' after 3 buttons
if (x%10==0) {
document.body.appendChild(myP);
}
}
}
function checkLetter(){
//this refers to the object that called this function
document.getElementById("p1").innerHTML += this.id;
for (i = 0; i < hangmanWord.length; i++) {
guess = hangmanWord[i];
if (this.id == guess) {
character[i] = hangmanWord[i];
character.appendChild(document.createTextNode(hangmanWord[i]));
character.classList.add('visible');
}
}
}
Here is where I am in trouble. If I do this (the code I wrote after the if statement) the letters will be added on the end of the string. I Want to have it on the specific dashes that I created earlier. How can I manage to do that? Do I have to do something called "object passing." I am relatively new to js (high school student) and I am keen on any insight! Once again thanks for the help in advance!
</script>
</head>
<body>
<p>Click the button to make a BUTTON element with text.</p>
<div id = "contents">
<div id = "hold"></div>
</div>
<p id ="p1"> Letters picked: </p>
<div id= "picBox"></div>
<div id = "test"></div>
</div>
</body>
You could store the guessing word and the guessed characters in an object and just output the replaced result of such instead. Seems easier to me.
<html>
<head>
<script>
//The hangman object
var Hangman = {
wordToGuess: 'RIGHTEOUSNESS', //The word to guess. Just one for my example
guessedLetters: [] //The guessed characters
};
window.onload = function(){
//Creating the buttons
for(var tF=document.createDocumentFragment(), x=1; x<=26; x++){
var tLetter = String.fromCharCode(x+64),
tButton = tF.appendChild(document.createElement("button"));
tButton.id = tLetter;
tButton.addEventListener("click", checkLetter);
tButton.appendChild(document.createTextNode(tLetter));
(x%10 === 0) && tF.appendChild(document.createElement('br'))
};
document.body.appendChild(tF);
startTheGame()
};
//Starts a game of hangman
function startTheGame(){
var tWord = Hangman.wordToGuess,
tPlacement = document.getElementById('hold');
document.getElementById('test').innerHTML = tWord;
//Resetting the guesses
Hangman.guessedLetters = [];
//Creating dashes for all letters in our word
for(var i=0, j=tWord.length; i<j; i++){
tPlacement.appendChild(document.createTextNode('_'))
}
}
function checkLetter(){
var tButton = this,
tLetter = tButton.id,
tWord = Hangman.wordToGuess,
tPlacement = document.getElementById('hold');
//Make a guess
document.getElementById('p1').innerHTML += tLetter;
(Hangman.guessedLetters.indexOf(tLetter) === -1) && Hangman.guessedLetters.push(tLetter.toLowerCase());
//Clear the current word
while(tPlacement.firstChild) tPlacement.removeChild(tPlacement.firstChild);
//Now we reverse replace the hangman word by the guessed characters
for(var i=0, j=tWord.length; i<j; i++){
tPlacement.appendChild(document.createTextNode(
(Hangman.guessedLetters.indexOf(tWord[i].toLowerCase()) === -1) ? '_' : tWord[i]
))
}
}
</script>
</head>
<body>
<p>Click the button to make a BUTTON element with text.</p>
<div id = 'contents'>
<div id = 'hold'></div>
</div>
<p id = 'p1'> Letters picked: </p>
<div id= "picBox"></div>
<div id = "test"></div>
<!-- This one seems to be too much
</div>
-->
</body>
</html>
https://jsfiddle.net/zk0uhetz/
Update
Made a version with propert object handling, separating the actual hangman logic from the interface.
<html>
<head>
<style>
button{
margin: 1px;
min-width: 30px
}
button[disabled]{
background: #777;
color: #fff
}
</style>
<script>
//Handles the hangman game itself
;(function(ns){
'use strict';
var _listOfWord = ['COW', 'BETTER', 'HARDER', 'JUSTIFY', 'CONDEMN', 'CONTROL', 'HELLO', 'UNDERSTAND', 'LIFE', 'INSIGHT','DATE', 'RIGHTEOUSNESS'],
_wordToGuess = null, //The word to guess. Just one for my example
_guessedLetters = [] //The guessed characters
ns.Hangman = {
//Returns the current obstructed word
getCurrentObstructedWord: function(){
var tWord = []; //The current state of the game
if(_wordToGuess){
//Now we reverse replace the hangman word by the guessed characters
for(var i=0, j=_wordToGuess.length; i<j; i++){
tWord.push(
(_guessedLetters.indexOf(_wordToGuess[i].toLowerCase()) === -1) ? '_' : _wordToGuess[i]
)
}
};
return tWord
},
//Make a guess at the current game
Guess: function(letter){
//Add the guess to the list of guesses, unless already guessed
(_guessedLetters.indexOf(letter) === -1) && _guessedLetters.push(letter.toLowerCase());
return this.getCurrentObstructedWord()
},
isComplete: function(){
return !!(this.getCurrentObstructedWord().indexOf('_') === -1)
},
//Starts a new game
Start: function(){
_guessedLetters = []; //Resetting the guesses
_wordToGuess = _listOfWord[Math.floor(Math.random() * _listOfWord.length)];
return _wordToGuess
}
}
}(window._ = window._ || {}));
//Creates the buttons for hangman
function createButtons(){
var tContainer = document.querySelector('#buttons');
while(tContainer.firstChild) tContainer.removeChild(tContainer.firstChild);
//Creating the buttons
for(var tF=document.createDocumentFragment(), x=1; x<=26; x++){
var tLetter = String.fromCharCode(x+64),
tButton = tF.appendChild(document.createElement('button'));
tButton.id = tLetter;
tButton.addEventListener('click', makeAGuess);
tButton.appendChild(document.createTextNode(tLetter));
(x%10 === 0) && tF.appendChild(document.createElement('br'))
};
tContainer.appendChild(tF)
};
//Makes a guess
function makeAGuess(){
var tButton = this,
tLetter = tButton.id;
//Disable the button
tButton.setAttribute('disabled', 'disabled');
//Make a guess
var tElement = document.getElementById('hold');
tElement.textContent = _.Hangman.Guess(tLetter).join('');
//Check if finished
if(_.Hangman.isComplete()){
tElement.style.color = 'limegreen'
}
};
//Starts a new game of hangman
function Reset(){
createButtons(); //Recreated the buttons
_.Hangman.Start(); //Starting a game of hangman
var tElement = document.getElementById('hold');
tElement.textContent = _.Hangman.getCurrentObstructedWord().join('');
tElement.style.color = ''
};
window.onload = function(){
Reset()
};
</script>
</head>
<body>
<div id = 'hold'></div>
<p id = 'p1'>Make a guess:</p>
<div id = 'buttons'></div>
<br /><br />
<button onclick = 'Reset()'>Start a new game</button>
</body>
</html>
https://jsfiddle.net/mm6pLfze/
Can Push() and Pop() and Image Replacement Work within an Array?
8th Gr math teacher attempting to create a slide show of question images that pop() and push() through an image array based on student responses. If the student answers correctly the question is popped, but if they answer incorrectly it is added to the end of the queue. Additionally, since deleting elements in the DOM is bad, I am replacing the current image's src and id with that of the next element in queue. The array is then popped and pushed along, but whenever I enter in the incorrect answer twice the same image appears.
I have moved the global variable that holds the array, domEls, inside of the function retrieveAnsForImage to force it to randomize the images in the array. When I do this, the images change correctly so I believe it is the push() and pop() commands.
I included a snippet that doesn't work here, but works like a champ in Notepad ++. I just took a crash course in Javascript, HTML and CSS last month on Codecademy, I am very new to this. Thank you for reading.
//Jquery
$(document).ready(function() {
$(function() {
$('img.card').on('contextmenu', function(e) {
e.preventDefault();
//alert(this.id);
openPrompt(this.id);
});
});
});
//Provide and Shuffle array function
function shuffleImgs() {
var imgArr = [
"image1",
"image2",
"image3",
"image4",
"image5",
"image6",
"image7",
"image8",
"image9"
];
var currentIndex = imgArr.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = imgArr[currentIndex];
imgArr[currentIndex] = imgArr[randomIndex];
imgArr[randomIndex] = temporaryValue;
}
alert("shuffle");
return imgArr;
}
function arrStack() {
var imgArr = shuffleImgs();
//Map over the array to create Dom elements
var domElements = imgArr.map(function (imgName, index) {
var cardDiv = document.createElement('div');
var cardImage = document.createElement('img');
//Add img id and class
cardImage.id = imgName;
cardImage.classList.add('card');
//Set img source
cardImage.src = `images/${imgName}.jpg`;
//Put it all together
cardDiv.appendChild(cardImage);
return cardDiv;
});
//this notation to call nested function for Global var stack
this.nDomElements = function () {
stackDomEl = domElements;
return stackDomEl;
}
//Display last element in array
//this notation to call the nested function from outside the function
this.nDisplayLastArr = function displayLastArr() {
var lastImgArr = domElements[domElements.length - 1];
//alert(lastImgArr);
//Append the elements to the DOM
var modal = document.querySelector('div.modal');
modal.appendChild(lastImgArr);
return lastImgArr; //Use brackets when your are returning more than one variable
}
}
//Function called from Jquery to open prompt to answer question
function openPrompt(imageId) {
var userAns = prompt("Please enter your answer below and click OK");
if (userAns == null || userAns == "") {
alert("User cancelled the prompt. Exit and please try again!");
}
else {
/*Vain hope that I can pass imageId from click event through the user prompt
to the answer checking function retrieveAnsForImage*/
retrieveAnsForImage(imageId, userAns); //out of scope?
}
}
//Global variable
func = new arrStack();
window.domEls = func.nDomElements();
//Compare user responses with the question image by use of the click image id
function retrieveAnsForImage(imageId, userAns) {
//Change these variables to the correct answer whenever this website is reused in other assignments
var ansImage1 = "1";
var ansImage2 = "2";
var ansImage3 = "3";
var ansImage4 = "4";
var ansImage5 = "5";
var ansImage6 = "6";
var ansImage7 = "7";
var ansImage8 = "8";
var ansImage9 = "9";
//Give students a second chance to retry a question
//var hintCounter = 0; //include a while statement above the if statements to allow students a retry
/*Compare user response with correct case answer and correct clicked image.
Students may enter the right answer for the wrong image hence the &&.
Images will always be refered to as image1, image2, etc.*/
if (userAns === ansImage1 && imageId === "image1") {
correctAns(imageId);
}
else if (userAns === ansImage2 && imageId === "image2") {
correctAns(imageId);
}
else if (userAns === ansImage3 && imageId === "image3") {
correctAns(imageId);
}
else if (userAns === ansImage4 && imageId === "image4") {
correctAns(imageId);
}
else if (userAns === ansImage5 && imageId === "image5") {
correctAns(imageId);
}
else if (userAns === ansImage6 && imageId === "image6") {
correctAns(imageId);
}
else if (userAns === ansImage7 && imageId === "image7") {
correctAns(imageId);
}
else if (userAns === ansImage8 && imageId === "image8") {
correctAns(imageId);
}
else if (userAns === ansImage9 && imageId === "image9") {
correctAns(imageId);
}
else {
window.alert("Incorrect Answer");
incorrectAns();
}
function correctAns(){
//Second to last element in array
var SecLastElArr = domEls[domEls.length - 2];
//Pull image id from second to last element in array
var nextImgId = SecLastElArr.querySelector("div > img").id;
//Pull image id from document
var imgId = document.querySelector("div > img").id;
//Student incorrect answer change im
document.getElementById(imgId).src = `images/${nextImgId}.jpg`;
document.getElementById(imgId).id = nextImgId;
domEls.pop();
//Think about when the array is completely gone
//while domEls.length !== 0;
}
function incorrectAns(){
//Last element in array
var LastElArr = domEls[domEls.length - 1];
//Second to last element in array
var SecLastElArr = domEls[domEls.length - 2];
//Pull image id from second to last element in array
var nextImgId = SecLastElArr.querySelector("div > img").id;
//Pull image id from document
var imgId = document.querySelector("div > img").id;
//Student incorrect answer change image src and id to next element in queue
document.getElementById(imgId).src = `images/${nextImgId}.jpg`;
document.getElementById(imgId).id = nextImgId;
//Remove last element in array
domEls.pop();
//move the last element to the first element in the array for another attempt
domEls.push(LastElArr);
alert(domEls.length);
}
}
function overlay() {
var el = document.getElementById("overlay");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}
#overlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
text-align:center;
z-index: 1000;
background-color: rgba(0,191, 255, 0.8);
}
#overlay div {
width:70%;
margin: 10% auto;
background-color: #fff;
border:1px solid #000;
padding:15px;
text-align: center;
}
body {
height:100%;
margin:0;
padding:0;
}
#close-img {
float: right;
clear: right;
width: 30px;
height: 30px;
bottom: 0;
right: 0;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<span> "Left click to view any questions. Right click (two finger tap) to answer the question and claim the tile. Each player must claim 4 tiles to successfully complete the assignment."</span>
<link href="https://fonts.googleapis.com/css?family=Oswald:300,700|Varela+Round" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="Stack Rnd Temp.css">-->
<script type="text/javascript" src="Stack Rnd Temp.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="StackRndTempjq.js"></script>
</head>
<body>
<div class="title">
<h1></h1>
</div>
<div id="gameboard"> <!--Container for all nine divs-->
<a href='#' onclick='overlay()'>Click here to show the overlay</a>
</div>
<div class="modal" id="overlay">
<p> "Right click to answer the question"</p>
<script>
func = new arrStack();
func.nDisplayLastArr();
</script>
<img src="images/close.png" id="close-img" onclick="overlay()">
</div>
</body>
</html>
Your issue is that pop removes the last element from the array while push adds the element to end of the array.
What you probably want to do is use shift to remove the the first element from the array and pop it back to the end if the answer is wrong.
Alternately, you could pop the last element and use unshift to insert back into the beginning of you want to work in the other direction.
Here's a quick mockup without images.
var currentTest = null;
function getTest() {
$('#answer').html("").hide();
if (tests.length > 0) {
currentTest = tests.shift(); // remove the first question
$('#question').fadeIn(450).html(currentTest.q);
return currentTest;
} else {
$('#answer').html("Finished").fadeIn(500);
$('#btnCorrect').unbind();
$('#btnWrong').unbind();
}
}
var tests = [];
for (var i = 0; i < 5; i++) {
var question = "Question " + i;
var answer = "Answer " + i;
tests.push({
q: question,
a: answer
});
}
$('#btnCorrect').click(function() {
$('#question').hide();
$('#answer').fadeIn(450).html("Correct!");
window.setTimeout(getTest, 750);
});
$('#btnWrong').click(function() {
$('#question').hide();
tests.push(currentTest); // put the question back in the array
$('#answer').fadeIn(450).html("Incorrect!");
window.setTimeout(getTest, 750);
});
$(document).ready(function() {
getTest();
})
* {
font-family: arial;
}
#panel {
height: 50px;
}
#answer {
border: 1px solid #cccccc;
background: #dedede;
width: 400px;
}
#question {
border: 1px solid #999999;
background: #dedede;
width: 400px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="panel">
<div id="answer"></div>
<div id="question"></div>
</div>
<input id="btnCorrect" value="Mock Correct Answer" type="button">
<input id="btnWrong" value="Mock Wrong Answer" type="button">
</body>
</html>
So I'm trying to to use jQuery to append a div which will generate a card using the assigned class. The problem is I need to create a different ID each time so I can put random number on the card. I'm sure there's an easier way to do this. So i'm posing two questions. how to make the code where it put the random number on the card go endlessly. and how to append divs with unique ID's. Sorry if my code isn't the best. It's my first project.
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<title></title>
<style>
.cardLook {
border: 1px solid black;
width: 120px;
height: 220px;
border-radius: 5px;
float: left;
margin: 20px;
padding: 5px;
background-color: #fff;
}
#card1,#card2,#card3,#card4,#card5 {
transform:rotate(180deg);
}
#cardTable {
background-color: green;
height: 270px
}
.reset {
clear: both;
}
</style>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
</head>
<body>
<button id="deal">Deal</button>
<button id="hit">hit</button>
<button id="stand">Stand</button>
<button id="hi">hi</button>
<div id="number"></div>
<div id="arrayOutput"></div>
<div id="someId"></div>
<div id="out2"></div>
<div id="cardTable">
</div>
<div class="reset"></div>
<script>
var what;
//Services helper functon
document.getElementById('deal').onclick = function deal() {
var score1 = Math.floor(Math.random() *10 + 1);
var score2 = Math.floor(Math.random() *10 + 1);
var firstCard = score1;
var secondCard = score2;
//myNumberArray.push(firstCard, score2);
//card1.innerHTML = myNumberArray[0];
//card2.innerHTML = myNumberArray[1];
$("#deal").click(function(){
$("#cardTable").append("<div class='cardLook' id='card1'></div>");
});
console.log(score2, score1)
}
var myNumberArray = [];
$("#hit").click(function(){
$("#cardTable").append("<div class='cardLook' id="uniqueIdNumberOne"></div>");
if (myNumberArray > 1) {
#cardTable
}
var card = Math.floor(Math.random() * 10) + 1;
document.getElementById('number').innerHTML=card;
myNumberArray.push(card);
var number = myNumberArray.value;
var arrayOutput = document.getElementById('number');
var someId = document.getElementById('someId');
someId.innerHTML = myNumberArray;
card1.innerHTML = myNumberArray[0];
card2.innerHTML = myNumberArray[1];
card3.innerHTML = myNumberArray[2];
card4.innerHTML = myNumberArray[3];
card5.innerHTML = myNumberArray[4];
// console.log("myNumberArray: ", myNumberArray);
what = calcTotal(myNumberArray);
showMe(calcTotal(myNumberArray));
});
//var output = myNumberArray = calcTotal(list);
function calcTotal(myNumberArray) {
var total = 0;
for(var i = 0; i < myNumberArray.length; i++){
total += myNumberArray[i];
}
return total;
}
//document.getElementById('out2').innerHTML = out2;
console.log("myNumberArray: ", myNumberArray);
function showMe(VAL) {
var parent = document.getElementById('out2');
parent.innerHTML = VAL;
if (calcTotal(myNumberArray) > 21) {
alert('you lose');
}
};
document.getElementById('stand').onclick = function stand() {
var compterDeal1 = Math.floor(Math.random() *10 + 1);
var computerCards = compterDeal1;
console.log(computerCards);
computerArray.push(computerCards);
if (computerCards < 21) {
stand();
}
}
var computerArray = [];
</script>
</body>
</html>
Use an unique class with all of then, and call then by class
Add a global integer:
var cardNumber = 0;
A function to generate an id:
function newCardId() {
cardNumber ++;
return 'uniqueCardId' + cardNumber.toString();
}
And use:
var newId = newCardId();
$("#cardTable").append("<div class=\"cardLook\" id=\"" + newId + "\"></div>");
Finally to access your new div:
$('#' + newId).
Note: Escape quotes within a string using backslash!
So, i want to make game for my child. Have low experience in JS.
Scenario:
Have for example 4 square divs with blank bg. After refresh (or win) i want to:
Generate random numbers into div (1...4). And show them in them.
Then let player delete those divs by clicking on them, but in sequence how divs are numbered.
*For example after refresh divs have those numbers 2 3 1 4. So, user has to have rights to delete first div numbered 1 (2 3 _ 4) and so on.* If he clicks on 2 it get error , div stays in place, and user can try again delete right one.
It game for learning numbers. I have the begining.
Index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.css">
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
</head>
<body>
<div class="grid">
<div id="Uleft"></div>
<div id="Uright"></div>
<div id="Dleft"></div>
<div id="Dright"></div>
</div>
<script>
$(".grid").children( "div" ).on("click", function(){
$(this).css("visibility", "hidden");
});
</script>
</body>
</html>
css.css
.grid {
margin: 0 auto;
width: 430px;
}
#Uleft, #Uright, #Dleft, #Dright {
border: 1px solid black;
width: 200px;
height: 200px;
margin: 5px;
}
#Uright {
float: right;
background-color: red;
}
#Uleft {
float: left;
background-color: blue;
}
#Dleft {
float: left;
background-color: green;
}
#Dright {
float: right;
background-color: yellow;
}
So, i guess i have use jQuery as well, but i dont know how to make it dynamic and different after refresh of page. Please help :)
http://jsfiddle.net/bNa8Z/
There are a few things you have to do. First you have to create a random array which you use sort and Math.random() to do then, you need insert the text in the squares. Find the min of the visible squares and then remove/alert depending if its the min value.
// sort by random
var rnd = [1,2,3,4].sort(function() {
return .5 - Math.random();
});
// map over each div in the grid
$('.grid div').each(function(ii, div) {
$(div).text(rnd[ii]); // set the text to the ii'th rnd
});
function minVisible() {
var min = 1e10; // a big number
$('.grid div').each(function(ii, div) {
// if not visible ignore
if ($(div).css('visibility') === "hidden" ){
return;
}
// if new min, store
var curFloatValue = parseFloat($(div).text());
console.log(curFloatValue);
if (curFloatValue < min) {
min = curFloatValue;
}
});
return min;
}
$(".grid").children( "div" ).on("click", function(){
var clickedFloatValue = parseFloat($(this).text());
if (clickedFloatValue == minVisible()) {
$(this).css("visibility", "hidden");
} else {
alert("sorry little tike");
}
});
Updated jsfiddle http://jsfiddle.net/bNa8Z/2/
Roughly this is what it would look like:
var selected = {};
$('.grid div').each(function(idx){
var is_done = false;
do{
var rand = Math.floor((Math.random()*4)+1);
if( selected[rand] == undefined ){
$(this).html(rand);
selected[rand] = 1;
is_done = true;
}
}while(!is_done);
});
alert("Start the game");
var clicked = [];
$('.grid').on('click', 'div.block', function(){
var num = $(this).html();
if( num == clicked.length + 1 ){
//alert(num + " is correct!");
clicked.push(num);
$(this).addClass("hide");
}else{
alert("Failed!");
}
if( clicked.length == 4 ){
alert("You Won!");
}
});
HTML:
<div class="grid">
<div class="block" id="Uleft"></div>
<div class="block" id="Uright"></div>
<div class="block" id="Dleft"></div>
<div class="block" id="Dright"></div>
</div>
Added CSS:
#Uleft, #Uright, #Dleft, #Dright {
position:absolute;
...
}
#Uright {
left:220px;
top:0px;
background-color: red;
}
#Uleft {
left:0px;
top:0px;
background-color: blue;
}
#Dleft {
left:0px;
top:220px;
background-color: green;
}
#Dright {
left:220px;
top:220px;
background-color: yellow;
}
.hide {
display: none;
}
See the working version at
JSFiddle
You will need to re-"run" the fiddle per game.
please try it. I think that It will help you.
var generated_random_number_sequesce = function(){
var number_array = [];
var number_string = '';
var is_true = true;
while(is_true){
var ran_num = Math.round(1 + Math.random()*3);
if(number_string.indexOf(ran_num) == -1 && ran_num < 5){
number_array[number_array.length] = ran_num;
number_string = number_string + ran_num;
if(number_array.length == 4){is_true = false;}
}
}
return number_array;
}
var set_number_on_divs = function(){
var number_array = generated_random_number_sequesce();
$(".grid").children().each(function(index, element){
$(this).attr('data-div_number' , number_array[index]);
});
}
set_number_on_divs()
var clicked = 0;
$(".grid").children( "div" ).on("click", function(){
clicked += 1;
var current_div_number = $(this).attr('data-div_number');
if( parseInt(current_div_number) == clicked){
$(this).css("visibility", "hidden");
} else{
clicked -= 1;
alert('error');
}
});
Sorry about the confusing title, I'll explain better.
I have a 20x20 grid of div's, so its 400 of them each with an id, going from 0 to 399.
Each div is given one of three random values - red, green or blue - and when a div is clicked, a function is run to check if the div to the left, right, over and under are of the same value, if it is of the same value it will be simulated a click and the same function will run again.
The problem, is that the function sets vars, so if it finds that the div below has the same value, it will overwrite the vars set by the first click, hence never click any of the others.
JSfiddle - http://jsfiddle.net/5e52s/
Here is what I've got:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>untiteled</title>
<style>
body {
width: 420px;
}
.box {
width: 19px;
height: 19px;
border: 1px solid #fafafa;
float: left;
}
.box:hover {
border: 1px solid #333;
}
.clicked {
background: #bada55 !important;
}
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$().ready(function(){
var colors = ['red', 'green', 'blue'];
var i = 0;
while(i<400){
var color = colors[Math.floor(Math.random() * colors.length)];
$('.test').append('<div class="box" id="'+i+'" value="'+color+'" style="background:'+color+';">'+i+'</div>');
i++;
}
$('.box').click(function(){
var t = $(this);
t.addClass('clicked');
id = t.attr('id');
val = t.attr('value');
//Set color
up = parseInt(id) - 20;
right = parseInt(id) + 1;
down = parseInt(id) + 20;
left = parseInt(id) - 1;
clickup = false;
clickdown = false;
if($('#'+down).attr('value') === val){
clickdown = true;
}
if(up > -1 && ($('#'+up).attr('value') === val)){
clickup = true;
}
if(clickdown == true){
$('#'+down).click();
}
if(clickup == true){
$('#'+up).click();
}
});
});
</script>
</head>
<body>
<div class="test">
</div>
</body>
I think the biggest root cause of your problem is you don't check if it already has class 'clicked' or not. That could make the infinite recursive. For example, if you click on the div#2 then the div#1 receives a simulated click, and div#2 receives a simulated click from div#1.
$('.box').click(function(){
var t = $(this);
if(t.hasClass('clicked')) {
return;
}
t.addClass('clicked');
var id = t.attr('id');
var val = t.attr('value');
//Set color
var up = parseInt(id) - 20;
var right = (id%20 != 19) ? ((0|id) + 1) : 'nothing' ;
var down = parseInt(id) + 20;
var left = (id%20 != 0) ? ((0|id) - 1) : 'nothing';
console.log(up, right, down, left);
if($('#'+down).attr('value') === val) {
$('#'+down).click();
}
if($('#'+right).attr('value') === val) {
$('#'+right).click();
}
if($('#'+up).attr('value') === val) {
$('#'+up).click();
}
if($('#'+left).attr('value') === val) {
$('#'+left).click();
}
});
You can schedule the clicks onto the event loop instead of calling them directly, eg:
if(clickdown == true){
setTimeout(function () {
$('#'+down).click();
});
}
I don't think that's your root cause though, it's probably a combination of global vars and scope issues. Try reformatting as such:
$('.box').click(function (event){
var t = $(this), id, val, up, right, down, left, clickup, clickdown;
//...
Your variables id and val are not in a var statement, thus are implicitly created as members of the window object instead of being scoped to the local function. Change the semicolon on the line before each to a comma so that they become part of the var statement, and your code should begin working.