From 879a6566b51706aea061f3a0dc0ebb33bc81d1cc Mon Sep 17 00:00:00 2001 From: murog Date: Tue, 14 Nov 2017 16:07:27 -0800 Subject: [PATCH 01/18] installed npm --- package-lock.json | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..80043d7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,123 @@ +{ + "name": "js-scrabble", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "add-matchers": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/add-matchers/-/add-matchers-0.5.0.tgz", + "integrity": "sha1-UCGQ5HUM1XIWGDkyaLYaFXNm52U=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "eslint-plugin-jasmine": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.9.1.tgz", + "integrity": "sha1-IuGaWfFvOl9kOgSroEQ40OMEcDA=" + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "requires": { + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.8.0" + } + }, + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=" + }, + "jasmine-expect": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/jasmine-expect/-/jasmine-expect-3.8.1.tgz", + "integrity": "sha512-klARdR5AVX9nZhHhYDlbDYgxgi6kl9DGS0vguhaioKoSwr8HL1uOQ7FFUBASq/sqBL/s2nkh/1efqZ2ugcknFA==", + "requires": { + "add-matchers": "0.5.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} From 638835fac2a36119d93256b572a55902d6dffd06 Mon Sep 17 00:00:00 2001 From: murog Date: Tue, 14 Nov 2017 16:08:04 -0800 Subject: [PATCH 02/18] skipped all describe blocks except score, disabled es-lint --- spec/scrabble_spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index c195a03..b56b5e2 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -1,3 +1,5 @@ + +/* eslint-disable */ const Scrabble = require('../scrabble'); describe('score', function() { @@ -36,7 +38,7 @@ describe('score', function() { }); }); -describe('highestScoreFrom', function() { +xdescribe('highestScoreFrom', function() { it ('is defined', function() { expect(Scrabble.highestScoreFrom).toBeDefined(); }); @@ -97,7 +99,7 @@ describe('highestScoreFrom', function() { }); }); -describe('Player', function() { +xdescribe('Player', function() { it ('is defined', function() { expect(Scrabble.Player).toBeDefined(); }); From 1bef12ad32db5d041ad326dd09c1c2be5ab4f526 Mon Sep 17 00:00:00 2001 From: murog Date: Tue, 14 Nov 2017 16:08:21 -0800 Subject: [PATCH 03/18] passing tests for score describe block --- scrabble.js | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 7a1f161..4bb0642 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,6 +1,45 @@ +/* eslint-disable */ + const Scrabble = { - score: function(word) { - // TODO: implement score + score: function score(word) { + const letters = { + 1: ['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'], + 2: ['D', 'G'], + 3: ['B', 'C', 'M', 'P'], + 4: ['F', 'H', 'V', 'W', 'Y'], + 5: ['K'], + 8: ['J', 'X'], + 10: ['Q', 'Z'] + }; + const keys = Object.keys(letters); + console.log(keys); + let totalScore = 0; + console.log('score starting'); + if (/^[a-zA-Z]+$/.test(word)) { + + } + if (((typeof word === 'string')) && (/^[a-zA-Z]+$/.test(word)) && (word.length < 8)) { + console.log('im a string'); + const chars = word.toUpperCase().match(/\S/g); + console.log(chars); + chars.forEach(function(element) { + keys.forEach(function(num) { + let numLetters = letters[num]; + console.log(numLetters); + if (numLetters.includes(element)) { + console.log(`${num}`); + totalScore += parseFloat(num); + }}) + } + ) + if (word.length === 7) { + totalScore += 50; + } + } else { + throw 'Invalid input'; + } + return totalScore; + } // TODO: add the highestScoreFrom method From 1a5873e96e20a1fb94406a8b9a1f7567ebe7f7a1 Mon Sep 17 00:00:00 2001 From: murog Date: Tue, 14 Nov 2017 16:55:50 -0800 Subject: [PATCH 04/18] first test passing for highestscorefrom --- scrabble.js | 6 ++++-- spec/scrabble_spec.js | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scrabble.js b/scrabble.js index 4bb0642..1894cac 100644 --- a/scrabble.js +++ b/scrabble.js @@ -40,9 +40,11 @@ const Scrabble = { } return totalScore; - } + }, + + highestScoreFrom: function highestScoreFrom(array) { - // TODO: add the highestScoreFrom method + } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index b56b5e2..abec466 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -38,21 +38,21 @@ describe('score', function() { }); }); -xdescribe('highestScoreFrom', function() { +describe('highestScoreFrom', function() { it ('is defined', function() { expect(Scrabble.highestScoreFrom).toBeDefined(); }); - it ('throws if no words were passed', function() { + xit ('throws if no words were passed', function() { expect(function() { Scrabble.highestScoreFrom([]); }).toThrow(); expect(function() { Scrabble.highestScoreFrom('not array'); }).toThrow(); }); - it ('returns the only word in a length-1 array', function() { + xit ('returns the only word in a length-1 array', function() { expect(Scrabble.highestScoreFrom(['dog'])).toBe('dog'); }); - it ('returns the highest word if there are two words', function() { + xit ('returns the highest word if there are two words', function() { // Check score assumptions expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('pig')).toBe(6); @@ -62,7 +62,7 @@ xdescribe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom(['pig', 'dog'])).toBe('pig'); }); - it ('if tied, prefer a word with 7 letters', function() { + xit ('if tied, prefer a word with 7 letters', function() { const loser = 'zzzzzz'; const winner = 'iiiiddd'; @@ -75,7 +75,7 @@ xdescribe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom([winner, loser])).toBe(winner); }); - it ('if tied and no word has 7 letters, prefers the word with fewer letters', function() { + xit ('if tied and no word has 7 letters, prefers the word with fewer letters', function() { // Check score assumptions expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('goat')).toBe(5); @@ -85,7 +85,7 @@ xdescribe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom(['goat', 'dog'])).toBe('dog'); }); - it ('returns the first word of a tie with same letter count', function() { + xit ('returns the first word of a tie with same letter count', function() { // Check score assumptions expect(Scrabble.score('i')).toBe(1); expect(Scrabble.score('dog')).toBe(5); From 04019728f1d0ad75d8abc238f31e13602368b1c9 Mon Sep 17 00:00:00 2001 From: murog Date: Wed, 15 Nov 2017 14:30:58 -0800 Subject: [PATCH 05/18] refactored to include arrow functions and comply with airbnb style guide --- scrabble.js | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/scrabble.js b/scrabble.js index 1894cac..f65b3b8 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,6 +1,9 @@ -/* eslint-disable */ - const Scrabble = { + isValidWord: function isValidWord(word) { + if ((typeof word === 'string') && (/^[a-zA-Z]+$/.test(word)) && (word.length < 8) && (word.length > 0)) { + return true; + } throw new Error('Invalid Word'); + }, score: function score(word) { const letters = { 1: ['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'], @@ -9,42 +12,26 @@ const Scrabble = { 4: ['F', 'H', 'V', 'W', 'Y'], 5: ['K'], 8: ['J', 'X'], - 10: ['Q', 'Z'] + 10: ['Q', 'Z'], }; const keys = Object.keys(letters); - console.log(keys); let totalScore = 0; - console.log('score starting'); - if (/^[a-zA-Z]+$/.test(word)) { - - } - if (((typeof word === 'string')) && (/^[a-zA-Z]+$/.test(word)) && (word.length < 8)) { - console.log('im a string'); + if (this.isValidWord(word)) { const chars = word.toUpperCase().match(/\S/g); - console.log(chars); - chars.forEach(function(element) { - keys.forEach(function(num) { - let numLetters = letters[num]; - console.log(numLetters); - if (numLetters.includes(element)) { - console.log(`${num}`); - totalScore += parseFloat(num); - }}) - } - ) - if (word.length === 7) { - totalScore += 50; + chars.forEach((element) => { + keys.forEach((num) => { + const numLetters = letters[num]; + if (numLetters.includes(element)) { totalScore += parseFloat(num); } + }); + }); + if (word.length === 7) { totalScore += 50; } } - } else { - throw 'Invalid input'; - } return totalScore; - }, highestScoreFrom: function highestScoreFrom(array) { - } + }, }; From 23d6ce707de30d381093851d3541c1fe60cac8be Mon Sep 17 00:00:00 2001 From: murog Date: Wed, 15 Nov 2017 16:33:51 -0800 Subject: [PATCH 06/18] added word class --- scrabble.js | 23 ++++++++++++++++++++--- spec/scrabble_spec.js | 8 ++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/scrabble.js b/scrabble.js index f65b3b8..bbb3b42 100644 --- a/scrabble.js +++ b/scrabble.js @@ -30,13 +30,30 @@ const Scrabble = { }, highestScoreFrom: function highestScoreFrom(array) { - + if ((!Array.isArray(array)) || (array.length === 0)) { throw new Error('Invalid Array'); } + const results = array.map(word => this.score(word)); + const maxResult = { highScore: results[0], index: 0 }; + results.forEach((num, i) => { + if (num > maxResult.highScore) { + maxResult.highestScore = num; + maxResult.index = i; + } + }); + return array[maxResult.index]; }, - -}; +}; // end of class! Scrabble.Player = class { // TODO: implement the Player class }; +Scrabble.Word = class { + constructor(word) { + if (Scrabble.isValidWord(word)) { + this.word = word; + this.score = Scrabble.score(word); + } +}; + + module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index abec466..c0e8925 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -43,16 +43,16 @@ describe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom).toBeDefined(); }); - xit ('throws if no words were passed', function() { + it ('throws if no words were passed', function() { expect(function() { Scrabble.highestScoreFrom([]); }).toThrow(); expect(function() { Scrabble.highestScoreFrom('not array'); }).toThrow(); }); - xit ('returns the only word in a length-1 array', function() { + it ('returns the only word in a length-1 array', function() { expect(Scrabble.highestScoreFrom(['dog'])).toBe('dog'); }); - xit ('returns the highest word if there are two words', function() { + it ('returns the highest word if there are two words', function() { // Check score assumptions expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('pig')).toBe(6); @@ -62,7 +62,7 @@ describe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom(['pig', 'dog'])).toBe('pig'); }); - xit ('if tied, prefer a word with 7 letters', function() { + it ('if tied, prefer a word with 7 letters', function() { const loser = 'zzzzzz'; const winner = 'iiiiddd'; From 3d6fd6f1ec57511b4311c0a681fd8586de1a6ede Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 17:54:47 -0800 Subject: [PATCH 07/18] passing tests for highestScore from --- scrabble.js | 38 +++++++++++++++++++++++++++++--------- spec/scrabble_spec.js | 18 +++++++++--------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/scrabble.js b/scrabble.js index bbb3b42..f55a5f4 100644 --- a/scrabble.js +++ b/scrabble.js @@ -31,15 +31,34 @@ const Scrabble = { highestScoreFrom: function highestScoreFrom(array) { if ((!Array.isArray(array)) || (array.length === 0)) { throw new Error('Invalid Array'); } - const results = array.map(word => this.score(word)); - const maxResult = { highScore: results[0], index: 0 }; - results.forEach((num, i) => { - if (num > maxResult.highScore) { - maxResult.highestScore = num; - maxResult.index = i; - } - }); - return array[maxResult.index]; + const words = array.map(word => new Scrabble.Word(word)); + words.sort(Scrabble._compareWordScores); + const highestScore = words.pop(); + return highestScore.word; + }, + _compareWordScores: function _compareWordScores(a, b) { + const scoreA = a.score; + const scoreB = b.score; + const lengthA = a.word.length; + const lengthB = b.word.length; + + let comparison = 0; + if (scoreA > scoreB) { // greater score wins + comparison = 1; + } else if (scoreA < scoreB) { // lower score loses + comparison = -1; + } else if ((scoreA === scoreB) && (lengthA === 7)) { // tied score, 7 letter word wins + comparison = 1; + } else if ((scoreA === scoreB) && (lengthB === 7)) { // tied lose if other word is 7 letters + comparison = -1; + } else if ((scoreA === scoreB) && (lengthA < lengthB)) { // tied shorter word wins, + comparison = 1; + } else if ((scoreA === scoreB) && (lengthA > lengthB)) { // tied longer word loses + comparison = -1; + } else if ((scoreA === scoreB) && (lengthA === lengthB)) { // return first word + comparison = 1; + } + return comparison; }, }; // end of class! @@ -53,6 +72,7 @@ Scrabble.Word = class { this.word = word; this.score = Scrabble.score(word); } + } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index c0e8925..6063013 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -75,7 +75,7 @@ describe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom([winner, loser])).toBe(winner); }); - xit ('if tied and no word has 7 letters, prefers the word with fewer letters', function() { + it ('if tied and no word has 7 letters, prefers the word with fewer letters', function() { // Check score assumptions expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('goat')).toBe(5); @@ -85,7 +85,7 @@ describe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom(['goat', 'dog'])).toBe('dog'); }); - xit ('returns the first word of a tie with same letter count', function() { + it ('returns the first word of a tie with same letter count', function() { // Check score assumptions expect(Scrabble.score('i')).toBe(1); expect(Scrabble.score('dog')).toBe(5); @@ -99,12 +99,12 @@ describe('highestScoreFrom', function() { }); }); -xdescribe('Player', function() { +describe('Player', function() { it ('is defined', function() { expect(Scrabble.Player).toBeDefined(); }); - describe('Constructor', function() { + xdescribe('Constructor', function() { it('Creates a new player', function() { let name = 'test name'; let player = new Scrabble.Player(name); @@ -116,7 +116,7 @@ xdescribe('Player', function() { }); }); - describe ('play', function() { + xdescribe ('play', function() { it ('Records the played word', function() { let word = 'dog'; let player = new Scrabble.Player('test player'); @@ -150,7 +150,7 @@ xdescribe('Player', function() { }); }); - describe ('totalScore', function() { + xdescribe ('totalScore', function() { it ('Is zero if the player has not played anything', function() { let player = new Scrabble.Player('test player'); expect(player.totalScore()).toBe(0); @@ -168,7 +168,7 @@ xdescribe('Player', function() { }); }); - describe('hasWon', function() { + xdescribe('hasWon', function() { it('returns false when score < 100', function() { let player = new Scrabble.Player('test player'); expect(player.totalScore()).toBe(0); @@ -198,7 +198,7 @@ xdescribe('Player', function() { }); }); - describe('highestScoringWord', function() { + xdescribe('highestScoringWord', function() { // Tie-breaking logic is already described in the tests // for highestWordFrom, so we will not repeat it here. it('returns the highest scoring word played', function() { @@ -214,7 +214,7 @@ xdescribe('Player', function() { }); }); - describe('highestWordScore', function() { + xdescribe('highestWordScore', function() { it('returns the score of the highest scoring word played', function() { let player = new Scrabble.Player('test player'); player.play('cat'); From 2a7770513e76516642a0a5a333df1c0f19564c63 Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 19:01:22 -0800 Subject: [PATCH 08/18] removed extraneous conditional statements from compare function --- scrabble.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scrabble.js b/scrabble.js index f55a5f4..e8c5c37 100644 --- a/scrabble.js +++ b/scrabble.js @@ -47,15 +47,15 @@ const Scrabble = { comparison = 1; } else if (scoreA < scoreB) { // lower score loses comparison = -1; - } else if ((scoreA === scoreB) && (lengthA === 7)) { // tied score, 7 letter word wins + } else if (lengthA === 7) { // tied score, 7 letter word wins comparison = 1; - } else if ((scoreA === scoreB) && (lengthB === 7)) { // tied lose if other word is 7 letters + } else if (lengthB === 7) { // tied lose if other word is 7 letters comparison = -1; - } else if ((scoreA === scoreB) && (lengthA < lengthB)) { // tied shorter word wins, + } else if (lengthA < lengthB) { // tied shorter word wins, comparison = 1; - } else if ((scoreA === scoreB) && (lengthA > lengthB)) { // tied longer word loses + } else if (lengthA > lengthB) { // tied longer word loses comparison = -1; - } else if ((scoreA === scoreB) && (lengthA === lengthB)) { // return first word + } else if (lengthA === lengthB) { // return first word comparison = 1; } return comparison; @@ -63,9 +63,20 @@ const Scrabble = { }; // end of class! Scrabble.Player = class { - // TODO: implement the Player class + constructor(name) { + if (Scrabble.Player.isValidName(name)) { + this.name = name; + } + } + + static isValidName(name) { + if (name.length > 0) { + return true; + } throw new Error('Invalid Name'); } + }; + Scrabble.Word = class { constructor(word) { if (Scrabble.isValidWord(word)) { From 4fc941ef8008efdcac90dd23e325cbe0bc687a5d Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 19:02:48 -0800 Subject: [PATCH 09/18] passing test for creating valid player --- spec/scrabble_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 6063013..6f3b944 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -104,7 +104,7 @@ describe('Player', function() { expect(Scrabble.Player).toBeDefined(); }); - xdescribe('Constructor', function() { + describe('Constructor', function() { it('Creates a new player', function() { let name = 'test name'; let player = new Scrabble.Player(name); From f2f8e106eaeb759f36f9eb9578791838730dead9 Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 19:56:10 -0800 Subject: [PATCH 10/18] passing tests for play and total score --- scrabble.js | 33 +++++++++++++++++++++++++++------ spec/scrabble_spec.js | 4 ++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/scrabble.js b/scrabble.js index e8c5c37..13556d2 100644 --- a/scrabble.js +++ b/scrabble.js @@ -66,23 +66,44 @@ Scrabble.Player = class { constructor(name) { if (Scrabble.Player.isValidName(name)) { this.name = name; + this.plays = []; } } static isValidName(name) { if (name.length > 0) { return true; - } throw new Error('Invalid Name'); } - + } throw new Error('Invalid Name'); + } + play(word) { + if (!this.hasWon()) { + const playedWord = new Scrabble.Word(word); + this.plays.push(playedWord.word); + this.totalScore(); + return playedWord.word; + } return false; + } + hasWon() { + const currentScore = this.totalScore(); + if (currentScore >= 100) { + return true; + } return false; + } + totalScore() { + const words = this.plays.map(word => (new Scrabble.Word(word)).score); + // words = words.map(word => word.score); + const score = words.reduce((a, b) => a + b, 0); + return score; + } }; Scrabble.Word = class { constructor(word) { - if (Scrabble.isValidWord(word)) { - this.word = word; - this.score = Scrabble.score(word); - } + if (Scrabble.isValidWord(word)) { + this.word = word; + this.score = Scrabble.score(word); + } } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 6f3b944..6397fb0 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -116,7 +116,7 @@ describe('Player', function() { }); }); - xdescribe ('play', function() { + describe ('play', function() { it ('Records the played word', function() { let word = 'dog'; let player = new Scrabble.Player('test player'); @@ -150,7 +150,7 @@ describe('Player', function() { }); }); - xdescribe ('totalScore', function() { + describe ('totalScore', function() { it ('Is zero if the player has not played anything', function() { let player = new Scrabble.Player('test player'); expect(player.totalScore()).toBe(0); From 0ce66c027dc8bc4115c165634d05fe34217a77eb Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 19:59:03 -0800 Subject: [PATCH 11/18] passing tests for hasWon --- spec/scrabble_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 6397fb0..624500f 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -168,7 +168,7 @@ describe('Player', function() { }); }); - xdescribe('hasWon', function() { + describe('hasWon', function() { it('returns false when score < 100', function() { let player = new Scrabble.Player('test player'); expect(player.totalScore()).toBe(0); From 702587d1259a55401d3116dbaa74820888f589cb Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:07:35 -0800 Subject: [PATCH 12/18] passing tests for highestScoringWord in player --- scrabble.js | 6 ++++++ spec/scrabble_spec.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/scrabble.js b/scrabble.js index 13556d2..ff1bc98 100644 --- a/scrabble.js +++ b/scrabble.js @@ -95,6 +95,12 @@ Scrabble.Player = class { const score = words.reduce((a, b) => a + b, 0); return score; } + highestScoringWord() { + const words = this.plays.map(word => new Scrabble.Word(word)); + words.sort(Scrabble._compareWordScores); + const highestScore = words.pop().word; + return highestScore; + } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 624500f..f684bee 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -198,7 +198,7 @@ describe('Player', function() { }); }); - xdescribe('highestScoringWord', function() { + describe('highestScoringWord', function() { // Tie-breaking logic is already described in the tests // for highestWordFrom, so we will not repeat it here. it('returns the highest scoring word played', function() { From a98753e1db75db3dacf40a5fc139c44fdab2734f Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:14:10 -0800 Subject: [PATCH 13/18] passing test highestWordsScore --- scrabble.js | 7 +++++++ spec/scrabble_spec.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/scrabble.js b/scrabble.js index ff1bc98..b514a3b 100644 --- a/scrabble.js +++ b/scrabble.js @@ -101,6 +101,13 @@ Scrabble.Player = class { const highestScore = words.pop().word; return highestScore; } + + highestWordScore() { + const words = this.plays.map(word => new Scrabble.Word(word)); + words.sort(Scrabble._compareWordScores); + const highestScore = words.pop().score; + return highestScore; + } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index f684bee..2b3f6dd 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -214,7 +214,7 @@ describe('Player', function() { }); }); - xdescribe('highestWordScore', function() { + describe('highestWordScore', function() { it('returns the score of the highest scoring word played', function() { let player = new Scrabble.Player('test player'); player.play('cat'); From 8663ff45d84affd96e456b897bb2e3f413fec546 Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:16:59 -0800 Subject: [PATCH 14/18] added array of word objects to player objects, updated totalScore and play functions to use this array to DRY up methods --- scrabble.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index b514a3b..e489e64 100644 --- a/scrabble.js +++ b/scrabble.js @@ -67,6 +67,7 @@ Scrabble.Player = class { if (Scrabble.Player.isValidName(name)) { this.name = name; this.plays = []; + this.words = []; } } @@ -79,6 +80,7 @@ Scrabble.Player = class { if (!this.hasWon()) { const playedWord = new Scrabble.Word(word); this.plays.push(playedWord.word); + this.words.push(playedWord); this.totalScore(); return playedWord.word; } return false; @@ -90,9 +92,9 @@ Scrabble.Player = class { } return false; } totalScore() { - const words = this.plays.map(word => (new Scrabble.Word(word)).score); + const wordScores = this.words.map(word => word.score); // words = words.map(word => word.score); - const score = words.reduce((a, b) => a + b, 0); + const score = wordScores.reduce((a, b) => a + b, 0); return score; } highestScoringWord() { From 352a823ef9c082cc61b0dfef16b1b261279b451a Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:18:31 -0800 Subject: [PATCH 15/18] updated higestScoringWord to used words array --- scrabble.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scrabble.js b/scrabble.js index e489e64..fe4b6f3 100644 --- a/scrabble.js +++ b/scrabble.js @@ -98,9 +98,9 @@ Scrabble.Player = class { return score; } highestScoringWord() { - const words = this.plays.map(word => new Scrabble.Word(word)); - words.sort(Scrabble._compareWordScores); - const highestScore = words.pop().word; + const playerWords = this.words; + playerWords.sort(Scrabble._compareWordScores); + const highestScore = playerWords.pop().word; return highestScore; } From 172164eed7050d0843c9d63e736093e720465bec Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:24:51 -0800 Subject: [PATCH 16/18] updated helper methods to start with underscores --- scrabble.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scrabble.js b/scrabble.js index fe4b6f3..5723505 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,5 +1,5 @@ const Scrabble = { - isValidWord: function isValidWord(word) { + _isValidWord: function _isValidWord(word) { if ((typeof word === 'string') && (/^[a-zA-Z]+$/.test(word)) && (word.length < 8) && (word.length > 0)) { return true; } throw new Error('Invalid Word'); @@ -16,7 +16,7 @@ const Scrabble = { }; const keys = Object.keys(letters); let totalScore = 0; - if (this.isValidWord(word)) { + if (this._isValidWord(word)) { const chars = word.toUpperCase().match(/\S/g); chars.forEach((element) => { keys.forEach((num) => { @@ -64,14 +64,14 @@ const Scrabble = { Scrabble.Player = class { constructor(name) { - if (Scrabble.Player.isValidName(name)) { + if (Scrabble.Player._isValidName(name)) { this.name = name; this.plays = []; this.words = []; } } - static isValidName(name) { + static _isValidName(name) { if (name.length > 0) { return true; } throw new Error('Invalid Name'); @@ -105,9 +105,9 @@ Scrabble.Player = class { } highestWordScore() { - const words = this.plays.map(word => new Scrabble.Word(word)); - words.sort(Scrabble._compareWordScores); - const highestScore = words.pop().score; + const playerWords = this.words; + playerWords.sort(Scrabble._compareWordScores); + const highestScore = playerWords.pop().score; return highestScore; } }; @@ -115,7 +115,7 @@ Scrabble.Player = class { Scrabble.Word = class { constructor(word) { - if (Scrabble.isValidWord(word)) { + if (Scrabble._isValidWord(word)) { this.word = word; this.score = Scrabble.score(word); } From 22a6adeddbafae6df71384d523cefa0a5876dfcc Mon Sep 17 00:00:00 2001 From: murog Date: Thu, 16 Nov 2017 20:25:50 -0800 Subject: [PATCH 17/18] removed commented lines --- scrabble.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scrabble.js b/scrabble.js index 5723505..00bf258 100644 --- a/scrabble.js +++ b/scrabble.js @@ -93,7 +93,6 @@ Scrabble.Player = class { } totalScore() { const wordScores = this.words.map(word => word.score); - // words = words.map(word => word.score); const score = wordScores.reduce((a, b) => a + b, 0); return score; } From 8505b5723c57e4499d5cd9efabbbe9574b0700ad Mon Sep 17 00:00:00 2001 From: murog Date: Fri, 17 Nov 2017 01:12:07 -0800 Subject: [PATCH 18/18] DRYed up code by sorting array during play and returning last element of sorted array in other methods --- scrabble.js | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/scrabble.js b/scrabble.js index 00bf258..e6b77fd 100644 --- a/scrabble.js +++ b/scrabble.js @@ -16,26 +16,32 @@ const Scrabble = { }; const keys = Object.keys(letters); let totalScore = 0; - if (this._isValidWord(word)) { + if (Scrabble._isValidWord(word)) { const chars = word.toUpperCase().match(/\S/g); chars.forEach((element) => { keys.forEach((num) => { const numLetters = letters[num]; - if (numLetters.includes(element)) { totalScore += parseFloat(num); } + if (numLetters.includes(element)) { + totalScore += parseFloat(num); + } }); }); - if (word.length === 7) { totalScore += 50; } + if (word.length === 7) { + totalScore += 50; + } } return totalScore; }, highestScoreFrom: function highestScoreFrom(array) { - if ((!Array.isArray(array)) || (array.length === 0)) { throw new Error('Invalid Array'); } + if ((!Array.isArray(array)) || (array.length === 0)) { + throw new Error('Invalid Array'); + } const words = array.map(word => new Scrabble.Word(word)); words.sort(Scrabble._compareWordScores); - const highestScore = words.pop(); - return highestScore.word; + return words.slice(-1)[0].word; }, + _compareWordScores: function _compareWordScores(a, b) { const scoreA = a.score; const scoreB = b.score; @@ -76,50 +82,44 @@ Scrabble.Player = class { return true; } throw new Error('Invalid Name'); } + play(word) { if (!this.hasWon()) { const playedWord = new Scrabble.Word(word); this.plays.push(playedWord.word); this.words.push(playedWord); + this.words.sort(Scrabble._compareWordScores); this.totalScore(); return playedWord.word; } return false; } + hasWon() { const currentScore = this.totalScore(); if (currentScore >= 100) { return true; } return false; } + totalScore() { - const wordScores = this.words.map(word => word.score); - const score = wordScores.reduce((a, b) => a + b, 0); + const score = this.words.reduce((a, b) => a + b.score, 0); return score; } + highestScoringWord() { - const playerWords = this.words; - playerWords.sort(Scrabble._compareWordScores); - const highestScore = playerWords.pop().word; - return highestScore; + return this.words.slice(-1)[0].word; } highestWordScore() { - const playerWords = this.words; - playerWords.sort(Scrabble._compareWordScores); - const highestScore = playerWords.pop().score; - return highestScore; + return this.words.slice(-1)[0].score; } -}; - +}; // end of Player class Scrabble.Word = class { constructor(word) { - if (Scrabble._isValidWord(word)) { - this.word = word; - this.score = Scrabble.score(word); - } + this.word = word; + this.score = Scrabble.score(word); } -}; - +}; // end of Word class module.exports = Scrabble;