JavaScript syntax issue - javascript

I'm doing "fifteen puzzle" game. I'm only a beginner, so I chose this project to implement. My problem is shuffle algorithm :
function shuffle() {
$('td').empty();
var p = 0;
var f = 0;
do {
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var rand = arr[Math.floor(Math.random() * arr.length)];
if ($('#' + rand).is(':empty')) {
p = p + 1;
document.getElementById(rand).textContent = p
var f = $('td').not(":empty").length;
} else {}
} while (f < 15)
That works cool, but I've heard that almost 50% of all random shuffle like mine is unsolvable. So I found math formula at wikipedia.org for this game, explaining how you can avoid that.
Here's modified algorithm that doesn't work either. The way I know it is alert stuff: it launches only 2 times instead of 31.
array = [];
function algorithm (){
// alert('works')
for (var c=16; c<17; c++){
document.getElementById(c).textContent = '100';
}
for (var i=1; i<16; i++){
var curId = document.getElementById(i).id;
var curIdNum = Math.floor(curId);
alert('works')
var curIn = document.getElementById(i).textContent;
var curInNum = Math.floor(curIn);
array.push(i);
array[i] = new Array();
for (var j=1; j<15; j++){
var nextId = curIdNum + j; //curIdNum NOT cerIdNum
var nextIn = document.getElementById(nextId).textContent;
//alert('works')
if (nextId < 16){
var nextInNum = Math.floor(nextIn);
if (curInNum > nextInNum){
array[i].push(j)
}
}
}
var sum = 0;
for (var a=0; a<15; a++){
var add = array[a].length;
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){
document.getElementById('16').textContent = "";
}
else {
shuffle();
}
}
}
The question is the same:
What's wrong? Two-dimensional array doesn't work.If you've got any questions - ask.
Just to make it clear: 2 for loops with i and j should make a 2-dimensional array like this [ this is " var i" -->[1,3,4,5,7], this is "var i" too-->[5,7,9,14,15]]. Inside each i there's j. The for loop with var a should count the number of js inside each i. if the number of js is even, the code is finished and shuffle's accomplished, otherwise shuffle should be made once again.

var nextId = cerIdNum + j;
in that fiddle, I don't see this cerIdNum declared & defined neither as local nor as global variable, I suppose that is curIdNum

Please use the below definition of algorithm and let us know if this works. Basically, the alert messages would come only twice, since there were usages of undefined variables. For the purpose of illustration, I have placed comments at where the problem points occured. Due to these problems, your script would stop executing abruptly thereby resulting in the behavior you described.
Oh and by the way - I did not have time to go through the Wiki link provided - hence you will have to verify your logic is correct. However, I have definitely resolved the errors causing the behavior you observed.
As an aside - consider using jQuery, your code will be a lot cleaner...
function algorithm (){
// alert('works')
for (var c=16; c<17; c++){
document.getElementById(c).textContent = '100';
}
for (var i=1; i<16; i++){
var curId = document.getElementById(i).id;
var curIdNum = Math.floor(curId);
alert('works')
var curIn = document.getElementById(i).textContent;
var curInNum = Math.floor(curIn);
array.push(i);
for (var j=1; j<15; j++){
var nextId = curIdNum + j; //curIdNum NOT cerIdNum
var nextIn = document.getElementById(nextId).textContent;
//alert('works')
if (nextId < 16){
var nextInNum = Math.floor(nextIn);
if (curInNum > nextInNum){
array.push(j) //array[i].push does not make sense
}
}
}
var sum = 0;
for (var a=0; a<15; a++){
var add = array.length; //array[1].length does not make sense
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){
document.getElementById('16').textContent = "";
}
else {
shuffle();
}
}
}

I found the solution by totally rewriting the code. Thank everyone for help!
Here's what do work:
function shuffle (){
press = 1;
$('td').empty().removeClass();
p=0;
var f;
do {
var arr=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var rand=arr[Math.floor(Math.random()*arr.length)];
if ($('#'+ rand).is(':empty')){
p = p + 1;
document.getElementById(rand).textContent = p
var f = $('td').not(":empty").length;
}
else{}
}while(f < 15){
winChance();
}
}
function winChance (){
array = [];
for (i=1;i<16;i++){
array[i]= new Array();
var currentId = $('#' + i).attr('id');
var currentIn = $('#' + i).html()
var currentIdNum = parseInt(currentId, 10);
var currentInNum = parseInt(currentIn, 10);
for (j=1;j<16;j++){
var nextId = currentIdNum + j;
if (nextId < 16){
var nextIn = $('#' + nextId).html();
var nextInNum = parseInt(nextIn, 10);
if (currentInNum > nextInNum){
array[i].push(j);
}
}
}
}
checkSum();
}
function checkSum(){
var sum = 0;
for (var a=1; a<16; a++){
var add = array[a].length;
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){}
else {
shuffle();
}
}

Related

JavaScript: how to loop by adding the values of variables with 1, 2, 3, ... at the end?

I'm a beginning JavaScript user. I'd like to calculate a score of 15 questions from a program.
What I need:
I put the value I received to JSq1, JSq2, etc. then I add them up and divided by total question and round up a score. I can lay everything in many lines but that does not look efficient. I'm trying to figure out a way to use loop to get all the same result.
Please help.
THANKS
<script language = "JavaScript">
// the following may work
var JSq1 =Varq1score.getValue();
var JSq2 =Varq2score.getValue();
var JSq3 =Varq3score.getValue();
var JSq4 =Varq4score.getValue();
var JSq5 =Varq5score.getValue();
var JSq6 =Varq6score.getValue();
var JSq7 =Varq7score.getValue();
var JSq8 =Varq8score.getValue();
var JSq9 =Varq9score.getValue();
var JSq10 =Varq10score.getValue();
var JSq11 =Varq11score.getValue();
var JSq12 =Varq12score.getValue();
var JSq13 =Varq13score.getValue();
var JSq14 =Varq14score.getValue();
var JSq15 =Varq15score.getValue();
var totalScore = JSq1 + JSq2 + JSq3 + ...
var totalQuestion = 15
var finalScore = parseFloat(totalScore/totalQuestion*100).toFixed(0);
// I'd like to do the following but don't know how to specify JSq1, JSq2, etc in a loop so I don't have to repeat the lines so many times.
var totalQ = 15;
for (i = 0; i <= totalQ ; i++) {
var JSq+[i] = "Varq"+ i + "score.getValue()";
}
for (i = 0; i <= totalQ ; i++) {
var totalScore = totalScore + JSq + [i];
}
...
</script>
1) Build an object all_vars with all the variable. (Here with object shorthand property, { JSq1 } will be equivalent to { JSq1: Varq1score.getValue() }
2) Use Object.values to get values of above object in an array.
3) Use any loop (in this case we are using reduce) to build total score dynamically.
With these slight changes to your current code, you can achieve the result. Check the following sample code.
var JSq1 = 3;
var JSq2 = 3;
var JSq3 = 3;
var JSq4 = 3;
var JSq5 = 3;
var JSq6 = 3;
var JSq7 = 3;
var JSq8 = 3;
var JSq9 = 3;
var JSq10 = 3;
var JSq11 = 3;
var JSq12 = 3;
var JSq13 = 3;
var JSq14 = 3;
var JSq15 = 3;
var all_vars = {
JSq1,
JSq2,
JSq3,
JSq4,
JSq5,
JSq6,
JSq7,
JSq8,
JSq9,
JSq10,
JSq11,
JSq12,
JSq13,
JSq14,
JSq15
};
var totalScore = Object.values(all_vars).reduce((sum, jsq) => sum + jsq, 0);
var totalQuestion = 15;
var finalScore = parseFloat((totalScore / totalQuestion) * 100).toFixed(0);
console.log(finalScore)

