JavaScript loop and change variables - javascript

I am making an artificial intelligent agent to play google chromes t-rex game and need help creating a loop for the game to continuously play at the moment to begin the game I have to actually press space.
document.getElementById("botStatus").addEventListener("change", function() {
if (this.checked === true) {
// Activate bot
var INTERVAL = 2;
window.tRexBot = setInterval(function() {
var tRex = Runner.instance_.tRex;
var obstacles = Runner.instance_.horizon.obstacles;
var lengthsize = 0;
var a = 0.1;
var b = 5;
var c = 35;
var d = 160;
var posWidth = 20;
// if (!tRex.jumping && (obstacles.length > 0) && (obstacles[0].xPos + obstacles[0].width) <= ((parseInt(Runner.instance_.currentSpeed - 0.1) - 5) * 34 + 160) && (obstacles[0].xPos + obstacles[0].width) > 20) {
if (!tRex.jumping && (obstacles.length > lengthsize) && (obstacles[0].xPos + obstacles[0].width) <= ((parseInt(Runner.instance_.currentSpeed - a) - b) * c + d) && (obstacles[0].xPos + obstacles[0].width) > posWidth) {
// console.log(obstacles[0].xPos + obstacles[0].width + " | " + ((parseInt(Runner.instance_.currentSpeed - 0.1) - 5) * 34 + 160));
tRex.startJump();
}
}, INTERVAL);
} else {
// Disable bot
clearInterval(tRexBot);
}
});
what I require is for once the Interval ends, I would like it to take the games current speed and distance of obstacles then either increase or decrease the variables I have set into a new interval, so that it will hopefully learn how to get further and further into the game as it picks up speed...
If this sort of makes sense?

A number of changes you could make to improve the code.
1) Extract the code for starting/stopping the bot to their own functions
var INTERVAL = 2;
function startBot(){
var bot = {}; //empty bot info
bot.tRex = Runner.instance_.tRex;
....
bot.posWidth = 20;
bot.interval = setInterval(function() {
if (!bot.tRex.jumping && (bot.obstacles.length > bot.lengthsize) /*...*/) {
tRex.startJump();
}
},INTERVAL);
return bot;
}
function stopBot(bot) {
clearInterval(bot.interval);
}
document.getElementById("botStatus").addEventListener("change", function() {
if (this.checked === true) {
window.bot = startBot();
}
else {
stopBot(window.bot);
}
}
2) pass the config parameters into the "startBot" function so you can more easily change it on the outside.
var config = { posWidth:20,a: 01,...};
startBot(config);
function startBot(config) {
var bot = config;
//....
}

Related

How do I get my timer to stop, when my 10th and last question has been answered?

