JS Function Calls from HTML + Reactive display - javascript

The game is WAR, or Get Your Neighbour, a traditional game utilising a standard deck of 52 cards, no jokers. Currently the code recognises when a card is above 10 and so the rules of the game are being followed, all that is great, I've designed a timer that takes the value of the card 2-14, subtracts 10, then uses that number for the round of turns the other player has to draw above 10 before you win. Still building the cooperative/multiplayer element but for now, I'd just like to get this bloody button working!
When I click it, it does nothing. Before, it would tell me that "'timerf' is not a function". I'm probably doing something very obvious like problems with the order that things are loaded/data is parsed, but I'm still learning so I'd appreciate any help! Any questions, let me know.
var card = null; // setem 160517
var timer = null; //
window.onload = function() {
function draw(min, max) { // draw a card between 2-14
card = document.getElementById("draw").innerHTML = Math.floor(Math.random()*((max - min)+1) + min); // min 2, max 14
if (card > 10) {
timer = card - 10;
timerf(timer);
} else if (card < 11 && timer > 0) {
timer = timerf(timer-1);
}
} // draw
//draw(2,14);
document.getElementById("clickMe").onclick = draw(2,14);
} // window.onload
function timerf(timer) { // print turns to win
if (timer > 0 && timer < 5 && timer != 1) { // print turns to win
console.log("you have " + timer + " turns to win!");
} else if (timer == 1) {
console.log("you have " + timer + " turn to win!");
}
}
<div id="draw"></div>
<button id="clickMe">WAR!</button>

The return value of the draw function is undefined because it has no return statement.
document.getElementById("clickMe").onclick = draw(2,14);
… so you are assigning undefined to the onclick property.
You have to assign the function you want to call.

Related

How to properly print out list of scores in order from highest to lowest in code.org/javascript?

