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..f98418e 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,14 +1,158 @@ +const tiles = { + 'A': 1, + 'E': 1, + 'I': 1, + 'O': 1, + 'L': 1, + 'N': 1, + 'R': 1, + 'U': 1, + 'S': 1, + 'T': 1, + 'D': 2, + 'G': 2, + 'B': 3, + 'C': 3, + 'M': 3, + 'P': 3, + 'F': 4, + 'H': 4, + 'V': 4, + 'W': 4, + 'Y': 4, + 'K': 5, + 'J': 8, + 'X': 8, + 'Q': 10, + 'Z': 10 +}; + const Scrabble = { score: function(word) { - // TODO: implement score - } + let regex = /^[a-zA-Z]+$/; + let total = 0; + let playedWord = word.toUpperCase(); - // TODO: add the highestScoreFrom method + if (playedWord.length > 7) { + throw new UserException(`Illegal play, ${playedWord.length} exceeds allowed tile count`); + } + + if (playedWord === '') { + throw new UserException(`Illegal play ${playedWord} contains bad characters`); + } + + if (!playedWord.match(regex) ) { + throw new UserException('Illegal play, sorry only words allowed'); + } + + word.toUpperCase().split('').forEach(function(letter) { + total = tiles[letter] + total; + }); + + if (word.length == 7 && total > 0) { + total += 50; + } + return total; + }, + + highestScoreFrom: function(arrayOfWords) { + let max = 0; + let highestScoreWord = ''; + + if (arrayOfWords.length === 0) { + throw new Error('No words to score'); + } else if (arrayOfWords.length === 1){ + return arrayOfWords[0]; + } + + arrayOfWords.forEach(function(word) { + let wordScore = Scrabble.score(word) + let wordLength = word.length + + if ( wordScore > max ) { + max = wordScore; + highestScoreWord = word; + } else if ( wordScore === max ) { + if ( wordLength === 7 ) { + // console.log('HIGHEST ' + highestScoreWord + ' VALUE OF CURRENT WORD ' + word); + return highestScoreWord = word; + } else if (highestScoreWord.length === 7 ) { + // console.log('work ' + highestScoreWord); + return highestScoreWord; + } else if (wordLength === highestScoreWord.length ) { + // console.log('work ' + highestScoreWord); + return highestScoreWord; + } else if (( wordLength < highestScoreWord.length) && ( wordLength !== 7)) { + return highestScoreWord = word; + } + } + }); + return highestScoreWord; + } +}; // end of Scrabble function -}; Scrabble.Player = class { - // TODO: implement the Player class -}; + constructor(name) { + if (name === undefined) { + throw new Error('No argument passed'); + } + this.name = name; // return player's name + this.plays = []; // store words played + } + play(word) { + let regex = /^[a-zA-Z]+$/; + + if (this.hasWon()) { + return false; + } + + if ((word === undefined) || (!word.match(regex))) { + throw new Error('Invalid word'); + } + + this.plays.push(word) + return this.plays; + } + + // totalScore() { + // let total = 0; + // this.plays.forEach(function(playedWord) { + // total += Scrabble.score(playedWord) + // }); + // return total; + // } + + // arrow function + totalScore() { + return this.plays.reduce((total, playedWord) => { return total + Scrabble.score(playedWord) }, 0); + } + + hasWon() { + if (this.totalScore() < 100) { + return false; + } else { + return true; + } + } + + highestScoringWord() { + return Scrabble.highestScoreFrom(this.plays); + } + + highestWordScore() { + return Scrabble.score(this.highestScoringWord()); + } +}; // Scrabble.Player object + +// Optional Enhancements +// Scrabble.TileBag = class { +// +// } module.exports = Scrabble; + +//tests +// let name = 'Bob'; +// let player = new Scrabble.Player(name); +// console.log(player.name) diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index c195a03..da5e274 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -60,6 +60,7 @@ describe('highestScoreFrom', function() { expect(Scrabble.highestScoreFrom(['pig', 'dog'])).toBe('pig'); }); + it ('if tied, prefer a word with 7 letters', function() { const loser = 'zzzzzz'; const winner = 'iiiiddd'; @@ -147,7 +148,7 @@ describe('Player', function() { expect(player.plays.length).toBe(1); }); }); - +// describe ('totalScore', function() { it ('Is zero if the player has not played anything', function() { let player = new Scrabble.Player('test player');