Javascript syntax issue in code

Can someone tell me why this bit of JavaScript is buggy?
I have HTML also, but I don't want to make this a massive code dump.
<script type = 'text/javascript'>
var playerCards = [];
var dealerCards = [];
function deal() {
var newCard = Math.random() % 12;
var newCard2 = Math.random() % 12;
playerCards += newCard;
playerCards += newCard2;
var counter = 0;
for (var i = 0; i < playerCards.length; ++i) {
counter += i;
}
document.getElementById("playerTotal").innerHTML = counter;
var dCounter = 0;
for (var j = 0; j < playerCards.length; ++j) {
dCounter += j;
}
document.getElementById("dealerTotal").innerHTML = dCounter;
}
</script>
I'm gonna assume this is a silly syntax error someplace, but I can't find it.
I'm guessing that this isn't doing what you expect it to:
playerCards += newCard;
playerCards += newCard2;
Try this instead:
playerCards.push(newCard);
playerCards.push(newCard2);
The first snippet is trying to "add" a number to an array, which doesn't exactly make sense. Through some arcane JavaScript rules, this turns the result into a string.
I'm guessing that you want to concatenate to an array instead.
Math.random returns a number between 0 and 1 - so Math.random() % 12 will probably be zero
var playerCards = [];
playerCards += newCard; //
what are you even trying to do there?
var counter = 0;
for (var i = 0; i < playerCards.length; ++i) {
counter += i;
}
if playerCards had a length, this loop would result in counter having value of 0, 1, 3, 6, 10 .. n(n+1) / 2 - probably not what you intended, but who knows

