I have a game where every time the user's score is 5, 10, or 15 it adds a new enemy. The numbers I randomly chose and intend to change later on.
I was able to figure out how to add new enemies every time the player reaches one of these scores but I have to make a new boolean variable for every new score. How can I write this same code in a smarter way without many booleans?
Sketch.js
var addEnemyAt5= true; //boolean I have to create over and over
var addEnemyAt10 = true;
var addEnemyAt15 = true;
var score = 0;
if (score == 5 && enemyScore5) {
console.log("new enemy at 5");
addEnemyAt5 = false;
} else if (score == 10 && enemyScore10) {
console.log("new enemy at 10");
addEnemyAt10 = false;
} else if (score == 15 && enemyScore15) {
console.log("new enemy at 15");
addEnemyAt15 = false;
}
HUD.js
this.scoreUpdate = function() {
score += 5;
}
You could create a lastScore variable to track when changes to score have been accounted for:
Sketch.js:
var lastScore = 0
var score = 0
if (score > lastScore) {
if (score === 5) {
console.log("new enemy at 5")
} else if (score === 10) {
console.log("new enemy at 10")
} else if (score === 15) {
console.log("new enemy at 15")
}
lastScore = score
}
HUD.js:
this.scoreUpdate = function() {
score += 5
}
Demo Snippet:
var lastScore = 0
var score = 0
setInterval(function SketchDotJS() {
if (score > lastScore) {
if (score === 5) {
console.log("new enemy at 5")
} else if (score === 10) {
console.log("new enemy at 10")
} else if (score === 15) {
console.log("new enemy at 15")
}
lastScore = score
}
}, 10)
;(function HUDDotJS() {
this.scoreUpdate = function() {
score += 5
}
})()
<!-- Boilerplate code to get the demo to work -->
<button onclick="scoreUpdate()">Increase <var>score</var> by 5</button>
<pre><var>score</var> = <span id="score">0</span></pre>
<script>setInterval(function(e){score===+e.textContent||(e.textContent=score)},10,document.getElementById('score'))</script>
Try perhaps:
createEnemyAtScore = {
5: true,
10: true,
15: true
};
var score = 10;
if (createEnemyAtScore[score]) {
// create your enemy... or whatever..
}
but I would suggest moving this question to CodeReview
You can organize theme into an object
var milestoneMet = {
5: false,
10: false,
15: false
};
// for each milestone, check and set milestoneMet
Related
I'm developing a memory game and i need to calculate the fair score for the game, based on:
number of tries,
time and
number of matches
So, i tried using a function to calculate the score, but when i tried to display the score in the winning screen, the score do not appear. Help me out with this
the variables are
var matches = 0;
var moves = 0;
var counter = document.querySelector(".moves");
To check for the matches:
for (i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function (e) {
var turnable = e.target.dataset.turnable;
//first click
if (!wait && lastKnownButtonId == undefined && lastKnownButtonNumber == undefined && turnable == 'true') {
e.target.dataset.turnable = 'false';
e.target.innerHTML = getgImage(event.target.dataset.number);
e.target.style.backgroundColor = 'yellow';
lastKnownButtonId = e.target.id;
lastKnownButtonNumber = e.target.dataset.number;
}
//second click
else if (!wait && lastKnownButtonId != undefined && lastKnownButtonNumber != undefined && turnable == 'true' && e.target.id != lastKnownButtonId) {
e.target.dataset.turnable = 'false';
e.target.innerHTML = getgImage(event.target.dataset.number);
//match
if (e.target.dataset.number == lastKnownButtonNumber) {
e.target.style.backgroundColor = '#00FF7F';
document.getElementById(lastKnownButtonId).style.backgroundColor = '#00FF7F';
lastKnownButtonId = undefined;
lastKnownButtonNumber = undefined;
matches++;
if (matches == 8) {
document.getElementById("finalMove").innerHTML = moves;
showWinScreen();
//clearTimeout(timeoutHandle);
}
}
//no match
else {
document.getElementById(lastKnownButtonId).style.backgroundColor = 'red';
e.target.style.backgroundColor = 'red';
wait = true;
setTimeout(() => {
e.target.dataset.turnable = 'true';
e.target.style.backgroundColor = 'white'
e.target.innerHTML = getgImage(0);
var tempLastClickedButton = document.getElementById(lastKnownButtonId);
tempLastClickedButton.dataset.turnable = 'true';
tempLastClickedButton.style.backgroundColor = 'white';
tempLastClickedButton.innerHTML = getgImage(0);
lastKnownButtonId = undefined;
lastKnownButtonNumber = undefined;
wait = false;
}, 1000);
}
moveCounter();
}
});
}
i have inserted a function to calculate the score
function calcScore(){
var tilesbonus = (16 - matches) * 20; // 20 points for each successful tile
var timebonus = (60 - finaltime) * 8; // 8 points for each second
var triesbonus = (48 - moves) * 10; // (deduct) 10 points for each try
if (tilesbonus <0) { tilesbonus = 0; }
if (timebonus <0) { timebonus = 0; }
if (triesbonus <0) { triesbonus = 0; }
var totalscore= tilesbonus + timebonus + triesbonus;
return totalscore;
}
The function for timer:
window.onload = function() {
var timeoutHandle;
function countdown(minutes, seconds) {
function tick() {
var timecounter = document.getElementById("timer");
timecounter.innerHTML = minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
seconds--;
if (seconds >= 0) {
timeoutHandle = setTimeout(tick, 1000);
} else {
if (minutes >= 1) {
setTimeout(function () {
countdown(minutes - 1, 59);
}, 1000);
}
}
if (seconds==0 && minutes ==0){
alert("Game over");
//reset();
}
if (matches==8){
var totalscore = calcScore();
clearTimeout(timeoutHandle);
var finaltime= timecounter.innerHTML;
document.getElementById("seconds").innerHTML= finaltime;
document.getElementById("score").innerHTML=totalscore;
}
}
tick();
}
countdown(1, 00); }
the Move counter:
function moveCounter(){
moves++;
counter.innerHTML = moves;
}
the calscore() function is called when the game ends
if (matches==8){
calcScore();
clearTimeout(timeoutHandle);
var finaltime= timecounter.innerHTML;
document.getElementById("seconds").innerHTML= finaltime;
document.getElementById("score").innerHTML=totalscore;
document.getElementById("finalMove").innerHTML = moves;
}
The html code where the score should appear is :
<p><font size= "5">Your score: <span id=score> </span></font></p>
It's because you try to use a variables defined in a fonction from the global scope
here's an explanation of javascript scopes
basically if you declare a variable inside a fonction you can't use it outside of it
corrected and commented your code about this specific problem
var matches = 8
var finaltime = 42
var moves = 13
function calcScore(){
var tilesbonus = (16 - matches) * 20; // 20 points for each successful tile
var timebonus = (60 - finaltime) * 8; // 8 points for each second
var triesbonus = (48 - moves) * 10; // (deduct) 10 points for each try
if (tilesbonus <0) { tilesbonus = 0; }
if (timebonus <0) { timebonus = 0; }
if (triesbonus <0) { triesbonus = 0; }
var totalscore= tilesbonus + timebonus + triesbonus; // you defined the variable here
return totalscore;
} // totalscore is destroyed after the end of the function
if (matches==8){
var totalscore = calcScore(); // I modified this line and now it works
// I declare a new variable which contains the value returned by calcScore
clearTimeout(null); // i don't have the timeout var so I can't clear it
var finaltime= timecounter.innerHTML;
document.getElementById("seconds").innerHTML= finaltime;
document.getElementById("score").innerHTML=totalscore; // finally use the variable
}
<p><font size= "5">Your score: <span id=score> </span></font></p>
<p><font size= "5">finalTime: <span id=seconds> </span></font></p>
<span id=timecounter>42</span>
My goal is, if a page contains the specified button, click it, and increase the amt_clicked by 1. When amt_clicked is greater than 15, wait for 60 seconds and reset amt_clicked. I have no idea how do this if statement. Example:
var amt_clicked = 0;
while (1) {
while (amt_clicked < 15) {
if (button found) { // this is where I am lost
iimPlay("TAG POS={{amt_clicked}} TYPE=BUTTON ATTR=TXT:Get");
amt_clicked++;
}
}
iimPlay("WAIT SECONDS=60");
amt_clicked = 0;
}
This will run 20 times per second, using the window.setInterval() function:
var amt_clicked = 0;
var amt_cooldown = 1200;
setInterval(function(){
if (amt_cooldown === 0)
amt_cooldown = 1200;
else if (amt_cooldown < 1200)
amt_cooldown -= 1;
else if (amt_clicked > 15) {
amt_clicked = 1;
amt_cooldown -= 1;
} else {
amt_clicked -= 1;
//Click
}, 50);
You can use combination of setInterval and setTimeout.
I have added comments to code for you to understand.
var amt_clicked = 0;
var setTimeoutInProcess = false;
//processing the interval click function
setInterval(() => {
checkButtonAgain();
}, 200);
function checkButtonAgain() {
var element = document.getElementById('iNeedtoBeClicked');
//if clicked 15 times then need to wait for 60 seconds
if (amt_clicked === 15) {
if (!setTimeoutInProcess) {
setTimeoutInProcess = true;
setTimeout(function() {
//resetting the amt-clicked
amt_clicked = 0;
setTimeoutInProcess = false;
}, 60000);
} else {
console.log('waiting');
}
} else if (typeof(element) != 'undefined' && element != null) {
//triggering click and increasing the amt_clicked
element.click();
amt_clicked++;
}
console.log(amt_clicked);
}
<button id="iNeedtoBeClicked">Click ME Button</button>
var score = 0, time = 1, heart = 3;
window.onload = function() {
var input = document.getElementById("wordTyped");
var timeLeft = document.getElementById("time");
var life = document.getElementById("life");
input.addEventListener("click", timer, false);
function timer() {
var id = setInterval(countdown, 10);
function countdown() {
input.removeEventListener("click", timer, false);
timeLeft.innerHTML = "Time left: " + (time - 0.01).toFixed(2) + "s";
time = 1 * (time - 0.01).toFixed(2);
if (time == 0 && life.innerHTML == "") {
clearInterval(id);
} else if (time == 0) {
--heart;
time = 1;
life(heart);
}
}
function life(heart) {
heart *= 1; // To make sure it is a number type
console.log(heart);
switch (heart) {
case 2:
life.innerHTML = "❤️❤️";
console.log(life.innerHTML);
break;
case 1:
life.innerHTML = "❤️";
console.log(life.innerHTML);
break;
case 0:
default:
life.innerHTML = "";
console.log(life.innerHTML);
break;
}
/*if(heart === 2) {
life.innerHTML = "❤️❤️";
}
else if(heart == 1) {
life.innerHTML = "❤️";
}
else {
life.innerHTML = "";
}*/
}
}
}
<div id="wordGenerated">illustration</div>
<input id="wordTyped" type="text" />
<div id="time">Time left: 1.00s</div>
<div id="score">Score: 0</div>
<div id="life">❤️❤️❤️</div>
I'm not sure what is wrong within the function life(heart).
I'm trying to decrease the amount of '❤️' by one as the time hit 0 and reset back to its original value, repeating until heart equals to 0.
If I use life.innerHTML = " example " outside the function timer() scope, it will work.
Using console.log(), it shows that life.innerHTML has changed, however, the display of HTML document stays the same and I don't understand why.
I've tried .nodeValue, .innerText, and .textContent, and all still gave the same result
There is a conflict usage with life variable and life() function. Change life() function name to something else like updateLife() and your code works,
Note: You can't have the same name for variable or function or Objects within the scopes.
Demo
var score = 0, time = 1, heart = 3;
window.onload = function() {
var input = document.getElementById("wordTyped");
var timeLeft = document.getElementById("time");
var life = document.getElementById("life");
input.addEventListener("click", timer, false);
function timer() {
var id = setInterval(countdown, 10);
function countdown() {
input.removeEventListener("click", timer, false);
timeLeft.innerHTML = "Time left: " + (time - 0.01).toFixed(2) + "s";
time = 1 * (time - 0.01).toFixed(2);
if (time == 0 && life.innerHTML == "") {
clearInterval(id);
} else if (time == 0) {
--heart;
time = 1;
updateLife(heart);
}
}
function updateLife(heart) {
heart *= 1; // To make sure it is a number type
console.log(heart);
switch (heart) {
case 2:
life.innerHTML = "❤️❤️";
console.log(life.innerHTML);
break;
case 1:
life.innerHTML = "❤️";
console.log(life.innerHTML);
break;
case 0:
default:
life.innerHTML = "";
console.log(life.innerHTML);
break;
}
/*if(heart === 2) {
life.innerHTML = "❤️❤️";
}
else if(heart == 1) {
life.innerHTML = "❤️";
}
else {
life.innerHTML = "";
}*/
}
}
}
<div id="wordGenerated">illustration</div>
<input id="wordTyped" type="text" />
<div id="time">Time left: 1.00s</div>
<div id="score">Score: 0</div>
<div id="life">❤️❤️❤️</div>
there is a conflict between life and life function so you can go like $("#life").innerHTML="" or any thing else
haha = 0;
function dodat(){
haha++;
code here...
}
setInterval(function(){
dodat();
}, 1500-haha);
It is strange, it doesn't seem like time is actually getting added to the setinterval...
Here is my code, SetInterval starts on line 57, function dodat():
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<!DOCTYPE html>
<body onkeypress="pretend();">
<span id="money">25</span>$ - <span id="lives">100</span>/100 lives
<br><br>
<span style="background-color:#2cafe4;cursor:pointer;width:1000px;height:175px;overflow:hidden;position:relative;display:block;" id="track"></span>
<br>
<span id="divthing" style="position:relative;display:block;"></span>
<script>
money = 25;
lives = 100;
mycars = {};
original = 0;
function doofus() {
if($("div:first").offset().left > 1000){
$("div:first").remove();
lives = lives-1;
document.getElementById("lives").innerHTML = lives;
}
}
haha = 0;
function dodat() {
haha = haha+100;
var btn = document.createElement("div");
anyArray = new Array('http://i44.tinypic.com/i4l1r8.png', 'http://i41.tinypic.com/nxs4k8.jpg');
function randOrd(){
return (Math.round(Math.random())-0.5); }
anyArray.sort(randOrd);
btn.innerHTML="<img src='"+anyArray+"' style='height:60px;'>";
btn.style.position = "absolute";
btn.style.left = "0px";
var numba = Math.round(Math.random() * 50);
btn.class = "haha";
btn.id = numba;
mycars[numba] = -50;
var move = function () {
mycars[numba] = mycars[numba] + 1.5;
document.getElementById(numba).style.left = mycars[numba] + "px";
if(mycars[numba] > 100 && mycars[numba] < 150){
document.getElementById(numba).style.top = mycars[numba]/0.5-200 + "px";
}
};
setInterval(move, 10);
document.getElementById("track").appendChild(btn);
}
setInterval(function(){
dodat();
}, 1500-haha);
setInterval(doofus, 200);
function dis1() {
$("#shoot1").css("background-color", "red");
setTimeout('$("#shoot1").css("background-color", "blue");', '1000');
compareEl = $("#shoot1");
// Let's find the closest block!
var otherEls = $('div'),
compareTop = compareEl.offset().top,
compareLeft = compareEl.offset().left,
winningScore = Infinity,
score, winner, curEl;
otherEls.each(function () {
// Calculate the score of this element
curEl = $(this);
score = Math.abs(curEl.offset().left - compareLeft);
if (score < winningScore) {
winningScore = score;
winner = this;
}
});
$("#"+winner.id+"").remove();
money = money+1;
document.getElementById("money").innerHTML=""+money+"";
}
function dis2() {
$("#shoot2").css("background-color", "red");
setTimeout('$("#shoot2").css("background-color", "blue");', '1000');
compareEl2 = $("#shoot2");
// Let's find the closest block!
var otherEls2 = $('div'),
compareTop2 = compareEl2.offset().top,
compareLeft2 = compareEl2.offset().left,
winningScore2 = Infinity,
score2, winner2, curEl2;
otherEls2.each(function () {
// Calculate the score of this element
curEl2 = $(this);
score2 = Math.abs(curEl2.offset().left - compareLeft2);
if (score2 < winningScore2) {
winningScore2 = score2;
winner2 = this;
}
});
$("#"+winner2.id+"").remove();
money = money+1;
document.getElementById("money").innerHTML=""+money+"";
}
function dis3() {
$("#shoot3").css("background-color", "red");
setTimeout('$("#shoot3").css("background-color", "blue");', '1000');
compareEl3 = $("#shoot3");
// Let's find the closest block!
var otherEls3 = $('div'),
compareTop3 = compareEl3.offset().top,
compareLeft3 = compareEl3.offset().left,
winningScore3 = Infinity,
score3, winner3, curEl3;
otherEls3.each(function () {
// Calculate the score of this element
curEl3 = $(this);
score3 = Math.abs(curEl3.offset().left - compareLeft3);
if (score3 < winningScore3) {
winningScore3 = score3;
winner3 = this;
}
});
$("#"+winner3.id+"").remove();
money = money+1;
document.getElementById("money").innerHTML=""+money+"";
}
function dis4() {
$("#shoot4").css("background-color", "red");
setTimeout('$("#shoot4").css("background-color", "blue");', '1000');
compareEl4 = $("#shoot4");
// Let's find the closest block!
var otherEls4 = $('div'),
compareTop4 = compareEl4.offset().top,
compareLeft4 = compareEl4.offset().left,
winningScore4 = Infinity,
score4, winner4, curEl4;
otherEls4.each(function () {
// Calculate the score of this element
curEl4 = $(this);
score4 = Math.abs(curEl4.offset().left - compareLeft4);
if (score4 < winningScore4) {
winningScore4 = score4;
winner4 = this;
}
});
$("#"+winner4.id+"").remove();
money = money+1;
document.getElementById("money").innerHTML=""+money+"";
}
function dis5() {
$("#shoot5").css("background-color", "red");
setTimeout('$("#shoot4").css("background-color", "blue");', '1000');
compareEl5 = $("#shoot5");
// Let's find the closest block!
var otherEls5 = $('div'),
compareTop5 = compareEl5.offset().top,
compareLeft5 = compareEl5.offset().left,
winningScore5 = Infinity,
score5, winner5, curEl5;
otherEls5.each(function () {
// Calculate the score of this element
curEl5 = $(this);
score5 = Math.abs(curEl5.offset().left - compareLeft5);
if (score5 < winningScore5) {
winningScore5 = score5;
winner5 = this;
}
});
$("#"+winner5.id+"").remove();
money = money+1;
document.getElementById("money").innerHTML=""+money+"";
}
function whatareyousingingpatrick(){
if(money >= 15){
money = money-15;
original = original+1;
setInterval("dis"+original+"();", 2400);
var btn = document.createElement("shooter");
btn.style.display = "block";
btn.id = "shoot"+original+"";
btn.style.height = "25px";
btn.style.width = "25px";
btn.style.backgroundColor = "blue";
btn.innerHTML = "<img src='http://www.bubblews.com/assets/images/news/1317280976_1370202845.png' style='height:100%;width:100%;border-radius:100%;opacity:0.7;'>";
btn.style.borderRadius= "100%";
btn.style.boxShadow= "0px 0px 200px 75px rgba(0, 0, 0, 0.2)";
btn.style.position = "absolute";
btn.style.left = event.pageX-8;
btn.style.top = event.pageY-44;
document.getElementById("track").appendChild(btn);
}
else{
alert("Sorry, this dude costs 15 bucks.");
}
}
function whatareyousingingpatrick2(){
if(money >= 25){
money = money-25;
original = original+1;
setInterval("dis"+original+"();", 2000);
var btn = document.createElement("shooter");
btn.style.display = "block";
btn.id = "shoot"+original+"";
btn.style.height = "25px";
btn.style.width = "25px";
btn.style.backgroundColor = "blue";
btn.innerHTML = "<img src='http://static3.wikia.nocookie.net/__cb62439/xwing-miniatures/images/thumb/1/18/Missile_Icon.png/100px-0,111,0,110-Missile_Icon.png' style='height:100%;width:100%;border-radius:100%;opacity:0.7;'>";
btn.style.borderRadius= "100%";
btn.style.boxShadow= "0px 0px 200px 75px rgba(0, 0, 0, 0.2)";
btn.style.position = "absolute";
btn.style.left = event.pageX-8;
btn.style.top = event.pageY-44;
document.getElementById("track").appendChild(btn);
}
else{
alert("Sorry, this dude costs 25 bucks.");
}
}
function pretend(){
if (event.keyCode == 13) {
if(money >= 5){
money = money-5;
$("div").hide();
alert("You have bought the INSTANT KILL feature. Note that you can purchase this feature an unlimited number of times.");
}
else
{
alert("Sorry, the cost of the INSTANT KILL feature is 5$");
}
}
if (event.keyCode == 49) {
if(money >= 40){
money = money-40;
alert("You have bought the FASTER SHOOTING upgrade for your first missile. Note that you can purchase this upgrade an unlimited number of times.");
setInterval("dis1();", "8000");
}
else
{
alert("Sorry, the cost of the FASTER SHOOTING upgrade for this missile is 40$");
}
}
if (event.keyCode == 50) {
if(money >= 40){
money = money-40;
alert("You have bought the FASTER SHOOTING upgrade for your second missile. Note that you can purchase this upgrade an unlimited number of times.");
setInterval("dis2();", "8000");
}
else
{
alert("Sorry, the cost of the FASTER SHOOTING upgrade for this missile is 40$");
}
}
if (event.keyCode == 51) {
if(money >= 40){
money = money-40;
alert("You have bought the FASTER SHOOTING upgrade for your third missile. Note that you can purchase this upgrade an unlimited number of times.");
setInterval("dis3();", "8000");
}
else
{
alert("Sorry, the cost of the FASTER SHOOTING upgrade for this missile is 40$");
}
}
if (event.keyCode == 52) {
if(money >= 40){
money = money-40;
alert("You have bought the FASTER SHOOTING upgrade for your fourth missile. Note that you can purchase this upgrade an unlimited number of times.");
setInterval("dis4();", "8000");
}
else
{
alert("Sorry, the cost of the FASTER SHOOTING upgrade for this missile is 40$");
}
}
}
</script>
<br><br>
<button onclick='$("#track").on("click", function() { whatareyousingingpatrick(); });'>
Get sniper for 15$
</button>
<br>
<button onclick='$("#track").on("click", function() { whatareyousingingpatrick2(); });'>
Get bomb for 25$
</button>
In
setInterval(function(){
dodat();
}, 1500-haha);
The 1500-haha part is only evaluated once, which means the -haha is useless.
If you want the interval to reduce at each call, you might use setTimeout :
(function doone(){
dodat();
setTimeout(doone, 1500-haha); // a halting condition here would be nice
})();
The setInterval will only read that value once. If you want to read it again you have to clear the interval and re-start it.
Something like:
var theInterval = setInterval(function () {
dodat();
}, 1500);
setInterval(doofus, 200);
function reSetIntevar(value) {
clearInterval(theInterval);
theInterval = setInterval(function () {
dodat();
}, 1500 - value);
setInterval(doofus, 200);
}
In my script to generate a playing card, it's generating a 0, even though my random generator is adding a 1, so it should never be 0. What am I doing wrong?! If you refresh, you'll eventually get a "0 of Hearts/Clubs/Diamonds/Spades":
var theSuit;
var theFace;
var theValue;
var theCard;
// deal a card
function generateCard() {
var randomCard = Math.floor(Math.random()*52+1)+1;
return randomCard;
};
function calculateSuit(card) {
if (card <= 13) {
theSuit = "Hearts";
} else if ((card > 13) && (card <= 26)) {
theSuit = "Clubs";
} else if ((card > 26) && (card <= 39)) {
theSuit = "Diamonds";
} else {
theSuit = "Spades";
};
return theSuit;
};
function calculateFaceAndValue(card) {
if (card%13 === 1) {
theFace = "Ace";
theValue = 11;
} else if (card%13 === 13) {
theFace = "King";
theValue = 10;
} else if (card%13 === 12) {
theFace = "Queen";
theValue = 10;
} else if (card%13 === 11) {
theFace = "Jack";
theValue = 10;
} else {
theFace = card%13;
theValue = card%13;
};
return theFace;
return theValue
};
function getCard() {
var randomCard = generateCard();
var theCard = calculateFaceAndValue(randomCard);
var theSuit = calculateSuit(randomCard);
return theCard + " of " + theSuit + " (this card's value is " + theValue + ")";
};
// begin play
var myCard = getCard();
document.write(myCard);`
This line is problematic:
} else if (card%13 === 13) {
Think about it: how a remainder of division to 13 might be equal to 13? ) It may be equal to zero (and that's what happens when you get '0 of... '), but will never be greater than 12 - by the very defition of remainder operation. )
Btw, +1 in generateCard() is not necessary: the 0..51 still give you the same range of cards as 1..52, I suppose.
card%13 === 13
This will evaluate to 0 if card is 13. a % n will never be n. I think you meant:
card % 13 === 0
return theFace;
return theValue
return exits the function; you'll never get to the second statement.