The goal I am trying to achieve is to get my timer to stop when all the questions of my quiz has been answered. I have 10 total questions. I have been able to get the timer to start. But getting ot to stop on the click of submit on the 10th question is something I can't figure out.
Let me know if you know what I am doing
StackOverflow said my code was too long... I added my code to codepen. I also included my JS on here.
// variables
var score = 0; //set score to 0
var total = 10; //total nmumber of questions
var point = 1; //points per correct answer
var highest = total * point;
//init
console.log('script js loaded')
function init() {
//set correct answers
sessionStorage.setItem('a1', "b");
sessionStorage.setItem('a2', "a");
sessionStorage.setItem('a3', "c");
sessionStorage.setItem('a4', "d");
sessionStorage.setItem('a5', "b");
sessionStorage.setItem('a6', "d");
sessionStorage.setItem('a7', "b");
sessionStorage.setItem('a8', "b");
sessionStorage.setItem('a9', "d");
sessionStorage.setItem('a10', "d");
}
// timer
// var i = 1;
// $("#startButton").click(function (e) {
// setInterval(function () {
// $("#stopWatch").html(i);
// i++;
// }, 1000);
// });
// $("#resetButton").click(function (e) {
// i = 0;
// });
//hide all questions to start
$(document).ready(function() {
$('.questionForm').hide();
//show question 1
$('#question1').show();
$('.questionForm #submit').click(function() {
//get data attribute
current = $(this).parents('form:first').data('question');
next = $(this).parents('form:first').data('question') + 1;
//hide all questions
$('.questionForm').hide();
//show next question in a cool way
$('#question' + next + '').fadeIn(400);
process('' + current + '');
return false;
});
});
//process answer function
function process(n) {
// get input value
var submitted = $('input[name=question' + n + ']:checked').val();
if (submitted == sessionStorage.getItem('a' + n + '')) {
score++;
}
if (n == total) {
$('#results').html('<h3>Your score is: ' + score + ' out of ' + highest + '!</h3> <button onclick="myScore()">Add Your Name To Scoreboard!</a>')
}
return false;
}
window.yourPoints = function() {
return n;
}
function myScore() {
var person = prompt("Please enter your name", "My First Name");
if (person != null) {
document.getElementById("myScore").innerHTML =
person + " " + score
}
}
// function showTime() {
// var d = new Date();
// document.getElementById("clock").innerHTML = d.toLocaleTimeString();
// }
// setInterval(showTime, 1000);
var x;
var startstop = 0;
window.onload = function startStop() { /* Toggle StartStop */
startstop = startstop + 1;
if (startstop === 1) {
start();
document.getElementById("start").innerHTML = "Stop";
} else if (startstop === 2) {
document.getElementById("start").innerHTML = "Start";
startstop = 0;
stop();
}
}
function start() {
x = setInterval(timer, 10);
} /* Start */
function stop() {
clearInterval(x);
} /* Stop */
var milisec = 0;
var sec = 0; /* holds incrementing value */
var min = 0;
var hour = 0;
/* Contains and outputs returned value of function checkTime */
var miliSecOut = 0;
var secOut = 0;
var minOut = 0;
var hourOut = 0;
/* Output variable End */
function timer() {
/* Main Timer */
miliSecOut = checkTime(milisec);
secOut = checkTime(sec);
minOut = checkTime(min);
hourOut = checkTime(hour);
milisec = ++milisec;
if (milisec === 100) {
milisec = 0;
sec = ++sec;
}
if (sec == 60) {
min = ++min;
sec = 0;
}
if (min == 60) {
min = 0;
hour = ++hour;
}
document.getElementById("milisec").innerHTML = miliSecOut;
document.getElementById("sec").innerHTML = secOut;
document.getElementById("min").innerHTML = minOut;
document.getElementById("hour").innerHTML = hourOut;
}
/* Adds 0 when value is <10 */
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function reset() {
/*Reset*/
milisec = 0;
sec = 0;
min = 0
hour = 0;
document.getElementById("milisec").innerHTML = "00";
document.getElementById("sec").innerHTML = "00";
document.getElementById("min").innerHTML = "00";
document.getElementById("hour").innerHTML = "00";
}
//adding an event listener
window.addEventListener('load', init, false);
https://codepen.io/rob-connolly/pen/xyJgwx
Any help would be appreciated.
its a pretty simple solution just call the stop function in the if condition of n == total
if (n == total) {
$('#results').html('<h3>Your score is: ' + score + ' out of ' + highest + '!</h3>
<button onclick="myScore()">Add Your Name To Scoreboard!</a>')
stop()
}
https://codepen.io/nony14/pen/VwYREgr
Try using clearInterval() to stop the timer.
https://codepen.io/thingevery/pen/dyPrgwz

How to Change 2 Math.floor random numbers if they are equal

I'm trying to replicate the Monty Hall Problem, if you've heard of it, and I need to add in a system that will change one of two Math.floor random numbers when they are equal. My question is how do I change a variable that is random into another if it is equal to a second random variable. If you look into the Monty Hall Problem, the wrong variable would be an incorrect choice and door is correct, I set both to be random, but obviously, they cannot both be equal. This is what I have so far.
setInterval(gr, 1000)
function gr() {
if (wrong === door) {
door = Math.floor((Math.random() * 3) + 1);
}
}
var door1 = 0;
var door2 = 0;
var door3 = 0;
var door;
var wrong;
var attempt = 0;
var d1 = document.getElementById('door1');
var d2 = document.getElementById('door2');
var d3 = document.getElementById('door3');
setInterval(gr, 1000)
function gr() {
if (wrong === door) {
door = Math.floor((Math.random() * 3) + 1);
}
}
function dr1() {
document.getElementById('door1').style.pointerEvents = 'none';
document.getElementById('door2').style.pointerEvents = 'none';
document.getElementById('door3').style.pointerEvents = 'none';
document.getElementById('door1').style.backgroundColor = "green";
door1 = 1;
if (door2 === 1) {
document.getElementById('door2').style.backgroundColor = "black";
door2 = 0;
} else if (door3 === 1) {
document.getElementById('door3').style.backgroundColor = "black";
door3 = 0;
}
if (attempt === 0) {
wrong = Math.floor((Math.random() * 2) + 1);
door = Math.floor((Math.random() * 3) + 1);
if (wrong === 1) {
document.getElementById('door2').style.backgroundColor = "white";
change1a();
} else if (wrong === 2) {
document.getElementById('door3').style.backgroundColor = "white";
change1b();
}
}
attempt = 1;
}
function dr2() {
document.getElementById('door1').style.pointerEvents = 'none';
document.getElementById('door3').style.pointerEvents = 'none';
document.getElementById('door2').style.backgroundColor = "green";
door2 = 1;
if (door1 === 1) {
document.getElementById('door1').style.backgroundColor = "black";
door1 = 0;
} else if (door3 === 1) {
document.getElementById('door3').style.backgroundColor = "black";
door3 = 0;
}
if (attempt === 0) {
wrong = Math.floor((Math.random() * 2) + 1);
door = Math.floor((Math.random() * 3) + 1);
if (wrong === 1) {
document.getElementById('door1').style.backgroundColor = "white";
change2a();
} else if (wrong === 2) {
document.getElementById('door3').style.backgroundColor = "white";
change2b();
}
}
attempt = 1;
}
function dr3() {
document.getElementById('door1').style.pointerEvents = 'none';
document.getElementById('door2').style.pointerEvents = 'none';
document.getElementById('door3').style.backgroundColor = "green";
door3 = 1;
if (door1 === 1) {
document.getElementById('door1').style.backgroundColor = "black";
door1 = 0;
} else if (door2 === 1) {
document.getElementById('door2').style.backgroundColor = "black";
door2 = 0;
}
if (attempt === 0) {
wrong = Math.floor((Math.random() * 2) + 1);
door = Math.floor((Math.random() * 3) + 1);
if (wrong === 1) {
document.getElementById('door1').style.backgroundColor = "white";
change3a();
} else if (wrong === 2) {
document.getElementById('door2').style.backgroundColor = "white";
change3b();
}
}
attempt = 1;
}
function change1a() {
document.getElementById('door3').style.pointerEvents = "all";
}
function change1b() {
document.getElementById('door2').style.pointerEvents = "all";
}
function change2a() {
document.getElementById('door3').style.pointerEvents = "all";
}
function change2b() {
document.getElementById('door1').style.pointerEvents = "all";
}
}
I tried adapting your code, but it looked too messy for me to understand everything you wanted to do. So, instead, I decided to create my own, just for fun. You can get some inspiration in there.
To answer your specific question, this is the way I choose the door:
var selectedDoor = 1,
correctDoor = 2,
losingDoor = getLosingDoor();
function getLosingDoor() {
var losingDoor;
do {
losingDoor = Math.floor((Math.random() * 3) + 1);
} while ([correctDoor, selectedDoor].indexOf(losingDoor) > -1);
return losingDoor;
}
Full demo
// Create a MontyHall instance in the #app div
var myMontyHall = MontyHall(document.getElementById('app'));
function MontyHall(container) {
var self = {
// Will hold DOM references
refs: null,
// Will hold the MontyHall instance's state
state: null,
/*
* Creates the doors in the DOM and in the state
*/
init: function() {
self.state = {
attempts: 0,
doorCount: 3,
correctDoor: self.getRandomInt(0, 3)
};
self.refs = {
container: container,
instructions: document.createElement('p'),
doorsWrapper: document.createElement('div'),
doors: []
};
// Reset container
self.refs.container.innerHTML = '';
// Setup a container for the doors
self.refs.doorsWrapper.className = 'doors-wrapper';
self.refs.container.appendChild(self.refs.doorsWrapper);
// Setup a container for instructions
self.say('Please select a door.');
self.refs.container.appendChild(self.refs.instructions);
// For each door
for (var i=0; i<self.state.doorCount; i++) {
// Create a div
var el = document.createElement('div');
// Give it a class
el.className = 'door';
// Add click event listener
(function(index) {
el.addEventListener('click', function(){
self.clickOnDoor(index);
});
})(i);
// Append it to the doors container
self.refs.doorsWrapper.append(el);
// Store a reference to it
self.refs.doors.push(el);
}
return self;
},
/*
* Called when a door is clicked
*/
clickOnDoor: function(index) {
self.state.selectedDoor = index;
// If this is the first attempt
if (self.state.attempts === 0) {
// Show it is selected
self.refs.doors[self.state.selectedDoor].classList.add('selected');
// Find a non selected losing door
self.state.losingDoor = self.getLosingDoor();
// Open it
self.refs.doors[self.state.losingDoor].classList.add('disabled', 'loser');
// Update instructions
self.say(
'You selected door #' + (index + 1) + '.<br>'
+ 'I opened door #' + (self.state.losingDoor + 1) + ', '
+ 'it contains a sheep.<br>'
+ 'You can now keep your choice, or change your mind.'
);
self.state.attempts++;
} else {
// For each door
self.refs.doors.forEach(function(el, i) {
// Disable it
el.classList.add('disabled');
// Show it as a winner or a loser
el.classList.add(i === self.state.correctDoor ? 'winner' : 'loser');
// Show it as selected or not
el.classList.toggle('selected', i === index);
});
// Update instructions
self.say(
(
self.state.correctDoor === index ?
'<span class="green">Congratulations, you won!</span>' :
'<span class="red">Sorry, you lost...</span>'
)
+ '<br>'
+ 'The gold was behind door #' + (self.state.correctDoor + 1) + '.<br>'
+ '<button class="restart">Play again</button>'
);
// Enable restart button
self.refs.instructions.querySelector('.restart')
.addEventListener('click', self.init);
}
},
/*
* Returns the index of a losing door, which is not selected
*/
getLosingDoor: function() {
var losingDoor;
do {
losingDoor = self.getRandomInt(0, self.state.doorCount);
} while ([
self.state.correctDoor,
self.state.selectedDoor
].indexOf(losingDoor) > -1);
return losingDoor;
},
/*
* Sets the instructions innerHTML
*/
say: function(html) {
self.refs.instructions.innerHTML = html;
},
/*
* Returns an integer between min and max
*/
getRandomInt: function(min, max) {
return Math.floor((Math.random() * (max-min)) + min);
}
};
return self.init();
}
/* I minified the CSS to avoid cluttering my answer. Full version in link below */body{font-family:Arial,Helvetica,sans-serif;text-align:center}p{margin-top:.2em}button{margin-top:.5em}.door{display:inline-block;width:3em;height:5em;border:1px solid #000;margin:.5em;background-image:url(https://image.ibb.co/c7mssS/doors.jpg);background-size:300% 100%;background-position:center;cursor:pointer;box-shadow:0 0 5px 1px #1070ff;transition:all .3s ease}.door:not(.disabled):hover{opacity:.9}.door.selected{box-shadow:0 0 5px 3px #b910ff}.door.loser{background-position:right}.door.winner{background-position:left}.door.disabled{pointer-events:none}.door.disabled:not(.selected){box-shadow:none}span{font-weight:700}.green{color:#42e25d}.red{color:#ff2f00}
<div id="app"></div>
JSFiddle demo

Adding simple delay to JavaScript code without using external libraries

A quick question, tell me please how to add delay to this code.
I guess it is super simple, but I am new to JavaScript.
I think the answer is somewhere in the beginning within the duration variable.
Here is JavaScript code:
var modern = requestAnimationFrame, duration = 400, initial, aim;
window.smoothScroll = function(target) {
var header = document.querySelectorAll('.aconmineli');
aim = -header[0].clientHeight;
initial = Date.now();
var scrollContainer = document.getElementById(target);
target = document.getElementById(target);
do {
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
}
while (scrollContainer.scrollTop == 0);
do {
if (target == scrollContainer) break;
aim += target.offsetTop;
}
while (target = target.offsetParent);
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present-initial,
progress = Math.min(elapsed/duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
}
else {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {scroll(c, a, b, i)}, 20);
}
}
scroll(scrollContainer, scrollContainer.scrollTop, aim, 0);
}
By the way it is a great pure JavaScript only code for scrolling on clicking.
var modern = requestAnimationFrame,
duration = 400,
initial,
aim,
delay = 1000;
window.smoothScroll = function(target) {
setTimeout(function() {
window.doSmoothScroll(target);
}, delay);
};
window.doSmoothScroll = function(target) {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
var scrollContainer = document.getElementById(target);
target = document.getElementById(target);
do {
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
}
while (scrollContainer.scrollTop === 0);
do {
if (target == scrollContainer) break;
aim += target.offsetTop;
}
while (target == target.offsetParent);
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present - initial,
progress = Math.min(elapsed / duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
} else {
i++;
if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {
scroll(c, a, b, i);
}, 20);
}
};
scroll(scrollContainer, scrollContainer.scrollTop, aim, 0);
};

