Finding a path using multi-dimensional arrays in js - javascript

I have an x-y grid stored in a multi-dimensional array. Each point in the x-y grid has a value.
Example:
var xy = [
[0,3,1,1,0],
[0,0,2,2,1],
[0,0,1,1,0]
];
Assuming the layout of var xy is like an x-y grid (x 1 and y 2 would be 3 for example.
Here's a larger 'print-out' of such a variable, with greater height and width:
(1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)
(1) 0 0 0 1 1 1 2 2 1 1 0 0 0
(2) 0 0 1 1 1 2 2 3 2 2 1 0 0
(3) 0 0 0 1 2 2 3 3 2 1 0 0 0
(4) 0 4 0 1 1 1 2 2 1 0 0 0 8
(5) 0 0 0 0 0 0 1 1 0 0 0 0 4
(6) 0 0 0 0 9 9 9 0 0 0 0 0 0
(7) 0 0 0 0 9 9 0 0 0 0 0 0 0
Now, for the sake of example, pretend that the above layout were a map, like a chessboard. For starters, to pay no attention to the VALUES of each point on the grid, let's say we want to know which squares a 'game piece' could reach from, say, x4 y8....we could do something like this in js:
var n = ,//total # of items in grid
a = ,//a certain point on the grid
r = 5; //range of movement
for(var i = 0; i < n; i++){ //this would be a double for or something similar to go through the grid properly, but let's pretend i is a given point on the grid.
Math.abs(((a.xLocation + a.yLocation) - (i.xLocation + i.yLocation)) <= r) //if the positive difference between the current point in the loop and the location of the certain point is less than or equal to the range....true!
}
So in the rough example above a thing at point A can move 5 steps, diagonally, vertically, horizontally, whatever. We don't know the direction, just the potential for movement.
That's pretty easy to figure out. The part I'm still trying to get my head around is this: How do you know whether a thing at point a can reach point i based on the VALUES of the grid. 0 means no augmentation, but 1 or 2 takes 1 or 2 or whatever EXTRA the movement to get to.....how do you figure that out for EACH point on the map? Again, no knowing which direction or path - whether it will be optimal or not.
CLARIFICATION: Imagine a chessboard. Each square chessboard has a value that represents how many EXTRA movement points it takes to get there. A given piece, not at all using chess rules, can move, let's say, 5 'movement points' in any direction. Many squares have a value of 0, thus it requires no further expenditure of movement points. But a square of 1 would require 2 total movement points, 2 would require 3 total, etc. Really, you could just as easily add 1 to all the squares below to find out whether a piece in a neighboring square could move there. However you like. I'm just looking for some kind of forumula or suggestion that can derive an answer. Here, look at this much simpler example.
(1) (2) (3)
(1) 0 1 3
(2) 1 X 2
(3) 2 0 1
Think of it like a game, where each square represents some kind of terrain disadvantage. Some paths are easier than others, but others are more direct. You can take any path to get to a certain square, but before the move, which squares are legal and which are not? So our piece is on X2 Y2, right? He has 5 movement points. He wants to know which ones he can move to. Well, he can move to any of them. But X1Y1 will cost 1 movement point, X1Y2 will cost 2, X1Y3 will cost 4, etc etc etc. Easy to figure out. but if the board is larger, and each potential (unknown) movement takes points, which squares can he move to and which can't he? Does this make sense?
EDIT 2: A slightly more complex example:
(1) (2) (3) (4) (5)
(1) 0 1 3 0 0
(2) 1 X 2 1 0
(3) 2 0 1 0 0
(4) 1 0 0 1 3
(5) 0 0 0 0 4
So our piece in this example is in X2Y2 again, but he wants to know, for each square, if he can make it there - boolean, yes or no. It's easy with just nine squares, but as the grid grows, so does the complexity. I can do it manually of course - can he reach X4Y4? Yes. But programmatically, how do I get this?
EDIT3: The size of the grid is meaningless, I just realized. It's really the size of the range. E.g., if the range of movement is 5, I just need to figure out the viability of squares five squares out in each direction. So that simplifies it a bit.
EDIT4: I think I have a little better of an idea. Look at the outermost ring 5 out. Is it greater than 0? Then no. Next outermost ring (4 out). Greater than 1? No. Next outermost ring. Greater than 2? Then no. Etc. Will that work or could that lead to incorrect results?
Answers (or even just leads in the right direction) in js or jQuery preferred, but even if you can kind of work through the logic, I can translate that into js or jquery.

I think what you want to do is a basic kind of search, where on each iteration you check the surrounding squares. I've come up with a mockup example with this jsfiddle. Open the console, click run, and it should print out the example map and the places it can get to in 3 steps from (2, 2).
There's some extra code in there for setup, but the main code is the search_rec function:
function search_rec(
map, // The input 'difficulty' map
output, // The output map (puts '1's in spots that can be reached)
// Should be the same size as the input map
x, y, // The current/starting position
limit) { // The number of spaces you are allowed to move
// If the number of spaces allowed to move is negative, then we can't
// reach this position, so we stop
if (limit < 0) {
return;
}
// Otherwise, if the limit is >= 0, then we can make it here and we
// store that in the output
output[y][x] = 1;
// Now, for each of the four directions
// Check if we're at a map boundary
if (x > 0) {
// If we're not, then we recurse, moving our starting point in
// the given direction, and lowering our limit by 1 (for the
// base movement) as well as the 'difficulty' of the terrain of
// the space we're moving into
search_rec(map, output, x - 1, y,
// ^ change position
limit - 1 - map[y][x - 1]);
// lower limit ^ by the base ^ and the difficulty ^
}
if (x < map[0].length - 1) {
search_rec(map, output, x + 1, y, limit - map[y][x + 1] - 1);
}
if (y > 0) {
search_rec(map, output, x, y - 1, limit - map[y - 1][x] - 1);
}
if (y < map.length - 1) {
search_rec(map, output, x, y + 1, limit - map[y + 1][x] - 1);
}
}
Hopefully that logic makes sense, and it's actually solving the problem you wanted solved.

Related

js, if number is divisible and not decimal

I'm working on a code that counts the meters some dogs have travelled. It's just a gif constantly in loop. Now I wanted to show an image every 50 meters for like 3 seconds.
That's how I have tried it:
if (i % Number.isInteger(50)) {
document.getElementById("orange").style.display = "block";
}
That's how I've tried it but it doesn't work.
Can someone help me with that?
Thanks!
You can use FLOOR:
let frames = Math.floor(i / 50)
That will be 0 until 1==50, then it'll be 1 until i==100.
So 1234 steps will give you 24 frames played.
Then you have to decide how many images you have, lets say 5 images:
let currentImageIndex = itterations % 5;
That'll make it it go 0,1,2,3,4,0,...
That means in our example: 24%5 = 4, display the 5th image (because 0 is the first, that makes 4 the fifth image).
document.getElementById("my-image").src = `frame${currentImageIndex}.png`;
If the person would take a few steps more, 1251 steps, divided by 50 = 25 frames, modulo 5 -> currentImageIndex==0.
Note: this is untested, but should give you something to build off of
Note: Your current solution isnt working because Number.isInteger(50) always returns true because 50 is an integer. It doesnt convert anything, it just tests of it is an integer.

Fastest way to read large collection of objects

I need to store a large collection of small objects (chord diagrams) that will not change. It is a javascript project.
I have two questions:
how should I store these objects? As json, as text,... ?
what's the fastest way to find a specific item?
I search the item by it's key + type + "/" + bass:
Example: I get Am7/C# and I need to find the corresponding diagram. The key would be the file.
For now it's using only one file and search it with regex:
"{define: C frets x 3 2 0 1 0 fingers 0 3 2 0 1 0}",
"{define: C(add9) frets x 3 2 0 3 0 fingers 0 2 1 0 3 0}",
I will have 90 000 chords that I can split in 12 files (one for each key).
My object can look like this:
{type="m" bass="" frets="x 3 1 0 1 3" fingers="0 3 1 0 2 4" variation="1"}
I read a bit about binary search but I don't know if this can help me.
Thanks!

I have 4 different color health bars stacked on top of each other and need pseudo code to make them work together [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have 4 health bars stacked on top of each other each a different color
I want the top health bar to represent 50% of the players health
and to shrink from 1 to 0 based on the current health,
reaching zero when the health is at 50%
So 100 health would be 100 percent of the first bar,
75 health would be 50% of the first bar
and 50 health would be 0 percent of the first bar.
Then the second bar I would like to represent 30% of the players health
and start where the 50% ends.
Third bar going down after 80% of the health is gone and representing 15% of the total health and finally the
fourth bar representing 5% of the total health starting when 95% of the health is gone.
I cant even get the first bar to represent 50% of the players health and go down to 0 when the player reaches 50% health so if anyone would even know what the pseudo code for that would be I'd greatly appreciate it
Hope this question isn't too poorly written out and that I don't waste anyone's time.. I've just been working on this for a few hours now and getting no where.
I know how to make a single health bar representing 1 to 0 as Healthlength = FullLength/ FullHP * CurrentHP but that isn't getting me anywhere
example
FullLength = 1; //0 is completely slide to the left
FullHP = 100 //for example
CurrentHP = 50
this would returen HealthLength as .5 or half.
That about covers everything I can think to include in my question, I hope someone can help.
Thank you for your time.
Note: I included javascript and c# because those are the only two languages I kinda know and I don't see a pseudo code option
To generalise an answer to this, I'll work through how I made the formula to calculate a bar's length. The length will be a float from 0 - 1.
To calculate the bar's length, you need 3 values
The bar's maximum value: barMaximum
The bar's minimum value: barMinimum
The player's current health
To begin with, lets imagine the second from top bar (shown in blue). It has a barMinimum of 20, and a range of 30 (To get the range, subtract the minimum from the maximum).
What the formula will do is move and scale the blue bar's range to fit in our desired range (in this case 0 - 1).
Picture the (poorly drawn) number line below:
We see the blue bar ranges from 20 to 50, and our desired range is from 0 to 1. This blue bar represents the range of values that the player's health could be. The first thing we want to do is move it to our desired range.
We know the distance from the start of the blue bar the start of our desired range, as it is just the blue bar's minimum value (in this case its 20). So to move the blue bar to the start of our desired range, we need to move it left 20 spaces. And to move it left 20 spaces, we need to subtract 20 from it.
Don't forget that this bar simply represents the range of values that health could be, which is why I have named the variable movedHealth. To put this action into code, we could say:
movedHealth = health - 20;
And to generalise this (so it can be used for any bar) we could say:
movedHealth = health - barMinimum;
Okay, so now we have moved the blue bar into the correct place. Now we need to scale it so it fits within our desired range. As we are scaling, we can assume that we will need to use multiplying or dividing for our next move. But how can we find out what we need to multiply/divide by?
What we can do is look at a few examples of where we know our blue bar (which now represents movedHealth) will move.
We know that if movedHealth is half way through our blue bar (in this case 15), we want it to be half way through our desired range (which is 0.5). Another example: if movedHealth is at the moved bar's maximum (30 in this case), we want it to be at our desired range's maximum (which is 1).
Lets use the latter example to help us calculate our scale. We can use some simple algebra to figure out what to do here. We know that our moved bar's maximum value is 30, and our desired range's is 1. So the moved bar's maximum is 30 times our desired range's maximum
moved bar's maximum = desired range's maximum * 30
We can then generalise this for any value:
moved bar = desired range * 30
So this means that if we wanted to scale up a value from our desired range (0 - 1) to our moved bar, we would multiply it by 30. Therefore, if we wanted to scale down a value from our moved bar to our desired range, we would divide it by 30:
desired range = moved bar / 30
This can be visualised on our number line:
To re-iterate, to scale a value from our moved bar (0 - 30 here) to our desired range (0 - 1), we divide it by 30. This means that we can replace the "moved bar" part of our equation with movedHealth, since the bar is just representing the values movedHealth could be:
desired range = movedHealth / 30
And now that we have scaled down our movedHealth to our desired range, we can replace "desired range" with scaledHealth, since we have scaled down its possible values to the range of 0 to 1.
scaledHealth = movedHealth / 30;
Now we have this equation for this specific example, lets generalise it to fit any bar. The only part we need to change is the 30. This 30 came from the bar's maximum value after being moved. If we look at the diagram below we can not only see the progression of the blue bar, but also the links between certain aspects.
For example the fact that moved bar's maximum value, is equal to its range. This is because:
original bar's maximum = 50
original bar's minimum = 30
original bar's range = original bar's maximum - original bar's minimum
= 50 - 20
= 30
And when we look at how we calculated the moved bar's maximum value, we subtracted 20 (the original bar's minimum) from the original bar's maximum value. When visualise this in an equation we see:
moved bar's maximum = original bar's maximum - original bar's minimum
Which is identical to how we calculate the original bar's range. So because of this, we can now replace the "30" in our scaledHealth equation:
So
scaledHealth = movedHealth / 30;
becomes
scaledHealth = movedHealth / barRange;
And since scaledHealth is actually the length of the bar (from 0 - 1) we should probably replace it with a more fitting name, such as barLength. So:
barLength = movedHealth / barRange;
Now lets put all our code in one place:
movedHealth = health - barMinimum;
barRange = barMaximum - barMinimum;
scaledHealth = movedHealth / barRange;
To put this into one equation, we can first substitute any reference of movedHealth with (health - barMinimum), so we get:
barRange = barMaximum - barMinimum;
scaledHealth = (health - barMinimum) / barRange;
And now we can substitute any reference of barRange for (barMaximum - barMinimum), so we get:
barLength = (health - barMinimum) / (barMaximum - barMinimum);
And don't forget that this doesn't account for values of health which are outside of the bar's range. So to counteract this, we could do something like this:
Math.max(0, Math.min(1, barLength));
So now we can write a function, using this new found equation:
var health = 35; // can be ANY value, just put 35 as an example
var barMinimum = 20; // replace with whatever the current bar's minimum is
var barMaximum = 50; // again, replace with the bar's maximum
function calculateBarLength(health, barMinimum, barMaximum) {
return Math.max(0, Math.min(1, (health - barMinimum) / (barMaximum - barMinimum)));
}
var barLength = calculateBarLength(health, barMinimum, barMaximum);
console.log(barLength);
// outputs 0.5
Vuala!
This is very similar to scaling a number between to ranges. For example this post.

How does CHIP 8 graphics rendered on screen?

Opcode DXYN:
Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels. Each row of 8 pixels is read as bit-coded (with the most significant bit of each byte displayed on the left) starting from memory location I; I value doesn't change after the execution of this instruction. As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn't happen.
Basically I have an array called graphics which is a double array constructed out of 64 rows of new arrays per each with 32 columns.
//Creating new double arrays for storing graphics data
graphics = new Array(GFX_WIDTH);
for(var i = 0; i < graphics .length; i++){
graphics [i] = new Array(GFX_HEIGHT);
for(var j = 0; j < graphics [i].length; j++){
graphics [i][j] = 0;
}
}
and inside these arrays, I am storing graphics data as described above. My question is, do I just have to draw a square when an array element is 1 and empty that space when it's 0? According to a blog article on CHIP8, there is an extra array for font-set but what's the usage of it?
The blog article I have mentioned above
http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/
Thank you.
First of all, note that the pixels are bitpacked - each byte will contain 8 pixels of sprite data. In other words, the byte 0xAA is a single-pixel tall sprite with the first, third, fifth and seventh pixel set.
When drawing your sprite, you need to loop through each bit. If the bit is set, you flip the corresponding bit in your display - 0 becomes 1 and 1 becomes 0. This can, for example, be done by applying the XOR (^) operation to your display byte.
Note, however, that VF must be set to 1 if any pixels go from 1 to 0 in the process, and 0 if no pixels are unset - so you also need to do this. I find it is easiest to read if you have an if that checks whether or not to flip a bit, and then take care of both flipping and VF-updating inside that if.
For reference, my own Delphi implementation of this opcode looks like this:
procedure TChip8CPU.OpcodeD(inst: TInstruction);
var
X, Y, cX, cY, data: byte;
begin
Reg[$F] := 0;
for Y := 0 to inst.NibbleArg - 1 do begin
cY := (Reg[inst.Y] + Y) mod HEIGHT;
data := Memory[AddressI + Y];
for X := 0 to 7 do begin
if (data and ($80 shr X)) <> 0 then begin
cX := (Reg[inst.X] + X) mod WIDTH;
if Display[cY, cX] = 1 then Reg[$F] := 1;
Display[cY, cX] := Display[cY, cX] xor 1;
end;
end;
end;
end;
Note that for sprites which go outside the screen boundaries, they wrap around (this is done by the mod WIDTH/mod HEIGHT parts). This is mentioned in Cowgod's Chip-8 Technical Reference.

Math: I need to normalize some bar graphs

I'm generating bar graphs. The range of data generating said graphs is very wide, which means some areas of the graph are always low, and some areas go off the chart.
What's the math to "normalize" this towards a certain number (e.g. 200), so large values are shrunk the larger they are, and smaller values are increased?
If you are talking about actually changing the data for display purposes, then there are a few basic approaches to bring values closer to a target value. The simplest is to just do a weighted average with that value: A' = (1-α)*A + α*B where alpha is a weight between 0 and 1, A is a number on your graph, and B is the target value.
For instance, if you were trying to 'normalize' to 200 and your numbers were 100 120 200 220 400 then plugging in each for A, 200 for B, and .5 for alpha, you would get 150 160 200 210 300
You can choose a different alpha to adjust how much you want to stretch the data towards the target value. Higher numbers like .9 will stretch the data more and lower numbers like .1 will stretch the data less.
I dont know if you are willing to read a little but I found the the scaling tutorial for d3.js framework (http://d3js.org/) is a very solid introduction to the scaling part of visualisation:
http://alignedleft.com/tutorials/d3/scales/
For a zero-based graph : compute the max of your value, then display for each bar :
barHeight[i] = (maxBarHeight*value[i])/maxVal;
If you want your graph to be based on the minimum value and not zero, you might still want the
graph to have a non-zero height for the bar near the min value. So compute the minimum value, and display :
barHeight[i] = minBarHeight +
(maxBarHeight - minBarHeight ) * (value[i] - minVal) / ( maxVal - minVal );
( Rq : if minVal is Zero or 'near' zero, set minVal = minBarHeigth = 0 and you have the first case )

Categories