dice random value 1 to 10 and overthrow in Javascript - javascript

Hi I have code like this:
$('#Generator_Rzutow').click (function(){
var val1 = $('#rzucane').val();
var val2 = $('#zachowywane').val();
var zbior = [];
var limit = 10;
alert (val1);
alert (val2);
for (var i=0; i<val1;i++){
var wynik_rzutu = 1+Math.floor(Math.random()*10);
if (wynik_rzutu<limit){
zbior.push(wynik_rzutu);
} else {
limit = limit+10;
wynik_rzutu = wynik_rzutu+1+Math.floor(Math.random()*10);
if (wynik_rzutu<limit){
zbior.push(wynik_rzutu);
} else {
limit = limit+10;
wynik_rzutu = wynik_rzutu+1+Math.floor(Math.random()*10);
zbior.push(wynik_rzutu);
}
}
}
$('#wypisz').text (zbior);
});
My problem is that when it randoms '10' it sometimes add 10 to array, when it should randomize another time and ad it to prev value.
My second question is. How to get it to randomize another value and ad it to prev as long as it randomize 10. For ex: so it could get numer 74, when it randomize 7x10 and 4, and then it past it to array.
I know I should do it by while lop but I couldn`t get working solition, so instead I put 'if'

The first problem is that you don't reset your limit at each iteration. You start with limit 10, then when the first number larger than 10 is generated, the limit is increased to 20 and all subsequent numbers will be compared to 20 to see if they are added to the array or re-generated (and they will all be added to the array, since they are all smaller than 20).
As for your second problem, i think this piece of code behaves accordingly:
for (var i=0; i<val1;i++){
var wynik_rzutu = 0, limit = 0;
while (wynik_rzutu >= limit) {
wynik_rzutu += 1+Math.floor(Math.random()*10);
limit += 10;
}
zbior.push(wynik_rzutu);
}
You can also add a counter to prevent it from an infinite cycle (if Math.random() always returns 0.9 for example), but i doubt it is something you really require.

Related

Can't get stable result with copying random values from array to an object

So I'm in process of creating a bot for a tournament and I got stuck on the part where I want to split players in pairs for play-off-style tournament. I just want to take 2 random players, get them from an array and write it as a value to a key as a round id for an object. Also I should not use those players again in the pair, so need to delete them or smth.
Here's the code:
var users = inc.funcs.getDatabase() //Getting a raw array of users (using my func that's basically a simplified fs.readFileSync func)
var tournamentPairs = new Object() //Object initialization
var id = 1
for (var i = 0; i < 16; i = i + 2) {
var first = Math.floor(Math.random() * (users.length + 1)) //Randomizing 2 indexes
var second = Math.floor(Math.random() * (users.length + 1))
var player1 = client.users.get(users[first]) //Getting the players by id
var player2 = client.users.get(users[second])
tournamentPairs[id++] = [player1.id, player2.id] //Writing to the object
users.splice(first, 1) //Deleting user's indexes from the array to not use them anymore.
users.splice(second, 1)
}
console.log(tournamentPairs)
It works perfectly on the outside, but has a bad habit of duplicating users and I once could have a gamergod98 vs gamergod98 for example. I tried console.log this crap but it often get an error when trying to console.log player2 because it's undefined for some reason. If I try to print users[second] I get undefined though it never happened for the first player. So I tried different ways to prevent situations like this: first == second. Long story short it didn't help much.
I have 9 days 'till tournament starts, any ideas on how to improve this code?
You are getting undefined because you are going out of bounds of your users list. For a list of length the last element is list[length-1], but you are generating random numbers up to length.
To fix duplicate users, remove the first selected user from the list before selecting the second one (or for a less destructive approach, mark already selected users).
var id = 1
for (var i = 0; i < 16; i = i + 2) {
var first = Math.floor(Math.random() * users.length)
var player1 = client.users.get(users[first])
users.splice(first, 1)
var second = Math.floor(Math.random() * users.length)
var player2 = client.users.get(users[second])
users.splice(second, 1)
tournamentPairs[id++] = [player1.id, player2.id]
}
Create a collection of used indexes and then if first or second are in used indexes then continue
var usedIndices = [] ;
if (usedIndices.indexOf(first) >= 0 ||
usedIndices.indexOf(second) >= 0) {
continue;
} else {
usedIndices.push(first);
usedIndices.push(second);
}
Put the usedIndices variable before for loop and the if else block inside loop after second

Creating a Javascript function that returns random integers but with a specified distribution/"weight"

I have an array of values:
var my_arr = [/*all kinds of stuff*/]
I have a function that generates a random number, which I use as the index of an element in my_arr...
var RandomFromRange = function (min,max)
{
return Math.floor(Math.random()*(max-min+1)+min);
};
...so I could do stuff like this:
my_arr[RandomFromRange(0,my_arr.length)];
What I want to do is to designate certain elements within my_arr as having "priority", so that RandomFromRange returns 5, say, 25% of the time, returns 4, 14% of the time, and returns any other number...
(100 - 25 - 14)/(my_arr.length - 2)
...% of the time.
As I was doing my research, I came across several posts that describe similar problems, but their answers are not in Javascript, and I, alas, don't have enough math to understand their general principles. Any advice would be appreciated.
This may not be as exact as what you are looking for, but this certainly works. Basically this code returns a random number specified from the min and max like yours, but only after addressing the priority numbers based on the chance given.
First we gotta prioritize your priority numbers in the code. If there is no hit on your priority numbers, that is when we proceed to the normal RNG.
//priority = list of numbers as priority,
//chance = the percentage
//min and max are your parameters
var randomFromRange = function (min,max,priority,chance)
{
var val = null; //initialize value to return
for(var i = 0; i < priority.length; i++){ //loop through priority numbers
var roll = Math.floor(Math.random()*100); //roll the dice (outputs 0-100)
if(chance > roll){ ///check if the chance is greater than the roll output, if true, there's a hit. Less chance value means less likely that the chance value is greater than the roll output
val = priority[i]; //make the current number in the priority loop the value to return;
break; //if there's a hit, stop the loop.
}
else{
continue; //else, keep looping through the priority list
}
}
//if there is no hit to any priority numbers, return a number from the min and max range
if(val == null){
val = Math.floor(Math.random()*(max-min+1)+min);
}
//return the value and do whatever you want with it
return val;
};
document.getElementsByTagName('body')[0].onclick = function (){
console.log(randomFromRange(0,10,[20,30],50));
}
<!DOCTYPE html>
<html>
<body style='height: 1000px; width: 100%;'></body>
<script></script>
</html>
This code applies a single chance on all array of priority numbers. If you want individual chances for each number in the priority list, we gotta modify the structure and change parameters to a single array of objects that holds something like
var priorityList = [{num: 4, chance: 25},
{num: 5, chance: 12}]
etc

Create with javascript series of numbers increments starting with rounded number to the closest hundred

The goal is to generate a series beginning with a first number I input by rounding it to the first superior hundred (for example if number= 456, then first number in the series will be 500), then increment 200 by 200 until a number I give for example 2000.
For example if number I get is 758, and if i set limit_number to 2000 then i need to generate with javascript the following series and add it to the piece of code:
$('img').attr('data-stoppoints', '800,1000,1200, 1400, 1600,1800, 2000');
As you see the generated series of numbers need to be separated by commas.
So far my code is
var number = (screen.Width)
var rounded_number=Math.ceil(number/100)*100
$('img').attr('data-stoppoints', rounded_number,'<I don't know here what to write');
How to achieve this ?
Try calling this function as generateSeries(number) where you have written rounded_number, like so :
var number = (screen.Width)
$('img').attr('data-stoppoints',generateSeries(number));
The generateSeries function. (You'll need to add this code snippet to your JS. Adjust the variables limit and increment as desired) :
generateSeries = function(number) {
var limit = 2000;
var increment = 200;
var divisor = 100;
var nums = [];
var n = Math.ceil(number/divisor)*divisor;
for(;n<=limit;n=n+increment) {
nums.push(n);
}
return nums.join();
};
Input : 758
Outputs : "800,1000,1200,1400,1600,1800,2000"
You could use a helper function that produces an array of values (range):
function range(start, stop, step = 1, roundTo = 1) {
result = [];
for (var i = Math.ceil(start / roundTo) * roundTo; i < stop; i += step) {
result.push(i);
}
return result;
}
$('img').data('stoppoints', range(468, 1600, 200, 100).join(','));
// ^^^^ start,stop,step,round
console.log($('img').data('stoppoints'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img>
Note that jQuery has a data method that works well with data- attributes, so I would use that instead of attr.

Why is a bigger variable less than a smaller variable

Summary:
I have a code that takes words from a database, it puts it all in a box which has 3 by 3 text boxes (you can also expand instead of using 3 boxes, which I confirmed worked).
Inside the boxes, it takes the height of the words and sets that height to the height of the div holding the words, then places that height inside of a array. If a div is not there (no text), it places a 0.
Every 3rd time it does this, which is 1 row, it will check the height of the three in the row, and set the div above them as the biggest height, like so:
var tempN = 0; //Holds each number temporarily
var temp = []; //Holds all 9 box heights
for (var i = 0; i < Panels.length; i++) { //There are 9 panels
temp[i] = new Array(); //adding to array
if (document.getElementById('Column'+i+Id[Ten])!=null) {//Id[Ten] will be 3, 2, and 1, in a for loop
document.getElementById('Column'+i+Id[Ten]).style.height = document.getElementById('Text'+i+Id[Ten]).clientHeight+"px";
temp[i].push(document.getElementById('Column'+i+Id[Ten]).clientHeight); //puts number on table
} else {
temp[i].push(0); //since there is no panel, the height would be 0
}
if (i%3 == 2) { //every 3rd time
for (var x=2;x >= 0;x--) { //also could do (var x=0;x<3;x++)
alert(temp[i-x]+" is greater than "+tempN); //tells me what should work
if (tempN < temp[i-x]) { //also could do the other way around
tempN = temp[i-x]; //tempN will be the current biggest height
alert(tempN+' '+temp[i-x]); //just a show it went through if
document.getElementById('Row'+BoxRow+Id[Ten]).style.height = tempN + "px";
}
}
tempN = 0; //reset tempN for next 3 boxes
}
}
temp = []; //reset temp for next box
Now, the way my page is, temp will be:
temp = [0,158,0,0,158,0,0,50,0] when Id[Ten] is 3
temp = [0,50,0,0,0,0,0,0,0] when Id[Ten] is 2
temp = [284,50,50,50,50,50] when Id[Ten] is 1
The Problem:
when my code gets to Id[Ten] is 1, It will start by saying:
"284 is greater than 0"
which is planned, then I get:
"284 284"
which is also planned, then:
"50 is greater than 284"
Here is the problem: what came after that is what should have been skipped:
"50 50"
This tells me that the if statement I have passed True once it saw 284 < 50. I have done math at least more than once in my life, and I know 284 is a bigger number than 50. Due to this, my box has a smaller height than the text in it, and they overlap in an way uglier than me. I'm sure my code and I are having some kind of mid-life crisis, and would be great if someone can explain to me why my code is going through this rebellious stage.
This is caused because you are comparing string to string, when comparing string js verify only your alphabetical order.
You have to use parseInt in your variables.
This is the test I did in the chrome console.
var test1 = 50
var test2 = 200;
test1 > test2
false
--------
var test1 = "50"
var test2 = "200";
test1 > test2
true
parseInt(test1) > parseInt(test2)
false
Your code is comparing strings (alphabetical order):
"Zoo" > "Apple" // true
"50" > "284" // true
You need to compare numbers by using something like parseInt:
parseInt("50") > parseInt("284"); // false
var stringResult = "50" > "284"; // true
var intResult = parseInt("50") > parseInt("284"); // false
document.getElementById('strings').textContent = stringResult;
document.getElementById('ints').textContent = intResult;
<h3>Result of "50" > "284" =
<span id="strings"></span>
</h3>
<h3>
Result of parseInt("50") > parseInt("284") =
<span id="ints"></span>
</h3>
In javascript everything is an object.It does not has any type
It determines type by the way we declare it
Here you are comparing (tempN < temp[i-x])
tempN and temp[i-x] both are strings
you have to convert them to numbers and then compare
var number1=parseInt(tempN,10);
var number2=parseInt(temp[i-x],10);
console.log(number1<number2);
If you want to convert array of numbers to get sorted but not alphabetically you can do something like this
var numbers=[1,90,5,8];
numbers.sort(SortCompare);
function SortCompare(a,b){
return a-b;
}
Hope this helps

Code works on codeacademy's site, but won't work on coderbyte

I'm having problems with the code below, and it's really frustrating. The problem isn't seemingly the code itself: the program works just fine to find the second greatest and lowest numbers in an array, but only does so on the labs.codeacademy.com JavaScript environment thus far.
I went to Coderbyte.org to enter the correct code to pass the challenge. First, whenever I type, "input.sort(function(a,b){return (a-b);});" into coderbyte.org's site, it indents the remainder of the block from the middle of the page for some reason. This makes me think it could be the source of my problem.
When I cut and paste my code from codeacademy to coderbyte.org's website, it pastes with fine indentation, however it only returns a blank box instead of the second highest and lowest values still. My question: why does it work on one site, but not the other? I've been going nuts on this for two days: someone please help me?
function SecondGreatestLow(arr) {
input.sort(function(a,b){return (a-b);});
var input = arr;
var hashObject = {}
for (var i = input.length - 1; i >= 0; i--) {
var currentItem = input[i]; //WE LOOP THROUGH OUR NUMBER LIST
if (hashObject[currentItem] === true) {
input.splice(i, 1); //IF CURRENTITEM IS ALREADY IN HASHOBJECT, THEN DELETE THE COPY FOUND IN ARRAY AND MOVE ON TO NEXT NUMBER
}
hashObject[currentItem] = true; //IF CURRENTITEM IS NOT IN HASHOBJECT, ADD IT! THEN MOVE ON TO NEXT NUMBER.
}
//THE ARRAY HAS NOW BEEN "DE-DUPED":
//NEXT WE OUTPUT THE MAX AND MIN VALUES ACCORDING TO ARRAY SIZE
if (input.length >= 4) { //If 4+ chars, then remove the first two values to access the second by default
input.pop();
input.shift();
var min = Math.min.apply(null,input),
max = Math.max.apply(null,input);
return (max + " " + min);
} else {
var min2 = Math.min.apply(null,input),
max2 = Math.max.apply(null,input);
return max2 + " " + min2;
}
}
//example:
console.log(SecondGreatestLow(arr));
// THE OUTPUT ON CODEACADEMY IS AS FOLLOWS:
// arr = [ 1, 5, 10, 1, 25, 1, 5, 5, 5, 40, 5, 1, 100 ]; -> 40 5
// arr = [ 4, 90 ]; -> 90 4
Two things:
You define input after you try to sort it
You have to actually call your function on an array if you want it to output something (I assume you did this, but it would surprise you how many people forget; also, some editors will show you what's returned and others will require you to output it somewhere since, essentially, you're calling a function without doing anything with it; CCLabs is nice about this in that it shows the return values for every function call)

Categories

Resources