Var/Array Random Selection - javascript

I'm a hobbyist coder and I'm working on a side project. I want the "Random" coding at the bottom of this list of variables (which functions as an ...Array right?) to randomly select specifically from each set of variables. How do I make this work?
var flanks = [
"Androxus-Flank",
"Zhin-Flank",
"Buck-Flank",
"Evie-Flank",
"Lex-Flank",
"Maeve-Flank",
"Skye-Flank",
"Talus-Flank"
];
var frontline = [
"Ash-Frontline",
"Barik-Frontline",
"Fernando-Frontline",
"Inara-Frontline",
"Makoa-Frontline",
"Torvald-Frontline",
"Ruckus-Frontline"
];
var damage = [
"Bomb King-Damage",
"Tyra-Damage",
"Viktor-Damage",
"Willo-Damage",
"Kinessa-Damage",
"Lian-Damage",
"Sha Lin-Damage",
"Strix-Damage",
"Cassie-Damage",
"Drogoz-Damage"
];
var support = [
"Grohk-Support",
"Grover-Support",
"Mal'Damba-Support",
"Pip-Support",
"Jenos-Support",
"Seris-Support",
"Ying-Support"
];
$("#button").click(function() { 
$("#flanks").text(flanks[Math.floor(Math.random() * flanks.8)]);
$("#frontline").text(frontline[Math.floor(Math.random() * frontline.7)]);
$("#damage").text(damage[Math.floor(Math.random() * damage.10)]);
$("#support").text(support[Math.floor(Math.random() * support.7)]);
});
and this is the html I'm building alongside it; if anyone wouldn't mind proofreading.
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">Basic Functioning Demo for 'The Unofficial Hi-Rez Paladins' Champion Roulette'
</div>
<div class="panel-body">
<ul>
<li><strong>Flank</strong>--<span id="flanks"></span></li>
<li><strong>Frontline</strong>--<span id="frontline"></span></li>
<li><strong>Damage</strong>--<span id=damage></span></li>
<li><strong>Support</strong>--<span id="support"></span></li>
</ul>
</div>
<div class="panel-footer">
R o l l
</div>
</div>
</div>
<img src="https://i.imgur.com/u9nFQuH.png" class="center"/>

This should work if you just refer to the correct arrays
For example:
$("#race").text(races[Math.round((Math.random() * 32))]);
There is no races array
try changing races to flank
$("#race").text(flank[Math.round((Math.random() * 32))]);
An easy way to see if this is working is to use console logs
console.log(flank[Math.round((Math.random() * 32))]);

How do I make this work?
Change the multiplier to array's (race in this case) length and Math.round with Math.floor so that you don't get undefined
$( "#race" ).text( races[ Math.floor( Math.random() * races.length ) ] );

Related

jQuery remove duplicate but keep last occurance