I have function of "endgame" and here's how the function goes
function endgame() {
setScreen("scorescreen");
ismytimergoing = false;
appendItem(scorelist, score);
for (var i = 0; i < scorelist.length; i++) {
if (scorelist[i] > scorelist[i +1]) {
highestnumber = scorelist[i];
} else if ((scorelist[i] == scorelist[i + 1])) {
highestnumber = scorelist[i];
} else {
highestnumber = scorelist[i + 1];
}
}
setText("scoretext", (scorelist + " ") + namelist);
}
This is a fairly simple click button game and I have a loop which increases the score after each click, different amounts depending on how much the score currently is.
onEvent("clickbutton", "click", function( ) {
setProperty("gamescreen", "background-color", rgb(randomNumber(1, 250), randomNumber(1, 250), randomNumber(1, 250), 0.5));
if (score < 10) {
level = 1;
setText("levelbutton", "level " + level );
score += 1;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
else if ((score >= 10)) {
level = 2;
setText("levelbutton", "level " + level );
score += 2;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
else if ((score >= 50)) {
level = 3;
setText("levelbutton", "level " + level );
score += 3;
setText("scorecounter", "Score = " + score);
changebutton("clickbutton");
changebutton("dontclickbutton");
}
});
The changebutton is a function that changes the background color and text color of whatever "button" is through in the parameter, but that's not the main point here. The function of "Endgame" is what I'm expereincing difficulties with, so here we go. "endgame" is called at least when the wrong button is clicked and when the time runs out, which ever happens during the game. And in my endgame function I have
setText("scoretext", (scorelist + " ") + namelist);
But what is displayed is a whole bunch of numbers, but what I want to be displayed is the list of scores from highest to lowest with the respective names lined up from the namelist. As a side point my start button takes the user input, sets it as a variable called "name" and appends to my namelist. This is an example of the results, I put in meir for name and that displayed ok, but my score was 5 and it showed up as
0,0,0,0,1,2,2,3,3,4,
4,5,5,5 meir
even though the only that should be in my scorelist is 5, so it shouldn't print out all the other stuff. So if I could get any help on to properly sort the scorelist, and have it only print out the scores, and not whole bunch of numbers that would be great, and preferably have it print out the names in order with the scores from highest scoring names to lowest scoring names, that would be great. Thanks in advance.
Someone saw my code and pointed out at least part of the issue. One of the ways the "endgame" function starts is when the time == 0, and I have in my "endgame" function the following.
ismytimergoing = false;
appendItem(scorelist, score);
so I think
ismytimergoing = false;
stops the timer, but that happens when the timer == 0 so the endgame function is keep on happening constantly increasing the scorelist size making it print out a lot of numbers. so I changed the endgame function to be the following.
function endgame() {
setScreen("scorescreen");
ismytimergoing = false;
seconds = 60;
appendItem(scorelist, score);
for (var i = 0; i < scorelist.length; i++) {
if (scorelist[i] > scorelist[i +1]) {
highestnumber = scorelist[i];
} else if ((scorelist[i] == scorelist[i + 1])) {
highestnumber = scorelist[i];
} else {
highestnumber = scorelist[i + 1];
}
}
setText("scoretext", (scorelist + " ") + namelist);
}
I changed the endgame function, so now even if it happens because of the timer turning to zero, the seconds are reset and it's only run once, thus making the scorelist a much easier thing to deal with.

How to investigate why the setTimeout function is not working in my code?

My code works and all values are true so that it should be running, but it does not.
I have tried localizing the variables, changing the timing, and rearranging functions and nametags.
auto1();
var autocount = 0;
var autotrue = 0;
function auto1(){
setTimeout(function() {
while(autotrue==1){
money = money + autocount;
setText("money_display",money);
}
}, 1000);
onEvent("auto1", "click", function(){
if(money >= 10){autotrue = 1;
money = money - 10;
autocount = autocount+1;
console.log("You now have " + autocount + " J$ per second");
} else {
console.log("you have insufficient J$ for this purchase");
}
});
}
I expect it to add 1 to my money variable every 1000 ms. But it does nothing to the money variable
There are a few problems here:
setTimeout only runs once, at the end of 1000 ms. In this case, when it runs, you're going to enter an infinite loop because autotrue is never getting set true. It's still 0 and you're adding it to money and money will never get over 10 because 0+0=0.
If you wanted to repeatedly add to money every 1000 ms, you would use setInterval, without any loop inside. That will call your function over and over every 1000 ms.
There were several issues with your code:
the money variable was not defined
The while loop inside the timer would make the browser freeze
the timeout should be an interval instead
autotrue should probably be a boolean
I faked the setText() function and changed onEvent() to addEventListener() for the sake of a working example:
auto1();
var autocount = 0;
var autotrue = false;
var money = 10;
function auto1() {
autoAddInterval = setInterval(function() {
if (autotrue) {
money = money + autocount;
setText("money_display", money);
}
}, 1000);
document.getElementById('auto1').addEventListener("click", function() {
if (money >= 10) {
autotrue = true;
money = money - 10;
autocount = autocount + 1;
console.log("You now have " + autocount + " J$ per second");
} else {
console.log("you have insufficient J$ for this purchase");
}
});
}
function setText(id, value) {
document.getElementById(id).innerText = value + ' J$';
}
setText("money_display", money);
balance: <span id="money_display">0 J$</span><br>
<button id="auto1">purchase +1 J$ per second</button>
You call auto1 before the variables autocount and autotrue were initialized to 0, therefore they are still undefined and will break your calculations. You should call that function after initializing all the variables.
Additionally while(autotrue==1){ looks as if it is infinite, as there is nothing changing autotrue. Infinite loops are always bad.
Take this out and you will see that the timer works.
while(autotrue==1){
money = money + autocount;
setText("money_display",money);
Your problem is that you are not setting the autotrue var to 1 anywhere.

What is wrong with this code? Am I going about this the right way?

Okay, so I'm fairly new to programming. I've been learning to code for quite sometime now, but I hadn't really MADE anything. That considered, I'm attempting to make my first project using JavaScript and make a snake game. Unfortunately, I've ran into multiple problems, which obviously is something that comes hand in hand with programming, but I am new and I'm stuck. Can someone help me figure out if I'm coding this in an efficient way. Also, I have a more specific issue. I've added basic movement functionality to the head of my snake, but I can't figure out how to get the rest of it's parts to follow. If someone could explain to me how to do this, that would be incredible. I've worked about two weeks now to try and figure it out and I'm just stumped. I'm using Raphael's JavaScript Library to generate the graphics on an SVG canvas.
/*
Libraries in use:
1. Rapheal
2. jQuery
*/
// This variable is set to an array so that we can add multiple snakeParts to our PrimarySnake.
var snakeParts = [],
// This variable uses Raphael to generate a canvas.
snakeCanvas = Raphael(10, 10, 400, 400),
// This generates a rectangle that fills the canvas.
snakeCanvasBg = snakeCanvas.rect(0,0,400,400),
// This variable is set to an array so that we can use each and every direction that is pressed.
direction = [],
// This variable is set to an array so that we can use the turn coordinates of our first snake part.
turnCoords = [];
// Generates and returns a random number between 0 and 400. This function is used to help generate the goal of our snake at a random location on the canvas.
function getRandNum () {
var rand = Math.round(Math.random()*400);
// This while loop ensures that our snakeGoal never exceeds the coordinates x = 390 or y = 390. If it did, it's parts would be cut from the canvas.
while (rand > 395) {
rand = Math.round(Math.random()*400);
}
// This while loop ensures that our rand variabe will always be divisible by 10, which is used to make sure our snakeGoal and snakePart elements are always rendered in coordinates divisible by 10.
while (rand % 10 !== 0) {
var randString = rand.toString(),
// This variable stores the whole length of our randString variable.
randStringLength = randString.length,
// This variable stores the last number of our rand as a string character.
subtractionChar = randString.charAt(randStringLength - 1),
// This variable stores the last number of our rand as a integer.
subtractionInt = parseInt(subtractionChar),
// Finally, this line subtracts the last number of our rand from the entirety and then sets that value equal to rand, ensuring that rand is always divisible by 10.
rand = rand - subtractionInt;
}
return rand;
}
// This function is called any time a button is pressed. The jQuery which method allows our code to compare if the key pressed is equal to the keyCode of a designated key.
$(document).keydown(
function (pressedDirection) {
if (pressedDirection.which === 37) {
direction.push("left");
} else if (pressedDirection.which === 38) {
direction.push("up");
} else if (pressedDirection.which === 39) {
direction.push("right");
} else if (pressedDirection.which === 40) {
direction.push("down");
} else if (pressedDirection.which === 32) {
direction.push("stop");
}
if (pressedDirection.which === 37 || pressedDirection.which === 38 || pressedDirection.which === 39 || pressedDirection.which === 40 || pressedDirection.which === 32) {
console.log(direction[direction.length - 1]);
PrimarySnake.addTurnCoords();
PrimarySnake.movePeice();
}
// This prevents our screen from scrolling when an arrow key is
pressedDirection.preventDefault();
}
);
function Snake () {
// This method generates a new peice to the Snake.
this.addPart = function () {
console.log(snakeParts.length);
snakeParts[snakeParts.length] = snakeCanvas.rect(0,0,10,10);
snakeParts[snakeParts.length - 1].attr("fill", "blue");
snakeParts[snakeParts.length - 1].attr("stroke-width", ".25");
}
// This method provides the movement functionality of our Snake.
this.moveDirection = function () {
for (value in snakeParts) {
var currentCoord = [snakeParts[value].attr("x"), snakeParts[value].attr("y")];
// This if-else statement moves the snakePart at the -value- index up, down, left, or right according to the last direction pressed.
if (direction[direction.length - 1] === "up") {
snakeParts[value].attr("y", currentCoord[1] - 10);
} else if (direction[direction.length - 1] === "down") {
snakeParts[value].attr("y", currentCoord[1] + 10);
} else if (direction[direction.length - 1] === "left") {
snakeParts[value].attr("x", currentCoord[0] - 10);
} else if (direction[direction.length - 1] === "right") {
snakeParts[value].attr("x", currentCoord[0] + 10);
}
}
}
this.moveInterval;
// This function makes our moveDirection move our snakePeice every 50 milliseconds.
this.movePeice = function () {
var moveDirection = this.moveDirection;
// clearInterval is used to eliminate any interval previously running, ensuring that our peices only move one direction at a time.
clearInterval(this.moveInterval);
this.moveInterval = setInterval(function(){moveDirection()}, 50);
}
// This function adds an array of coordinates to the turnCoords array.
this.addTurnCoords = function () {
turnCoords.push([snakeParts[0].attr("x"), snakeParts[0].attr("y")]);
}
}
// This generates a new instance of our Snake class.
var PrimarySnake = new Snake();
// This generates a new part on the canvas.
PrimarySnake.addPart();
// This fills our snakeCanvasBg with a grey color, giving us a grey background.
snakeCanvasBg.attr("fill", "#CDCDCD");
Well, your code seems nice, or at least "efficient" as you are calling it.
To make the parts of your snake follow its head, you must iterate through its parts and assign each (n+1) piece the coordinates from (n). To do so, start with the last piece and iterate up to the first one, which movement is defined by the user, like in:
this.moveDirection = function () {
// Move every piece except the head.
for (var i = snakeParts.length - 1; i > 0; i--) {
snakeParts[i].attr("x", snakeParts[i-1].attr("x"));
snakeParts[i].attr("y", snakeParts[i-1].attr("y"));
}
// Now move the head.
if (direction[direction.length - 1] === "up") {
snakeParts[value].attr("y", currentCoord[1] - 10);
} else if (direction[direction.length - 1] === "down") {
snakeParts[value].attr("y", currentCoord[1] + 10);
} else if (direction[direction.length - 1] === "left") {
snakeParts[value].attr("x", currentCoord[0] - 10);
} else if (direction[direction.length - 1] === "right") {
snakeParts[value].attr("x", currentCoord[0] + 10);
}
}
That code may need a bit of work but that's the idea. Hope it helps!

Javascript countdown then count-up from a prompted variable?

Please Help! I'm new to Javascript, so there's probably an easier solution to this. Basically, I need it to prompt for a number and then count down from that number to zero. Once it reaches zero, I need it to count-up and stop at the same prompted number.
I got it to count down at first, then I completely butchered it, I have no clue what to do.
<script type="text/javascript">
// get number from user
var startNum = parseInt(prompt("Input a number to start counting down from.",""));
var counter = setInterval(timer, 1000);
console.log(startNum);
function timer() {
startNum--; // reduce number by 1
console.log(startNum);
if (startNum <= 0) {
clearInterval(counter);
}
}
var counter = setInterval(timer2, 1000);
var endNum = 0
function timer2() {
console.log(endNum)
endNum++; // add number by 1
console.log(endNum);
if (endNum >= startNum) {
clearInterval(counter);
}
}
</script>
You've got a couple issues here. the first one was pointed out by Rob in the comments. You're running both functions at the same time.
The other issue you have is that you're never storing the number. You're just subtracting and adding to nothing essentially.
So -
<script type="text/javascript">
// get number from user
var startNum = parseInt(prompt("Input a number to start counting down from.",""));
var currentNum = startNum;
var counter = setInterval(timer, 1000);
function timer() {
console.log(currentNum);
currentNum -= 1; // reduce number by 1
console.log(currentNum);
if (currentNum == 0) {
clearInterval(counter);
counter = setInterval(timer2, 1000);
}
}
function timer2() {
console.log(currentNum)
currentNum += 1; // add number by 1
console.log(currentNum);
if (currentNum == startNum) {
clearInterval(counter);
}
}
</script>
Something like this should do the trick. Basically creating another variable to hold your start number and consider that the current number and the value that is going to change.
here's a fiddle - http://jsfiddle.net/w5FM6/
cheers

Javascript code freezes screen for set amount of time

I'm attempting with the following code to
Display the results of a card game,
Wait for 3 seconds while displaying a countdown and then,
Reload the screen.
//Display results, at least that was the idea.
for(var player = 0; player < players.length; player++)
{
resultString = players[player][6]
if (result == null) { resultString += ", its a tie."; }
else
{
resultString += (player == 0 ? ", you" : ", cassino") +
(player == result ? (player == 0 ? " win" : " wins") :
(player == 0 ? " lose" : " loses"));
document.getElementById(player == 0 ? "player" : "casino").
childNodes[0].nodeValue = resultString;
}
showHand(players[player]);
}
//Lag for 3 seconds while displaying a countdown. At least it lags alright.
var time = new Date().getTime();
while (((time / 1000) + 3) - (new Date().getTime() / 1000 ) > 0)
{
document.getElementById("call").childNodes[0].nodeValue = "Next round in "
+ Math.ceil(((time / 1000) + 3) - (new Date().getTime() / 1000 ))
.toFixed(0);
}
//Reload screen. Working fine.
dealHands();
}
The problem is that by running this code the screen instead freezes for 3 seconds before loading the reloading the screen, even though console.log points out no problems with the values to be displayed in the "//Display results" section of the program. In fact, if I comment the portion after the comment "//Lag for 3 seconds..." the results are displayed as intended.
Is there some property of .time() that I'm unaware of that is overriding the code?
If you want to display countdown after 3 seconds, you can put your code to reload the screen in a function and call that function using window.setTimeout which wouldn't freeze the window and function gets invoked after the amount of time you specify there.
And for the countdown display, you can use window.setInterval.

Categories