"Look and say sequence" in javascript

1
11
12
1121
122111
112213
122211
....
I was trying to solve this problem. It goes like this.
I need to check the former line and write: the number and how many time it was repeated.
ex. 1 -> 1(number)1(time)
var antsArr = [[1]];
var n = 10;
for (var row = 1; row < n; row++) {
var lastCheckedNumber = 0;
var count = 1;
antsArr[row] = [];
for (var col = 0; col < antsArr[row-1].length; col++) {
if (lastCheckedNumber == 0) {
lastCheckedNumber = 1;
antsArr[row].push(lastCheckedNumber);
} else {
if (antsArr[row-1][col] == lastCheckedNumber) {
count++;
} else {
lastCheckedNumber = antsArr[row-1][col];
}
}
}
antsArr[row].push(count);
antsArr[row].push(lastCheckedNumber);
}
for (var i = 0; i < antsArr.length; i++) {
console.log(antsArr[i]);
}
I have been on this since 2 days ago.
It it so hard to solve by myself. I know it is really basic code to you guys.
But still if someone who has a really warm heart help me out, I will be so happy! :>
Try this:
JSFiddle Sample
function lookAndSay(seq){
var prev = seq[0];
var freq = 0;
var output = [];
seq.forEach(function(s){
if (s==prev){
freq++;
}
else{
output.push(prev);
output.push(freq);
prev = s;
freq = 1;
}
});
output.push(prev);
output.push(freq);
console.log(output);
return output;
}
// Sample: try on the first 11 sequences
var seq = [1];
for (var n=0; n<11; n++){
seq = lookAndSay(seq);
}
Quick explanation
The input sequence is a simple array containing all numbers in the sequence. The function iterates through the element in the sequence, count the frequency of the current occurring number. When it encounters a new number, it pushes the previously occurring number along with the frequency to the output.
Keep the iteration goes until it reaches the end, make sure the last occurring number and the frequency are added to the output and that's it.
I am not sure if this is right,as i didnt know about this sequence before.Please check and let me know if it works.
var hh=0;
function ls(j,j1)
{
var l1=j.length;
var fer=j.split('');
var str='';
var counter=1;
for(var t=0;t<fer.length;t++)
{
if(fer[t]==fer[t+1])
{
counter++;
}
else
{
str=str+""+""+fer[t]+counter;
counter=1;
}
}
console.log(str);
while(hh<5) //REPLACE THE NUMBER HERE TO CHANGE NUMBER OF COUNTS!
{
hh++;
//console.log(hh);
ls(str);
}
}
ls("1");
You can check out the working solution for in this fiddle here
You can solve this by splitting your logic into different modules.
So primarily you have 2 tasks -
For a give sequence of numbers(say [1,1,2]), you need to find the frequency distribution - something like - [1,2,2,1] which is the main logic.
Keep generating new distribution lists until a given number(say n).
So split them into 2 different functions and test them independently.
For task 1, code would look something like this -
/*
This takes an input [1,1,2] and return is freq - [1,2,2,1]
*/
function find_num_freq(arr){
var freq_list = [];
var val = arr[0];
var freq = 1;
for(i=1; i<arr.length; i++){
var curr_val = arr[i];
if(curr_val === val){
freq += 1;
}else{
//Add the values to the freq_list
freq_list.push([val, freq]);
val = curr_val;
freq = 1;
}
}
freq_list.push([val, freq]);
return freq_list;
}
For task 2, it keeps calling the above function for each line of results.
It's code would look something like this -
function look_n_say(n){
//Starting number
var seed = 1;
var antsArr = [[seed]];
for(var i = 0; i < n; i++){
var content = antsArr[i];
var freq_list = find_num_freq(content);
//freq_list give an array of [[ele, freq],[ele,freq]...]
//Flatten so that it's of the form - [ele,freq,ele,freq]
var freq_list_flat = flatten_list(freq_list);
antsArr.push(freq_list_flat);
}
return antsArr;
}
/**
This is used for flattening a list.
Eg - [[1],[1,1],[1,2]] => [1,1,1,1,2]
basically removes only first level nesting
**/
function flatten_list(li){
var flat_li = [];
li.forEach(
function(val){
for(ind in val){
flat_li.push(val[ind]);
}
}
);
return flat_li;
}
The output of this for the first 10 n values -
OUTPUT
n = 1:
[[1],[1,1]]
n = 2:
[[1],[1,1],[1,2]]
n = 3:
[[1],[1,1],[1,2],[1,1,2,1]]
n = 4:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1]]
n = 5:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3]]
n = 6:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1]]
n = 7:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1]]
n = 8:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3]]
n = 9:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3],[1,1,2,2,1,1,3,1,1,3,2,1,1,1,3,1,1,2,3,1]]

