Generating a random number that is divisible by 10 in JavaScript - javascript

I'm making a snake game and have hit a stop when generating the food coordinates.
I want a random number that is divisible by 10. By that I mean that it has to be a number mod(10) == 0. The snake is of width 10 so in order for the coordinates to match, I need numbers like 80, 130, 10, 40, 200
Only even numbers without singulars are allowed. This is my current code:
let width = 100;
let height = 100;
let x = Math.floor(Math.random()*width/2)*2;
let y = Math.floor(Math.random()*height/2)*2;
console.log(x + " : " + y);

Use 10 in your snippet then (instead of 2):
let width = 100;
let height = 100;
let x = Math.floor(Math.random()*width/10)*10+10;
let y = Math.floor(Math.random()*height/10)*10+10;
console.log(x + " : " + y);
added 10 to avoid 0, I guess that's what you mean on singular. If not, please clarify in the question
this way code generates 10 <= x <= width and 10 <= y <= height, where both x and y are integer multiples of 10.

You can generate a random multiple of 10 between 10 and 150 by first generating a random number between 1 and 15 and then multiplying it by 10. You can do this in plain JavaScript as follows:
var min = 1;
var max = 15;
console.log(Math.floor(Math.random() * (max - min + 1) + min) * 10);
Or, you can do it in a cryptographically secure way with rando.js like this:
console.log(rando(1, 15) * 10);
<script src="https://randojs.com/2.0.0.js"></script>

Related

Getting X and Y coordinates from tile ID

