From b611af270d8c97ba3b286a1c4421b3cf9eda309e Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 19:43:48 -0800 Subject: [PATCH 01/17] scores simple words --- package-lock.json | 123 ++++++++++++++++++++++++++++++++++++++++++ scrabble.js | 46 ++++++++++++++-- spec/scrabble_spec.js | 14 ++--- 3 files changed, 172 insertions(+), 11 deletions(-) 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=" + } + } +} diff --git a/scrabble.js b/scrabble.js index 7a1f161..0c657dd 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,12 +1,50 @@ +const LETTERVALUES = { + A: 1, + B: 3, + C: 3, + D: 2, + E: 1, + F: 4, + G: 2, + H: 4, + I: 1, + J: 8, + K: 5, + L: 1, + M: 3, + N: 1, + O: 1, + P: 3, + Q: 10, + R: 1, + S: 1, + T: 1, + U: 1, + V: 4, + W: 4, + X: 8, + Y: 4, + Z: 10, +}; + const Scrabble = { - score: function(word) { - // TODO: implement score - } + score(word) { + let wordArray = word.toUpperCase().split(''); + let sum = 0; + wordArray.forEach((letter) => { + // console.log(letter); + // console.log(LETTERVALUES[letter]); + sum += LETTERVALUES[letter]; + }); + + return sum; + }, - // TODO: add the highestScoreFrom method }; +console.log(Scrabble.score('win')); + Scrabble.Player = class { // TODO: implement the Player class }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index c195a03..ba40524 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -11,32 +11,32 @@ describe('score', function() { expect(Scrabble.score('pig')).toBe(6); }); - it ('adds 50 points for a 7-letter word', function() { + xit ('adds 50 points for a 7-letter word', function() { expect(Scrabble.score('academy')).toBe(65); }); - it ('throws on bad characters', function() { + xit ('throws on bad characters', function() { expect(function () { Scrabble.score('char^'); }).toThrow(); }); - it ('handles all upper- and lower-case letters', function() { + xit ('handles all upper- and lower-case letters', function() { expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('DOG')).toBe(5); expect(Scrabble.score('DoG')).toBe(5); }); - it ('does not allow words > 7 letters', function() { + xit ('does not allow words > 7 letters', function() { expect(function() { Scrabble.score('abcdefgh'); }).toThrow(); }); - it ('does not allow empty words', function() { + xit ('does not allow empty words', function() { expect(function() { Scrabble.score(''); }).toThrow(); }); }); -describe('highestScoreFrom', function() { +xdescribe('highestScoreFrom', function() { it ('is defined', function() { expect(Scrabble.highestScoreFrom).toBeDefined(); }); @@ -97,7 +97,7 @@ describe('highestScoreFrom', function() { }); }); -describe('Player', function() { +xdescribe('Player', function() { it ('is defined', function() { expect(Scrabble.Player).toBeDefined(); }); From 38f8a2be64b832a0c8f0d738e6292465905b2e70 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 19:52:20 -0800 Subject: [PATCH 02/17] scores extra points for seven letter words --- scrabble.js | 6 +++--- spec/scrabble_spec.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scrabble.js b/scrabble.js index 0c657dd..1fbe7a6 100644 --- a/scrabble.js +++ b/scrabble.js @@ -30,10 +30,10 @@ const LETTERVALUES = { const Scrabble = { score(word) { let wordArray = word.toUpperCase().split(''); - let sum = 0; + // let sum; + // (wordArray.length == 7) ? sum = 50 : sum = 0; + let sum = (wordArray.length === 7) ? 50 : 0; wordArray.forEach((letter) => { - // console.log(letter); - // console.log(LETTERVALUES[letter]); sum += LETTERVALUES[letter]; }); diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index ba40524..a8f7aa9 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -11,7 +11,7 @@ describe('score', function() { expect(Scrabble.score('pig')).toBe(6); }); - xit ('adds 50 points for a 7-letter word', function() { + it ('adds 50 points for a 7-letter word', function() { expect(Scrabble.score('academy')).toBe(65); }); From 5c00e8369f86e79339886c57f8303c1a6266c048 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 20:04:16 -0800 Subject: [PATCH 03/17] throws an error for invalid characters --- scrabble.js | 6 +++++- spec/scrabble_spec.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 1fbe7a6..3953a35 100644 --- a/scrabble.js +++ b/scrabble.js @@ -34,7 +34,11 @@ const Scrabble = { // (wordArray.length == 7) ? sum = 50 : sum = 0; let sum = (wordArray.length === 7) ? 50 : 0; wordArray.forEach((letter) => { - sum += LETTERVALUES[letter]; + if (letter in LETTERVALUES) { + sum += LETTERVALUES[letter]; + } else { + throw new Error('word contains invalid characters'); + } }); return sum; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index a8f7aa9..1757e67 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -15,7 +15,7 @@ describe('score', function() { expect(Scrabble.score('academy')).toBe(65); }); - xit ('throws on bad characters', function() { + it ('throws on bad characters', function() { expect(function () { Scrabble.score('char^'); }).toThrow(); From f6a673823b6cdca293e4f6fd536b5820712bf3b2 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 20:28:52 -0800 Subject: [PATCH 04/17] throws an error for words shorter than 1 or larger than 7 --- scrabble.js | 4 ++++ spec/scrabble_spec.js | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/scrabble.js b/scrabble.js index 3953a35..9ff9a7c 100644 --- a/scrabble.js +++ b/scrabble.js @@ -29,6 +29,10 @@ const LETTERVALUES = { const Scrabble = { score(word) { + if (word.length > 7 || word.length < 1) { + throw new Error('word must be between 1 and 7 letters'); + } + let wordArray = word.toUpperCase().split(''); // let sum; // (wordArray.length == 7) ? sum = 50 : sum = 0; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 1757e67..f776c37 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -21,17 +21,17 @@ describe('score', function() { }).toThrow(); }); - xit ('handles all upper- and lower-case letters', function() { + it ('handles all upper- and lower-case letters', function() { expect(Scrabble.score('dog')).toBe(5); expect(Scrabble.score('DOG')).toBe(5); expect(Scrabble.score('DoG')).toBe(5); }); - xit ('does not allow words > 7 letters', function() { + it ('does not allow words > 7 letters', function() { expect(function() { Scrabble.score('abcdefgh'); }).toThrow(); }); - xit ('does not allow empty words', function() { + it ('does not allow empty words', function() { expect(function() { Scrabble.score(''); }).toThrow(); }); }); From c034f0ca693985f248550d50d981f28bdba16eec Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 20:42:25 -0800 Subject: [PATCH 05/17] defined highestscorefrom --- scrabble.js | 4 ++++ spec/scrabble_spec.js | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/scrabble.js b/scrabble.js index 9ff9a7c..7d890ad 100644 --- a/scrabble.js +++ b/scrabble.js @@ -48,6 +48,10 @@ const Scrabble = { return sum; }, + highestScoreFrom(wordsArray) { + + }, + }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index f776c37..1199322 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -36,21 +36,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); @@ -60,7 +60,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'; @@ -73,7 +73,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); @@ -83,7 +83,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 ab4abd60af8ade4c5b2005807420080ec4c3481c Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 20:52:52 -0800 Subject: [PATCH 06/17] highest score throws if no words are passed --- scrabble.js | 4 +++- spec/scrabble_spec.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 7d890ad..ba807c3 100644 --- a/scrabble.js +++ b/scrabble.js @@ -49,7 +49,9 @@ const Scrabble = { }, highestScoreFrom(wordsArray) { - + if (wordsArray.length === 0 || wordsArray !== Array) { + throw new Error('no words to compare score'); + } }, diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 1199322..abed7ed 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -41,7 +41,7 @@ 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(); }); From d19f8e92e538ef50ea81347111e629425e0b6790 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 21:02:39 -0800 Subject: [PATCH 07/17] simple scores highest word --- scrabble.js | 15 +++++++++++++-- spec/scrabble_spec.js | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/scrabble.js b/scrabble.js index ba807c3..6f38240 100644 --- a/scrabble.js +++ b/scrabble.js @@ -49,15 +49,26 @@ const Scrabble = { }, highestScoreFrom(wordsArray) { - if (wordsArray.length === 0 || wordsArray !== Array) { + if (wordsArray.length === 0 || wordsArray.constructor !== Array) { throw new Error('no words to compare score'); } + let scores = wordsArray.map(word => this.score(word)); + let maxIndex = 0; + let max = scores[0]; + for (let i = 0; i < wordsArray.length; i += 1) { + if (scores[i] > max) { + max = scores[i]; + maxIndex = i; + } + } + return wordsArray[maxIndex]; }, }; -console.log(Scrabble.score('win')); +// console.log(Scrabble.score('win')); +// console.log(Scrabble.highestScoreFrom(['dog'])); Scrabble.Player = class { // TODO: implement the Player class diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index abed7ed..148c6a0 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -46,11 +46,11 @@ describe('highestScoreFrom', function() { 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); From dc008f1365f9c13c7c815ebce6d435c930a31de7 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 21:24:50 -0800 Subject: [PATCH 08/17] highest score prefers word with seven letters --- scrabble.js | 2 +- spec/scrabble_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 6f38240..8837f67 100644 --- a/scrabble.js +++ b/scrabble.js @@ -56,7 +56,7 @@ const Scrabble = { let maxIndex = 0; let max = scores[0]; for (let i = 0; i < wordsArray.length; i += 1) { - if (scores[i] > max) { + if ((scores[i] > max) || (scores[i] === max && wordsArray[i].length === 7)) { max = scores[i]; maxIndex = i; } diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 148c6a0..da146f6 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -60,7 +60,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 c44ff4b266a6094e42643c3c7db1e1a61149a3b0 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 22:07:39 -0800 Subject: [PATCH 09/17] prefers seven letter word win --- scrabble.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scrabble.js b/scrabble.js index 8837f67..0c3d53f 100644 --- a/scrabble.js +++ b/scrabble.js @@ -56,9 +56,17 @@ const Scrabble = { let maxIndex = 0; let max = scores[0]; for (let i = 0; i < wordsArray.length; i += 1) { - if ((scores[i] > max) || (scores[i] === max && wordsArray[i].length === 7)) { + if (scores[i] > max) { max = scores[i]; maxIndex = i; + } else if (scores[i] === max) { + if (wordsArray[i].length === 7) { + max = scores[i]; + maxIndex = i; + } else if (wordsArray[i].length < max.length && max.length !== 7) { + max = scores[i]; + maxIndex = i; + } } } return wordsArray[maxIndex]; From 3edd1701bda4f5c6c42623a5c115610749856c88 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 22:45:09 -0800 Subject: [PATCH 10/17] shortest tie non-7 letter word wins --- scrabble.js | 6 +++++- spec/scrabble_spec.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 0c3d53f..888b118 100644 --- a/scrabble.js +++ b/scrabble.js @@ -55,16 +55,20 @@ const Scrabble = { let scores = wordsArray.map(word => this.score(word)); let maxIndex = 0; let max = scores[0]; + let winningWord = wordsArray[0]; for (let i = 0; i < wordsArray.length; i += 1) { if (scores[i] > max) { max = scores[i]; + winningWord = wordsArray[i]; maxIndex = i; } else if (scores[i] === max) { if (wordsArray[i].length === 7) { max = scores[i]; + winningWord = wordsArray[i]; maxIndex = i; - } else if (wordsArray[i].length < max.length && max.length !== 7) { + } else if ((wordsArray[i].length < winningWord.length) && (winningWord.length !== 7)) { max = scores[i]; + winningWord = wordsArray[i]; maxIndex = i; } } diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index da146f6..98f0e00 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -73,7 +73,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); From c0eefcc4126449fecb78c62ea91d6a1c9c5e34d1 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Tue, 14 Nov 2017 22:45:56 -0800 Subject: [PATCH 11/17] all tests pass highestScoreFrom --- 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 98f0e00..bce0504 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -83,7 +83,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); From 25c05e19feec50e936d44a7b170237caad954745 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Wed, 15 Nov 2017 12:15:21 -0800 Subject: [PATCH 12/17] forgot to commit for several.. play, hasWon, totalScore, highestScoringWord --- scrabble.js | 41 ++++++++++++++++++++++++++++++++++++----- spec/scrabble_spec.js | 4 ++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/scrabble.js b/scrabble.js index 888b118..4b1c5b2 100644 --- a/scrabble.js +++ b/scrabble.js @@ -75,15 +75,46 @@ const Scrabble = { } return wordsArray[maxIndex]; }, +}; +Scrabble.Player = class { + constructor(name) { + if (!name) { + throw new Error('player must have a name'); + } + this.name = name; + this.plays = []; + } -}; + play(word) { + if (this.hasWon() === true) { + return false; + } + if (!(word.match(/^[a-zA-Z0-9]{1,7}$/))) { + throw new Error('must be a word between 1 and 7 letters'); + } + this.plays.push(word); + return Scrabble.score(word); + } -// console.log(Scrabble.score('win')); -// console.log(Scrabble.highestScoreFrom(['dog'])); + totalScore() { + let totalScore = 0; + this.plays.forEach((play) => { + totalScore += Scrabble.score(play); + }); + return totalScore; + } -Scrabble.Player = class { - // TODO: implement the Player class + hasWon() { + return (this.totalScore() > 99); + } + + highestScoringWord() { + if (this.plays.length === 0) { + throw new Error('no words played'); + } + return Scrabble.highestScoreFrom(this.plays); + } }; module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index bce0504..9ca1564 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -97,7 +97,7 @@ describe('highestScoreFrom', function() { }); }); -xdescribe('Player', function() { +describe('Player', function() { it ('is defined', function() { expect(Scrabble.Player).toBeDefined(); }); @@ -220,7 +220,7 @@ xdescribe('Player', function() { expect(player.highestWordScore()).toBe(40); }); - it('throws an error if no words have been played', function() { + xit('throws an error if no words have been played', function() { let player = new Scrabble.Player('test player'); expect(() => { player.highestWordScore() }).toThrow(); }); From f9e8d8e9ed3afcd80859de2845dacd0046ebeefa Mon Sep 17 00:00:00 2001 From: Shaunna Date: Wed, 15 Nov 2017 12:56:12 -0800 Subject: [PATCH 13/17] highestScoringWord function added: --- scrabble.js | 10 +++++++++- spec/scrabble_spec.js | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 4b1c5b2..a19718b 100644 --- a/scrabble.js +++ b/scrabble.js @@ -90,7 +90,7 @@ Scrabble.Player = class { if (this.hasWon() === true) { return false; } - if (!(word.match(/^[a-zA-Z0-9]{1,7}$/))) { + if (!(word.match(/^[a-zA-Z]{1,7}$/))) { throw new Error('must be a word between 1 and 7 letters'); } this.plays.push(word); @@ -115,6 +115,14 @@ Scrabble.Player = class { } return Scrabble.highestScoreFrom(this.plays); } + + highestWordScore() { + if (this.plays.length === 0) { + throw new Error('no words played'); + } + return Scrabble.score(this.highestScoringWord()); + } }; + module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 9ca1564..24e5368 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -220,9 +220,11 @@ describe('Player', function() { expect(player.highestWordScore()).toBe(40); }); - xit('throws an error if no words have been played', function() { + it('throws an error if no words have been played', function() { let player = new Scrabble.Player('test player'); expect(() => { player.highestWordScore() }).toThrow(); }); }); }); + +describe 'Tilebag' From 0bba04a1079cb5e671ac0dcdfd04b43c370e90e7 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Wed, 15 Nov 2017 22:33:11 -0800 Subject: [PATCH 14/17] create tile bag --- scrabble.js | 88 +++++++++++++++++++++++++++---------------- spec/scrabble_spec.js | 14 ++++++- 2 files changed, 67 insertions(+), 35 deletions(-) diff --git a/scrabble.js b/scrabble.js index a19718b..6c977ba 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,30 +1,30 @@ const LETTERVALUES = { - A: 1, - B: 3, - C: 3, - D: 2, - E: 1, - F: 4, - G: 2, - H: 4, - I: 1, - J: 8, - K: 5, - L: 1, - M: 3, - N: 1, - O: 1, - P: 3, - Q: 10, - R: 1, - S: 1, - T: 1, - U: 1, - V: 4, - W: 4, - X: 8, - Y: 4, - Z: 10, + A: [1, 9], + B: [3, 2], + C: [3, 2], + D: [2, 4], + E: [1, 12], + F: [4, 2], + G: [2, 3], + H: [4, 2], + I: [1, 9], + J: [8, 1], + K: [5, 1], + L: [1, 4], + M: [3, 2], + N: [1, 6], + O: [1, 8], + P: [3, 2], + Q: [10, 1], + R: [1, 6], + S: [1, 4], + T: [1, 6], + U: [1, 4], + V: [4, 2], + W: [4, 2], + X: [8, 1], + Y: [4, 2], + Z: [10, 1], }; const Scrabble = { @@ -33,13 +33,13 @@ const Scrabble = { throw new Error('word must be between 1 and 7 letters'); } - let wordArray = word.toUpperCase().split(''); - // let sum; - // (wordArray.length == 7) ? sum = 50 : sum = 0; + const wordArray = word.toUpperCase().split(''); + let sum = (wordArray.length === 7) ? 50 : 0; + wordArray.forEach((letter) => { if (letter in LETTERVALUES) { - sum += LETTERVALUES[letter]; + sum += LETTERVALUES[letter][0]; } else { throw new Error('word contains invalid characters'); } @@ -52,10 +52,12 @@ const Scrabble = { if (wordsArray.length === 0 || wordsArray.constructor !== Array) { throw new Error('no words to compare score'); } - let scores = wordsArray.map(word => this.score(word)); + const scores = wordsArray.map(word => this.score(word)); + let maxIndex = 0; let max = scores[0]; let winningWord = wordsArray[0]; + for (let i = 0; i < wordsArray.length; i += 1) { if (scores[i] > max) { max = scores[i]; @@ -77,6 +79,25 @@ const Scrabble = { }, }; +Scrabble.TileBag = class { + constructor() { + this.tiles = Scrabble.TileBag.setTiles(); + } + + static setTiles() { + const tiles = []; + Object.keys(LETTERVALUES).forEach((letter) => { + let quantity = LETTERVALUES[letter][1]; + for (let i = 0; i < quantity; i += 1) { + tiles.push(letter); + } + }); + console.log(tiles); + return tiles; + } +}; + + Scrabble.Player = class { constructor(name) { if (!name) { @@ -87,7 +108,7 @@ Scrabble.Player = class { } play(word) { - if (this.hasWon() === true) { + if (this.hasWon()) { return false; } if (!(word.match(/^[a-zA-Z]{1,7}$/))) { @@ -106,7 +127,7 @@ Scrabble.Player = class { } hasWon() { - return (this.totalScore() > 99); + return (this.totalScore() >= 100); } highestScoringWord() { @@ -125,4 +146,5 @@ Scrabble.Player = class { }; + module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 24e5368..6ee7f31 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -97,6 +97,18 @@ describe('highestScoreFrom', function() { }); }); +describe('TileBag', function() { + it ('is defined', function() { + expect(Scrabble.TileBag).toBeDefined(); + }); + describe('Constructor', function() { + it('creates a set of tiles', function() { + let tilebag = new Scrabble.TileBag(); + expect(tilebag.tiles.length).toBe(98); + }); + }); +}); + describe('Player', function() { it ('is defined', function() { expect(Scrabble.Player).toBeDefined(); @@ -226,5 +238,3 @@ describe('Player', function() { }); }); }); - -describe 'Tilebag' From 1611a367c73f935e3e18fd9edbbe537482ad3911 Mon Sep 17 00:00:00 2001 From: Shaunna Date: Wed, 15 Nov 2017 22:50:32 -0800 Subject: [PATCH 15/17] draw tile --- scrabble.js | 7 +++++-- spec/scrabble_spec.js | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 6c977ba..2a84cac 100644 --- a/scrabble.js +++ b/scrabble.js @@ -87,14 +87,17 @@ Scrabble.TileBag = class { static setTiles() { const tiles = []; Object.keys(LETTERVALUES).forEach((letter) => { - let quantity = LETTERVALUES[letter][1]; + const quantity = LETTERVALUES[letter][1]; for (let i = 0; i < quantity; i += 1) { tiles.push(letter); } }); - console.log(tiles); return tiles; } + + drawTile() { + return this.tiles.splice(Math.floor(Math.random() * this.tiles.length), 1); + } }; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index 6ee7f31..e1b3449 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -107,6 +107,16 @@ describe('TileBag', function() { expect(tilebag.tiles.length).toBe(98); }); }); + + describe('drawTile', function() { + it('returns a random tile', function() { + let tilebag = new Scrabble.TileBag(); + let tile = tilebag.drawTile(); + // TODO: Find a way to test this: + // expect(tile.).toBe(); + expect(tilebag.tiles.length).toBe(97); + }); + }); }); describe('Player', function() { From 9adda72a7b57debdb357cb66ab14b011e784e0ef Mon Sep 17 00:00:00 2001 From: Shaunna Date: Thu, 16 Nov 2017 09:14:33 -0800 Subject: [PATCH 16/17] tilebag in progress --- scrabble.js | 1 - spec/scrabble_spec.js | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/scrabble.js b/scrabble.js index 2a84cac..08ce374 100644 --- a/scrabble.js +++ b/scrabble.js @@ -149,5 +149,4 @@ Scrabble.Player = class { }; - module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index e1b3449..1195944 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -109,13 +109,19 @@ describe('TileBag', function() { }); describe('drawTile', function() { - it('returns a random tile', function() { + it('decreases the tilebag count by 1', function() { let tilebag = new Scrabble.TileBag(); let tile = tilebag.drawTile(); // TODO: Find a way to test this: // expect(tile.).toBe(); expect(tilebag.tiles.length).toBe(97); }); + it('returns a tile from the tiles', function() { + let tilebag = new Scrabble.TileBag(); + let tile = tilebag.drawTile(); + // TODO: Find a way to test this: + // expect(tile.).toBe(); + }); }); }); From 5883b772e2aeafeedea04aa03c656092e518d28f Mon Sep 17 00:00:00 2001 From: Shaunna Date: Thu, 16 Nov 2017 17:13:09 -0800 Subject: [PATCH 17/17] refactor highestScoreFrom() function --- scrabble.js | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/scrabble.js b/scrabble.js index 08ce374..44ef6c6 100644 --- a/scrabble.js +++ b/scrabble.js @@ -48,34 +48,31 @@ const Scrabble = { return sum; }, - highestScoreFrom(wordsArray) { - if (wordsArray.length === 0 || wordsArray.constructor !== Array) { + highestScoreFrom(words) { + if (words.length === 0 || words.constructor !== Array) { throw new Error('no words to compare score'); } - const scores = wordsArray.map(word => this.score(word)); - - let maxIndex = 0; - let max = scores[0]; - let winningWord = wordsArray[0]; - - for (let i = 0; i < wordsArray.length; i += 1) { - if (scores[i] > max) { - max = scores[i]; - winningWord = wordsArray[i]; - maxIndex = i; - } else if (scores[i] === max) { - if (wordsArray[i].length === 7) { - max = scores[i]; - winningWord = wordsArray[i]; - maxIndex = i; - } else if ((wordsArray[i].length < winningWord.length) && (winningWord.length !== 7)) { - max = scores[i]; - winningWord = wordsArray[i]; - maxIndex = i; + + let max = this.score(words[0]); + let winningWord = words[0]; + + words.forEach((word) => { + const score = this.score(word); + + if (score > max) { + max = score; + winningWord = word; + } else if (score === max) { + if (word.length === 7) { + max = score; + winningWord = word; + } else if (word.length < winningWord.length && winningWord.length !== 7) { + max = score; + winningWord = word; } } - } - return wordsArray[maxIndex]; + }); + return winningWord; }, };