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..b127922 100644 --- a/scrabble.js +++ b/scrabble.js @@ -1,14 +1,183 @@ + + +function InputException(message) { + this.message = message; + this.name = 'inputException'; +} + const Scrabble = { - score: function(word) { + + letterValues: { + a: 1, + e: 1, + i: 1, + o: 1, + u: 1, + l: 1, + n: 1, + r: 1, + s: 1, + t: 1, + d: 2, + g: 2, + b: 3, + c: 3, + m: 3, + p: 3, + f: 4, + h: 4, + v: 4, + y: 4, + k: 5, + j: 8, + x: 8, + q: 10, + z: 10, + }, + score(word) { // TODO: implement score - } + let totalValue = 0; + const downcase = word.toLowerCase(); + // (/^[a-z]+$/.test(downcase) returns true if all characters in the downcase string are letters + if ((/^[a-z]+$/.test(downcase)) && typeof downcase === 'string' && downcase.length < 8) { + let ch = downcase[0]; + for (let i = 0; i < word.length; i += 1) { + ch = downcase[i]; + totalValue += this.letterValues[ch]; + } + } else { + throw new InputException('InvalidInput'); + } + + if (downcase.length === 7) { + totalValue += 50; + } + return totalValue; + }, + highestScoreFrom(arrayofWords) { + if (!(typeof arrayofWords === 'object' && arrayofWords.length > 0)) { + throw new InputException('InvalidInput: must provide a valid array of words'); + } - // TODO: add the highestScoreFrom method + let highestScore = 0; + let topWord = arrayofWords[0]; + + for (let word of arrayofWords) { + if (this.score(word) === highestScore) { + if (topWord.length === 7) { + break; + } else if (word.length === 7 || (word.length < topWord.length)) { + topWord = word; + } + } else if (this.score(word) > highestScore) { + highestScore = this.score(word); + topWord = word; + } + } + return topWord; + }, }; Scrabble.Player = class { - // TODO: implement the Player class + constructor(name) { + if (!name) { + throw new InputException('Error:name required for new player'); + } + this.name = name; + this.plays = []; + } + play(word) { + if (this.hasWon()) { + return false; + } + const downcase = word.toLowerCase(); + if ((/^[a-z]+$/.test(downcase)) && typeof downcase === 'string' && downcase.length < 8) { + (this.plays).push(word); + return true; + } + return false; + } + totalScore() { + let totalScore = 0; + this.plays.forEach((word) => { + totalScore += Scrabble.score(word); + }); + return totalScore; + } + hasWon() { + return (this.totalScore() >= 100); + } + highestScoringWord() { + if (this.plays.length < 1) { + throw new InputException('Error: No words have been played'); + } + // what happens with two + words that share the same high score + // sorted is the player's plays array sorted in descending order + // const sorted = this.plays.sort((a, b) => Scrabble.score(b) - Scrabble.score(a)); + // + // return sorted[0]; + return Scrabble.highestScoreFrom(this.plays); + } + highestWordScore() { + if (this.plays.length < 1) { + throw new InputException('Error: No words have been played'); + } + return Scrabble.score(this.highestScoringWord()); + } }; +// Scrabble.Tilebag = { +// tileQuantity: { +// j: 1, +// k: 1, +// q: 1, +// x: 1, +// z: 1, +// b: 2, +// c: 2, +// f: 2, +// h: 2, +// m: 2, +// p: 2, +// v: 2, +// w: 2, +// y: 2, +// g: 3, +// d: 4, +// l: 4, +// s: 4, +// u: 4, +// n: 6, +// r: 6, +// t: 6, +// o: 8, +// a: 9, +// i: 9, +// e: 12, +// }, +// // remainingTiles: Object.assign({}, this.startingTileQuantity), +// availableTiles: [], +// constructor() { +// this.availableTiles = []; +// Scrabble.Tilebag.tileQuantity.keys.forEach((ch) => { +// let numTiles = Scrabble.Tilebag.tileQuantity[ch]; +// for (let i = 0; i < numTiles; i += 1) { +// this.availableTiles.push(ch); +// } +// }); +// }, +// drawTiles(num) { +// let tilesDrawn = []; +// for (let i = 0; i < num; i += 1) { +// let numRemainingTiles = this.availableTiles.length; +// let random = Math.floor(Math.random() * numRemainingTiles); +// let drawn = (availbleTiles.splice(random, 1)).toString(); +// tilesDrawn.push(drawn); +// } +// return tilesDrawn; +// }, +// }; + + module.exports = Scrabble; diff --git a/spec/scrabble_spec.js b/spec/scrabble_spec.js index c195a03..8add82d 100644 --- a/spec/scrabble_spec.js +++ b/spec/scrabble_spec.js @@ -1,3 +1,4 @@ +/* eslint-disable */ const Scrabble = require('../scrabble'); describe('score', function() {