How to store the numbers for the 2048 game - javascript

I have been trying to implement the game 2048.
I can add numbers in random positions of the grid and I can also slide them to a side, as that is what the console.log shows me.
But somehow I am not able to maintain that effect of a slide. Whenever I call key again, the rows are like there was no effect of the previous slides.
function slide(row) {
arr = row.filter(e => e);
let missing = 4 - arr.length;
let zeros = Array(missing).fill(0);
arr = arr.concat(zeros);
console.log(arr);
return arr;
}
function key() {
for (let i = 0; i < 4; i++) {
slide(grid[i]);
}
addNumber();
}

The problem is that you do not modify the row that the function receives as argument. Instead you create a new array, which you return. But then the caller does not process the return value.
Instead of:
for (let i = 0; i < 4; i++) {
slide(grid[i])
}
do:
for (let i = 0; i < 4; i++) {
grid[i] = slide(grid[i])
}
Now your grid will actually stay in sync with what the slide function does.

Related

Create array with function javascript

I need to create function that creates and returns array. Its size needs to match the rows parameter, and each next element contains consecutive integers starting at 1. To call this function I need to use argument 5. Here below is what I wrote so far. Can you tell me what's wrong here?
function createArray(rows) {
for(let i = 1; i < rows.length; i++) {
console.log(rows[i]);
}return rows;
}
createArray(5);
You need to create an array and return it, whereas you return just rows which is a number. The idea of using a for loop is the best way to go. In that loop you just need to set the values in the array accordinlgy.
Another problem in your code is that rows is of type number and does have a property length but that does not have the desired value. So we just use rows in the for loop. We start the loop with i = 0 because array indices start at 0.
Code
function createArray(rows) {
let arr = new Array(rows);
for (let i = 0; i < rows; i++) {
arr[i] = i + 1;
}
return arr;
}
console.log(createArray(5));
We can not use length property for number. create an empty array and then push values into that array until required size is achieved.
function createArray(rows) {
var arr = [];
for(let i = 1; i <= rows; i++) {
arr.push(i);
}return arr;
}
createArray(5);
I think what you want is createArray(5) return [1,2,3,4,5] if that's the case you could do this
function createArray(rows) {
const arr = []
for(let i = 1; i <= rows; i++) {
arr.push(i);
}
return arr;
}
console.log(createArray(5));
The problem is, that rows.length is not available on 5, because 5 is a number.
You have to use an array as parameter:
Array(5) creates an array with the length of 5 and fill("hello") fills this array with "hello" values.
function createArray(rows) {
for (let i = 1; i < rows.length; i++) {
console.log(rows[i]);
}
return rows;
}
const rows = Array(5).fill("hello");
createArray(rows);
I don't know, if this is the behaviour you want, if not, I misunderstood your question.

Is there any leak in my code, Only 1 case isn't working I don't know why?

I am trying to write a programme to move all the zeroes at the end of the array and retain and the original order of other elements.
Here is my code:-
var moveZeros = function (arr) {
// TODO: Program me
var k=0;
for (var i=0;i<=arr.length-1;i++){
var s=arr[i];
if (s===0){
arr.splice(i,1);
k++
}
}
for (var j=0;j<=k-1;j++){
arr.push(0);
}
return arr
}
But when zeros are next to each other like [1,0,0,1] it doesn't work.
I don't see why.
Can anybody tell?
And please also explain why k-1 not k I wrote k-1 by observing the output.
Please don't tell the answer to the original problem I just want to fix the problem with my code. :)
The problem is that in each loop you increase the i variable by one. Meaning, you go to the next index. But if you have 2 or more zeros in the row, and you remove the first one, you shouldn't change i to i + 1, because i already points at a new value in the array(which is zero) :)
var moveZeros = function (arr) {
// TODO: Program me
var k = 0;
for (var i = 0; i <= arr.length - 1;) {
var s = arr[i];
if (s === 0) {
arr.splice(i, 1);
k++;
} else {
i++;
}
}
for (var j = 0; j <= k - 1; j++) {
arr.push(0);
}
return arr;
};
console.log(moveZeros([1,0,0,2]));

using for loop in quick sort in Js

i am writing quick sort algorthm, and when i testing my code, the result makes me confused.
RangeError: Maximum call stack size exceeded
at Array.push ()
let arr = [0,-1,1,0,1,-1,100,23,17,56,39,47,23,-34,-56];
export default function quickSort(array){
let len = array.length;
if(len <= 1) return array;
let piviot = array.pop();
let left = [], right = [];
for (let i = 0; i < len; i++) {
if(array[i] < piviot){
left.push(array[i]);
}
else{
right.push(array[i])
}
}
return quickSort(left).concat(piviot,quickSort(right));
}
when i change for loop to forEach, problem is disappeared, but i don't know why.
export default function quickSort(array){
let len = array.length;
if(len <= 1) return array;
let piviot = array.pop();
let left = [], right = [];
array.forEach(item => {
if(item < piviot){
left.push(item)
}
else{
right.push(item);
}
});
return quickSort(left).concat(piviot,quickSort(right));
}
Thanks.
This will work as piviot = array.pop(); changes array size which causes the issue
export default function quickSort(array){
let len = array.length;
if(len <= 1) return array;
let piviot = array.pop();
len = array.length;
let left = [], right = [];
for (let i = 0; i < len; i++) {
if(array[i] < piviot){
left.push(array[i]);
}
else{
right.push(array[i])
}
}
return quickSort(left).concat(piviot,quickSort(right));
}
I won't write the quicksort algorithm for you, but I will explain the behavior:
Why the first piece of code overflows stack
This is very common in recursive functions that never end. You are never reaching the magic
if(len <= 1) return array;
All your function calls end up on the call stack. There is a limit depending on the browser on how many can be called on the stack at the same time. Thus when you reach that limit with recursion (and not only) you overflow the stack.
Why for each works
It doesn't, it just won't overflow your stack. Why? Foreach is a callback. It won't run first and then go to the next line.
Using foreach, you are effectively calling the next recursion with empty arrays and they return automatically.

