Last active
August 29, 2015 22:52
-
-
Save rick4470/62bd2cf6865d78278097 to your computer and use it in GitHub Desktop.
Programming Challenge: Object Oriented Pet Store
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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