For Loops inside For Loops inside For Loops... = Problems

So. I have 4 for loops inside other for loops in JS, and my code appears (FireBug agrees with me) that my code is syntactically sound, and yet it refuses to work. I'm attempting to calculate the key length in a vigenere cipher through the use of the Index of Coincidence, and Kappa tests <- if that helps any.
My main problem is that the task seems to be too computationally intensive for Javascript to run, as Firefox shoots up past 1GB of memory usage, and 99% CPU when I attempt to run the keylengthfinder() function. Any ideas of how to solve this problem, even if it takes much longer to calculate, would be greatly appreciated. Here's a link to the same code - http://pastebin.com/uYPBuZZz - Sorry about any indenting issues in this code. I'm having issues putting it on the page correctly.
function indexofcoincidence(text){
text = text.split(" ").join("").toUpperCase();
var textL = text.length;
var hashtable = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (d=0; d<=25; d++) {
for (i=0; i < textL; i++){
if (text.charAt(i) === alphabet.charAt(d)){
hashtable[d] = hashtable[d] + 1;
}
}
}
var aa = hashtable[0]/textL;
var A = aa*aa;
var bb = hashtable[1]/textL;
var B = bb*bb;
var cc = hashtable[2]/textL;
var C = cc*cc;
var dd = hashtable[3]/textL;
var D = dd*dd;
var ee = hashtable[4]/textL;
var E = ee*ee;
var ff = hashtable[5]/textL;
var F = ff*ff;
var gg = hashtable[6]/textL;
var G = gg*gg;
var hh = hashtable[7]/textL;
var H = hh*hh;
var ii = hashtable[8]/textL;
var I = ii*ii;
var jj = hashtable[9]/textL;
var J = jj*jj;
var kk = hashtable[10]/textL;
var K = kk*kk;
var ll = hashtable[11]/textL;
var L = ll*ll;
var mm = hashtable[12]/textL;
var M = mm*mm;
var nn = hashtable[13]/textL;
var N = nn*nn;
var oo = hashtable[14]/textL;
var O = oo*oo;
var pp = hashtable[15]/textL;
var P = pp*pp;
var qq = hashtable[16]/textL;
var Q = qq*qq;
var rr = hashtable[17]/textL;
var R = rr*rr;
var ss = hashtable[18]/textL;
var S = ss*ss;
var tt = hashtable[19]/textL;
var T = tt*tt;
var uu = hashtable[20]/textL;
var U = uu*uu;
var vv = hashtable[21]/textL;
var V = vv*vv;
var ww = hashtable[22]/textL;
var W = ww*ww;
var xx = hashtable[23]/textL;
var X = xx*xx;
var yy = hashtable[24]/textL;
var Y = yy*yy;
var zz = hashtable[25]/textL;
var Z = zz*zz;
var Kappa = A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z;
var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
}
function keylengthfinder(text){
// Average Function Definition
Array.prototype.avg = function() {
var av = 0;
var cnt = 0;
var len = this.length;
for (var i = 0; i < len; i++) {
var e = +this[i];
if(!e && this[i] !== 0 && this[i] !== '0') e--;
if (this[i] == e) {av += e; cnt++;}
}
return av/cnt;
}
// Begin the Key Length Finding
var textL = text.length;
var hashtable = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
for (a = 0; a <= 12; a++){ // This is the main loop, testing each key length
var stringtable = [];
for (z = 0; z <= a; z++){ // This allows each setting, ie. 1st, 4th, 7th AND 2nd, 5th, 8th to be tested
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
}
hashtable[a] = stringtable.avg();
}
return hashtable;
}
Your problem is definitely right here
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
Notice that if a=0 i never changes and therefore you are in an infinite loop.
Array.prototype.avg = function() {...}
should be only done once, and not every time keylengthfinder is called.
var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
Why do you computer those variables if you don't use them at all?
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
I don't know what you are trying to do in here. The string will always be only one character?
for (i = z; i < textL; i + a) {
...
stringtable[z] = ...
}
In this loop, you are computing values for i from z to textL - but you overwrite the same array item each time. So it would be enough to compute the stringtable[z] for i=textL-1 - or your algorithm is flawed.
A much shorter and more concise variant of the indexofcoincidence function:
function indexofcoincidence(text){
var l = text.replace(/ /g, "").length;
text = text.toUpperCase().replace(/[^A-Z]/g, "");
var hashtable = {};
for (var i=0; i<l; i++) {
var c = text.charAt(i);
hashtable[c] = (hashtable[c] || 0) + 1;
}
var kappa = 0;
for (var c in hashtable)
kappa += hashtable[c] * hashtable[c];
return kappa/(l*l)/0.0385;
}
All right. Now that we found your problem (including the infinite loop in case a=0, as detected by qw3n), let's rewrite the loop:
function keylengthfinder(text) {
var length = text.length,
probabilities = []; // probability by key length
maxkeylen = 13; // it might make more sense to determine this in relation to length
for (var a = 1; a <= maxkeylen; a++) { // testing each key length
var stringtable = Array(a); // strings to check with this gap
// read "a" as stringtable.length
for (var z = 0; z < a; z++) {
var string = '';
for (var i = z; i < textL; i += a) {
string += text.charAt(i);
}
// a string consisting of z, z+a, z+2a, z+3a, ... -th letters
stringtable[z] = string;
}
var sum = 0;
// summing up the coincidence indizes for current stringtable
for (var i=0; i<a; i++) {
sum += indexofcoincidence(stringtable[i]);
}
probabilities[a] = sum / a; // average
}
return probabilities;
}
Every of the loop statements has changed against your original script!
Never forget to declare the running variable to be local (var keyword)
a needs to start at zero - a key must have a minimum length of 1
to run from 1 to n, use i=1; i<=n; i++
to run from 0 to n-1, use i=0; i<n; i++ (nearly all loops, especially on zero-based array indizes).
Other loops than those two never occur in normal programs. You should get suspicious if you have loops from 0 to n or from 1 to n-1...
The update expression needs to update the running variable. i++ is a shortcut for i+=1 is a shortcut for i=i+1. Your expression, i + a, did not assign the new value (apart from the a=0 problem)!

Javascript/Dom loading images in to grid

I'm pretty new to programming and javascript/dom. Ultimately, I'm trying to make a sliding puzzle game but to start off with, I'm just trying to get the images loading up in a random order. It's going to be a 4x4 grid of images. The images are named Tree00, 01, 02, 03, 10, etc up to 33. Here's my code so far:
<html>
<head>
<title>Shuffle</title>
</head>
<body>
<script language="JavaScript">
<!--
Pics = new Array();
var Top = 16;
for(i = 0; i < Top; i++) {
document.write("<img><img><img><img><br>");
}
function RandomInt(Min, Max) {
RI = Math.floor(Math.random() * (Max - Min + 1)) + Min;
return(RI);
}
function Shuffle() {
N = RandomInt(0, 1);
this.Image.src=Pics[N];
this.Image.style.left = 220;
}
function ViewerObj(Image, Pics, i) {
this.Image = Image;
this.Image.style.left = 800;
this.Pics = Pics;
this.Shuffle = Shuffle;
this.Image.id = "ID" + i;
}
function Randomise() {
var i;
for(i = 0; i < Top; i++) {
Viewers[i].Shuffle();
Viewers[i].Image.style.left = 200;
}
}
Viewers = new Array();
var i;
for(i = 0; i < 3; i++) {
Pics[i] = "images/Tree" + (i) + (i + 1) + ".jpg";
}
for(i = 0; i < Top; i++) {
document.images[i].src = "images/Blank.jpg";
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>
I just can't quite fathom what I need to be changing and how I'd go about it. Any help + explanation would be much appreciated. What I am trying to achieve is it loading every image but just in a random order, but with no duplicates.
Here are a few problems in your script :
first replace
for(i = 0; i < Top; i++) {
document.write("<img><img><img><img><br>");
}
by
for(i = 0; i < Top; i++) {
document.write("<img>");
if ((i+1)%4 == 0) {
document.write("<br>");
}
}
you will get only 16 IMG elements instead of 4*16 in your code
then you will need 16 different names for your images : replace
for(i = 0; i < 3; i++) {
Pics[i] = "images/Tree" + (i) + (i + 1) + ".jpg";
}
by
for(var i = 0; i < 4; i++) {
for(var j = 0; j < 4; j++) {
Pics[j+4*i] = "images/Tree" + (i) + (j) + ".jpg";
}
}
Then you biggest problem is the shuffling. You cannot shuffle the "Viewers" one-by-one because you want to avoid duplicates. Each viewer must randomly select a unique image.
For this you can use the technique in mdarwi's answer : shuffle the Pics table for instance.
check your modified code on jsbin here
If your problem is simply that you'd like the images to be properly shuffled, you can use the following code (taken directly from the Javascript sample code for the Fisher-Yates shuffle on Wikipedia:
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;
}
The easiest thing to do would be to rename your images Tree1 to TreeN, and then place N integers in an array and shuffle them using the above algorithm.
(This is a code-comment, not an answer)
Pics = new Array();
The Pics variable should be declared before using. Also, use the shorthand notation []
var Pics = [];
var Top = 16;
for (i = 0; i < Top; i++) {
document.write("<img><img><img><img><br>");
}
The i variable is declared only later in the code. It should be declared at the top of the program.
function RandomInt(Min, Max) {
RI = Math.floor(Math.random() * (Max - Min + 1)) + Min;
return (RI);
}
This is particularly dangerous: the RI variable is not declared inside the function, so it becomes an implicit global property. That should be avoided. Also, the parens in the return statement are superfluous.
function RandomInt(Min, Max) {
return Math.floor(Math.random() * (Max - Min + 1)) + Min;
}
function Shuffle() {
N = RandomInt(0, 1);
this.Image.src = Pics[N];
this.Image.style.left = 220;
}
Again, the N variable should be declared. Also, why is this "method" declared outside of the ViewerObj constructor? Either, put it inside, or - even better - add it to the constructors prototype object. That way, there will only be one Shuffle function object instead of many.
function ViewerObj(Image, Pics, i) {
this.Image = Image;
this.Image.style.left = 800;
this.Pics = Pics;
this.Shuffle = Shuffle;
this.Image.id = "ID" + i;
}
function Randomise() {
var i;
for (i = 0; i < Top; i++) {
Viewers[i].Shuffle();
Viewers[i].Image.style.left = 200;
}
}
Viewers = new Array();
var i;
As mentioned above, the i variable should be declared on top. Also, the Viewers variable should be declared.
var Viewers = [];
for (i = 0; i < 3; i++) {
Pics[i] = "images/Tree" + (i) + (i + 1) + ".jpg";
}
for (i = 0; i < Top; i++) {
document.images[i].src = "images/Blank.jpg";
document.images[i].style.left = 300;
Viewers[i] = new ViewerObj(document.images[i], Pics, i);
}

Categories

Resources