var pass = 'budi baj baj bastajpan';
var vpass = '';
var password = document.querySelector('#password-field');
function getPassword() {
vpass = Array.from(pass);
for (i = 0; i < vpass.length; i++) {
if (vpass[i] === ' ') {
vpass[i] = ' ';
} else {
vpass[i] = '_';
}
}
password.innerHTML = vpass;
addLetters();
}
var lettersField = document.querySelector('#letters');
var alfabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'w', 'x', 'y', 'z'];
function addLetters() {
var letters = '';
for (i = 0; i < 25; i++) {
letters = letters + '<span class="letter" id="let' + i + '" onclick="checkLetter(' + i + ')">' + alfabet[i] + '</span>';
}
lettersField.innerHTML = letters;
}
function checkLetter(nr) {
passArr = Array.from(pass);
for (i = 0; i < 25; i++) {
if (passArr[i] == alfabet[nr]) {
document.querySelector("#let" + nr).style.background = "green";
vpass[i] = alfabet[nr];
password.innerHTML = vpass;
} else {
document.querySelector("#let" + nr).style.background = "red";
}
}
}
window.onload = getPassword;
/*
So, basically i know i probably made ton of mistakes but can u explain me why does this two rows:
vpass[i] = alfabet[nr];
password.innerHTML = vpass;
Work exactly as i want that means it only changes the password when i click on right letter.
But background changes to red whatever letter i click. (every style i put to ELSE work on every letter but styles in IF work fine.
*/
#game {
width: 600px;
height: 400px;
margin: 20px auto;
border: 3px solid green;
}
#password-field {
width: 100%;
height: 100px;
background: dimgray;
color: white;
box-sizing: border-box;
border-bottom: 2px solid white;
display: flex;
justify-content: center;
align-items: center;
}
#status {
width: 50%;
height: 300px;
background: lightgray;
position: relative;
left: 0;
box-sizing: border-box;
border-right: 1px solid white;
}
#letters {
width: 50%;
height: 300px;
background: lightgray;
position: relative;
left: 50%;
top: -300px;
box-sizing: border-box;
border-left: 1px solid white;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.letter {
width: 40px;
height: 40px;
margin: 5px;
border: 1px solid white;
text-align: center;
line-height: 2;
border-radius: 10px;
font-size: 20px;
transition: .5s;
}
.letter:hover {
background: lightblue;
border-color: blue;
transition: none;
cursor: pointer;
}
<!DOCTYPE HTML>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Ramphastos Toco</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="game">
<div id="password-field"></div>
<div id="status"></div>
<div id="letters"></div>
</div>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="main.js"></script>
</body>
</html>
var pass = 'budi baj baj bastajpan';
var vpass = '';
var password = document.querySelector('#password-field');
function getPassword() {
vpass = Array.from(pass);
for (i = 0; i < vpass.length; i++) {
if (vpass[i] === ' ') {
vpass[i] = ' ';
} else {
vpass[i] = '_';
}
}
password.innerHTML = vpass;
}
var lettersField = document.querySelector('#letters');
var alfabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'w', 'x', 'y', 'z'];
function addLetters() {
var letters = '';
for (i = 0; i < 25; i++) {
letters = letters + '<span class="letter" id="let' + i + '" onclick="checkLetter(' + i + ')">' + alfabet[i] + '</span>';
}
lettersField.innerHTML = letters;
}
function checkLetter(nr) {
passArr = Array.from(pass);
for (i = 0; i < 25; i++) {
if (passArr[i] === alfabet[nr]) {
document.querySelector("#let" + nr).style.background = "green";
vpass[i] = alfabet[nr];
password.innerHTML = vpass;
} else {
document.querySelector("#let" + nr).style.background = "red";
}
}
}
Can u explain me why does this two rows:
vpass[i] = alfabet[nr];
password.innerHTML = vpass;
Work exactly as i want that means it only changes the password when i click on right letter.
But background changes to red whatever letter i click. (every style i put to ELSE work on every letter but styles in IF work fine).
Stackoverflow wants me to put some more details if i want to add snippet so i will just put some text cuz i dont know what more can i really say about...
I'm glad you edited your question a bit further, it was hard to understand.
Your problem is exacly the "for" loop.
You iterate through every letter of the password, so:
else {
document.querySelector("#let" + nr).style.background = "red";
}
Will always be executed for all the letters of the alphabet that don't match the letter of the password you're evaluating. And this will override any previously made match!
So, if the current letter you're evaluating is not a "z", the background will always be red!
My correction suggestion:
function checkLetter(nr) {
let flag=0;
passArr = Array.from(pass);
for (i = 0; i < 25; i++) {
if (passArr[i] === alfabet[nr]) {
document.querySelector("#let" + nr).style.background = "green";
flag=1; //if the letter is found, stop checking for the background
vpass[i] = alfabet[nr];
password.innerHTML = vpass;
} else {
if(flag==0)
document.querySelector("#let" + nr).style.background = "red";
}
}
}
EDIT:
Now the code uses a flag, to stop changing the background as soon as a letter is found. So the cycle runs the full way, but on the first letter found it switches the color to green. Otherwise, it will always be red.
Related
I want to randomly assign a class at two boxes.
But even with indexOf(randomIndex) === -1) Math.random is duplicating the numbers.
If you refresh you will see that the boxes are changing classes but sometimes they both have the same class, this should happened.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
var weapon3 = [];
while (weapon3.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weapon3.indexOf(randomIndex) === -1) {
weapon3.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
You are using two different arrays for storing the weapons. Use same array so that the number is not repeated.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
while (weaponTwo.length < 2) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
Better Approach : You can create an array of classes and then shuffle it using this alogrithm. Then you can pop from the array and add to classes one by one.
I need some help or advice I am trying to limit the random number to only generate 20 out of the 50 numbers and this activated when a button is pressed/clicked sometimes i get duplicates too which i would to stop happening
function lottoNumbers()
{
var lottoNums = [];
for(var i=0; i <1 ; i++)
{
var temp = Math.floor(Math.random() *50);
if(lottoNums.indexOf(temp) == -1)
{
lottoNums.push(temp);
document.getElementById('circle'+i).innerHTML = lottoNums[i];
}
else
{
i--;
}
}
}
Rather than using a for loop - use a while loop (ie - while length < 20) and as you are doing - only push the numbers into it if they are not already there.
For demo purposes- i am building a list dynamically and then styling the li's to give a rounded shape with border-radius;
lottoNumbers();
function lottoNumbers() {
var lottoNums = [];
var lottoNumStr = '';
while(lottoNums.length <20) {
var temp = Math.floor(Math.random() *50);
if(lottoNums.indexOf(temp) == -1) {
lottoNums.push(temp);
lottoNumStr += '<li>' + temp + '</li>';
}
}
document.getElementById('lottoNumList').innerHTML = lottoNumStr;
}
#lottoNumList {
list-style: none;
}
#lottoNumList li {
border: solid 1px #d4d4d4;
border-radius: 50%;
display: inline-block;
margin: 5px;
padding: 4px;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
}
<h1>Lotto Numbers</h1>
<ul id ="lottoNumList"></ul>
I am trying to make an interface where you can select tickets and buy them, I want that when I click on a seat it displays like "You are currently buying the next tickets + (The tickets chosen by the user)".
This is my code so far:
var seatsUnclicked = document.getElementsByClassName("seat-unique");
var seatsClicked = document.getElementsByClassName("seatClicked");
var images = document.getElementsByTagName("IMG");
var seatsOutput = document.getElementsById("seatsOutput");
var ticketsData = 0
for (let i = 0; i < seatsUnclicked.length; i++) {
seatsUnclicked[i].onmouseover = function() {
this.src = "chairclicked.svg";
this.onmouseout = function() {
this.src = "chair.svg"
}
if ($(this).hasClass('seatClicked')) {
this.src = "chairclicked.svg";
this.onmouseout = function() {
this.src = "chairclicked.svg"
}
}
}
seatsUnclicked[i].onclick = function() {
this.classList.add("new")
if ($(this).hasClass('seatClicked')) {
this.classList.remove("seatClicked")
this.classList.remove("new")
this.src = "chair.svg";
this.onmouseout = function() {
this.src = "chair.svg"
}
ticketsData = ticketsData - /* "the id of this element in a string" */
}
if ($(this).hasClass('new')) {
this.src = "chairclicked.svg";
this.classList.add("seatClicked")
this.classList.remove("new")
this.onmouseout = function() {
this.src = "chairclicked.svg"
}
ticketsData = ticketsData + /* "the ID of this element in a string" */
}
seatsOutput.innerHTML = "THE TICKETS YOU HAVE CHOSEN ARE" + string(ticketsData)
}
}
<div class="seats-row-A">
<img id="A1" class="seat-unique " src="http://via.placeholder.com/100x100?text=A1">
<img id="A2" class="seat-unique " src="http://via.placeholder.com/100x100?text=A2">
<img id="A3" class="seat-unique " src="http://via.placeholder.com/100x100?text=A3">
<img id="A4" class="seat-unique " src="http://via.placeholder.com/100x100?text=A4">
<img id="A5" class="seat-unique" src="http://via.placeholder.com/100x100?text=A5">
<img id="A6" class="seat-unique " src="http://via.placeholder.com/100x100?text=A6">
<img id="A7" class="seat-unique " src="http://via.placeholder.com/100x100?text=A7">
</div>
<h2 id="seatsOutput">Chosen Tickets:</h2>
jQuery
The only jQuery statement in OP code is: $(this).hasClass('seatClicked').
The plain JavaScript equivalent is: this.classList.contains('seatClicked').
Question
I couldn't follow the OP code because there was only a class, an id, and img tags that match the JavaScript, but it's not that clear because of the *.svg files (not provided.) Also, there's a curly bracket } missing (I think it belongs to the for loop, but I'm not wasting time on debugging typos.)
The Demo was built in mind with what the question and comments had mentioned:
"...I want that when I click on a seat it displays like "You are currently buying..."
Highlight icon when hovered over.
Reveal icon's id when hovered on.
All hover behavior is done with CSS: :hover, ::before, ::after, content: attr(id), content: '\a0\1f4ba'. Using JavaScript for behavior CSS can do will result in more CPU cycles. CSS will use GPU of your graphics card instead of the CPU.
Testing
The seats are dynamically generated with id="A* by entering a number in the input and clicking the View button. For each additional click of the button a new batch of seats are appended and have ids that correspond to it's group:
input: 55 and first click A0-A55,
input: 12 and second click B0-B12,
input: 222 and third click C0-C222
...
Last group is J
References
The Demo is basically a <form>. HTMLFormControlsCollection API is used to set/get form controls and values.
Reference the tag
const ui = document.forms.tickets;
This is a collection of all form controls in form#tickets
const t = ui.elements;
Now all form controls are now accessible by prefixing a form control's #id or [name] with the HTMLFormControlsCollection Object.
<textarea name='textA'></textarea>
Without HFCC API
var ta = document.querySelector('[name=textA]');
With HFCC API
var ta = t.textA;
The links are collected by Links Collection.
document.links
DocumentFragment is used to insert a huge amount of dynamic HTML in one shot efficiently and quickly.
document.createDocumentFragment();
Various array methods were used:
Array.from()
map()
fill()
indexOf()
Demo
const ui = document.forms.tickets;
const t = ui.elements;
const seats = document.getElementById('seats');
t.btn.addEventListener('click', seatsAvailable);
seats.addEventListener('click', function(e) {
let picked = [];
pickSeat(e, picked);
}, false);
function pickSeat(e, picked) {
const display = t.display;
if (e.target.tagName === "A") {
e.target.classList.toggle('picked');
picked = Array.from(document.querySelectorAll('.picked'));
}
picked = picked.map(function(seat, index, picked) {
return seat.id;
});
display.value = "";
display.value = picked;
}
function seatsAvailable(e) {
const qty = this.previousElementSibling;
const last = document.links[document.links.length - 1].id;
console.log(last);
const limit = parseInt(qty.value, 10) + 1;
const spots = new Array(limit);
spots.fill(0, 0, limit);
return generateSeats(spots, last);
}
function generateSeats(spots, last) {
if (last.charAt(0) === "J") {
t.display.textContent += "Last row available";
return false;
}
const rowID = ['x', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];
let row = rowID.indexOf(last.charAt(0)) + 1;
const frag = document.createDocumentFragment();
const avSeats = spots.map(function(A, idx) {
const seat = document.createElement('a');
seat.id = rowID[row] + idx;
seat.href = "#/";
frag.appendChild(seat);
return seat;
});
seats.appendChild(frag);
if (document.links[0].id === 'x') {
const x = document.getElementById('x');
x.parentElement.removeChild(x);
}
if (document.links.length > 114) {
const ext = (Math.round(document.links.length / 114)*600)+600;
seats.style.maxHeight = ext+'px';
}
return avSeats;
}
html,
body {
width: 100%;
height: 10%;
font: 400 16px/1.3 Consolas;
}
#seats {
display: flex;
flex-flow: column wrap;
max-height: 600px;
width: auto;
border: 3px ridge grey;
}
.box {
display: table
}
input,
button,
label {
font: inherit
}
#qty {
text-align: right
}
#display {
display: table-cell;
}
.tag {
overflow-x: scroll;
overflow-y: hidden;
display: block;
width: 400px;
line-height: 1.3
}
a,
a:link,
a:visited {
display: inline-block;
margin: 0;
text-align: center;
text-decoration: none;
transition: all 500ms ease;
}
a:hover,
a:active {
background: rgba(0, 0, 0, 0);
color: #2468ac;
box-shadow: 0 0 0 3px #2468ac;
}
a::before {
content: attr(id);
color: transparent;
}
a:hover::before {
color: #2468ac;
}
a.picked::before {
color: #000;
}
a::after {
content: '\a0\1f4ba';
font-size: 1.5rem;
}
#x {
pointer-events: none
}
.as-console-wrapper {
width: 30%;
margin-left: 70%
}
<form id='tickets'>
<fieldset class='box'>
<legend>Available Seats</legend>
<fieldset class='box'>
<input id='qty' type='number' min='0' max='50' value='1'> <button id='btn' type='button'>View</button>
<label class='tag'>Current ticket purchases to seats:
<output id='display'></output>
</label>
</fieldset>
<section id='seats'>
<a id='x' href='#/'></a>
</section>
</fieldset>
</form>
I'm creating a minefiled game and I'm trying to put 10 bombs in a random location each time. The problem is that sometimes 2 or more bombs can be placed in the same block, resulting in less than 10 bombs in the game. How can I prevent this?
I've already tried saving all the bombs locations in an array and each time compare the new bomb location to all the past ones, but id didn't work.
Here is my code:
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
create_blocks();
create_bombs();
});
function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
var random_block = bombs_do_not_repeat();
var bomb = document.getElementById(random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
bombs[i] = random_block;
}
}
function bombs_do_not_repeat() {
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
SOLVED:
function bombs_do_not_repeat(){
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1,number_of_blocks);
for(var j = 0; j < bombs.length; j++){
if(random_num == bombs[j]){
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
return random_num = bombs_do_not_repeat();
}
}
return random_num;
}
You're recursively calling bombs_do_not_repeat(), but always ignoring the recursive result and just going with whatever was selected first whether it's a repeat or not.
I suspect you mean to assign the result of the recursion:
random_num = bombs_do_not_repeat();
I suggest you to change your function to this
function bombs_do_not_repeat() {
var check = false;
var random_num;
do{
random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length && !check; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
check = true;
}
}
}while(check);
return random_num;
}
Instead of creating each random number prepare a random (shuffled) array. Something like this.
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
var blockArr = []; //helper array
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
//reset blockArr and bombs
bombs = [];
blockArr = [];
//clean the field
document.getElementById('field').innerHTML = '';
create_blocks();
//blockArr is now fillewd
bombs = blockArr.sort(function() {
return Math.random() < 0.5 ? -1 : 1;
}) //shuffle
.slice(0, number_of_bombs);
//for debug purpose
//console.log(bombs);
create_bombs();
});
//function random(min, max) {//obsolete
// return Math.floor(Math.random() * (max - min)) + min;
//}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
//fill blockArr in the samee loop
blockArr.push(i);
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
//var random_block = bombs_do_not_repeat(); //no need
var bomb = document.getElementById('b' + bombs[i]); //random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
//bombs[i] = random_block;
}
}
/*
function bombs_do_not_repeat() { //obsolete
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
*/
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
I am making a set of minigames for my major project, have being following a tutorial on the internet to make a memory game for one of them.
The code works up to where I generate a new board but the rest of the code doesn't seem to work. Have I done something wrong in my scipting? Can anyone tell me where I'm going wrong?
This is my code for the memory minigame.
$(document).ready(function() {
//speech
var progress = 0;
var txt;
$('#complete, #speech').hide();
function eventHandler() {
switch (progress) {
case 0:
txt = "Complete";
break;
case 1:
txt = "Move on the the next game";
$('#speech').click(function() {
window.location.href = "minigame4.html"; //next minigame
});
break;
}
progress++;
$('#speech').html(txt);
}
$('#speech').click(eventHandler);
// Memory Game //
var memory_array = ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F', 'G', 'G', 'H', 'H', 'I', 'I', 'J', 'J', 'K', 'K', 'L', 'L'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
//shuffle method
Array.prototype.memory_tile_shuffle = function() {
var i = this.length,
j, temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
//generate new board
function newBoard() {
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for (var i = 0; i < memory_array.length; i++) {
output += '<div id="tile_' + i + '" onclick="memoryFlipTile(this,\'' + memory_array[i] + '\')" class="tiles"></div>';
}
$('#memory_board').html(output);
}
newBoard();
//
// all code works up to here
function memoryFlipTile(tile, val) {
// When tile is clicked, change colour to white along with its letter
if (tile.html == "" && memory_values.length < 2) {
tile.style.background = '#FFF';
tile.html = val;
// If no tiles are flipped
if (memory_values.length == 0) {
memory_values.push(val);
memory_tile_ids.push(tile.id);
// If one tile is already flipped
} else if (memory_values.length == 1) {
memory_values.push(val);
memory_tile_ids.push(tile.id);
// See if both tiles are a match
if (memory_values[0] == memory_values[1]) {
tiles_flipped += 2;
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
// then display complete
if (tiles_flipped == memory_array.length) {
$("#complete").show(0, function() {
eventHandler()
$('#speech').show();
});
}
} else {
function flip2Back() {
// Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background - image = 'url(images/puzzle5/blank.png) no-repeat';
tile_1.html = "";
tile_2.style.background - image = 'url(images/puzzle5/blank.png) no-repeat';
tile_2.html = "";
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flip2Back, 700);
}
}
}
}
});
div#memory_board {
padding: 24px;
margin: 0px auto;
width: 456px;
height: 300px;
}
div#memory_board div {
float: left;
margin: 10px;
padding: 28px;
font-size: 50px;
cursor: pointer;
text-align: center;
background-image: url(images/puzzle5/blank.png);
}
#complete {
position: absolute;
width: 105px;
height: 25px;
top: 240px;
left: 289px;
background-color: black;
color: white;
font-size: 20px;
padding: 10px;
border-style: solid;
border-width: 5px;
border-color: white;
z-index: 5;
}
#speech {
position: absolute;
width: 655px;
height: 100px;
top: 330px;
left: 15px;
background-color: black;
color: white;
font-size: 25px;
padding: 10px;
border-style: solid;
border-width: 5px;
border-color: white;
z-index: 99;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MAS340</title>
<link href="styles.css" rel="stylesheet" />
<script src="jquery-3.1.1.min.js"></script>
<script>
//javascript goes here
</script>
</head>
<body>
<div id="stage">
<div id="memory_board"></div>
</div>
</body>
</html>
Apart from mentioned changes by some users, there are also other changes required in your script. As you are already using jQuery why don't utilize it fully?
Also have attached the event using jQuery like below as I suspect its able to see the function defined in the script while putting elements in dom. (Not sure about reason though yet)
I have changed your code in below fiddle. please check if its work for you (just corrected the syntax and replace some javascript code with jquery)
$(document).on('click','.tiles',function(){
memoryFlipTile($(this),$(this).data("memchar"))
})
Check Fiddle
There is still a scope to optimize the code.
You have syntax errors in line 93 and 95. In addition, html should be innerHTML
Change
tile_1.style.background - image = 'url(images/puzzle5/blank.png) no-repeat';
tile_1.html = "";
tile_2.style.background - image = 'url(images/puzzle5/blank.png) no-repeat';
tile_2.html = "";
To
tile_1.style.['background-image'] = 'url(images/puzzle5/blank.png) no-repeat';
tile_1.innerHTML = "";
tile_2.style.['background-image'] = 'url(images/puzzle5/blank.png) no-repeat';
tile_2.innerHTML = "";