SO is full of these questions, I know, but after going through 20+ pages and numerous google searches I end up asking because I can't find the answer.
I want to filter through data attributes and keep the last occurrence. So for instance with this code:
<div data-id="001">Hello</div>
<div data-id="001">World</div>
<div data-id="002">Keep</div>
<div data-id="002">Only</div>
<div data-id="002">Unique</div>
<div data-id="003">Last</div>
<div data-id="003">Word</div>
<div data-id="004">Please</div>
<br><br>
<p>Result should be: World Unique Word Please</p>
I tried numerous ideas from the SO pages and google searches but I have no luck in keeping the last items. First items though work perfectly with this code.
var found = {};
$('[data-id]').each(function(){
var $this = $(this);
if(found[$this.data('id')]){
$this.remove();
}
else{
found[$this.data('id')] = true;
}
});
Here is a fiddle, hopefully that makes things easier http://jsfiddle.net/hx9Lzqf6/
We can find the last index with same id,store them into an array,then call $.each() again to remove elements with index not in the array
let result = {}
$('[data-id]').each(function(i,e){
let id = $(e).attr("data-id")
result[id] = i
});
result = Object.values(result)
$('[data-id]').each(function(i,e){
let id = $(e).attr("data-id")
if(!result.includes(i)){
$(e).remove()
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-id="001">Hello</div>
<div data-id="001">World</div>
<div data-id="002">Keep</div>
<div data-id="002">Only</div>
<div data-id="002">Unique</div>
<div data-id="003">Last</div>
<div data-id="003">Word</div>
<div data-id="004">Please</div>
<br><br>
<p>Result should be: World Unique Word Please</p>

element .innerText not displaying

I'm trying to replace the text content of two divs ("city" and "budget"), one with a random US city from an array and one with a randomly generated number. The code works fine when I run it in the console, but for some reason it won't display in the browser. Any idea what's going wrong here? For my purposes I'm not using JQuery, just straight JavaScript.
HTML:
<div id="result">
<div class="city">
<h1>City</h1>
</div>
<div class="budget">
<h1>Budget</h1>
</div>
</div>
JS
function city() {
document.getElementsByClassName('.city').innerText = usCities[Math.floor(Math.random() * usCities.length)];
}
function budget() {
document.getElementsByClassName('.budget').innerText = Math.floor(Math.random() * 1000000) + 100000;
}
The problems are:
You doesn't give [0] to getElementsByClassName.
Using . in the paremeter of getElementsByClassName.
You doesn't call the function
You doesn't define the usCities
This should works:
let usCities = ["Chicago", "New York"]
function city() {
document.getElementsByClassName('city')[0].innerText = usCities[Math.floor(Math.random() * usCities.length)];
}
function budget() {
document.getElementsByClassName('budget')[0].innerText = Math.floor(Math.random() * 1000000) + 100000;
}
city();
budget();
<div id="result">
<div class="city">
<h1>City</h1>
</div>
<div class="budget">
<h1>Budget</h1>
</div>
</div>

Generating huge amounts of HTML

I am working on a browser game. I have lots of upgrades, crafting, planets, etc that I generate with jS (1 box (or square?) PER EACH item). Here is a mini snippet from my game, displaying my current method of generating HTML
JSFiddle example
I do a simple loop and insert as many boxes as there are upgrades
for(i = 0; i < 9; i ++)
Then, I put a gigantic HTML code block in a function, and use arrays to identify upgrades ID, name, info...
Is this a good practice to generate loads of HTML content? If not, what can I do to improve it?
Also, I started "coding" a game with one main goal to learn JS. If you have better solutions, but they include a lib (jQuery, etc) then you can post it, but I'm going pure jS here. Thanks!
-- Update --
I've been learning lots of JS in the past year. #DoXicK provided a great example a while ago but I didn't understand it then. This is the final rendering method I come up with, thanks to his examples, and I guess I'll stick with it:
JS:
const game = {};
// make our life easier
const $ = key => document.getElementById(key);
const render = (key, str) => $(key).insertAdjacentHTML("beforeend", str);
// a function that returns upgrades html content
const html = self => `
<div class="some-class" id="${self.id}">
<h2>${self.name}</h2>
<p>${self.damage}</p>
</div>
`;
// object containing each upgrades template
const template = {
laserGun: {
id: "laserGun",
name: "Laser Gun",
damage: 10
},
plasmaGun: {
id: "plasmaGun",
name: "Plasma Gun",
damage: 30
}
};
// Upgrade class
class Upgrade {
constructor(upg) {
this._id = upg.id;
this._name = upg.name;
this._damage = upg.damage;
}
get id() {return this._id;}
get name() {return this._name;}
get damage() {return this._damage;}
generate() {
// find div with upgrade id, and inject it's html content inside
render("upgrade", html(this));
}
static make(key) {
game.upgrade[key] = new Upgrade(template[key]);
game.upgrade[key].generate();
}
}
let laserGun = Upgrade.make("laserGun");
HTML:
<div class="upgrade-container" id="upgrade">
I hope you find it helpful!
As i already explained in comments, your code will become quite unmaintainable if you keep it as spaghetti code like that.
I've made an updated example which does the exact same thing as you did, just with a bit of updated javascript and by making a javascript-component out of your "template".
https://jsfiddle.net/7L8e5kmg/3/
class UpgradeBlock {
constructor(props) {
this.props = props;
}
render() {
let { Id, Name, Info, Res } = this.props;
// basically:
// let Id = this.props.Id;
// let Name = this.props.Name;
// etc
return (`
<div class="hud-item" id="${Id}">
<img src="client/img/${Id}.png" id="${Id}Img" />
<div class="hud-tooltip f16 fwhite">
<div class="hud-tt-header-container">
<div class="hud-tt-info-container">
<div class="col-full">${Name}</div>
<div class="col-half">
<img style="vertical-align: text-bottom;" src="img/${Res}16.png" />
<span id="${Id}Cost"></span>
</div>
<div class="col-half">
+<span id="${Id}dmgPerLv"></span>
<img style="vertical-align: text-bottom;" src="client/img/character/dps16.png" />
</div>
</div>
<div class="hud-tt-lv-container">
<canvas id="${Id}Bar" width="64px" height="64px"></canvas>
</div>
</div>
<hr/>
<div class="hud-tt-info-container">
<div class="col-half fwhite f16">
<img style="vertical-align: text-bottom" src="client/img/character/dps16.png" />
<span id="${Id}Dmg"></span>
</div>
<div class="col-half fgrey f10"><span class="fwhite f16" id="${Id}ofTotal"></span> of total</div>
<div class="col-full fgrey f10">${Info}</div>
<div class="col-full f10" id="${Id}click"></div>
</div>
</div>
</div>
`)
}
}
You use it by doing:
let upgrade = {
Id: 'id',
Name: 'name',
Info: 'info',
Res: 'res'
};
let html = new UpgradeBlock(upgrade).Render()
For people that do react: yes, it is intended to steer that way.

Recursive "parsing" function in javascript

I'm trying to create a kind of recursive parsing function, but it does not work as it should.
The array to be parsed:
gridArray = [
{
type:"row",
text:"row1",
cols: [
{
type:"col",
text:"col1",
rows: [
{
type:"row",
text:"row1 nested",
cols: [{}]
}
]
},
{
type:"col",
text:"col2",
rows: [{}]
}
]
}
]
The function:
function createHtmlCode(gridArray,level){
for(var y=0; y<gridArray.length; y++){
obRow = gridArray[y];
r+="<div class='row'>";
arCol = obRow.cols;
for(var x=0; x<arCol.length; x++){
obCol = arCol[x];
r+="<div class='col'>";
if(obCol.rows){
createHtmlCode(obCol.rows,level++);
}
r+="</div>";
}
r+="</div>";
}
}
r="";
createHtmlCode(gridArray,1);
At the moment the result (r) is:
<div class="row">
<div class="col">
<div class="row">
<div class="col">
</div>
</div>
</div>
</div>
... but it shoud be:
<div class="row">
<div class="col">
<div class="row">
<div class="col">
</div>
</div>
</div>
<div class="col">
<div class="row">
</div>
</div>
</div>
What am I doing wrong?
Thank you in advance for your tips!
Hahaha! You have a very subtle (but very common) error.
See here:
arCol = obRow.cols;
That's the bug, if you look closely.
Got it? Or you want me to spoil it?
The error is: in Javascript, if you don't declare a variable as local, it defaults to global. arCol gets reset in the recursive call!
All the variable declarations should be explicit:
var arCol = obRow.cols;
Other tips:
x and y should be used to indicate spatial information (on the "x-axis" and "y-axis"); use i and j (and if necessary k) for array indices. And declare them as local.
do not use global mutable values -- in this example r. Instead have the function return the string
never use the same name for a global variable and a formal parameter (gridArray in this case) or a local variable. The computer will not be confused, but you will be.
don't put a type name ("array") in a variable name without a specific reason.
don't put a simple expression a variable if you are only going to use it once without a good reason
So the corrected code would be
function createHtmlCode(grid,level){
var r = "";
for(var i=0; i<grid.length; i++){
r+="<div class='row'>";
var arCol = grid[i].cols;
for(var j=0; j<arCol.length; j++){
r+="<div class='col'>";
var rows = arCol[j].rows;
if(rows){
r += createHtmlCode(rows,level++);
}
r+="</div>";
}
r+="</div>";
}
return r;
}
console.log(createHtmlCode(myGrid,1));

Is javascript namespace polluted?

I do not have a good grasp of the js namespace and am WAGing* re the title, but that's one of my guesses about what's happening.
WAG = Wild Guess
My app is crashing (dramatically); trying to figure out why. In fact, after 3 Q/A pairs, it blows up the entire Chrome tab..! I'm beginning to suspect I've done something wrong in my code...
Warning: Save your browsing session before running these jsFiddles. (In Chrome, the jsFiddle only blows up its own tab but I can't comment on other browsers)
jsFiddle One
jsFiddle Two - dupe in case jsFiddle One blown away
Please help me to understand exactly which spectacular moronism I've committed today.
HTML:
<div id="result">
<div class="truth tr0"><h2>---</h2></div>
<div class="truth tr1"><h2>answer to one</h2></div>
<div class="truth tr2"><h2>answer to two</h2></div>
<div class="truth tr3"><h2>answer to three</h2></div>
<div class="truth tr4"><h2>answer to four</h2></div>
</div>
<div id="replaceLink">
<div class="youcould yc1">
<h2>QUESTION ONE</h2>
</div>
<div class="youcould yc2">
<h2>QUESTION TWO</h2>
</div>
<div class="youcould yc3">
<h2>QUESTION THREE</h2>
</div>
<div class="youcould yc4">
<h2>QUESTION FOUR</h2>
</div>
<div class="youcould yc5">
<h2>THANK YOU</h2>
</div>
</div>
<div id="response"></div>
<input type="button" id="mybutt" value="Start Test" />
Javascript/jQuery:
var cnt = 0;
var window = {};
window.arrDone = [];
function nextQues() {
if (window.arrDone.length == 4) return 5;
success = 0;
while (success == 0) {
nn = Math.floor(Math.random() * 3) + 1;
if (window.arrDone.indexOf(nn) == -1 && nn != 5) {
success++;
window.arrDone.push(nn);
}
}
return nn;
}
$('.youcould, .truth').hide();
$('.tr0').show();
$('.youcould').click(function() {
$(this).hide();
thisA = window.arrDone[window.arrDone.length -1];
$('.tr'+thisA).show();
});
$('.truth').click(function() {
$(this).hide();
nextQ = nextQues();
$('.yc'+nextQ).show();
});
$('#mybutt').click(function () {
$(this).hide();
$('.tr0').hide();
nextQ = nextQues();
$('.yc'+nextQ).show();
});
My guess would be
var window = {};
window is special, so creating a global variable named window is begging for trouble.
Your while loop runs infinitely on the third pass because it doesn't meet the condition.
At some point, arrDone will contain the numbers 1, 2, and 3, as produced by your random generator (which will never produce 5, btw). In that case, nextQues() does not abort and return five (as arrDone.lenght == 3), and will enter the loop. Your random generator produces nothing but the numbers 1, 2, and 3, which always are already in the array, so the if-condition (that would end the loop) is never fulfilled. You have an infinite loop generating random numbers.
I guess you want
function nextQues() {
var l = 4;
if (window.arrDone.length >= l)
return l+1;
while (true) {
var nn = Math.floor(Math.random() * l) + 1; // generate 1, 2, 3 or 4
if (window.arrDone.indexOf(nn) == -1) {
window.arrDone.push(nn);
return nn;
}
}
}

Categories