Skip to content

Instantly share code, notes, and snippets.

@rick4470
Last active August 29, 2015 22:52
Show Gist options
  • Select an option

  • Save rick4470/62bd2cf6865d78278097 to your computer and use it in GitHub Desktop.

Select an option

Save rick4470/62bd2cf6865d78278097 to your computer and use it in GitHub Desktop.
Programming Challenge: Object Oriented Pet Store
/* Animal */
var Animal = function () {
var name,
type;
};
Animal.prototype.toString = function (type, location) {
return "A " + type + " moves along the " + location;
};
Animal.prototype.move = function () {};
Animal.prototype.setName = function (name) {
this.name = name;
};
Animal.prototype.getName = function () {
return this.name;
};
Animal.prototype.setType = function (type) {
this.type = type;
};
Animal.prototype.getType = function () {
return this.type;
};
/* Reptile */
var Reptile = function () { /* Abstract Class */ };
Reptile.prototype = new Animal(); // Setup the prototype chain
Reptile.prototype.isAColdBoolded = getBlood('cold');
Reptile.prototype.toString = function () {
return this.getToString();
};
/* ReptileLaysEggs */
var ReptileLaysEggs = function (type, name) {
this.setType(type);
this.setName(name);
};
ReptileLaysEggs.prototype = new Reptile(); // Setup the prototype chain
ReptileLaysEggs.prototype.isFromAnEgg = getBirth('egg');
ReptileLaysEggs.prototype.getToString = function () {
return this.isFromAnEgg() + '\n' + this.isAColdBoolded() + '\n' + Animal.prototype.toString(this.type, 'ground') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
/* ReptileGivesBirth */
var ReptileGivesBirth = function (type, name) {
this.setType(type);
this.setName(name);
};
ReptileGivesBirth.prototype = new Reptile(); // Setup the prototype chain
ReptileGivesBirth.prototype.isALiveBearer = getBirth('livebearer');
ReptileGivesBirth.prototype.getToString = function () {
return this.isALiveBearer() + '\n' + this.isAColdBoolded() + '\n' + Animal.prototype.toString(this.type, 'ground') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
/* Arthropod */
var Arthropod = function () { /* Abstract Class */ };
Arthropod.prototype = new Animal(); // Setup the prototype chain
Arthropod.prototype.isAColdBoolded = getBlood('cold');
Arthropod.prototype.isFromAnEgg = getBirth('egg');
Arthropod.prototype.toString = function () {
return this.getToString();
};
/* Arthropod With Wings */
var ArthropodWithWings = function (type, name) {
this.setType(type);
this.setName(name);
};
ArthropodWithWings.prototype = new Arthropod(); // Setup the prototype chain
ArthropodWithWings.prototype.getToString = function () {
return this.isFromAnEgg() + '\n' + this.isAColdBoolded() + '\n' + this.hasWings() + '\n' + Animal.prototype.toString(this.type, 'sky') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
ArthropodWithWings.prototype.hasWings = function () {
return "A " + this.getType() + " has wings";
};
/* Arthropod Without Wings */
var ArthropodWithoutWings = function (type, name) {
this.setType(type);
this.setName(name);
};
ArthropodWithoutWings.prototype = new Arthropod(); // Setup the prototype chain
ArthropodWithoutWings.prototype.getToString = function () {
return this.isFromAnEgg() + '\n' + this.isAColdBoolded() + '\n' + this.notWinged() + '\n' + Animal.prototype.toString(this.type, 'ground') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
ArthropodWithoutWings.prototype.notWinged = function () {
return "A " + this.getType() + " does not have wings";
};
/* Bird */
var Bird = function (type, name) {
this.setType(type);
this.setName(name);
};
Bird.prototype = new Animal(); // Setup the prototype chain
Bird.prototype.isAWormBoolded = getBlood('warm');
Bird.prototype.hasWings = function () {
return "A " + this.getType() + " uses it's wings";
};
Bird.prototype.isFromAnEgg = getBirth('egg');
Bird.prototype.toString = function () {
return this.isFromAnEgg() + '\n' + this.isAWormBoolded() + '\n' + Animal.prototype.toString(this.type, 'sky') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
/* Amphibian */
var Amphibian = function (type, name) {
this.setType(type);
this.setName(name);
};
Amphibian.prototype = new Animal(); // Setup the prototype chain
Amphibian.prototype.isAColdBoolded = getBlood('cold');
Amphibian.prototype.isFromAnEgg = getBirth('egg');
Amphibian.prototype.toString = function () {
return this.isFromAnEgg() + '\n' + this.isAColdBoolded() + '\n' + Animal.prototype.toString(this.type, 'ground') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
/* Mammal */
var Mammal = function (type, name) {
this.setType(type);
this.setName(name);
};
Mammal.prototype = new Animal(); // Setup the prototype chain
Mammal.prototype.isALiveBearer = getBirth('livebearer');
Mammal.prototype.isAWormBoolded = getBlood('warm');
Mammal.prototype.toString = function () {
return this.isALiveBearer() + '\n' + this.isAWormBoolded() + '\n' + Animal.prototype.toString(this.type, 'ground') + '\nYour ' + this.type + ' is named: ' + this.getName();
};
/* Helper Functions */
function getBlood(type) {
return function () {
return "A " + this.getType() + " is " + type + " blooded";
};
}
function getBirth(type) {
if (type === 'egg') {
return function () {
return "A " + this.getType() + " is from an " + type;
};
} else {
return function () {
return "A " + this.getType() + " is a " + type;
};
}
}
/* Menu Manager */
var Menu = function () {};
Menu.prototype.init = function () {
var animal;
(function promptUser(prompted) {
var prompts = {
menu: 'Main Menu\n1. Select pet\n2. Display selected pet\n3. Exit\n',
rangeMessage: getRangeMessage(1, 3)
};
if (!prompted) {
clearConsole();
}
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
petSelection(false, function (back) {
if (back) {
clearConsole();
promptUser(true);
}
});
break;
case 2:
if (animal === undefined) {
promptUser(false);
console.log('No pet has been selected, please select one');
} else {
clearConsole();
console.log(animal.toString());
prompts = {
message: '\nPress ↳ return key, to back to the main menu.....\n'
};
prompt(prompts, function (keyPressed) {
promptUser(false);
});
}
break;
case 3:
clearConsole();
process.exit();
break;
default:
invalidSelection(undefined, promptUser);
break;
}
});
}());
function petSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Animal Menu\n1. Reptile\n2. Arthropod\n3. Bird\n4. Amphibian\n5. Mammal\n6. Return to main menu\n',
min: 1,
max: 6,
rangeMessage: getRangeMessage(1, 6)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
reptileSelection(false, function (reptile) {
if (reptile instanceof Reptile) {
animalSelected(reptile);
} else {
goBackToMenu(reptile);
}
});
break;
case 2:
arthropodSelection(false, function (arthropod) {
if (arthropod instanceof Arthropod) {
animalSelected(arthropod);
} else {
goBackToMenu(arthropod);
}
});
break;
case 3:
birdSelection(false, function (bird) {
if (bird instanceof Bird) {
animalSelected(bird);
} else {
goBackToMenu(bird);
}
});
break;
case 4:
amphibianSelection(false, function (amphibian) {
if (amphibian instanceof Amphibian) {
animalSelected(amphibian);
} else {
goBackToMenu(amphibian);
}
});
break;
case 5:
mammalSelection(false, function (mammal) {
if (mammal instanceof Mammal) {
animalSelected(mammal);
} else {
goBackToMenu(mammal);
}
});
break;
case 6:
callback(true);
break;
default:
invalidSelection('Animal', petSelection, callback);
break;
}
});
function goBackToMenu(goBack) {
if (goBack && typeof goBack === 'boolean') {
petSelection(false, function (back) {
if (back) {
callback(goBack);
}
});
}
}
function animalSelected(animalSelected) {
clearConsole();
animal = animalSelected;
callback(true);
}
}
function arthropodSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Arthropod Menu\n1. Arthropod Winged\n2. Arthropod Not Winged.\n3. Return to animal\'s menu\n',
rangeMessage: getRangeMessage(1, 3)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
arthropodWinged(false, callback);
break;
case 2:
arthropodNotWinged(false, callback);
break;
case 3:
callback(true);
break;
default:
invalidSelection('Arthropod', arthropodSelection, callback);
break;
}
});
function arthropodWinged(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Arthropod Winged List\n1. Butterflie\n2. Fleas.\n3. Bee\n4. Return to Arthropod menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
var wings = true;
selection = parseInt(selection);
switch (selection) {
case 1:
createArthropod('Butterflie', wings, callback);
break;
case 2:
createArthropod('Fleas', wings, callback);
break;
case 3:
createArthropod('Bee', wings, callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Arthropod', arthropodWinged, callback);
break;
}
});
}
function arthropodNotWinged(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Arthropod NOT winged List\n1. Ants\n2. Cockroache.\n3. Termite\n4. Return to Arthropod menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
var wings = false;
selection = parseInt(selection);
switch (selection) {
case 1:
createArthropod('Ants', wings, callback);
break;
case 2:
createArthropod('Cockroache', wings, callback);
break;
case 3:
createArthropod('Termite', wings, callback);
break;
case 4:
createArthropod(true);
break;
default:
invalidSelection('Arthropod', arthropodNotWinged, callback);
break;
}
});
}
function createArthropod(type, wings, callback) {
prompts = {
message: 'Please enter the name of the ' + type + ': '
};
prompt(prompts, function (name) {
var animal;
if (typeof wings === 'boolean') {
if (wings) {
animal = new ArthropodWithWings(type, name);
} else {
animal = new ArthropodWithoutWings(type, name);
}
}
callback(animal);
});
}
}
function reptileSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Reptile Menu\n1. Reptile that lays eggs\n2. Reptile that is a live bearer.\n3. Return to animal\'s menu\n',
rangeMessage: getRangeMessage(1, 3)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
reptileThatLaysEggs(false, callback);
break;
case 2:
reptileIsLiveBearer(false, callback);
break;
case 3:
callback(true);
break;
default:
invalidSelection('Reptile', reptileSelection, callback);
break;
}
});
function reptileThatLaysEggs(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Reptiles That Lays Eggs List\n1. Cobra\n2. Turtle.\n3. Lizard\n4. Return to Reptile menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
var birthType = 'egg';
selection = parseInt(selection);
switch (selection) {
case 1:
createReptile('Cobra', birthType, callback);
break;
case 2:
createReptile('Turtle', birthType, callback);
break;
case 3:
createReptile('Lizard', birthType, callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Reptile', reptileThatLaysEggs, callback);
break;
}
});
}
function reptileIsLiveBearer(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Reptiles that DONT lay Eggs List\n1. Viper\n2. Llizard.\n3. Chameleon\n4. Return Reptile menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
var birthType = 'birth';
selection = parseInt(selection);
switch (selection) {
case 1:
createReptile('Viper', birthType, callback);
break;
case 2:
createReptile('Llizard', birthType, callback);
break;
case 3:
createReptile('Chameleon', birthType, callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Reptile', reptileIsLiveBearer, callback);
break;
}
});
}
function createReptile(type, birthType, callback) {
prompts = {
message: 'Please enter the name of the ' + type + ': '
};
prompt(prompts, function (name) {
var animal;
if (typeof birthType === 'string' && birthType.length > 0) {
if (birthType === 'birth') {
animal = new ReptileGivesBirth(type, name);
} else if (birthType === 'egg') {
animal = new ReptileLaysEggs(type, name);
}
}
callback(animal);
});
}
}
function birdSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Birds List\n1. Blue bird\n2. Gray bird\n3. Hummingbird\n4. Return to animal\'s menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
createBird('Blue bird', callback);
break;
case 2:
createBird('Gray bird', callback);
break;
case 3:
createBird('Hummingbird', callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Bird', birdSelection, callback);
break;
}
});
function createBird(type, callback) {
prompts = {
message: 'Please enter the name of the ' + type + ': '
};
prompt(prompts, function (name) {
var bird = new Bird(type, name);
callback(bird);
});
}
}
function amphibianSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Amphibian List\n1. Frog\n2. Toad\n3. Caecilian\n4. Return to animal\'s menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
createAmphibian('Frog', callback);
break;
case 2:
createAmphibian('Toad', callback);
break;
case 3:
createAmphibian('Caecilian', callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Bird', birdSelection, callback);
break;
}
});
function createAmphibian(type, callback) {
prompts = {
message: 'Please enter the name of the ' + type + ': '
};
prompt(prompts, function (name) {
var amphibian = new Amphibian(type, name);
callback(amphibian);
});
}
}
function mammalSelection(prompted, callback) {
if (!prompted) {
clearConsole();
}
var prompts = {
menu: 'Mammals Available\n1. Dog\n2. Monkey\n3. Elephant\n4. Return to animal\'s menu\n',
rangeMessage: getRangeMessage(1, 4)
};
prompt(prompts, function (selection) {
selection = parseInt(selection);
switch (selection) {
case 1:
createMammal('Dog', callback);
break;
case 2:
createMammal('Monkey', callback);
break;
case 3:
createMammal('Elephant', callback);
break;
case 4:
callback(true);
break;
default:
invalidSelection('Mammal', mammalSelection, callback);
break;
}
});
function createMammal(type, callback) {
prompts = {
message: 'Please enter the name of the ' + type + ': '
};
prompt(prompts, function (name) {
var mammal = new Mammal(type, name);
callback(mammal);
});
}
}
/* Helper Functions */
function prompt(prompts, callback) {
var stdin = process.stdin,
stdout = process.stdout;
stdin.resume();
if ('menu' in prompts) {
stdout.write(prompts.menu);
}
if ('rangeMessage' in prompts) {
stdout.write(prompts.rangeMessage);
}
if ('message' in prompts) {
stdout.write(prompts.message);
}
stdin.once('data', function (data) {
callback(data.toString().trim());
});
}
function clearConsole() {
process.stdout.write('\033c');
}
function invalidSelection(type, menu, callback) {
clearConsole();
if (typeof type === 'string') {
console.log('Invalid ' + type + ' Selection! Please try again.');
} else {
console.log('Invalid Selection! Please try again.');
}
setTimeout(function () {
menu(true, callback);
}, 300);
}
function getRangeMessage(min, max) {
return "**** Make your choice? It needs be between " + min + " and " + max + " ****\n";
}
}
var menu = new Menu();
menu.init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment