Super noob question here. I have the code below from an as3 project below where frame numbers are randomized then clicking a sprite (next) will move to the next random frame. I am having trouble figuring out what else I need to do to convert it to javascript. Can anyone help me out or point me in the right direction? TIA!
var sortedNumbers:Array = [];
for(var i:int = 1; i < 21; i++)
{
sortedNumbers.push(i);
}
var unsortedNumbers:Array = sortedNumbers.slice();
while(sortedNumbers.join() == unsortedNumbers.join())
{
unsortedNumbers.sort(function (a:int, b:int):int { return Math.random() > .5 ? -1 : 1; });
}
this.start.addEventListener("click", f_nextRE.bind(this));
function f_nextRE() {
if(index == 20) {
gotoAndStop (22);
}
else {
gotoAndStop (unsortedNumbers [index] + 1);
index +=1;
}
}
So it took me a few days but I found my answer (a combination of several sources many on this site)... Posting it here to help others...
//create array
var shuffledFrames = [];
//fill array
for (var i = 1; i <= 35; i++) {
shuffledFrames.push(i);
}
//shuffle array
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
}
//run shuffle function
shuffle(shuffledFrames);
//function to call next random frame then repeat when reaching the end.
function f_next()
{
if (shown == 1){
if (nextF == 35) {
nextF = 0;
}
else {
nextF += 1;
}
this.gotoAndStop (shuffledFrames [nextF]);
}
}
Related
I am making tetris in JS. When making a block fall, it makes the block reach the bottom of the screen in one draw instead of slowly approaching the bottom. I tried creating a variable that stores the changes to be made so that it only looks at the current board, but no luck. After checking whether the output variable is == to the board, it seems like the board is changing after all, as it returns true. What's going on?
EDIT: I have successfully made a shallow copy of the array. It still falls to the bottom immediately, though. What's going on?
var data = [];
function array(x, text) {
var y = [];
for (var i = 0; i < x-1; i++) {y.push(text);}
return y;
}
for (var i=0; i<20; i++){data.push(array(10, "b"));}
function draw(){
var j;
var i;
var dataOut = [...data];
for (i = 0; i < data.length - 1; i++){
for (j = 0; j < data[i].length; j++){
if (data[i][j] == "a" && data[i + 1][j] == "b" && i < data.length - 1) {
dataOut[i][j] = "b";
dataOut[i + 1][j] = "a";
}
}
}
data = dataOut;
}
data[0][4] = 'a';
draw();
console.log(data);
In JavaScript, Arrays and Objects are passed by reference. So when you do this:
var dataOut = data;
Both of these references point to the same Array. You could clone the Array every time:
var dataOut = JSON.parse(JSON.stringify(data));
Or simply revert your loop, to go from the bottom to the top. I took the liberty of renaming the variables to make this more clear. Try it below:
var chars = {empty: '.', block: '#'},
grid = createEmptyGrid(10, 20);
function createEmptyGrid(width, height) {
var result = [], x, y;
for (y = 0; y < height; y++) {
var row = [];
for (x = 0; x < width; x++) {
row.push(chars.empty);
}
result.push(row);
}
return result;
}
function draw() {
var x, y;
for (y = grid.length - 1; y > 0; y--) {
for (x = 0; x < grid[y].length; x++) {
if (grid[y][x] === chars.empty && grid[y - 1][x] === chars.block) {
grid[y][x] = chars.block;
grid[y - 1][x] = chars.empty;
}
}
}
}
// Just for the demo
var t = 0, loop = setInterval(function () {
draw();
if (grid[0].includes(chars.block)) {
clearInterval(loop);
grid[9] = 'GAME OVER!'.split('');
}
document.body.innerHTML = '<pre style="font-size:.6em">'
+ grid.map(row => row.join(' ')).join('\n')
+ '</pre>';
if (t % 20 === 0) {
grid[0][Math.floor(Math.random() * 10)] = chars.block;
}
t++;
}, 20);
I'm currently developing the Battleship game in Javascript, however, everytime a run the code there's a Cannot read property '4' of undefined error.
I've searched everywhere for an answer but couldn't find any. I've also tried console.log to see what it's undefined, which I think it's my variable tab which is the board of the game, but I can't find a solution do make it not undefined.
Here's the code where I create the board:
var tab = [];
for (var i=0; i<dim; i++) {
tab.push([]);
for(var j=0; j<dim; j++) {
tab[i].push(0);
}
}
generateships(tab, dim, 1, 4);
generateships(tab, dim, 2, 3);
generateships(tab, dim, 3, 2);
generateships(tab, dim, 4, 1);
On the last part of the code I call the function that checks if it's okay to insert a boat in that position. It requires tab, dim which is the dimension of the board, for example 10, the number of ships and finally the boat's length.
function generateships(tab, dim, numbships, boatlen) {
for (var i = 0; i < numbships; i++) {
var empty = false;
while (!empty) {
var direction = Math.floor(Math.random() * 2);
if (direction === 1) {
var X = Math.floor(Math.random() * (dim - boatlen));
var Y = Math.floor(Math.random() * dim);
for (var i = 0; i < dim; i++) {
if (tab[X][Y + i] == 0) {
empty = true;
} else {
empty = false;
}
}
} else {
var X = Math.floor(Math.random() * dim);
var Y = Math.floor(Math.random() * (dim - boatlen));
for (var k = 0; k < dim; k++) {
if (tab[X + k][Y] == 0) {
empty = true;
} else {
empty = false;
}
}
}
}
shiplocations(numbships, boatlen, direction, X, Y);
}
}
The last function I call is the fucntion that inserts a ship on a specific location. It requires the number of ships, the boat's length, their direction and the coordinates.
function shiplocations(numbships, boatlen, direction, X, Y) {
for (var k = 0; k < numbships; k++) {
for (var i = 0; i < boatlen; i++) {
if (direction === 1) {
tab[X][Y + i] = boatlen;
} else if (direction != 1) {
tab[X + i][Y] = boatlen;
}
}
}
}
I'd really appreciate youre help, thank you.
I haven't debugged your code, but this sounds like an index vs count problem. When you have four items and you loop through them, the indexes are 0, 1, 2, 3 for items 1, 2, 3, & 4. Most likely you are trying to reference item nbr 4 but it's going to be at index 3 (the 4th index). There will be nothing at index 4 (undefined). Try starting your loops at i = 1 instead of i = 0 or better yet start your items at zero instead of 1.
I was looking for an answer for a question from Project Euler and I found one here
http://www.mathblog.dk/triangle-number-with-more-than-500-divisors/
int number = 0;
int i = 1;
while(NumberOfDivisors(number) < 500){
number += i;
i++;
}
private int NumberOfDivisors(int number) {
int nod = 0;
int sqrt = (int) Math.Sqrt(number);
for(int i = 1; i<= sqrt; i++){
if(number % i == 0){
nod += 2;
}
}
//Correction if the number is a perfect square
if (sqrt * sqrt == number) {
nod--;
}
return nod;
}
So I tried to implement the same solution in Javascript but it doesn't give me the same result.
var number = 0;
var i = 1;
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.sqrt(num);
for (i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
I tested the other code in C# and it gives the right solution. I was wondering if I made a mistake or whether they work differently in some aspect I'm unaware of.
The problem is that you are testing non-triangle numbers because you forgot one important thing ... scope ...
for (i = 1; i <= sqr; i++) {
screws your (global) value of i ...
see in c# you have
for(int i = 1; i<= sqrt; i++){
^^^
give javascript the same courtesy and try
for (var i = 1; i <= sqr; i++) {
^^^
you should also get the square root as an integer, otherwise you'll be one off in most counts
var sqr = Math.floor(Math.sqrt(num));
i.e.
var number = 0;
var i = 1;
console.time('took');
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.timeEnd('took');
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.floor(Math.sqrt(num));
for (var i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
(added some timing info for fun)
I'm creating an animation to show how a pattern matching algorithm works. Right now I have the full animation running from start to end when the sort button is pressed.
I am trying to implement a 'forward step' button (and also a 'back step' button) which when pressed will compare the pattern at the first position and then will compare it at the second position when it is pressed again etc. I'm unsure how I could implement this if it is even possible.
function kmp(p,t){
var k=0, j=0, result;
var fail=[];
var next=[];
var shifts = 0, comparisons = 0;
var boxWidth = $('#text_array .panel').outerWidth(true);
var places;
var previousMove = 0;
var totalMoves = 0;
kmpSetup(p, fail, next);
xx = setInterval(function () {
if(t[j] == p[k]) {
turnGreen('#p', k);
for(n=0; n<k; n++) {
turnGreen('#p', n);
}
turnGreenWhite('#t', j);
k = k+1;
j = j+1;
} else if(k==0) {
j++;
} else {
turnRed('#p', k);
turnRed('#t', j);
for (var m = 0; m < p.length; m++) {
turnWhite('#p', m);
}
turnWhite('#t', j);
var position = k;
k = next[k];
//calculating how many places to shift the pattern
// depending on the value in the table
if (k == -1) {
places = position + 1;
totalMoves+=places;
animatePattern(boxWidth, totalMoves, result);
k = k+1;
} else {
places = position - k;
totalMoves+=places;
animatePattern(boxWidth, totalMoves, result);
}
if(j>=t.length && k>=p.length) {
clearInterval(xx);
}
}
}, 1000);
if(k>=p.length){
result='match found';//match found
} else {
result='match not found';//no match found
}
return result;
}
jsfiddle
While working on problem 3 of Project Euler, I'm coming across a problem I can't seem to fix where javascript keeps freezing. Here's my code:
var is_prime = function(n) {
if (n === 1) {
return true;
}
if (n === 2) {
return true;
}
var list1 = []
for (i = 2; i < n; i++) {
list1.push(i);
}
for (i = 2; i < list1.length; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}
var list_of_primes = function(n) {
var list1 = [];
var list2 = [];
for (i = 2; i < n; i++) {
list1.push(i);
}
for (i = 2; i < list1.length; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
return list2;
}
confirm(list_of_primes(1000))
I know my algorithm isn't the most efficient and that I'm just brute forcing the problem, but I'm just wondering what it is I'm doing wrong. I'm pretty sure the problem lies somewhere within this block of code:
for (i = 2; i < list1.length; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
I think a potential problem is that my algorithm is taking too long and that is what is causing javascript to freeze. Is there anyway to get my problem to run long enough to give me the answer?
You could try this.
var is_prime = function(n) {
if (n == 1) {
return true;
}
if (n == 2) {
return true;
}
for (var i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
var list_of_primes = function(n) {
var list2 = [];
for (var i = 2; i < n; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
return list2;
}
confirm(list_of_primes(1000))
Working fine in less than seconds. https://jsfiddle.net/LL85rxv5/
A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
Strictly speaking, 1 is not a prime number so be sure to update that in your code.
Not really sure why your code is timing out, it's just a bit longhand and has an unnecessary array (list1). Anyway, here's a pretty shortened version of the code that comes up with a list of prime numbers from 2 to n.
This isn't too efficient for a large number set because it checks every number individually.
var list_of_primes = function(n) {
var list = [];
for (i = 2; i < n; i++) {
if (is_prime(i)) {
list.push(i);
}
}
return list;
}
function is_prime(i) {
for (var c = 2; c <= Math.sqrt(i); ++c)
if (i % c === 0)
return false;
return true;
}
If you want a bit more efficiency, look into the Sieve of Eratosthenes which can handle much larger sets:
// Credit: http://stackoverflow.com/a/15471749/1265817
var eratosthenes = function(n) {
// Eratosthenes algorithm to find all primes under n
var array = [], upperLimit = Math.sqrt(n), output = [];
// Make an array from 2 to (n - 1)
for (var i = 0; i < n; i++) {
array.push(true);
}
// Remove multiples of primes starting from 2, 3, 5,...
for (var i = 2; i <= upperLimit; i++) {
if (array[i]) {
for (var j = i * i; j < n; j += i) {
array[j] = false;
}
}
}
// All array[i] set to true are primes
for (var i = 2; i < n; i++) {
if(array[i]) {
output.push(i);
}
}
return output;
};
Working examples: https://jsfiddle.net/daCrosby/wfgq28no/
i is a global variable within is_prime function, which interferes with instance used in list_of_primes function. Fix by declaring i as local like this...
var is_prime = function(n) {
var i; // <~~ declare i as local variable here
if (n === 1) {