Randomly generate enemies faster and faster Javascript

Hey I am using a Spawn function I found for a javascript game I am creating to randomy generate enemies to click on. But it is very slow and I would like it to be able to generate faster and faster.. is it possible to modify this code in that way? the spawn function is at the end of the code.
function Gem(Class, Value, MaxTTL) {
this.Class = Class;
this.Value = Value;
this.MaxTTL = MaxTTL;
};
var gems = new Array();
gems[0] = new Gem('green', 10, 0.5);
gems[1] = new Gem('blue', 20, 0.4);
gems[2] = new Gem('red', 50, 0.6);
function Click(event)
{
if(event.preventDefault) event.preventDefault();
if (event.stopPropagation) event.stopPropagation();
else event.cancelBubble = true;
var target = event.target || event.srcElement;
if(target.className.indexOf('gem') > -1){
var value = parseInt(target.getAttribute('data-value'));
var current = parseInt( score.innerHTML );
var audio = new Audio('music/blaster.mp3');
audio.play();
score.innerHTML = current + value;
target.parentNode.removeChild(target);
if (target.className.indexOf('red') > 0){
var audio = new Audio('music/scream.mp3');
audio.play();
endGame("You lose");
}
}
return false;
}
function Remove(id) {
var gem = game.querySelector("#" + id);
if(typeof(gem) != 'undefined')
gem.parentNode.removeChild(gem);
}
function Spawn() {
var index = Math.floor( ( Math.random() * 3 ) );
var gem = gems[index];
var id = Math.floor( ( Math.random() * 1000 ) + 1 );
var ttl = Math.floor( ( Math.random() * parseInt(gem.MaxTTL) * 1000 ) + 1000 ); //between 1s and MaxTTL
var x = Math.floor( ( Math.random() * ( game.offsetWidth - 40 ) ) );
var y = Math.floor( ( Math.random() * ( game.offsetHeight - 44 ) ) );
var fragment = document.createElement('span');
fragment.id = "gem-" + id;
fragment.setAttribute('class', "gem " + gem.Class);
fragment.setAttribute('data-value', gem.Value);
game.appendChild(fragment);
fragment.style.left = x + "px";
fragment.style.top = y + "px";
setTimeout( function(){
Remove(fragment.id);
}, ttl)
}
function Stop(interval) {
clearInterval(interval);
}
function endGame( msg ) {
count = 0;
Stop(interval);
Stop(counter);
var left = document.querySelectorAll("section#game .gem");
for (var i = 0; i < left.length; i++) {
if(left[i] && left[i].parentNode) {
left[i].parentNode.removeChild(left[i]);
}
}
time.innerHTML = msg || "Game Over!";
start.style.display = "block";
UpdateScore();
}
this.Start = function() {
score.innerHTML = "0";
start.style.display = "none";
interval = setInterval(Spawn, 750);
count = 4000;
counter = null;
function timer()
{
count = count-1;
if (count <= 0)
{
endGame();
return;
} else {
time.innerHTML = count + "s left";
}
}
counter = setInterval(timer, 1000);
setTimeout( function(){
Stop(interval);
}, count * 1000)
};
addEvent(game, 'click', Click);
addEvent(start, 'click', this.Start);
HighScores();
}
JS/HTML Performance tips:
1) var gems = new Array(); change to new Array(3);
2) cache all new Audio('...');
3) use getElementById it faster then querySelector('#')
4) prepare var fragment = document.createElement('span'); and cache it, use cloneNode to insert it.
5) fragment.style.left & top change to CSS3 transform: translate(). CSS3 transform use your video card GPU, style.left use CPU...
6) Use only single setInterval and run on all list of fragments.
7) You can make a pool of "fragments" and just show\hide, it will increase performance dramatically.
Basically it works slow due to many page redraws, every time you add new elements to page browser must to redraw whole screen, do not add elements, just show\hide them.

