Swapping images with Javascript/Dom - javascript

this is my second Javascript/Dom query this evening but this is really quite a different query and thus probably deserves a new topic. My ultimate goal is to create a sliding puzzle game with a 4 x 4 grid. With some help in the other thread I have got the script to show the images in a 4 x 4 grid in a random order, with a shuffle button that again randomizes the images. The images are name image00, 01, 02, 03, 10, 11 etc up to 33 - 33 is my blank image.
Now I want to add commands that say if this image is clicked and it is next to the blank tile (image 33) then swap with the blank image. The only problem is, that I have no idea where to begin. My code so far is below. From what I've seen it would be something along the lines of using the images ID's but I am very new to javascript and haven't been able to find much that has helped me so far. Any help is really appreciated.
<html>
<head>
<title>Shuffle</title>
</head>
<body>
<script language="JavaScript">
<!--
var Pics = [];
var Top = 16;
Pics = new Array();
for(i = 0; i < Top; i++) {
document.write("<img>");
if ((i+1)%4 == 0) {
document.write("<br>");
}
}
function ShuffleArray(a) {
var n = a.length;
for(var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
function ViewerObj(Image, Pics, i) {
this.Image = Image;
this.Image.style.left = 800;
this.Pics = Pics;
this.Image.id = "ID" + i;
}
function Randomise() {
var i;
ShuffleArray(Pics);
for(i = 0; i < Top; i++) {
Viewers[i].Image.src = Pics[i];
Viewers[i].Image.style.left = 200;
}
}
Viewers = new Array();
var i;
for(var i = 0; i < 4; i++) {
for(var j = 0; j < 4; j++) {
Pics[j + 4*i] = "images/Tree" + (i) + (j) + ".jpg";
}
}
for(i = 0; i < Top; i++) {
document.images[i].src = Pics[i];
document.images[i].style.left = 300;
Viewers[i] = new ViewerObj(document.images[i], Pics, i);
}
//-->​
</script>
<h1>Shuffle</h1>
<form>
<input type="button" value="Shuffle" onClick="Randomise();"/>
</form>
</body>
</html>

You should go for jQuery. It will make many things easier.

Related

How to change the background of a table cell if it meets a requirement with a button

Write a program that dynamically creates a 100x100 table. Each element
in the table will have a unique number, starting at 1 and increasing
by 1.
This page will also have a button that will be "Calculate almost prime
numbers." This button will cause all the cells in the table that have
“Almost Prime” numbers to have a yellow background.
Almost prime number: it is a number that is only divisible by itself,
the unit and by a single number that is neither the unit nor itself.
Hello, I am relatively new to the world of JavaScript and I am trying to solve this JavaScript exercise and as you can see the first part is to make a 100x100 table, which I have been able to do, the problem is the second part in which I have to change the background of the cells to the "almost prime numbers"
Here I leave my code, probably many things can be improved apart from finding a solution to putting the background color of the cells, anyway thanks if you can help me.
window.addEventListener("DOMContentLoaded", main);
function main() {
var body = document.getElementsByTagName("body")[0];
var tabla = document.createElement("table");
var tblBody = document.createElement("tbody");
for (var i = 0; i < 100; i++) {
var fila = document.createElement("tr");
for (var j = 0; j <= 100; j++) {
var columna = document.createElement("td");
var numero = document.createTextNode(j + i * 100);
columna.appendChild(numero);
fila.appendChild(columna);
}
tblBody.appendChild(fila);
}
tabla.appendChild(tblBody);
body.appendChild(tabla);
tabla.setAttribute("border", "2");
}
function casiprimos() {
let contador = 0;
for (var i = 0; i < 100; i++) {
for (var j = 0; j <= 100; j++) {
let num = (j + i * 100)
for (var z = 1; z <= num; z++) {
let resultado = num % z;
if (resultado == 0) {
contador = contador + 1;
}
}
if (contador == 3) {
// num.setAttribute("style","background-color: yellow;"); ? Idk
contador = 0;
} else {
contador = 0;
}
}
}
}

Construct a triangular pattern with two symbols

I know how to construct the above triangle using a single symbol.
I do not understand how to change my code to use two symbols.
Your problem may be solved using a number of different solutions...
For the heck of it, here's how I would do it using canvas, to create an image (copied/pasted and adapted an answer I gave to another SO user yesterday...). This solution probably won't fit your needs but then again as Jishnu V S stated, you gave us nothing to help you with.
ps : Yeah, I know, WAY overkill compared to simple html lists... Oh well xD
fiddle
HTML
<canvas id="canvas" width=1000 height=1000></canvas>
JS
var rows = 8,
cols = 1,
size = 64;
var canvas = document.getElementById("canvas");
var surface = canvas.getContext("2d");
//creating tile
function box(img) {
this.xaxis = 64;
this.yaxis = 0;
//Set your image selection logic here...
this.src = (img > 0 ) ? "https://cdn0.iconfinder.com/data/icons/typicons-2/24/times-512.png" : "http://img.freepik.com/free-icon/minus-big-symbol_318-70354.jpg?size=338&ext=jpg";
console.log(img);
}
//creating map
var map =[];
function setMap() {
for (var i = 0; i < rows; i++) {
var arr = [];
map.push(arr);
for (var o = 0; o < cols; o++) {
var selectImg = (i % 2 == 0) ? 0 : 1; //select your image based on row
map[i].push(new box(selectImg));
}
cols = (cols < 8) ? cols + 1 : cols;
}
}
console.log(map)
//rendering map
function render() {
for (var i = 0; i < rows; i++) {
for (var x = 0; x < map[i].length; x++) {
var tile = map[i][x];
tile.xaxis *= x;
tile.yaxis += (i*64);
var img = new Image();
img.onload = (function(x,y) {
return function() {
surface.drawImage(this, x, y, 64, 64);
}
})(tile.xaxis, tile.yaxis);
img.src = tile.src;
}
}
}
setMap();
render();

Speeding up simple math operations on numeric 2D array (matrix) in JavaScript

I have a numeric 2D array (an array of arrays, or a matrix) and I need to do simple matrix operations like adding a value to each row, or multiplying every value by a single number. I have little experience with math operations in JavaScript, so this may be a bone-headed code snippet. It is also very slow, and I need to use it when the number of columns is 10,000 - 30,000. By very slow I mean roughly 500 ms to process a row of 2,000 values. Bummer.
var ran2Darray = function(row, col){
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var myArray = ran2Darray(5, 100);
var offset = 2;
for (i = 0; i < myArray.length; i++) {
aRow = myArray[i];
st = Date.now();
aRow.map(function addNumber(offset) {myArray[i] + offset*i; })
end = Date.now();
document.write(end - st);
document.write("</br>");
myArray[i] = aRow;
}
I want to avoid any added libraries or frameworks, unless of course, that is my only option. Can this code be made faster, or is there another direction I can go, like passing the calculation to another language? I'm just not familiar with how people deal with this sort of problem. forEach performs roughly the same, by the way.
You don't have to rewrite array items several times. .map() returns a new array, so just assign it to the current index:
var myArray = ran2Darray(5, 100000);
var offset = 2;
var performOperation = function(value, idx) {
return value += offset * idx;
}
for (i = 0; i < myArray.length; i++) {
console.time(i);
myArray[i] = myArray[i].map(performOperation)
console.timeEnd(i);
}
It takes like ~20ms to process.
Fiddle demo (open console)
Ok, Just a little modification and a bug fix in what you have presented here.
function addNumber(offset) {myArray[i] + offset*i; }) is not good.
myArray[i] is the first dimention of a 2D array why to add something to it?
function ran2Darray (row, col) {
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var oneMillion = 1000000;
var myArray = ran2Darray(10, oneMillion);
var offset = 2;
var startTime, endTime;
for (i = 0; i < myArray.length; i++) {
startTime = Date.now();
myArray[i] = myArray[i].map(function (offset) {
return (offset + i) * offset;
});
endTime = Date.now();
document.write(endTime - startTime);
document.write("</br>");
}
try it. It's really fast
https://jsfiddle.net/itaymer/8ttvzyx7/

Script JS with For Loop over tables

I am a very beginner with Javascript and I want to write a script that modifies the style of (some) tables, at the end of the parsing of an html page.
I have a (hopefully) MWE of such script:
<script type="application/javascript">
<!--
var Ri = document.getElementsByTagName("tr");
var Ca = document.getElementsByTagName("td");
var nRi = Ri.length;
var nCa = Ca.length;
var nCo = nCa/nRi;
for (var i = 0; i < nCo; i++)
{
Ca[i].style.backgroundColor="rgb(221,247,255)";
}
for (var i = nCo; i < nCa; i = i+nCo)
{
Ca[i].style.backgroundColor="rgb(221,247,255)";
}
//-->
</script>
but, as you can easily verify, it would work correctly only if there's a single table in the html page.
The question is the following. Let us say there are m tables with the attribute class="tabx" in the html page. How can I edit the script so that it counts the m tables with the attribute class="tabx" in the page and, say for j=1,...,m, performs the loops
for (var i = 0; i < nCo; i++)
{
Ca[i].style.backgroundColor="rgb(221,247,255)";
}
for (var i = nCo; i < nCa; i = i+nCo)
{
Ca[i].style.backgroundColor="rgb(221,247,255)";
}
on each of such tables?
Thanks, I couldn't find this in particular on this network with keywords search, and not even in documentation in italian that's plentyful as well...and I know it would take 2 seconds using CSS instead...
Here is how you do it.
var t1 = document.getElementsByClassName("tabx");
for(index = 0; index < t1.length; ++index)
{
var Ri = t1[index].getElementsByTagName("tr");
var Ca = t1[index].getElementsByTagName("td");
var nRi = Ri.length;
var nCa = Ca.length;
var nCo = nCa / nRi;
for (var i = 0; i < nCo; i++) {
Ca[i].style.backgroundColor = "rgb(221,247,255)";
}
for (var i = nCo; i < nCa; i = i + nCo) {
Ca[i].style.backgroundColor = "rgb(221,247,255)";
}
}
http://jsfiddle.net/a5F9b/1/
hope that help.

Randomly storing elements from an array into a table

I'm trying to create a simple memory matching game and I'm having trouble assigning one number to each table cell from my cardValues array. My giveCellValue function is supposed to generate a random number then pick that number from the array and give it to one of the table cells but I'm a little over my head on this one and having trouble accomplishing this task.
var countCells;
var cardValues = [];
var checker = true;
var createTable = function (col, row) {
$('table').empty();
for (i = 1; i <= col; i++) {
$('table').append($('<tr>'));
}
for (j = 1; j <= row; j++) {
$('tr').append($('<td>'));
}
countCells = row * col;
};
createTable(3, 6);
for (i = 1; i <= countCells / 2; i++) {
cardValues.push(i);
if (i === countCells / 2 && checker) {
checker = false;
i = 0;
}
}
var giveCellValue = function () {
var random = Math.ceil(Math.random() * cardValues.length) - 1;
for (i = 0; i <= cardValues.length; i++) {
$('td').append(cardValues[random]);
cardValues.splice(random, 1);
}
};
giveCellValue();
console.log(cardValues);
Use
var countCells;
var cardValues = [];
var checker = true;
var createTable = function (col, row) {
$('table').empty();
for (var i = 0; i < col; i++) {
$('table').append($('<tr>'));
}
for (var j = 0; j < row; j++) {
$('tr').append($('<td>'));
}
countCells = row * col;
};
createTable(3, 6);
for (i = 0; i < countCells; i++) {
cardValues.push(i % 9 + 1);
}
var giveCellValue = function () {
var len = cardValues.length, tds = $('td');
for (var i = 0; i < len; i++) {
var random = Math.floor(Math.random() * cardValues.length);
tds.eq(i).append(cardValues.splice(random, 1));
}
};
giveCellValue();
console.log(cardValues);
Demo: Fiddle
Leaving aside the problems that have already been mentioned in the comments above...
If I understand it right, you want to assign each of the numbers in cardValues to a random table cell?
Seems like the problem is with this line:
var random = Math.ceil(Math.random() * cardValues.length) - 1;
What this does is generates a random number once. If you access the variable random at a later time, you're not calling the full line of code again, you're just getting the same value that was calculated the first time. E.g. if the above code runs, spits out '7' as its random number and stores that in random, then every time you go through the for loop, the value of random will always be '7' rather than being re-generated every time - make sense?
Try putting the randomiser inside the for loop - that way it will be run multiple times, generating a new random number every time:
var giveCellValue = function () {
var random;
for (i = 0; i <= cardValues.length; i++) {
random = Math.ceil(Math.random() * cardValues.length) - 1;
$('td').append(cardValues[random]);
cardValues.splice(random, 1);
}
};
Actually, I'd change line 4 above to random = Math.floor(Math.random() * cardValues.length); too which should have the same effect.

Categories