Why this reverse function isn't working?

Why isn't this working?
ps. I don't want to use any other variable to make it work, and i don't want to use built in functions, just asking why THIS is not working?
function reverse(arr){
for(var i =0; i< arr.length; i++){
arr.push(arr[arr.length-i]);
}
return arr;
}
There are a lot of flaws in your code.
When you start pushing arr.push(arr[arr.length-i]); the array length increases, thereby, you won't get a consistency in the data.
This goes inside an infinite loop, as every time, the arr is ahead of its length.
It is better to use another variable and reverse, or you can use the built-in reverse() function. There's nothing wrong in having another variable and add temporary contents in it.
Solutions:
Using a temporary array:
function reverse(arr) {
var final = [];
for (var i = arr.length - 1; i >= 0; i--) {
final.push(arr[i]);
}
return final;
}
Using built-in function (Array.prototype.reverse()):
function reverse(arr) {
return arr.reverse();
}
Using few temporary variables:
a = [5,4,3,2,1];
function reverse(arr) {
var i = 0, j = arr.length - 1;
for (i = 0; i < j; i++, j--) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return arr;
}
console.log(reverse(a));
You're going to run out of memory. What you're doing is adding what was initially the last element of that array infinitely to the end of your array. Every time that you call arr.push(...) you increase arr.length by one. Your for loop will never be able to finish because i will never be less than arr.length
I don't want to use any other variable to make it work, and i don't want to use built in functions
You cannot.
Use temporary array for result
function reverse(arr) {
var res = []
for (var i = arr.length - 1; i > -1; i--) {
res.push(arr[i]);
}
return res;
}

loop different arrays javascript

Hello there am trying to save news tweets into three different array which are dynamically created.
am finding trouble when i want to get the text from each one of those array and make another request to twitter.
news_tweets("reuters","1652541",3);
function news_tweets(query, user_id,count) {
news_array = [];
$.getJSON("https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=false&user_id=" + user_id + "&count="+count+
"&callback=?",
function (data) {
for (var i = 0; i < count; i++) {
var user = data[i].user.name;
var date = data[i].created_at;
var profile_img = data[i].user.profile_image_url;
var text = data[i].text;
var url = (data[i].entities.urls.length > 0 ? data[i].entities.urls[0].url : '');
news_array[i] = [{user:user,date:date,profile_img:profile_img,text:text,url:url}];
}
for (var i = 0; i < news_array.length; i++) {
for (var x=0; x<i.length; x++){
console.log(news_array[i][x].user);
}
}
});
}
It doesn't show anything on the console.log.
thanks for the help!!!!!
First, make sure that your count is smaller than the data array's length, otherwise this could lead to some undefined values:
for (var i = 0; i < count && i < data.length; i++) …
Then, why are you creating all those one-element-arrays in the news_array? Just use only objects.
This would solve your actual issue: You are looping wrong over those inner arrays. The correct code would be
for (var i = 0; i < news_array.length; i++) {
for (var x = 0; x < news_array[i].length; x++){
console.log(news_array[i][x].user);
}
}
Also, you should indent your code properly. You have some odd braces around, which don't make the code readable.
The problem is the x<i.length in the for loop near the end. i is a number, so it doesn't have a length. You probably meant x < news_array[i].length.
You may try the following:
Use the push method to append elements / data in your array new_array
Use only 1 loop for to display the user value on console
So your code will be something like this:
news_tweets("reuters","1652541",3);
function news_tweets(query, user_id,count) {
news_array = [];
$.getJSON("https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=false&user_id=" + user_id + "&count="+count+
"&callback=?",
function (data) {
for (var i = 0; i < count; i++) {
var user = data[i].user.name;
var date = data[i].created_at;
var profile_img = data[i].user.profile_image_url;
var text = data[i].text;
var url = (data[i].entities.urls.length > 0 ? data[i].entities.urls[0].url : '');
// Pushing your elements in your array, 1 by 1
news_array.push({user:user,date:date,profile_img:profile_img,text:text,url:url});
}
// Here you only need 1 loop!
for (var i = 0; i < news_array.length; i++) {
console.log(news_array[i][x].user);
}
});
}
First thing is i would loop the first one till data.length rather than count because its an api and it "might" or "might not" return all the data. So it will be fool proof to loop till data.length
And your problem is with i.length
for (var i = 0; i < news_array.length; i++) {
console.log(news_array[i].user);
}
this should work. not sure why you had to loop through a loop.

Categories

Resources