JavaScript countdown timer not starting

I tried using this JavaScript countdown timer on my page but the timer won't start.
What am I doing wrongly?
var CountdownID = null;
var start_msecond = 9;
var start_sec = 120;
window.onload = countDown(start_msecond, start_sec, "timerID");
function countDown(pmsecond, psecond, timerID) {
var msecond = ((pmsecond < 1) ? "" : "") + pmsecond;
var second = ((psecond < 9) ? "0": "") + psecond;
document.getElementById(timerID).innerHTML = second + "." + msecond;
if (pmsecond == 0 && (psecond-1) < 0) { //Recurse timer
clearTimeout(CountdownID);
var command = "countDown("+start_msecond+", "+start_sec+", '"+timerID+"')";
CountdownID = window.setTimeout(command, 100);
alert("Time is Up! Enter your PIN now to subscribe!");
}
else { //Decrease time by one second
--pmsecond;
if (pmsecond == 0) {
pmsecond=start_msecond;
--psecond;
}
if (psecond == 0) {
psecond=start_sec;
}
var command = "countDown("+pmsecond+", "+psecond+", '"+timerID+"')";
CountdownID = window.setTimeout(command, 100);
}
}
<span style="color:red" name="timerID" id="timerID">91.6</span>
here is what you need to do first
window.onload = countDown(start_msecond, start_sec, "timerID");
should be
window.onload = function () {
countDown(start_msecond, start_sec, "timerID");
}
also you should avoid using a string in your setTimeout function:
CountdownID = window.setTimeout(function () {
countDown(pmsecond,psecond,"timerID");
}, 100);
See here http://jsbin.com/ifiyad/2/edit

Categories

Resources