Javascript - Repeated if-statements don't work - javascript

My code works (doesn't fail), but it doesn't do the right thing.
I call the "generate" function every time i want to generate a new "chunk", passing a new number into the function each time its called. It generates the chunk fine, but it doesn't generate what I want it to generate.
I want it to generate either a space, a jump, a slide, or a gap, if the previous generation was a space. But if the previous generation wasn't a space, generate a space.
It doesn't do that. It sometimes generates 2 gaps, 2 jumps, or 2 slides after each other and i have no idea why... ???
Here is my code:
var ptg = 'space'; // what was previously generated to top
var wtgt; // what is currently being generated to top
var chunktogenerateto = 0;
function generate(a){
chunktogenerateto = a;
var rand1 = Math.floor(Math.random()*100) + 1;
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
wtgt = 'jump';
}
else if(ptg == 'space' && rand1 <= 75 && rand1 > 50){
wtgt = 'slide';
}
else if(ptg == 'space' && rand1 > 75){
wtgt = 'gap';
}
else{
wtgt = 'space';
}
ptg = wtgt;
topGen(wtgt);
}
function topGen(g){
document.getElementById('t' + chunktogenerateto).setAttribute('src','images/terrain/t' + g + '.png');
}
I hope it's not a typo... HELP!
Where the calls to "generate" are coming from:
var chunkpos = new Array();
chunkpos[0] = -100;
chunkpos[1] = 0;
chunkpos[2] = 100;
chunkpos[3] = 200;
chunkpos[4] = 300;
chunkpos[5] = 400;
chunkpos[6] = 500;
chunkpos[7] = 600;
chunkpos[8] = 700;
chunkpos[9] = 800;
chunkpos[10] = 900;
chunkpos[11] = 1000;
var temppos = new Array();
var time1;
var millis1;
var time2;
var millis2;
var millis3;
var firstreset = true;
var pos;
var poschange;
function moveLevel(){
if(firstreset == true){
resetTime();
}
var time2 = new Date();
var millis2 = time2.getTime();
var millis3 = millis2 - millis1;
poschange = Math.floor(millis3 / 5);
for(i = 0; i < chunkpos.length; i++){
temppos[i] = chunkpos[i] - poschange;
if(temppos[i] <= -150){
generate(i);
temppos[i] += 1200;
}
pos = temppos[i];
document.getElementById('chunk' + i).setAttribute('style','left: ' + pos + 'px;');
}
}
function resetTime(){
time1 = new Date();
millis1 = time1.getTime();
if(firstreset != true){
for(i = 0; i < chunkpos.length; i++){
chunkpos[i] = temppos[i];
}
}
firstreset = false;
setTimeout('resetTime()',1000);
}
Where the calls to "moveLevel" are coming from:
window.onload = function(){
if(test = 'runnable')
{
gameLoop();
}
else
{
document.getElementById('gm').innerHTML = (gm + 'Failed to run game.');
}
}
function gameLoop(){
if(currentscreen == 'playing'){
moveLevel();
}
setTimeout('gameLoop()',0);
}
Here is a download link to a zip file containing all of the code:
ParkourFreak.zip
The code i'm having trouble with is under scripts/generation.js.
The main game page (where the generation is visible is index.html.

Rather than each if statement starting with "if(ptg == 'space' ... etc" - do this first in one simple "if not space return space".
After that you can start on your random - that should work for you.

Roughly a quarter of the time you previously had a space, it will create another, because of this code:
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
Note that it's creating a space when a space was previously created.
Side note:
There's no need for the && rand1 > 25 on this line:
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
Since you previously had if(ptg == 'space' && rand1 <= 25){, it's impossible as of that line for rand1 to be <= 25 when ptg == 'space'.
(And similarly the && rand2 > 50 on the following condition.)

Are you sure you're incrementing chunktogenerateto?
It appears to stay at 0 with the current code, is that in a segment you haven't shown?
Edit: oh, it's the argument of the function. Try logging that variable, maybe that's the problem?

// elsewhere
var wtgts = ['space','jump','slide','gap'];
// in the function
if(ptg !== 'space') {
wtgt = 'space';
} else {
var randidx = Math.floor(Math.random()*4);
wtgt = wtgts[randidx];
}
Or even in the function:
var newidx = (ptg == 'space') ? Math.floor(Math.random()*4) : 0;
wtgt = wtgts[newidx];
The weights were equal, so just pick a random index from 0 to 3 and use that to pick an action from an array.
Separate the logic for ptg being space so that you only test for it once
Consider denoting the actions as numbers instead of strings, as the assignment, comparison etc will be faster and more robust.

I thought the problem lied with the generation, when in fact all I had to do to solve it was to change this:
if(temppos[i] <= -100){
generate(i);
temppos[i] += 1200;
}
to this:
if(temppos[i] <= -100){
generate(i);
chunkpos[i] += 1200;
temppos[i] += 1200;
}

Related

Odds/Evens Javascript Value not updating between turns

all the code was given by the teacher and you just had to place it in the right spot. even working with the teacher we couldn't get it to update the "value" attribute in between turns. it updates at the finish of the game but not during? what are we not seeing? any help appreciated.. if you need to see html i can add as comment
"use strict";
var $ = function(id) { return document.getElementById(id); };
var getRandomNumber = function(max) {
var random;
if (!isNaN(max)) {
random = Math.random(); //value >= 0.0 and < 1.0
random = Math.floor(random * max); //value is an integer between 0 and max - 1
random = random + 1; //value is an integer between 1 and max
}
return random;
};
var playGame = function() {
var odd = 0;
var even = 0;
var player, computer, total;
resetFields(); // clear any previous entries
while (odd < 50 && even < 50) {
//get computers fingers
computer = getRandomNumber(5);
// get player's fingers
player = parseInt(prompt("Enter a number between 1 and 5, or 999 to quit", 999));
if (!isNaN(player) && player <= 5) {
// show current round
$("player").value = player;
$("computer").value = computer;
// update totals
total = player + computer;
if (total % 2 === 0) {
even = even + total;
$("even").value = even;
} else {
odd = odd + total;
$("odd").value = odd;
}
}
//if loop for player quitting
if (player === 999) {
resetFields();
break;
}
}
//after loop ends, determine winner
if (odd >= 50) { $("message").firstChild.nodeValue = "You WIN!"; }
else if (even >= 50) { $("message").firstChild.nodeValue = "You lose :("; }
else { $("message").firstChild.nodeValue = "You quit"; }
// set focus on button so you can play again
$("play").focus();
};
var resetFields = function() {
$("player").value = "0";
$("computer").value = "0";
$("odd").value = "0";
$("even").value = "0";
$("message").firstChild.nodeValue = "";
};
window.onload = function() {
$("play").onclick = playGame;
$("play").focus();
};

javascript absolute beginner = stuck on function returning "undefined"

Just for exercise, I'm trying to print out this pattern:
Here's the code so far:
var even = " #";
var odd = "# ";
var size = 4;
var rowCount = 1;
var lineLength = 1;
function writeOdd(size){
while(lineLength<=size){
document.write(odd)
if(lineLength === size){
document.write("<br>")
}
lineLength++;
}
}
function writeEven(size){
while(lineLength<=size){
document.write(even)
if(lineLength === size){
document.write("<br>")
}
lineLength++;
}
}
if(rowCount <= size && rowCount % 2 !== 0) {document.write(writeEven(size));}
else if(rowCount <= size && rowCount % 2 === 0){document.write(writeOdd(size));}
rowCount++;
I'm stuck - first line prints out ok, second gives "undefined" and that's it.
The issue is in document.write(writeEven(size)) and document.write(writeOdd(size)). writeEven and writeOdd don't explicitly return anything. When a function doesn't explicitly return anything, it will return undefined by default. So when those functions return, undefined gets passed in to document.write, and is written to the screen.
Note that document.write(writeOdd(size)) gets evaluated from the inside out. First writeOdd(size) is executed. Then it returns. The return value basically takes its place, giving us document.write(undefined). Then document.write(undefined) is executed, and prints "undefined" to the screen.
Check out https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Return_values for more information on return values.
Your functions call document.write, so no need to use it when calling writeEven and writeOdd, also you're missing a while loop for incrementing rows, and lineLength should be initialzed in each function
var even = " #";
var odd = "# ";
var size = 4;
var rowCount = 1;
function writeOdd(size){
var lineLength = 1;
while(lineLength<=size){
document.write(odd)
if(lineLength === size){
document.write("<br>")
}
lineLength++;
}
}
function writeEven(size){
var lineLength = 1;
while(lineLength<=size){
document.write(even)
if(lineLength === size){
document.write("<br>")
}
lineLength++;
}
}
while (rowCount <= 5) {
if(rowCount <= size && rowCount % 2 !== 0) {writeEven(size);}
else if(rowCount <= size && rowCount % 2 === 0){writeOdd(size);}
rowCount++;
}
function print() {
let flag = true;
for(let i = 0; i < 4; i++) {
for(let j = 0; j < 8; j++) {
flag ? process.stdout.write('#') : process.stdout.write(' ');
flag = !flag;
}
flag = !flag;
process.stdout.write('\n');
}
}
print();

JavaScript else if not working

I have a simple screen with 2 text boxes, one to enter Methane data, One ot enter Hydrogen Data, I have written a little JS to divide one by the other. As below.
<script type="application/javascript">
function RRC()
{
var Methane = document.getElementById('MethaneVPM').value;
var Hydrogen = document.getElementById('HydrogenVPM').value;
var RRC1 = Methane / Hydrogen;
var RRR1 = parseFloat(RRC1).toFixed(1);
if (!isNaN(RRR1))
{
document.getElementById('RogerRatio').value = RRR1;
}
}
</script>
This works with an on focus, If I put 62 in Methane and 52 in Hydrogen I get 1.2, which is correct.
However when I add some else if statements to it, it fails.
I've been looking at this for days now, I know I am missing something I just can't work out what.
So below just stops responding.
<script type="application/javascript">
function RRC()
{
var Methane = document.getElementById('MethaneVPM').value;
var Hydrogen = document.getElementById('HydrogenVPM').value;
var RRC1 = Methane / Hydrogen;
var RRR1 = parseFloat(RRC1).toFixed(1);
var RRC1R = 0;
if(RRR1 < 0.1){RRC1R = 5;}
else if(RRR1 >= 0.1 && < 0.9){RRC1R = 0;}
else if(RRR1 >= 1 && < 2.9){RRC1R = 1;}
else if(RRR1 >= 3){RRC1R = 2;}
else {RRC1R = 'Boo';}
if (!isNaN(RRC1R))
{
document.getElementById('RogerRatio').value = RRC1R;
}
}
</script>
Any pointers at this stage would be a huge help.
Thanks in advance
You're missing a value in your if statements:
else if(RRR1 >= 0.1 && < 0.9)
should be
else if(RRR1 >= 0.1 && RRR1 < 0.9)
the same goes for all conditions
see the working code here
You are missing RRR1 in your conditions. I would also suggest to change condition as follows:
<script type="application/javascript">
function RRC()
{
var Methane = document.getElementById('MethaneVPM').value;
var Hydrogen = document.getElementById('HydrogenVPM').value;
var RRC1 = Methane / Hydrogen;
var RRR1 = parseFloat(RRC1).toFixed(1);
var RRC1R = 0;
if(RRR1 < 0.1){RRC1R = 5;}
else if(RRR1 >= 0.1 && RRR1 < 1){RRC1R = 0;}
else if(RRR1 >= 1 && RRR1 < 3){RRC1R = 1;}
else if(RRR1 >= 3){RRC1R = 2;}
else {RRC1R = 'Boo';}
if (!isNaN(RRC1R))
{
document.getElementById('RogerRatio').value = RRC1R;
}
}
</script>

Multiple instance of object interfering

So, I'm creating a game in HTML/JS (Mostly Jquery).
I got an array of objects initialized at the beginning of the game (when user press P to play).Each object is a falling object (I know it's failing with a boolean named "working"), with "move" method setting a position going from 1 to 22. Each time it move, it show the current div with a number as ID (representing the position), and hide the previous div.
The problem is that, the game work perfectly with only one instance of the Object (so only one cell in the array), but when I try to put few other object, they don't move.
Here is the object constructor :
function flyers(){
this.pos = 0;
this.working = false;
this.jump = 0;
this.interval;
this.move = function(){
if (this.working == true){
if (this.pos == 22)
{
$("#perso21").hide();
this.pos = 0;
this.startWork();
}
checkSave();
if (this.jump == 0)
{ if ((this.pos == 5 && playerPos != 1) || (this.pos == 13 && playerPos != 2) || (this.pos == 19 && playerPos != 3))
{
this.die();
}
if ((this.pos == 4 && playerPos == 1) || (this.pos == 12 && playerPos == 2) || (this.pos == 18 && playerPos == 3))
this.jump = 1;
}
else
{
if (this.pos == 5 || this.pos == 13 || this.pos == 19)
{
score++;
this.jump = 0;
}
$(".score").html("" + score + "");
}
$("#perso" + (this.pos - 1) + "").hide();
$("#perso" + this.pos + "").show(); this.pos++;
}
else
clearInterval(this.interval);
};
this.startWork = function()
{
clearInterval(this.interval);
this.working = true;
this.interval = setInterval(this.move, 1000 - (score / 10 * 100));
}
this.die = function(){
this.working = false;
this.pos = 0;
this.jump = 0;
if (miss < 2)
{
miss++;
}
else
{
quitGame();
}
clearInterval(this.interval);
};
return this;}
And the array initialization :
flyerstab[0] = new flyers();
flyerstab[1] = new flyers();
flyerstab[2] = new flyers();
flyerstab[3] = new flyers();
flyerstab[0].startWork();
The spawner (only possible to have 4 objects falling at the same time)
spawn = setInterval(function()
{
var i;
for (var i = flyerstab.length - 1; i >= 0; i--) {
if (flyerstab[i].working == false)
{
flyerstab[i].startWork();
break;
}
else
console.log(i + " is working");
};
}, 5000 - (score / 10 * 100));
I tried to find why all the day, but I didn't manage to.. Am I constructing them bad ?
Inside of this.interval = setInterval(this.move, 1000 - (score / 10 * 100));, this.move is called with this as the global context. Instead, use
this.interval = setInterval(this.move.bind(this), 1000 - (score / 10 * 100));

Use jquery or javascript to add commas to disabled field

I have a form that I'm using to calculate some numbers, and the final 3 input fields on the form are disabled because they show the results of the calculator.
I'm using the following javascript/jquery to add commas to the user editable fields which works great but I can't seem to find a way to add commas to the "results" fields:
$('input.seperator').change(function(event){
// skip for arrow keys
if(event.which >= 37 && event.which <= 40){
event.preventDefault();
}
var $this = $(this);
var num = $this.val().replace(/,/gi, "").split("").reverse().join("");
var num2 = RemoveRougeChar(num.replace(/(.{3})/g,"$1,").split("").reverse().join(""));
// the following line has been simplified. Revision history contains original.
$this.val(num2);
});
function RemoveRougeChar(convertString){
if(convertString.substring(0,1) == ","){
return convertString.substring(1, convertString.length)
}
return convertString;
}
This is what I'm using the populate the fields, basically the fields show the results in dollars, so I'm trying to add a comma every 3 numbers:
$('#incorrect-payment').val(fieldK);
$('#correcting-payment').val(fieldL);
$('#total-cost').val(fieldM);
I think you'd want to use a function like this:
function FormatCurrency(amount, showDecimals) {
if (showDecimals == null)
showDecimals = true;
var i = parseFloat(amount);
if (isNaN(i)) { i = 0.00; }
var minus = false;
if (i < 0) { minus = true; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if (showDecimals) {
if (s.indexOf('.') < 0) { s += '.00'; }
if (s.indexOf('.') == (s.length - 2)) { s += '0'; }
}
//s = minus + s;
s = '$' + FormatCommas(s, showDecimals);
if (minus)
s = "(" + s + ")";
return s;
}
function FormatCommas(amount, showDecimals) {
if (showDecimals == null)
showDecimals = true;
var delimiter = ","; // replace comma if desired
var a = amount.split('.', 2)
var d = a[1];
var i = parseInt(a[0]);
if (isNaN(i)) { return ''; }
var minus = '';
if (i < 0) { minus = '-'; }
i = Math.abs(i);
var n = new String(i);
var a = [];
while (n.length > 3) {
var nn = n.substr(n.length - 3);
a.unshift(nn);
n = n.substr(0, n.length - 3);
}
if (n.length > 0) { a.unshift(n); }
n = a.join(delimiter);
if (!showDecimals) {
amount = n;
}
else {
if (d.length < 1) { amount = n; }
else { amount = n + '.' + d; }
}
amount = minus + amount;
return amount;
}
May be you might want to trigger change event manually through javascript for your three read-only input fields. Using jquery trigger . I am not sure but it seems like a bad idea to have a read-only input field if no user can change these values. Usually having read-only input fields is good if a user with some security can edit those and some cannot.

Categories