I've created a simple higher or lower card guessing game, it works but once it completes once it then loops through the game logic n^2 times and I cant explain why. I'm really new to coding and JavaScript and I cant figure out what's happening. The issue I currently have is while I'm able to look up concepts in isolation I don't understand enough about the bigger picture to know what interaction is causing the looping.
less useful further info:
Currently the whole script is really a proof of concept, ultimately I will replace the deck building function and just use the random number generator to find images of cards, record all of the previous game events and remove cards from the deck as the game progresses but I cant have it looping by the square of the number of times its been through the game cycle.
Here is the code, please feel free to talk to me like I'm 5, I currently feel like a monkey with a gun.
console.log(">>>>>>>>>>>>>>>>>>>>>>> SCRIPT START");
console.log("variables are defined");
var suitClubs = [];
var suitDiamonds = [];
var suitHearts = [];
var suitSpade = [];
var history = [];
var userGuess;
var activeCard;
var nextCard;
var randomSuitOne;
var randomCardOne;
var randomSuitTwo;
var randomCardTwo;
var activeCardValue;
var nextCardValue;
var gameCycle = 0;
const card = document.querySelector(".card");
const title = document.querySelector(".title");
const historyP = document.querySelector(".history-p");
console.log("buildDeck() is called")
buildDeck();
function buildDeck() {
console.log("Deck is built");
for (i = 1; i <= 13; i++) {
suitDiamonds.push(i + " Diamond");
}
for (i = 1; i <= 13; i++) {
suitHearts.push(i + " Heart");
}
for (i = 1; i <= 13; i++) {
suitClubs.push(i + " Club");
}
for (i = 1; i <= 13; i++) {
suitSpade.push(i + " Spade");
}
var deck = suitClubs.concat(suitDiamonds, suitHearts, suitSpade);
console.log("cardChoice is called");
cardChoice();
};
function cardChoice() {
gameCycle = gameCycle + 1;
console.log(">>>>>>>>>>>>>>>>>>>>>>> GAME CYCLE START");
title.innerHTML = "Higher or Lower!"
activeSequenceCard();
// console.log("activeSequenceCard is called to randomize the active card");
function activeSequenceCard() {
randomSuitOne = Math.floor((Math.random() * 4) + 1);
randomCardOne = Math.floor((Math.random() * 13));
switch (randomSuitOne) {
case 1:
activeCard = suitClubs[randomCardOne];
break;
case 2:
activeCard = suitDiamonds[randomCardOne];
break;
case 3:
activeCard = suitSpade[randomCardOne];
break;
case 4:
activeCard = suitHearts[randomCardOne];
break;
}
card.innerHTML = activeCard;
nextSequenceCard();
// console.group("nextSequenceCard is called to randomize the next card in the deck")
}
function nextSequenceCard() {
randomSuitTwo = Math.floor((Math.random() * 4) + 1);
randomCardTwo = Math.floor((Math.random() * 13));
switch (randomSuitTwo) {
case 1:
nextCard = suitClubs[randomCardTwo];
break;
case 2:
nextCard = suitDiamonds[randomCardTwo];
break;
case 3:
nextCard = suitSpade[randomCardTwo];
break;
case 4:
nextCard = suitHearts[randomCardTwo];
break;
}
historyP.innerHTML = ("The next card will be: " + nextCard);
console.log("randomSuitOne is: " + randomSuitOne + " randomCardOne is: " + randomCardOne);
console.log("randomSuitTwo is: " + randomSuitTwo + " randomCardTwo is: " + randomCardTwo);
gamePlay();
}
}
function gamePlay() {
for (let i = 0; i < 2; i++) {
document.getElementsByClassName("game-button")[i].addEventListener("click", function () {
userGuess = parseInt(this.value);
console.log("The users guess was button (" + this.value + ") " + this.innerHTML + " and is a: " + typeof this.value);
switch (userGuess) {
case 1: console.log("User clicked HIGHER");
if (activeCardValue <= nextCardValue) {
console.log("Case 1: TRUE fired");
title.innerHTML = "CORRECT!"
setTimeout(cardChoice, 2000);
break;
} else {
console.log("Case 1: FALSE fired");
title.innerHTML = "GAME OVER!"
}
break;
case 2: console.log("User clicked LOWER");
if (activeCardValue >= nextCardValue) {
console.log("Case 2: TRUE fired");
title.innerHTML = "CORRECT!"
setTimeout(cardChoice, 2000);
break;
} else {
console.log("Case 2: FALSE fired");
title.innerHTML = "GAME OVER!"
}
break;
} console.log(">>>>>>>>>>>>>>>>>>>>>>> GAME CYCLE ENDS, this is cycle: " + gameCycle);
})
}
activeCardValue = activeCard.split(" ");
activeCardValue = parseInt(activeCardValue.splice(0, 1));
console.log("activeCardValue is: " + activeCardValue);
nextCardValue = nextCard.split(" ");
nextCardValue = parseInt(nextCardValue.splice(0, 1));
console.log("nextCardValue is: " + nextCardValue);
}
Related
I am trying to make a game when you have to guess a number that is generated by the Math.random() function in JavaScript. But I realized that when I do that I have to rerun the function if they get the number wrong. Then the number regenerates when it reruns the function. Is there a way that I can make the variable stay until I want to change it. I was going to change it using the const function but I realized it would do the same thing. Here is my full code:
var tries = 5;
var howMany = 0;
var wrong = 0;
var player1 = 0;
var player2 = 0;
var triesmulti = 10;
var turn = 'player 1';
var number;
function start() {
var min = document.getElementById('min').value;
var max = document.getElementById('max').value;
number = Math.floor(Math.random() * (+max - +min)) + +min;
if (tries < 1) {
alert('You \don\'t have any more tries left. The number was \n' + number);
tries = 5;
wrong += 1;
document.getElementById('wrong').innerHTML = 'You have got the number wrong ' + wrong + ' times';
} else {
var guess = prompt();
if (guess == number) {
alert('You got the number right!\n' + number);
howMany += 1;
tries = 5;
document.getElementById('howMany').innerHTML = 'You have guessed the number ' + howMany + ' times';
document.getElementById('tries').innerHTML = 'You have 5 tries left';
} else {
alert('You got the number wrong.');
tries -= 1;
document.getElementById('tries').innerHTML = 'You have ' + tries + ' tries left';
setTimeout(start, 1000);
}
}
}
function multiplayer() {
var min = document.getElementById('minm').value;
var max = document.getElementById('maxm').value;
number = Math.floor(Math.random() * (+max - +min)) + +min;
if (triesmulti < 1) {
alert('You \don\'t have any more tries left\n' + number);
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
var guess = prompt(turn);
if (turn == 'player 1') {
if (guess == number) {
alert('You got the number right!\n' + number);
player1 += 1;
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
alert('You got the number wrong!');
turn = 'player 2';
setTimeout(multiplayer, 1000);
}
} else if (turn == 'player 2') {
if (guess == number) {
alert('You got the number right!\n' + number);
player2 += 1;
triesmulti = 10;
document.getElementById('triesmulti').innerHTML = 'You have 5 tries for each player';
} else {
alert('You got the number wrong!');
turn = 'player1';
setTimeout(multiplayer, 1000);
}
}
}
}
If you see there, in the setTimeout() it reruns the function.
You can create a stateful random number generator quite easily with an object or closure:
const rndRng = (lo, hi) => ~~(Math.random() * (hi - lo) + lo);
const intRng = (lo, hi) => {
let n = rndRng(lo, hi);
return {
next: () => (n = rndRng(lo, hi)),
get: () => n
};
};
const rng = intRng(10, 20);
console.log(rng.get());
console.log(rng.get());
rng.next();
console.log(rng.get());
console.log(rng.get());
But having to do this shouldn't really be necessary for your application. Currently, the application uses non-idempotent functions that rely on global state, repeated/duplicate logic and deeply nested conditionals, so it's become too encumbered to easily work with.
I'd start by storing state in an object. A game like this can be modeled well by a finite state machine.
The below code is a naive implementation of this with plenty of room for improvement, but hopefully demonstrates the idea. It works for any number of players and it's fairly easy to add features to.
However, string messages are baked into business logic so the class is overburdened. A good next step would be creating a separate view class to abstract business logic from display. However, although the message strings are baked into the game logic, the DOM is decoupled. This makes it fairly easy for the caller to use the class in other UIs such as substituting the DOM for alert/prompt.
The below solution is far from the only way to approach this design problem.
class GuessingGame {
constructor(players=1, guesses=5, lo=0, hi=10) {
this.players = Array(players).fill().map(() => ({
guesses: guesses, score: 0
}));
this.guesses = guesses;
this.lowerBound = lo;
this.upperBound = hi;
this.state = this.initialize;
}
initialize() {
const {lowerBound: lo, upperBound: hi} = this;
this.players = this.players.map(({score}) => ({
guesses: this.guesses,
score: score
}));
this.target = ~~(Math.random() * (hi - lo) + lo);
this.currentPlayer = ~~(Math.random() * this.players.length);
this.state = this.guess;
this.message = `guess a number between ${lo} and ${hi - 1} ` +
`(inclusive), player ${this.currentPlayer}:`;
}
handleCorrectGuess() {
this.state = this.initialize;
this.players[this.currentPlayer].score++;
this.message = `player ${this.currentPlayer} guessed ` +
`${this.target} correctly! press 'enter' to continue.`;
}
handleNoGuessesLeft(guess) {
this.state = this.initialize;
this.players[this.currentPlayer].score--;
this.flash = `${guess} was not the number, player ` +
`${this.currentPlayer}.`;
this.message = `player ${this.currentPlayer} ran out of ` +
`guesses. the secret number was ${this.target}. press ` +
`'enter' to continue.`;
}
handleIncorrectGuess(guess) {
this.flash = `${guess} was not the number, player ` +
`${this.currentPlayer}.`;
this.currentPlayer = (this.currentPlayer + 1) % this.players.length;
const {lowerBound: lo, upperBound: hi} = this;
this.message = `guess a number between ${lo} and ${hi - 1} ` +
`(inclusive), player ${this.currentPlayer}:`;
}
guess(guess) {
if (String(+guess) !== String(guess)) {
this.flash = `sorry, ${guess || "that"} ` +
`isn't a valid number. try something else.`;
return;
}
if (this.target === +guess) {
this.handleCorrectGuess();
}
else if (!--this.players[this.currentPlayer].guesses) {
this.handleNoGuessesLeft(+guess);
}
else {
this.handleIncorrectGuess(+guess);
}
}
nextState(...args) {
this.flash = "";
return this.state(...args);
}
scoreBoard() {
return game.players.map((e, i) =>
`player ${i}: {score: ${e.score}, guesses remaining: ` +
`${e.guesses}} ${game.currentPlayer === i ? "<--" : ""}`
).join("\n");
}
}
const msgElem = document.getElementById("message");
const responseElem = document.getElementById("response");
const scoresElem = document.getElementById("scoreboard");
const game = new GuessingGame(3);
game.nextState();
msgElem.innerText = game.message;
scoresElem.innerText = game.scoreBoard();
let timeout;
responseElem.addEventListener("keydown", e => {
if (timeout || e.code !== "Enter") {
return;
}
game.nextState(e.target.value);
e.target.value = "";
e.target.disabled = true;
msgElem.innerText = game.flash;
clearTimeout(timeout);
timeout = setTimeout(() => {
msgElem.innerText = game.message;
scoresElem.innerText = game.scoreBoard();
timeout = null;
e.target.disabled = false;
e.target.focus();
}, game.flash ? 1300 : 0);
});
* {
background: white;
font-family: monospace;
font-size: 1.03em;
}
input {
margin-bottom: 1em;
margin-top: 1em;
}
<div id="message"></div>
<input id="response">
<div id="scoreboard"></div>
Well, your code is not organised, have lot of duplicates, you could devide it into functions anyway, you can add a boolean variable to check against when you should change the number, I don't know about your HTML code or css but I just added those elements according to you selectors, you can change the multiplayer function too.
var tries = 5;
var howMany = 0;
var wrong = 0;
var player1 = 0;
var player2 = 0;
var triesmulti = 10;
var turn = 'player 1';
var number;
var isAlreadyPlaying = false;
function start() {
var min = document.getElementById('min').value;
var max = document.getElementById('max').value;
if(!isAlreadyPlaying) {
isAlreadyPlaying = true;
number = Math.floor(Math.random() * (+max - +min)) + +min;
}
if (tries < 1) {
alert('You \don\'t have any more tries left. The number was \n' + number);
tries = 5;
wrong += 1;
document.getElementById('wrong').innerHTML = 'You have got the number wrong ' + wrong + ' times';
isAlreadyPlaying = false;
} else {
var guess = prompt();
if (guess == number) {
alert('You got the number right!\n' + number);
howMany += 1;
tries = 5;
document.getElementById('howMany').innerHTML = 'You have guessed the number ' + howMany + ' times';
document.getElementById('tries').innerHTML = 'You have 5 tries left';
isAlreadyPlaying = false;
} else {
alert('You got the number wrong.');
tries -= 1;
document.getElementById('tries').innerHTML = 'You have ' + tries + ' tries left';
setTimeout(start, 1000);
}
}
}
Min <input type="number" id="min" value="1"><br>
Max<input type="number" id="max" value="10"><br>
<button onclick="start()">Play</button>
<p id="wrong"></p>
<p id="howMany"></p>
<p id="tries"></p>
This is a function for a simple shopping app (kinda) thing that I coded to work on my JS skills, considering my elementary experience in it. But everything works except for one thing:
The applyStaffDiscount function doesn't seem to work. Everytime I try to apply an employee discount, the program just returns the same original value that was present before trying to apply the discount. Please help and also let me know how I can improve this program.
function StaffMember(name, discountPercent) {
this.name = name;
this.discountPercent = discountPercent;
}
var sally = new StaffMember("sally", 5);
var bob = new StaffMember("bob", 10);
var arhum = new StaffMember("arhum", 20);
var cashRegister = {
total: 0,
lastTransactionAmount: 0,
add: function(itemCost) {
this.total += (itemCost || 0);
this.lastTransactionAmount = itemCost;
},
scan: function(item, quantity) {
switch (item) {
case "eggs": this.add(0.98 * quantity); break;
case "milk": this.add(1.23 * quantity); break;
case "magazine": this.add(4.99 * quantity); break;
case "chocolate": this.add(0.45 * quantity); break;
}
return true;
},
voidLastTransaction: function() {
this.total -= this.lastTransactionAmount;
this.lastTransactionAmount = 0;
},
applyStaffDiscount: function(employee) {
this.total -= (this.total * (employee.discountPercent/100))
}
};
var cont = confirm("Are you ready to shop?")
while (cont) {
var user = ("Choose your function: A to Add Item, ED for Employee Discount, VT to Void Transaction or just X to Close")
var askUser = prompt(user).toUpperCase()
if (askUser === "A") {
var itemName = prompt("What item would you like?", "Eggs, Milk, Magazine, Chocolate").toLowerCase()
var itemNum = prompt("How many?")
cashRegister.scan(itemName, itemNum)
var cont = confirm("Your total bill is $" + cashRegister.total.toFixed(2) + ". Would you like anything else?")
}
else if (askUser === "ED") {
var name1 = prompt("Please enter you name").toLowerCase()
cashRegister.applyStaffDiscount[name1]
alert("Your total bill is $" + cashRegister.total.toFixed(2) + ".")
}
else if (askUser === "VT") {
cashRegister.voidLastTransaction()
alert("Your previous transaction has been voided. Your total bill is $" + cashRegister.total.toFixed(2) + " now.")
}
else if (askUser === "X") {
cont = false
}
if (cont === false) {
alert("We hope you had a good time. have a nice day!")
}
}
calling applyStaffDiscount should be done as shown below
cashRegister.applyStaffDiscount(name1);
Then inside applyStaffDiscount function, it should be accessed as below
this.total -= (this.total * (window[employee].discountPercent/100))
You didn't call the function in here:
cashRegister.applyStaffDiscount[name1]
Try it with something like this:
cashRegister.applyStaffDiscount(name1);
hey everyone im in my first semester and im pretty new to javascript. i have an assignment thats due in in a few hours and i have been racking my brain trying to figure out why my code wont display the actual function results. this is the assignment.
**Write JavaScript program which implements a fully functioning, five feature
(addition, subtraction, multiplication, division, and modulo/remainder) calculator.
when i run my code it acts like i dont have any input values and returns my alert statement with a 0 or a NaN.
MY CODE SO FAR
var input1 = 0;
var input2 = 0;
var again = true;
function main()
{
while (again === true)
{
inputnum1();
inputnum2();
operator();
}
}
function inputnum1()
{
var input1 = 0;
input1 = parseInt(prompt("Input first number: ", "1"));
while ((isNaN(input1)) || (input1 < 1))
{
input1 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
}
}
function inputnum2()
{
var input2 = 0;
input2 = parseInt(prompt("Input second number: ", "1"));
while ((isNaN(input2)) || (input2 < 1))
{
input1 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
input2 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
}
}
function operator()
{
var option = 0;
var string = "";
string += "\nEnter 0 to terminate calculator: ";
string += "\nEnter 1 for addition: ";
string += "\nEnter 2 for subtraction : ";
string += "\nEnter 3 for multiplication: ";
string += "\nEnter 4 for division: ";
string += "\nEnter 5 for modulo/remainder: ";
option = parseInt(prompt(string, "1"));
while ((isNaN(option)) || (option < 0) || (option >5))
{
option = parseInt(prompt(string, "1"));
}
chosenop(option);
}
function chosenop(option)
{
switch (option)
{
case 0:
alert ("Terminated successfully");
again = false;
break;
case 1:
addition();
break;
case 2:
subtract();
break;
case 3:
multiply();
break;
case 4:
divide();
break;
case 5:
modulo();
break;
}
}
function addition()
{
var sum = input1+input2;
alert ("The sum is: " + sum);
}
function subtract()
{
var diff = input1-input2;
alert("The difference is: " + diff);
}
function multiply()
{
var prod = input1*input2;
alert ("The product is: " + prod);
}
function divide()
{
var quot = (input1 + 0.0)/(input2 + 0.0);
alert ("The quotient is: " + quot);
}
function modulo()
{
var mod = input1%input2;
alert ("The modulo is: " + mod);
}
main();
First off, I'd like you to read through this guide.
Now, to your assignment. This line in inputnum2():
input1 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
is superflous.
At the beginning of your code, you have defined variables input1 and input2. However, in inputnum1() and inputnum2() you do var input1 = 0 and var input2 = 0, which limits their scope to the function block. Here's a wikipedia article on scope. So essentially, just remove them.
This is what your code should look like:
var input1 = 0;
var input2 = 0;
var again = true;
function main()
{
while (again === true)
{
inputnum1();
inputnum2();
operator();
}
}
function inputnum1()
{
input1 = parseInt(prompt("Input first number: ", "1"));
while ((isNaN(input1)) || (input1 < 1))
{
input1 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
}
}
function inputnum2()
{
input2 = parseInt(prompt("Input second number: ", "1"));
while ((isNaN(input2)) || (input2 < 1))
{
input2 = parseInt(prompt("Numeric values starting at 1 only: " , "1"));
}
}
function operator()
{
var option = 0;
var string = "";
string += "\nEnter 0 to terminate calculator: ";
string += "\nEnter 1 for addition: ";
string += "\nEnter 2 for subtraction : ";
string += "\nEnter 3 for multiplication: ";
string += "\nEnter 4 for division: ";
string += "\nEnter 5 for modulo/remainder: ";
option = parseInt(prompt(string, "1"));
while ((isNaN(option)) || (option < 0) || (option >5))
{
option = parseInt(prompt(string, "1"));
}
chosenop(option);
}
function chosenop(option)
{
switch (option)
{
case 0:
alert ("Terminated successfully");
again = false;
break;
case 1:
addition();
break;
case 2:
subtract();
break;
case 3:
multiply();
break;
case 4:
divide();
break;
case 5:
modulo();
break;
}
}
function addition()
{
var sum = input1+input2;
alert ("The sum is: " + sum);
}
function subtract()
{
var diff = input1-input2;
alert("The difference is: " + diff);
}
function multiply()
{
var prod = input1*input2;
alert ("The product is: " + prod);
}
function divide()
{
var quot = (input1 + 0.0)/(input2 + 0.0);
alert ("The quotient is: " + quot);
}
function modulo()
{
var mod = input1%input2;
alert ("The modulo is: " + mod);
}
main();
I'm working on an ordering application that needs to allow for the user to remove a previously entered order. The 'Remove' button currently removes all output from the screen, and when a new order is added, all past orders and the new order reappear, rather than the single new order.
// Global Variables
var orderTotal = 0;
var grandTotal = 0;
var burritos = [];
function init() {
var btnAddToOrder = document.getElementById("addToOrder");
btnAddToOrder.onclick = processOrder;
}
function processOrder() {
var fieldBurrito = document.getElementById("burrito");
var index = fieldBurrito.selectedIndex;
var burritoChoice = fieldBurrito.options[index].value;
var fieldRice = document.getElementsByName("rice");
for (var a = 0; a < fieldRice.length; a++) {
if (fieldRice[a].checked) {
var riceChoice = fieldRice[a].value;
} else {
riceChoice = "No";
}
}
var fieldBeans = document.getElementsByName("beans");
for (var e = 0; e < fieldBeans.length; e++) {
if (fieldBeans[e].checked) {
var beansChoice = fieldBeans[e].value;
} else {
beansChoice = "No";
}
}
var fieldSalsa = document.getElementsByName("salsa");
var salsaChoice = "";
for (var i = 0; i < fieldSalsa.length; i++) {
if (fieldSalsa[i].checked) {
salsaChoice += fieldSalsa[i].value + " ";
}
}
var fieldGuac = document.getElementsByName("guacamole");
for (var o = 0; o < fieldGuac.length; o++) {
if (fieldGuac[o].checked) {
var guacChoice = fieldGuac[o].value;
} else {
guacChoice = "No Guac";
}
}
//Reset the cost of each individual order
orderTotal = 0;
grandTotal = 0;
//Determine the type of burrito and associate correct cost
switch (burritoChoice) {
case "Chicken":
orderTotal += 6.20;
break;
case "Steak":
orderTotal += 6.75;
break;
case "Carnitas":
orderTotal += 6.60;
break;
case "Sofritas":
orderTotal += 6.20;
break;
case "Barbacoa":
orderTotal += 6.60;
break;
}
if (guacChoice == "Guacamole") {
orderTotal += 1.40;
}
var burritoInstance = {
"Burrito":burritoChoice,
"Rice":riceChoice,
"Beans":beansChoice,
"Salsa":salsaChoice,
"Guacamole":guacChoice,
"Price":orderTotal
};
burritos.push(burritoInstance);
// Check to see that the fieldValues array has at least one element
if (burritoChoice !== "Choose a Burrito") {
generateReceipt(burritos);
} else {
console.log("Please choose a burrito type to continue. All other toppings are optional.");
}
}
//********************************************************************************************
function removeButton(i) {
var removeButton = document.createElement("button");
var value = document.createTextNode("Remove Order");
removeButton.appendChild(value);
removeButton.id = i;
removeButton.onclick = function() {
var thing = this.parentNode;
thing.parentNode.removeChild(thing);
}
return removeButton;
}
//--------------------------------------------------------------------------------------------
function br() {
return document.createElement('br');
}
//********************************************************************************************
function generateReceipt(burritos) {
var element = document.getElementById("output");
if(element) {
element.parentNode.removeChild(element);
}
var burritoList = document.createElement("div");
burritoList.id = "output";
for(var i=0; i < burritos.length; i++) {
var outputList = document.createTextNode(burritos[i].Burrito + " Burrito - " +
burritos[i].Rice + " Rice - " +
burritos[i].Beans + " Beans - " +
burritos[i].Salsa + " Salsa - " +
burritos[i].Guacamole + " - $" +
burritos[i].Price);
outputList.id = "burritoInstance";
grandTotal += burritos[i].Price;
burritoList.appendChild(outputList);
burritoList.appendChild(removeButton(i));
burritoList.appendChild(br());
}
var orderTotal = document.createTextNode("Order Total: $" + grandTotal);
burritoList.appendChild(orderTotal);
document.body.appendChild(burritoList);
}
At some point I will need to include logic in the button click to adjust the order total when an order is removed, but first I need to be able to access the order preceding each button.
JSFiddle
For example, 4 is converted to "Four" and 33333 is converted to "Thirty three thousands three hundred and thirty three". I am thinking of using JQUERY instead of plain JAVASCRIPT.
Here is the code in its entirety:
<script language="javascript" type="text/javascript">
function NumberToTextConverter()
{
this.TEN = 10;
this.HUNDRED = 100;
this.THOUSAND = 1000;
this.MILLION = 1000000;
this.BILLION = 1000000000;
this.wordList = new Array("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "TEN", "ELEVEN", "Twelve", "Thirteen", "Fourteen", "fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen");
this.wordList2 = [];
this.initializeTwentys(); // this would populate the twentys
}
NumberToTextConverter.Convert = function(number)
{
var currentConverter = new NumberToTextConverter();
return currentConverter.Convert(number);
};
NumberToTextConverter.prototype.Convert = function(number)
{
var quotient = Math.floor(number / this.BILLION);
var remainder = number % this.BILLION;
var word = "";
var realValue = "";
var converter = this;
if (number < this.BILLION)
{
return converter.ConvertToMillions(number);
}
else
{
var quotientValue = quotient.toString();
if (quotientValue.length == 3)
{
realValue = realValue + converter.ConvertHundreds(quotient) + " billions ";
}
else if (quotientValue.length == 2)
{
realValue = realValue + converter.ConvertToDoubleDigit(quotient) + " billions ";
}
else
{
realValue = realValue + this.wordList[quotient] + " billions ";
}
realValue = realValue + converter.ConvertToMillions(remainder);
}
return realValue;
};
NumberToTextConverter.prototype.ConvertToMillions = function(number)
{
var quotient = Math.floor(number / this.MILLION);
var remainder = number % this.MILLION;
var word = "";
var realValue = "";
var converter = this;
if (number < this.MILLION)
{
return converter.ConverToThousands(number);
}
else
{
var quotientValue = quotient.toString();
if (quotientValue.length == 3)
{
realValue = realValue + converter.ConvertHundreds(quotient) + " millions ";
}
else if (quotientValue.length == 2)
{
realValue = realValue + converter.ConvertToDoubleDigit(quotient) + " millions ";
}
else
{
realValue = realValue + this.wordList[quotient] + " millions ";
}
realValue = realValue + converter.ConverToThousands(remainder);
}
return realValue;
};
NumberToTextConverter.prototype.ConverToThousands = function(number)
{
var quotient = Math.floor(number / this.THOUSAND);
var remainder = number % this.THOUSAND;
var word = "";
var realValue = "";
var converter = this;
if (number < this.THOUSAND)
{
return converter.ConvertHundreds(number);
}
else
{
var quotientValue = quotient.toString();
if (quotientValue.length == 3)
{
realValue = realValue + converter.ConvertHundreds(quotient) + " thousands ";
}
else if (quotientValue.length == 2)
{
realValue = realValue + converter.ConvertToDoubleDigit(quotient) + " thousands ";
}
else
{
realValue = realValue + this.wordList[quotient] + " thousands ";
}
realValue = realValue + converter.ConvertHundreds(remainder);
}
return realValue;
};
NumberToTextConverter.prototype.ConvertHundreds = function(number)
{
var quotient = Math.floor(number / this.HUNDRED);
var remainder = number % this.HUNDRED;
var word = "";
var converter = this;
if (number >= 100)
{
return this.wordList[quotient] + " hundred " + converter.ConvertToDoubleDigit(remainder);
}
else
{
return converter.ConvertToDoubleDigit(remainder);
}
};
NumberToTextConverter.prototype.initializeTwentys = function()
{
this.wordList2[0] = "";
this.wordList2[1] = "TEN";
this.wordList2[2] = "TWENTY";
this.wordList2[3] = "THIRTY";
this.wordList2[4] = "FOURTY";
this.wordList2[5] = "FIFTY";
this.wordList2[6] = "Sixty";
this.wordList2[7] = "Seventy";
this.wordList2[8] = "Eighty";
this.wordList2[9] = "Ninety";
};
NumberToTextConverter.prototype.ConvertSingleDigit = function(number)
{
return this.wordList[number];
};
NumberToTextConverter.prototype.ConvertToDoubleDigit = function(number)
{
var quotient = Math.floor(number / this.TEN);
var remainder = number % this.TEN;
var word = "";
if (number > 19)
{
switch (quotient)
{
case 2: word = this.wordList2[2]; break;
case 3: word = this.wordList2[3]; break;
case 4: word = this.wordList2[4]; break;
case 5: word = this.wordList2[5]; break;
case 6: word = this.wordList2[6]; break;
case 7: word = this.wordList2[7]; break;
case 8: word = this.wordList2[8]; break;
case 9: word = this.wordList2[9]; break;
}
return word + " " + this.wordList[remainder];
}
else
{
return this.wordList[number];
}
};
function PleaseConvert()
{
var value = document.getElementById("txtNumberInput").value;
var checkValue = NumberToTextConverter.Convert(parseInt(value));
var currentSpanTag = document.getElementById("spanText");
currentSpanTag.style.backgroundColor = '#aadd88';
currentSpanTag.style.border = 'dotted 1px #333377';
currentSpanTag.innerHTML = checkValue;
}
Your opinions and ideas are appreciated!! My Question is whether it would be good idea to spend time by implementing this logic using JQUERY? Here is the working code :
http://www.coolaspdotnetcode.com/Web/JavaScriptInfoAndCode.aspx
What exactly do you mean by "convert to jQuery code"? jQuery has really pretty much nothing to do with the code you posted. It is not a different language, it has no magic that will make the Javascript any different. jQuery is a library intended to make it easy to manipulate DOM elements and perform common Javascript tasks cross-browser. It is Javascript, and there's nowhere really where it would fit to have a function such as this one.
If what you really mean is "make a plugin out of this", then it's a 5 liner:
$.fn.humanizeNumber = function() {
return this.each(function() {
$(this).html(CALLTHEFUNCTION($(this).html()));
}
});
Where CALLTHEFUNCTION is whatever is the main function of the code you posted above (I don't really care to go through it and find what it is). That plugin would then let you do this:
$('#myelement').humanizeNumber();
To convert the value in #myelement from "123" to whatever your function returns.
If it's already done this way and it's working I don't see why spending time implementing this in jQuery.
Unless if you want to learn/practice jQuery.
If your code works, then no, don't refactor. Why? Because we don't have much time here, on Earth.
I think a better place for this would be http://refactormycode.com/
Stackoverflow is more geared towards direct Question and Answers, and less for discussions.