I have written this code to get the value of the Timer in a div :
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = document.createElement("div");
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container.innerHTML = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
This code works when I link the var timerGenartor with a div. But, now I would like to return the var container into a string. So I changed my code to this : (I just changed the initialization of container and this value)
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
With this modification nothing is returned or display in the console and I don't understand why. However, the comment "console.log" gives me good the timer. So, why the first console.log displays the good result and not the second one ?
The working code as you expected with two JS functions
// JS 1
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
return container;
};
var boundTimeUpdate = timeUpdate.bind(time);
return boundTimeUpdate;
})();
// JS 2
var spanGenerator = (function() {
var container = document.createElement('span');
window.setInterval(function(){
container.innerHTML = timerGenerator();
}, 10);
return container;
})();
document.getElementById('timer').appendChild(spanGenerator);
<div id="timer"></div>
It can be because your container is empty as it is initialized in timeUpdate function which is eventually called 10ms later(for the first time) because of the setInterval. U will have to call the timeUpdate function before putting it in setInterval.
Related
I understand this question has been answered already, but most of them are in jquery. At the moment function one and function two run at the same time. But how do I alter this code so function two only runs after function one has completed its journey to the top of the screen and back down again?
<html>
<head>
<title>JavaScript Animation</title>
</head>
<body>
<script>
function start() {
animation();
animationone();
}
function animation() {
obj = document.getElementById("jbtext");
obj.style.position = "absolute";
obj.style.bottom = "0px";
w = document.body.clientHeight;
goUp = true;
animateText();
}
var obj, w, goUp;
function animateText() {
var pos = parseInt(obj.style.bottom, 10);
(goUp) ? pos++ : pos--;
obj.style.bottom = pos + "px";
if (pos < 0) {
goUp = true;
}
if (pos > w) {
goUp = false;
}
if (pos < 0) {
return;
}
setTimeout(animateText, 10);
}
document.addEventListener("DOMContentLoaded", start, false);
function animationone() {
obja = document.getElementById("jbtexta");
obja.style.position = "absolute";
obja.style.left = "10px";
obja.style.bottom = "10px";
wtwo = document.body.clientWidth;
goRight = true;
animatesecond();
}
var obja, wtwo, goRight;
function animatesecond() {
var position = parseInt(obja.style.left, 10);
(goRight) ? position++ : position--;
obja.style.left = position + "px";
if (position > wtwo) {
goRight = false;
}
if (position < 0) {
goRight = true;
}
if (position < 0) {
return;
}
setTimeout(animatesecond, 10);
}
</script>
<p id="jbtext"> first function</p>
<p id="jbtexta"> second function</p>
</body>
</html>
You can use promises in javascript. Promises are a block of code that will run asynchronously and return at a later point in time. It "returns" by calling the resolve method which is an argument of the Promise constructor. You can then chain promises together to accomplish what you need.
function animationOne() {
return new Promise(function(resolve) {
// ... do your logic for the first animation here here.
resolve(); // <-- call this when your animation is finished.
})
}
function animationTwo() {
return new Promise(function(resolve) {
// ... do your logic for animation two here.
resolve(); // <-- call this when your animation is finished.
})
}
animationOne().then(function() {
animationTwo();
})
This is just another way of Peter LaBanca's answer.
I do not enjoy using Promises. Instead, I use async and await
function runFirst() {
//animation
}
async function waitThenRun() {
await runFirst();
//second animation
}
waitThenRun();
I just don't enjoy the idea of Promise. The code above runs waitThenRun(). That function then runs runFirst(), but waits until it has been finished to run the rest of the function. Having setTimeout or other ways of delaying code in runFirst means you should use Promise. (Pure JS)
MDN
How about the following script AnimationOneAndTwo? The script uses setInterval to “run” the animations. To use it create an instance using the factory method createInstance. Then when the condition or conditions to end the first animation are true call on the next method of the instance to start the second animation. Then when the condition or conditions to end the second animation are true call on the end method of the instance. The following snippet includes the definition for AnimationOneAndTwo and its application to your situation. For more details on how I created the function please refer to “How to Run One Animation after Another: A Reply to a Question at Stack Overflow”.
<html>
<head>
<title>JavaScript Animation</title>
</head>
<body>
<script>
/***
* AnimationOneAndTwo
* Copyright 2019 John Frederick Chionglo (jfchionglo#yahoo.ca)
***/
function AnimationOneAndTwo(parms) {
this.id = parms.id;
}
AnimationOneAndTwo.objs = [];
AnimationOneAndTwo.createProcessLogic = function(parms) {
var obj;
obj = new AnimationOneAndTwo({id: parms.id});
AnimationOneAndTwo.objs[parms.id] = obj;
if ("animationStepOne" in parms) {}
else {
throw new RangeError("animationStepOne not found in parms.");
}
obj["animationStepOne"] = parms.animationStepOne;
if ("animationStepTwo" in parms) {}
else {
throw new RangeError("animationStepTwo not found in parms.");
}
obj["animationStepTwo"] = parms.animationStepTwo;
if ("speed" in parms) {
obj.msf_0 = parms.speed;
}
return obj;
};
with (AnimationOneAndTwo) {
prototype.ap = window;
prototype.dc = window.document;
prototype.np = 6;
prototype.nt = 4;
prototype.ni = 7;
prototype.no = 3;
prototype.nn = 1;
prototype.nr = 1; (function(ia, pa) {
var str, j;
for (j=0; j<ia.length; j++) {
str = ' prototype.' + 'iE_in_' + ia[j] + ' = function() {\n';
str += ' this.s_in_' + ia[j] + ' = ( this.m_' + pa[j] + ' < 1 ? true : false );\n';
str += '};\n';
eval(str);
}
})([1], [0]);
(function(ia, pa) {
var str, j;
for (j=0; j<ia.length; j++) {
str = ' prototype.' + 'iE_in_' + ia[j] + ' = function() {\n';
str += ' this.s_in_' + ia[j] + ' = ( this.m_' + pa[j] + ' < 1 ? false : true );\n';
str += '};\n';
eval(str);
}
})([0,2,3,4,5,6], [0,2,0,2,5,4]);
(function(ia, pa) {
var str, j;
for (j=0; j<ia.length; j++) {
str = ' prototype.' + 'fE_in_' + ia[j] + ' = function() {\n';
str += ' this.m_' + pa[j] + ' -= 1;\n';
str += '};\n';
eval(str);
}
})([3,4,5,6], [0,2,5,4]);
(function(oa, pa, ka) {
var str, j;
for (j=0; j<oa.length; j++) {
str = ' prototype.' + 'fE_ou_' + oa[j] + ' = function() {\n';
str += ' this.m_' + pa[j] + ' += 1;\n';
str += '};\n';
eval(str);
}
})([0,1,2], [1,3,2]);
(function(ta, ia) {
var str, j, k, h;
for (j=0; j<ta.length; j++) {
str = ' prototype.' + 'iE_T_' + ta[j] + ' = function() {\n';
for (h=0; h<ia[j].length; h++) {
k = ia[j][h];
str += ' this.iE_in_' + k + '();\n';
}
if (ia[j].length<1) {
str += ' this.s_t_' + ta[j] + ' = true;\n';
} else {
str += ' this.s_t_' + ta[j] + ' = this.s_in_' + ia[j][0];
for (k=1; k<ia[j].length; k++)
str += ' && this.s_in_' + ia[j][k];
}
str += ';\n';
str += '};\n';
eval(str);
}
})([0,1,2,3], [[0], [1, 2], [3, 6], [4, 5]]);
(function(ta, ia, oa) {
var str, j, k, h;
for (j=0; j<ta.length; j++) {
str = ' prototype.' + 'fE_T_' + ta[j] + ' = function() {\n';
for (h=0; h<ia[j].length; h++) {
k = ia[j][h];
str += ' this.fE_in_' + k + '();\n';
}
for (h=0; h<oa[j].length; h++) {
k = oa[j][h];
str += ' this.fE_ou_' + k + '();\n';
}
str += '};\n';
eval(str);
}
})([0,1,2,3], [[], [], [3, 6], [4, 5]], [[], [], [2], []]);
(function(parms) {
var str, j, k, h, i;
var ta = parms.ta;
var pad = parms.pad;
var pat = parms.pat;
var tar = parms.tar;
var tad = parms.tad;
var tav = parms.tav;
for (i=0; i<ta.length; i++) {
j = ta[i];
str = ' prototype.' + ' pEv_T_' + j + ' = function() {\n';
str += ' this.fE_T_' + j + '();\n';
for (h=0; h<tar[j].length; h++) {
k = tar[j][h];
str += ' this.iE_T_' + k + '();\n';
}
str += ' };\n';
eval(str);
}
})({
ta: [0,1,2,3],
tar: [[0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3], [1, 3]]
});
prototype.pEv_T_0 = function() {
this.fE_T_0();
this.iE_T_0();
this.iE_T_1();
this.iE_T_2();
this.animationStepOne();
};
prototype.pEv_T_1 = function() {
this.fE_T_1();
this.iE_T_0();
this.iE_T_1();
this.iE_T_2();
this.iE_T_3();
this.animationStepTwo();
};
prototype.ipn = function() {
this.iE_T_0();
this.iE_T_1();
this.iE_T_2();
this.iE_T_3();
};
prototype.im = function() {
var j, h, pa;
for (j=0; j<this.np; j++) {
eval('this.m_' + j + ' = 0');
}
pa = [1,2,3];
for (h=0; h<pa.length; h++) {
j = pa[h];
eval('this.m_' + j + ' = ' + 0);
}
pa = [0,4,5];
for (h=0; h<pa.length; h++) {
j = pa[h];
eval('this.m_' + j + ' = ' + 1);
}
};
prototype.ai_0 = undefined;
prototype.msf_0 = 10;
prototype.mss_0 = 1500;
prototype.ms_0 = prototype.msf_0;
prototype.sp_0 = function() {
if (this.ai_0) { this.ap.clearInterval(this.ai_0); this.ai_0 = undefined; }
};
prototype.st_0 = function() {
if (this.ai_0) { this.sp_0(); }
this.ai_0 = this.ap.setInterval('AnimationOneAndTwo.objs[' + this.id + '].rn_0()', this.ms_0);
};
prototype.rn_0 = function() {
var t;
var et = [];
if (this.s_t_0) {
this.pEv_T_0();
} else if (this.s_t_1) {
this.pEv_T_1();
} else {
if (this.ai_0) {
this.sp_0();
}
}
};
prototype.start = function() {
with (this) {
if (ai_0) { sp_0(); }
im();
ipn();
st_0();
}
};
prototype.next = function() {
if (this.s_t_2) {
this.pEv_T_2();
} else if (this.s_t_3) {
this.pEv_T_3();
}
};
prototype.end = function() {
if (this.s_t_2) {
this.pEv_T_2();
}
if (this.s_t_3) {
this.pEv_T_3();
}
};
}
var aotobj;
function start() {
animation();
animationone();
aotobj = AnimationOneAndTwo.createProcessLogic({
id: 12345
, animationStepOne: animateText
, animationStepTwo: animatesecond
});
aotobj.start();
}
function animation() {
obj = document.getElementById("jbtext");
obj.style.position = "absolute";
obj.style.bottom = "0px";
w = document.body.clientHeight;
goUp = true;
// animateText();
}
var obj, w, goUp;
function animateText() {
var pos = parseInt(obj.style.bottom, 10);
(goUp) ? pos++ : pos--;
obj.style.bottom = pos + "px";
if (pos < 0) {
goUp = true;
}
if (pos > w) {
goUp = false;
}
if (pos < 0) {
aotobj.next();
return;
}
// setTimeout(animateText, 10);
}
document.addEventListener("DOMContentLoaded", start, false);
function animationone() {
obja = document.getElementById("jbtexta");
obja.style.position = "absolute";
obja.style.left = "10px";
obja.style.bottom = "10px";
wtwo = document.body.clientWidth;
goRight = true;
// animatesecond();
}
var obja, wtwo, goRight;
function animatesecond() {
var position = parseInt(obja.style.left, 10);
(goRight) ? position++ : position--;
obja.style.left = position + "px";
if (position > wtwo) {
goRight = false;
}
if (position < 0) {
goRight = true;
}
if (position < 0) {
// AnimationOneAndTwo.objs[12345].end();
aotobj.end();
return;
}
// setTimeout(animatesecond, 10);
}
</script>
<p id="jbtext"> first function</p>
<p id="jbtexta"> second function</p>
</body>
</html>
I am stumped. I am not receiving any errors or undefined errors when running this code just a blank return and then a new command line. I've run it about 100 times in the command prompt and still nothing. I figured after 100 times it should display the "Congratulations message". Can anyone take a look and see what I am missing? Thank you in advance.
//Player Class
function Player(name, weapons) {
this.playerName = name;
this.playerHealth = 10;
this.playerStrength = 2;
this.playerWeapons = weapons;
}
Player.prototype.applyDamage = function(damage) {
this.playerHealth = this.playerHealth - damage;
console.log(this.playerName + " " + "has sustained " + " " + this.playerHealth + " " + "amount of damage.");
}
Player.prototype.isAlive = function() {
if(this.playerHealth > 0)
return true;
else
return false;
}
Player.prototype.attacksWith = function() {
var random = Math.floor(Math.random() * 8);
return (this.weapon[random]);
}
//Minion Class
function Minion(minion, health, strength) {
this.minionName = 'Minion';
this.minionHealth = 5;
this.minionStrength = 2;
}
Minion.prototype.applyDamage = function(damage) {
this.minionHealth = this.minionHealth - damage;
console.log(this.minionName + " " + "has sustained " + " " + this.minionHealth + " " + "amount of damage.");
}
Minion.prototype.isAlive = function() {
if(this.minionHealth > 0)
return true;
else
return false;
}
Minion.prototype.attack = function(playerName) {
playerName.applyDamage(this.minionHealth);
}
//Weapons Class
function Weapons(weapon) {
this.weaponName = weapon;
this.weapondamage = Math.floor(Math.random() * 5) + 1;
}
var weaponsCache = [];
for (var i = 0; i < 8; i++) {
var axe = new Weapons("skullCracker");
var hxfx = new Weapons("Hexaflexagon");
var blade = new Weapons("Balmung");
var mario = new Weapons("cappy");
var fire = new Weapons("Fire Breath");
var staff = new Weapons("Magic Staff");
var hrp = new Weapons("Harpe");
var CobaltWep = new Weapons("Cobalt Rifle");
var w = new Weapons([i]);
weaponsCache[i] = w;
}
var player = [];
var i = 0;
while (i < 8) {
var m = new Player();
player[i] = m;
i++;
}
//Game Class
function Game(players, minions) {
this.players = [];
this.minions = [];
}
function attack(player, minion) {
while (playerName.isAlive() && minionName.isAlive()) {
actualDamage = player.strength * this.damage();
minion.applyDamage(actualDamage);
if (minion.isAlive())
minion.attack(player);
else
break;
}
}
function createMinions() {
var i = 0;
while (i > 20) {
var m = new Minion();
minion[i] = m;
i++;
}
}
function createPlayers() {
var player = []; {
var ph = new Player("Prophetic Hamster", weaponsCache);
var mm = new Player("Mighty Mathematician", weaponsCache);
var sieg = new Player ("Siegfried", weaponsCache);
var bd = new Player ("Blue Dragon", weaponsCache);
var ip = new Player("Iron Professor", weaponsCache)
}
Game.prototype.play = function() {
console.log("Simulating Battle...");
createMinion();
createPlayer();
var i = 0,
count = 0;
while (i < 20) {
if (minions[i].isAlive())
count++;
}
if (count == 20) {
i = 0;
var flag = 0;
while (i < 8) {
if (players[i].isAlive())
flag++;
}
while (count == 20 && flag > 0) {
var randomPlayer, randomMinion;
randomPlayer = Math.floor(Math.random() * 8);
randomMinion = math.floor(Math.random() * 20);
weapon = player.attackWith();
attack(minions);
attack(players);
}
count = 0;
i = 0;
while (i > 20) {
if (minions[i].isAlive())
count++;
}
flag = 0;
i = 0;
while (i < 8) {
if (players[i].isAlive())
flag++;
}
if (flag > count)
console.log("Congratulations!! You have defeated Scarlet Byte");
}
}
}
I have some code in my controller, but the code is reusable.. So I would like to move it in a factory and then use the factory everytime I need it... I am not able to move this code to the factory.. If I move it, nothing works anymore. Here the code I have in my controller and that I would like to move in the factory:
var app = angular.module("clock.app");
app.controller('timer',['$scope','$interval','$timeout','timerFactory',
function($scope, $interval,$timeout,timerFactory){
var framework7App = new Framework7();
var $$ = Dom7;
$scope.timeList = [
{"hour":0, "minutes":1, "seconds": 6},
{"hour":0, "minutes":3, "seconds": 180},
{"hour":0, "minutes":5, "seconds": 300}];
var today = new Date();
var arr,hour, minutes, seconds,convertedSec;
var getStoredList = JSON.parse(localStorage.getItem("timeListDetails"));
if(getStoredList !=null){
if(getStoredList.length != 0){
$scope.timeList = getStoredList;
}else{
localStorage.setItem("timeListDetails", JSON.stringify($scope.timeList));
}
}else{
getStoredList = $scope.timeList;
}
$scope.timerWithInterval = 0;
$scope.startTimerWithInterval = function() {
$scope.timerWithInterval = 0;
if($scope.myInterval){
$interval.cancel($scope.myInterval);
}
$scope.onInterval = function(){
$scope.timerWithInterval++;
}
$scope.myInterval = $interval($scope.onInterval,1000);
};
$scope.resetTimerWithInterval = function(){
$scope.timerWithInterval = 0;
$interval.cancel($scope.myInterval);
}
$scope.timeCounterInSeconds= function(seconds) {
$scope.startTimerWithInterval();
$timeout(function () {
$scope.timeCounter(seconds)
}, 1000);
};
$scope.timeCounter = function(seconds) {
if($scope.timerWithInterval==seconds) {
$scope.resetTimerWithInterval();
framework7App.alert('Time Over','');
}
else {
$timeout(function () {
$scope.timeCounter(seconds)
}, 1000);
}
};
$scope.submit = function() {
$scope.timeList.push({"hour":hour,
"minutes":minutes,
"seconds":seconds,
"convertedSec":convertedSec,
"timeFlag": true});
localStorage.setItem("timeListDetails", JSON.stringify($scope.timeList));
$scope.hidePopup();
};
$scope.displayPopup = function(){
$scope.popupAddTimer = true;
}
$scope.hidePopup = function(){
$scope.popupAddTimer = false;
}
timerFactory.picker();
}]);
I have used below factory method:
var factoryApp = angular.module('clock.factories');
factoryApp.factory('timerFactory',[
function() {
var timerFactory = {};
var framework7App = new Framework7();
var $$ = Dom7;
var today = new Date();
var arr,hour, minutes, seconds,convertedSec;
timerFactory.picker = function() {
framework7App.picker({
input: '#picker-date',
container: '#picker-date-container',
toolbar: false,
rotateEffect: true,
value: [today.getHours(), (today.getMinutes() < 10 ? '0' + today.getMinutes() : today.getMinutes()), today.getSeconds()],
onOpen: function(p){
},
formatValue: function (p, values, displayValues) {
arr = displayValues[0] + ':' + values[1] + ':' +values[2];
hour = displayValues[0];
var arrVal = arr.split(":");
convertedSec = (+arrVal[0] * 60 * 60 +(arrVal[1]) *60 +(+arrVal[2]));
minutes = values[1];
seconds = values[2];
return arr;
},
cols: [
// Hours
{
values: (function () {
var arr = [];
for (var i = 0; i <= 23; i++) { arr.push(i); }
return arr;
})(),
},
// Divider
{
divider: true,
content: ':'
},
// Minutes
{
values: (function () {
var arr = [];
for (var i = 0; i <= 59; i++) { arr.push(i < 10 ? '0' + i : i); }
return arr;
})(),
},
// Divider
{
divider: true,
content: ':'
},
// Seconds
{
values: (function () {
var arr = [];
for (var i = 0; i <= 59; i++) { arr.push(i < 10 ? '0' + i : i); }
return arr;
})(),
},
]
});
}
return timerFactory;
}]);
Successfully called picker method but unable to write another methods ($scope methods) in factory. Can anyone please guide me how to do that, as I am new to angularJS.
Also let me know, how to use variables from factory (i.e hour,seconds, minutes) into the controller?
It also not allowing me to use $scope and $interval.
no its not allowed $interval as well
To use the $interval service in a factory, simply inject it in the factory construction function:
app.factory("timerFactory", function($interval) {
//inject here ^^^^^^^^^^
var timer = {};
timer.count = 0;
var intervalPromise;
timer.start = function() {
if (intervalPromise) return;
intervalPromise = $interval(()=>(timer.count++), 1000);
};
timer.stop = function() {
$interval.cancel(intervalPromise);
intervalPromise = null;
};
return timer;
});
The DEMO on JSFiddle.
Counter = function ()
{
var _count;
_count = 0;
this.AddCounter = function()
{
_count++;
};
this.Reset = function ()
{
_count = 10;
};
Object.defineProperty( Counter, 'Value', {
get : function(){ return _count; },
set : function(){ _count = Value; },
configurable: true } );
}
Clock = function ()
{
var second = new Counter();
var minute = new Counter ();
var hour = new Counter();
this.Reset = function()
{
second.Reset();
minute.Reset();
hour.Reset();
};
this.Tick = function()
{
second.AddCounter();
if (second.Value == 60)
{
second.Reset();
minute.AddCounter();
if (minute.Value == 60)
{
minute.Reset();
hour.AddCounter();
}
}
};
this.ReadClock = function()
{
var sz = 0;
var mz = 0;
var hz = 0;
if (second.Value == 9)
{sz = null;}
if (minute.Value == 9)
{mz = null;}
if (hour.Value == 9)
{hz = null;}
document.getElementById("clock").innerHTML = ("" + hz + hour.Value + ":" + mz + minute.Value + ":" + sz +second.Value);
};
}
function Init()
{
var myClock = new Clock();
myClock.Tick();
myClock.ReadClock();
}
window.onload = Init;
The result I'm getting is:
0undefined:0undefined:0undefined
I think the issue is something to do with my Get/Set Property.
Also struggling to get the clock to tick, but that might be solvable once I put the Tick() function in a for loop.
You're creating the accessor property on the Counter constructor function (i.e. Counter.Value), not on the currently created instance:
function Counter() {
var _count = 0;
this.AddCounter = function() {
_count++;
};
this.Reset = function() {
_count = 10;
};
Object.defineProperty(this, 'Value', {
// ^^^^
get: function(){ return _count; },
set: function(val){ _count = val; },
configurable: true
});
}
I've tried this a thousand different ways in a thousand different times and my JS code won't come out the way I want it. When I run it in the Mozilla scratchpad, I get "userHand is undefined" and the second printHand shows as undefined, too. Could someone show me where are the errors in my blackjack game?
function Card (s, n) {
var suit = s;
var number = n;
this.getNumber = function () {
return number;
};
this.getSuit = function () {
return suit;
};
this.getValue = function () {
if (number > 10) {
return 10;
} else if (number === 1) {
return 11;
} else {
return number;
}
};
}
var cardNames = {1:"Ace", 2:"2", 3:"3", 4:"4", 5:"5", 6:"6", 7:"7", 8:"8", 9:"9", 10:"10", 11:"Joker", 12:"Queen", 13:"King"};
var suitNames = {1:"Clubs", 2:"Diamonds", 3:"Hearts", 4:"Spades"};
var deal = function () {
var s = Math.floor(Math.random() * 4 + 1);
var n = Math.floor(Math.random() * 13 + 1);
return new Card(s, n);
};
function Hand(){
var cards = [];
cards.push(deal());
cards.push(deal());
this.getHand = function () {
return cards;
};
this.score = function () {
var score;
for (i = 0; i < cards.length; i++) {
score = score + cards[i].getValue();
}
for (i = 0; i < cards.length; i++) {
if (score > 21 && cards[i].getValue() === 11) {
score = score - 10;
}
} return score;
};
this.printHand = function () {
for (i = 0; i < cards.length; i++) {
var hand;
if (i === 0) {
hand = cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
} else {
hand = hand + " and a " + cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
}
} alert(hand);
};
this.hitMe = function () {
cards.push(deal());
};
}
var playAsDealer = function () {
var playDealer = new Hand();
while (playDealer.score() < 17) {
playDealer.hitMe();
}
this.printHand = function () {
return playDealer.printHand();
};
this.score = function () {
return playDealer.score();
};
};
var playAsUser = function () {
var playUser = new Hand();
this.printHand = function () {
return playUser.printHand();
};
this.score = function () {
return playUser.score();
};
var decision = confirm("Your hand is " + playUser.printHand() + ". Click OK to hit or Cancel to stand");
for (i = 0; decision !== false; i++) {
playUser.hitMe();
decision = confirm("Your hand is " + playUser.printHand() + ". Click OK to hit or Cancel to stand");
}
};
var declareWinner = function (userHand, dealerHand) {
if ((userHand.score < dealerHand.score) || userHand.score > 21) {
return "You lose.";
} else if (userHand.score > dealerHand.score) {
return "You win.";
} else {
return "You tied.";
}
};
var playGame = function () {
var user = playAsUser();
var dealer = playAsDealer();
declareWinner(user, dealer);
console.log("User got " + user.printHand());
console.log("Dealer got " + dealer.printHand());
};
playGame();
You aren't returning nothing on printHand()
I just added the return statement and worked. See this fiddle
this.printHand = function () {
for (i = 0; i < cards.length; i++) {
var hand;
if (i === 0) {
hand = cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
} else {
hand = hand + " and a " + cardNames[cards[i].getNumber()] + " of " + suitNames[cards[i].getSuit()];
}
}
//alert(hand); //remove this alert
return hand; // <----- solution
};