I'm stumped on what is probably some pretty simple math. I need to get the X and Y coordinates from each tiles referenced ID. The grid below shows the order the ids are generated in. Each tile has a width and height of 32. Number ones x & y would be equal to (0,0). This is for a game I'm starting to make with canvas using a tileset.
1|2|3
4|5|6
7|8|9
So far for X, I've come up with...
(n % 3) * 32 - 32 // 3 is the width of the source image divded by 32
And for Y...
(n / 3) * 32
This is obviously wrong, but It's the closest I've come, and I don't think I'm too far off from the actual formula.
Here is my actual code so far:
function startGame() {
const canvas = document.getElementById("rpg");
const ctx = canvas.getContext("2d");
const tileSet = new Image();
tileSet.src = "dungeon_tiles.png";
let map = {
cols: 10,
rows: 10,
tsize: 32,
getTileX: function(counter, tiles) {
return ((tiles[counter] - 1) % 64) * 32;
},
getTileY: function(counter, tiles) {
return ((tiles[counter] - 1) / 64) * 32;
}
};
let counter = 0;
tileSet.onload = function() {
for (let c = 0; c < map.cols; c++) {
for (let r = 0; r < map.rows; r++) {
let x = map.getTileX(counter, mapObj.layers[0].data); // mapObj.layers[0].data is the array of values
let y = map.getTileY(counter, mapObj.layers[0].data);
counter += 1;
ctx.drawImage(
tileSet, // image
x, // source x
y, // source y
map.tsize, // source width
map.tsize, // source height
r * map.tsize, // target x
c * map.tsize, // target y
map.tsize, // target width
map.tsize // target height
);
}
}
};
}
If 1 is (0,0) and each tile is 32*32, then finding your horizontal position is a simple 32*(t-1) where t is your tile number. t-1 because your tiles start from 1 instead of 0. Now, you have 3 tiles per row so you want to reset every 3, so the final formula for your x is 32*((t-1)%3).
For the vertical position it's almost the same, but you want to increase your position by 32 only once every 3 tiles, so this is your y: 32*floor((t-1)/3).
floor((t-1)/3) is simply integer division since the numbers are always positive.
If I understand this correctly, you want to get the 1|2|3 values based on x, y correct? You can do something like this:
((y * total # of rows) + x) + 1
This would convert the 2D x, y index to a single index which is, as you stated, 1|2|3. This formula is based on your example where count starts at 1 and not 0. If you want to convert it to 0 base, just remove the + 1.
If you have the width and height, or probably location of input/character, you can have a GetX(int posX) and GetY(int posY) to get the x and y based on the position. Once you have converted the position to x, y values, use the formula above.
int GetX(int posX)
{
return (posX / 32);
}
int GetY(int posY)
{
return (posY / 32);
}
int GetIndex(int posX, int posY)
{
return ((GetY(posY) / totalRows) + GetX(posX)) + 1;
}

Javascript logic get percentage of each number between two numbers

I have this progress bar in JS and I'm filling up progress by increasing its width using this code:
function move(ValueSC) {
var elem = document.getElementById("scaleOrig");
var width = 0;
var internalVlue = ValueSC;
var id = setInterval(frame(internalVlue), 50);
function frame(internalVlue) {
if (width >= internalVlue) {
clearInterval(id);
} else {
width += internalVlue;
elem.style.width = width + '%';
}
}
}
This works perfectly but the problem is that I will get a value (result) from my calculator which is something between numbers 15 to 40, so with this stated 15 will be 0% and 40 will 100%. I want the width of progress bar to go up to 100 percent if the result (from my calculator) is 40 and if it is 15 the value of progress bar should be 0%. Basically I need the logic to convert all the 25 numbers from 15 to 40 to have a percentage value between 0 to 100%.
As a broader answer, the formula you're looking for is ((value - min) / (max - min)) * 100. max and min are the bounds of your value and value is the current progress. This will return the percentage of the progress so far for any given value between two other values.
var percent = ((value - 15) / (40 - 15)) * 100
40 will give you 100 and 15 will give you 0
Before you call your method do this:
ValueSC= ((Max-Min)/100)*(Current-Min))
Where:
Current: Your value
Min = Minimum Value
Max = Max Value
First you have to divide up 100 to smaller steps. There can be 25 (40-15) different values for your number, so the length of a step should be 100 / 25, and your starting number is 15. Something like this should work:
function getPercentage(number) {
return (number - 15) * (100 / 25);
}

How to generate numbers within a range in a non random way with JavaScript?

I know how to generate a random number between two numbers. But what I'd like to achieve is a way to generate a number between two numbers in a not totally random way. Let me explain...
So I have a function that generates a color based on a number passed into it. If that number is between 0 and 600, I'd like it to pass a number between 0 and 120 to the hue of the hsl value. If the number is greater than 600, I'd like a number between 120 and 240 passed to the hue of the hsl value. My function looks something like this:
getColor:function (number {
var hue;
var color;
if (number <= 600) {
hue = [A number between 0 and 120];
} else if (number >= 600) {
hue = [A number between 120 and 240];
}
color = 'hsl(' + hue + ', 100%, 80%)'
return color;
}
So the higher the number passed into the function, for example, between 0 and 600, the higher the hue value between 0 and 120. That make sense?
Thx u
-- Gaweyne
Simple Math:
hue = Math.floor(number * 120 / 600);
Or with both points:
function transpose(smin, smax, dmin, dmax) {
var slen = smax - smin;
var dlen = dmax - dmin;
var ratio = dlen / slen;
return function(num) {
return num * ratio + smin;
}
}
transpose(0, 600, 0, 120)(300); // 60
Ok first of all you should know the maximum and minimum values of number. In my example The maximum value of number will be 1200 and the minimum 0, so the range is between 0 and 1200. And the range of hue is between 0 and 240.
the higher the number passed into the function, the higher the hue value.
0 hue = 0 number;
120 hue = 600 number;
240 hue = 1200 number;
=> 1 hue = (600 / 120) number = (1200 / 240) number
=> 1 hue = 5 number
In my example, (with number between 0 and 1200 and 600 is the middle) 1 value in hue is equal to 5 value in number. So :
hue = number / 5;
if you want hue to be an integer just use Math :
hue = Math.floor(number / 5);
In my example hue will grow up by 1 every time you add 5 to number, it doesn't matter if number is less or more than 600 because the range of number on both sides of 600 is the same (600 is in the middle of the range). In case this is not what you want, and 600 is not in the middle of the range, you will have to do the same calculation above twice.
var max = [maximum value of number];
var min = [minimum value of number];
getColor:function (number {
var hue;
var color;
if (number <= 600) {
hue = Math.floor( number / ((600 - min) / 120) );
} else if (number >= 600) {
hue = Math.floor( number / ((max - 600) / 120) ) + 120;
}
color = 'hsl(' + hue + ', 100%, 80%)';
return color;
}

Weighted Random Number Generator in Javascript

I am using the following code to generate a random number:
function getRandomInt (min, max) {
return Math.floor((Math.random() * (max - min + 1)) + min;
}
What I want to do is add a weighting that favours the numbers at the lower end of the range.
I thought about maybe trying to multiply the numbers by 1/cosine.
Would this work and does anyone know how I might go about it?
Many thanks!
First Solution
You need a function which contains the points (0, 0) and (1, 1). For instance: x^n when n > 0
Math.pow(1, n) === 1
And
Math.pow(0, n) === 0
Therefore, you would just change n depending on how you want the weighting to work.
When n = 1 : y === x
When n > 1 : y <= x
When 0 < n < 1 : y >= x
So, if you want lower values to be favored over higher values, simply use n > 1.
var weighted = Math.pow(Math.random(), 2);
Then you can scale the result as usual.
var scaled = Math.floor(weighted * (max - min + 1)) + min;
Other Functions
Likewise, you could use any continuous function which contains the points (0, 0), (1, 1), and has range and domain of [0, 1].
Sine
y = sin(xπ/2)
Cosine
y = 1 - cos(xπ/2)
EDIT: there was a type in the final formula, log(2+log(x)) is incorrect it should have been log(1+log(x))+1, its fixed now.
If you are using logarithmic weighting, using something like
var x = Math.random();
var weighted = x * Math.log(1+x);
would make 0.5 weigh in at around 0.2, but 1 would only weigh in at around 0.69.
Using this
var x = Math.random();
var weighted = x * Math.log(2 + Math.log(x));
would allow 1 to weigh in at 1. So combine them, and this
var x = Math.random();
var weighted = (x <= 0.5) ? x * Math.log(1 + x) : x * Math.log(1 + Math.log(x))+1;
should do the trick

context.strokeText using for

I am trying to get an amount of numbers on my canvas. My code is being repeated using eventhandlers on my timer.
For every 5 seconds that pass, I want to add another number on my canvas. It is used for a flowing timeline underneath my graph.
The forloop itself works fine, but every time it runs, it overwrites the current stroked-text.
Here is the for;
pos = (time * (360 / 60) - 360); // calculate position in graph
var t = new Array(); // array of numbers
var x = new Array(); // array of xPos
var y = new Array(); // array of yPos
// new time number, position + distance to next number for each 5 seconds + compensation(60), yPos
for (var i = 0 ; i < add / 5; i++) { // add / 5 is the count of numbers to add
t[i] = add + 35;
x[i] = -pos + (30 * (add / 5) + 60); // positions the number 30px next to the number before it.
y[i] = 330;
}
for (var i = 0; i < t.length; i++) {
ctx.strokeText(t[i], x[i], y[i]); // draws the number
}
//this line here gives back the exact same result as the code above.
//ctx.strokeText((add + 35).toString(), -pos + (30 * (add / 5) + 60), 330);
I can't call new on ctx... and this just overwrites the old stroke..
It is currently live here:
http://worms.azurewebsites.net/#
If you press the play-button you'll see the blue bar move to 30, from here on the numbers should be moving to the left. This is somewhat working(shocking start) but if you wait a couple of seconds you can see the new numbers appearing and disappearing.
I just can't figure out a way to add an extra number to the canvas..
x[i] = -pos + (30 * (add / 5) + 60); // positions the number 30px next to the number before
This calculation can't be right -- it doesn't depend on i (or any other variable that changes during the course of the loop) at all, so you're just drawing the same thing in the same place add / 5 times over. Same for t[i] in the line above it. Maybe you mean something like this?
t[i] = add + 35 + 30 * i; // Just guessing here on how i and t relate...
x[i] = -pos + (30 * i + 60);

Categories

Resources