diff --git a/assignments/lambda-classes.js b/assignments/lambda-classes.js index 71acfca0e..71f50077d 100644 --- a/assignments/lambda-classes.js +++ b/assignments/lambda-classes.js @@ -1 +1,128 @@ -// CODE here for your Lambda Classes +class Person { + constructor(attributes) { + this.name = attributes.name; + this.age = attributes.age; + this.location = attributes.location; + this.gender = attributes.gender; + } + speak() { + console.log(`Hello my name is ${this.name}, I am from ${this.location}`); + } +} + +class Instructor extends Person { + constructor(attributes) { + super(attributes); + this.specialty = attributes.specialty; + this.favLanguage = attributes.favLanguage; + this.catchPhrase = attributes.catchPhrase; + } + demo(subject) { + console.log(`Today we are learning about ${subject}`); + } + grade(student, subject) { + console.log(`${student.name} receives a perfect score on ${subject}`); + } + educate(student) { + let roundToDecimal = function (num, dec) { + return dec * Math.floor((num / dec)) + }; + while (student.grade > 0 && student.grade < 70) { + + let sign = ( Math.random() < .5 ) ? -1 : 1; + let number = roundToDecimal(Math.random()*10, .01); + let gradeChange = sign * number; + student.grade = roundToDecimal(student.grade + gradeChange, .01); + console.log (`${student.name}'s grade was changed by ${gradeChange}% as a result of the most recent assignment. ${student.name}'s new grade is ${student.grade}%.\n`) + } + student.graduate(); + } +} + +class Student extends Person { + constructor(attributes) { + super(attributes); + this.previousBackground = attributes.background; + this.className = attributes.className; + this.favSubjects = attributes.favSubjects; + this.grade = attributes.grade; + } + listsSubjects() { + for (let subjIndex in this.favSubjects) { + console.log(this.favSubjects[subjIndex]); + } + } + PRAssignment(subject) { + console.log(`${this.name} has submitted a PR for ${subject}`); + } + sprintChallenge(subject) { + console.log(`${this.name} has begun sprint challenge on ${subject}`); + } + graduate() { + if (this.grade < 0) { + console.log(`${this.name} failed out. Fortunately ${this.name} won the lottery soon afterwards and became a professional figure skater.` ); + } else { + console.log(`${this.name} graduated from Lambda School! In an unexpected twist, they abandoned programming for a career in figure skating.`); + } + } +} + +class ProjectManager extends Instructor { + constructor(attributes) { + super(attributes); + this.gradClassName = attributes.gradClassName; + this.favInstructor = attributes.favInstructor; + } + standUp(channel) { + console.log(`${this.name} announces to ${channel}, @channel standup time!`); + } + debugsCode(student, subject) { + console.log(`${this.name} debugs ${student.name}'s code on ${subject}`); + } +} + +const kam = new Student ({ + 'name': 'Kamry Bowman', + 'age': 30, + 'location': 'Denver', + 'gender': 'M', + 'previousBackground': 'Loan Officer', + 'favSubjects': ['Javascript', 'CSS'], + 'grade': 50 +}); +kam.speak(); +kam.listsSubjects(); +kam.PRAssignment('HTML'); +kam.sprintChallenge('Bootstrap'); + +const josh = new Instructor ({ + 'name': 'Josh Knell', + 'age': 33, + 'location': 'San Francisco', + 'gender': 'M', + 'specialty': 'Front-end and Javascript', + 'favLanguage': 'Muong', + 'catchPhrase': 'Of course I know dank memes.' +}); +josh.speak(); +josh.demo('Bootstrap'); +josh.grade(kam, 'touch typing'); + + +const haywood = new ProjectManager ({ + 'name': 'Haywood Johnshon', + 'age': 'Age is just a number', + 'location': 'Next concert venue', + 'gender': 'M', + 'specialty': 'React', + 'favLanguage': 'Python', + 'catchPhrase': 'That\'s what\'s up.', + 'gradClassName': 'CS11', + 'favInstructor': 'All of them equally' +}) +haywood.speak(); +haywood.demo('HTML'); +haywood.grade(kam, 'etiquette'); +haywood.standUp('CS11_Haywood'); +haywood.debugsCode(kam, 'Sign Language'); +haywood.educate(kam); \ No newline at end of file diff --git a/assignments/prototype-refactor.js b/assignments/prototype-refactor.js index e55ae39c0..5b39f69c5 100644 --- a/assignments/prototype-refactor.js +++ b/assignments/prototype-refactor.js @@ -1,83 +1,223 @@ -// Here we have a functioning solutoin to your challenge from yesterday. -// Today your goal is to refactor all of this code to use ES6 Classes. -// The console.log() statements should still return what is expected of them. +/* + Object oriented design is commonly used in video games. For this part of the assignment + you will be implementing several classes with their correct inheritance heirarchy. -function GameObject(options) { - this.createdAt = options.createdAt; - this.dimensions = options.dimensions; + In this file you will be creating three classes: GameObject, CharacterStats, Humanoid. + At the bottom of this file are 3 objects that all inherit from Humanoid. Use the objects at the bottom of the page to test your classes. + + Each class has unique properites and methods that are defined in their block comments below: +*/ + +//GameState +//Holds the current game state, principally characters. Initiates with a list of characters. Characters are Hero and Villain objects held in an array. GameState.heroes and GameState.counts keep +class GameState { + constructor() { + this.characters = []; + this.heroes = 0; + this.villains = 0; + } + //Game Method that receives an initial array of characters and iterates through them, adding each to the GameSTate.characters array by calling GameState.addChar repeatedly. + start(charArr) { + for (let i = 0; i < charArr.length; i++) { + this.addChar(charArr[i]) + } + console.log('Game has begun. Time is not on your side.'); + } + + //adds a character to the characters array. It also increments the heroes or villains properties depending on which character type is added. + addChar(char) { + char.gameloc = this; + this.characters.push(char); + this.updateCharCounts(char, 1); + } + + //removes a character from the characters array. If no villains left, declares victory. If no heroes left, declares loss. + removeChar(char) { + let charArr = this.characters; + let index = -1; + for (let i = 0; i < charArr.length; i++) { + if (charArr[i] === char) { + index = i; + break; + } + } + charArr.slice(index, 1); + this.updateCharCounts(char, -1); + this.checkContinue(); + } + + // receives a character, and an inc Number to change the hero and villain counts of the GameState depending on whether character is a hero or villain. + updateCharCounts(char, inc) { + if (char instanceof Hero) { + this.heroes += inc; + } else if (char instanceof Villain) { + this.villains += inc; + } + } + + //checks if there are still heroes or villains remaining. If one of these counts has gone to 0, then victory or defeat string is logged. + checkContinue() { + if (this.villains < 1) { + console.log('Good has triumphed over evil! This time...'); + } + if (this.heroes < 1) { + console.log('The prophecy has been fulfilled. You and your people are doomed. You see a black mist descend on the village. As you take your last breathe, you realize that death now can only be a mercy.'); + } + } } -GameObject.prototype.destroy = function() { - return `Object was removed from the game.`; -}; +/* + === GameObject === + * createdAt + * dimensions + * destroy() // +*/ +class GameObject { + constructor(dataObj) { + this.createdAt = dataObj.createdAt; + this.dimensions = dataObj.dimensions; + } + //logs the string 'Object was removed from the game.' + destroy() { + if (this.name) { + console.log(`${this.name} was removed from game`); + } + console.log(`${this.constructor.name} was removed from game`); + } +} -function CharacterStats(characterStatsOptions) { - GameObject.call(this, characterStatsOptions); - this.hp = characterStatsOptions.hp; - this.name = characterStatsOptions.name; +/* + === CharacterStats === + * hp + * name + * takeDamage() // prototype method -> logs the string ' took damage.' + * should inherit destroy() from GameObject's prototype +*/ +class CharacterStats extends GameObject { + constructor(dataObj) { + super(dataObj); + this.hp = dataObj.hp; + this.name = dataObj.name; + } + //Logs that object took damage. + //Mutation Effect: Reduces Characters HP. + takeDamage(dmgPts) { + this.hp -= dmgPts; + if (this.hp > 0) { + console.log(`${this.name} took damage. ${this.hp} hit points remain.`); + } else { + if (this instanceof Hero) { + console.log(`Alas, ${this.name} has died.`); + } else { + console.log(`${this.name} was slain!`); + } + this.gameloc.removeChar(this); + } + } } -CharacterStats.prototype = Object.create(GameObject.prototype); +/* + === Humanoid === + * faction + * weapons + * language + * greet() // prototype method -> logs the string ' offers a greeting in .' + * should inherit destroy() from GameObject through CharacterStats + * should inherit takeDamage() from CharacterStats +*/ +class Humanoid extends CharacterStats { + constructor(dataObj) { + super(dataObj); + this.faction = dataObj.faction; + this.weapons = dataObj.weapons; + this.language = dataObj.language; + } + greet() { + console.log(`${this.name} offers a greeting in ${this.language}.`); + } +} -CharacterStats.prototype.takeDamage = function() { - return `${this.name} took damage.`; -}; +//Hero Constructor, descendent of Humanoid +class Hero extends Humanoid { + constructor(dataObj) { + super(dataObj); + } + attack(target) { + // See genericAttack() description + genericAttack.call(this, target, 2); + } +} -function Humanoid(humanoidOptions) { - CharacterStats.call(this, humanoidOptions); - this.faction = humanoidOptions.faction; - this.weapons = humanoidOptions.weapons; - this.language = humanoidOptions.language; +//Villain Constructor, descendent of Humanoid +class Villain extends Humanoid { + constructor(dataObj) { + super(dataObj); + } + attack(target) { + // See genericAttack() description + genericAttack.call(this, target, 3); + } } -Humanoid.prototype = Object.create(CharacterStats.prototype); +//Attack function, used by Hero and Villain classes for their attack methods. Logs a string stating that this attacked target and with what weapon. +//NOTE: Loweres HP of target, and updates GameState if necessary +let genericAttack = function (target, dmg) { + console.log(`${this.name} attacked ${target.name} with ${this.weapons[0]}.`); + target.takeDamage(dmg); +} -Humanoid.prototype.greet = function() { - return `${this.name} offers a greeting in ${this.language}.`; -}; -const mage = new Humanoid({ +const mage = new Hero({ createdAt: new Date(), dimensions: { length: 2, width: 1, - height: 1 + height: 1, }, hp: 5, name: 'Bruce', faction: 'Mage Guild', - weapons: ['Staff of Shamalama'], - language: 'Common Toungue' + weapons: [ + 'Staff of Shamalama', + ], + language: 'Common Toungue', }); -const swordsman = new Humanoid({ +const swordsman = new Villain({ createdAt: new Date(), dimensions: { length: 2, width: 2, - height: 2 + height: 2, }, hp: 15, name: 'Sir Mustachio', faction: 'The Round Table', - weapons: ['Giant Sword', 'Shield'], - language: 'Common Toungue' + weapons: [ + 'Giant Sword', + 'Shield', + ], + language: 'Common Toungue', }); -const archer = new Humanoid({ +const archer = new Hero({ createdAt: new Date(), dimensions: { length: 1, width: 2, - height: 4 + height: 4, }, hp: 10, name: 'Lilith', faction: 'Forest Kingdom', - weapons: ['Bow', 'Dagger'], - language: 'Elvish' + weapons: [ + 'Bow', + 'Dagger', + ], + language: 'Elvish', }); +/* console.log(mage.createdAt); // Today's date console.log(archer.dimensions); // { length: 1, width: 2, height: 4 } console.log(swordsman.hp); // 15 @@ -86,5 +226,26 @@ console.log(swordsman.faction); // The Round Table console.log(mage.weapons); // Staff of Shamalama console.log(archer.language); // Elvish console.log(archer.greet()); // Lilith offers a greeting in Elvish. -console.log(mage.takeDamage()); // Bruce took damage. +console.log(mage.takeDamage(6)); // Bruce took damage. console.log(swordsman.destroy()); // Sir Mustachio was removed from the game. +*/ + +let startingChars = [mage, swordsman, archer]; +let game = new GameState(); +game.start(startingChars); +archer.attack(swordsman); +swordsman.attack(archer); +swordsman.attack(mage); +archer.attack(swordsman); +archer.attack(swordsman); +mage.attack(swordsman); +mage.attack(swordsman); +swordsman.attack(mage); +archer.attack(swordsman); +archer.attack(swordsman); +swordsman.attack(archer); +swordsman.attack(archer); +swordsman.attack(archer); //comment out for victory +// archer.attack(swordsman); //uncomment for victory + +