diff --git a/eslint.config.mjs b/eslint.config.mjs index 1768aaf3..46423df7 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,6 +4,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import js from "@eslint/js"; import { FlatCompat } from "@eslint/eslintrc"; +import eslintConfigPrettier from "eslint-config-prettier"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -44,4 +45,6 @@ export default [...compat.extends("plugin:jest/recommended", "eslint:recommended camelcase: "error", }, -}]; \ No newline at end of file + }, + eslintConfigPrettier, +]; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0c4df718..7123d464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "babel-core": "^6.26.3", "babel-jest": "^29.7.0", "babel-plugin-module-resolver": "^5.0.2", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^28.8.3", "globals": "^15.11.0", "jest": "^29.7.0", @@ -5224,6 +5225,19 @@ } } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-plugin-jest": { "version": "28.8.3", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", diff --git a/package.json b/package.json index db1a72f2..c5c71d0c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "JavaScript version of the Adagrams project", "main": "index.js", "scripts": { - "test": "jest", + "test": "jest --coverage", "lint": "npx eslint", "coverage": "open coverage/lcov-report/index.html", "demo-game": "babel-node src/demo.js" @@ -30,6 +30,7 @@ "babel-core": "^6.26.3", "babel-jest": "^29.7.0", "babel-plugin-module-resolver": "^5.0.2", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^28.8.3", "globals": "^15.11.0", "jest": "^29.7.0", diff --git a/src/adagrams.js b/src/adagrams.js index 7ec5afc7..39224bf2 100644 --- a/src/adagrams.js +++ b/src/adagrams.js @@ -1,15 +1,154 @@ -export const drawLetters = () => { - // Implement this method for wave 1 +const LETTER_POOL = { + 'A': 9, + 'B': 2, + 'C': 2, + 'D': 4, + 'E': 12, + 'F': 2, + 'G': 3, + 'H': 2, + 'I': 9, + 'J': 1, + 'K': 1, + 'L': 4, + 'M': 2, + 'N': 6, + 'O': 8, + 'P': 2, + 'Q': 1, + 'R': 6, + 'S': 4, + 'T': 6, + 'U': 4, + 'V': 2, + 'W': 2, + 'X': 1, + 'Y': 2, + 'Z': 1 +}; + +const LETTER_SCORE = { + '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 HAND_SIZE = 10 +const MIN_BONUS_LENGTH = 7 +const LENGTH_BONUS = 8 + +const createWeightedLetterPool = () =>{ + let weightedLetterPool = []; + for (const [letter, freq] of Object.entries(LETTER_POOL)){ + for (let i=0; i { + const hand = []; + const weightedLetterPool = createWeightedLetterPool() + + while (hand.length < HAND_SIZE){ + let randomIdx = Math.floor(Math.random()*weightedLetterPool.length); + let randomLetter = weightedLetterPool[randomIdx]; + hand.push(randomLetter); + weightedLetterPool.splice(randomIdx,1); + } + return hand; +}; + export const usesAvailableLetters = (input, lettersInHand) => { - // Implement this method for wave 2 + const inputLower = input.toUpperCase(); + const copy = [...lettersInHand]; // I not sure how lettersInHand is used in the program as a whole, so I made a copy + + for (let letter of inputLower){ + if (copy.includes(letter)){ + let idx = copy.indexOf(letter); + copy.splice(idx,1); + } else { + return false; + } + } + return true; }; + + + + export const scoreWord = (word) => { - // Implement this method for wave 3 + if (!word.trim()) { + return 0; + } + word = word.toUpperCase(); + let score = 0; + for (let letter of word){ + score += LETTER_SCORE[letter]; + } + if(word.length >= MIN_BONUS_LENGTH){ + score += LENGTH_BONUS; + } + return score; }; +const getMaxScore = (words) =>{ + let maxScore = 0; + for (let word of words){ + maxScore = Math.max(maxScore, scoreWord(word)); + }; + return maxScore; +} + +const getHighScoreWords = (words, maxScore) => { + let highScoreWords = [] + for (let word of words){ + if(scoreWord(word) === maxScore){ + highScoreWords.push(word); + }; + }; + return highScoreWords; +} + export const highestScoreFrom = (words) => { - // Implement this method for wave 4 + let maxScore = getMaxScore(words); + let highScoreWords = getHighScoreWords(words, maxScore); + + let winningWord = highScoreWords[0]; + + for (let word of highScoreWords){ + if (winningWord.length === 10){ + return {word: winningWord, score: maxScore}; + }; + if (winningWord.length > word.length || word.length === 10){ + winningWord = word; + }; + }; + return {word: winningWord, score: maxScore}; }; + diff --git a/test/adagrams.test.js b/test/adagrams.test.js index 1a0dc94e..058bde0a 100644 --- a/test/adagrams.test.js +++ b/test/adagrams.test.js @@ -120,7 +120,11 @@ describe("Adagrams", () => { }); it("returns a score of 0 if given an empty input", () => { - throw "Complete test"; + expect(scoreWord("")).toBe(0); + expect(scoreWord(" ")).toBe(0); + expect(scoreWord(" ")).toBe(0); + + }); it("adds an extra 8 points if word is 7 or more characters long", () => { @@ -133,7 +137,7 @@ describe("Adagrams", () => { }); }); - describe.skip("highestScoreFrom", () => { + describe("highestScoreFrom", () => { it("returns a hash that contains the word and score of best word in an array", () => { const words = ["X", "XX", "XXX", "XXXX"]; const correct = { word: "XXXX", score: scoreWord("XXXX") }; @@ -145,7 +149,7 @@ describe("Adagrams", () => { const words = ["XXX", "XXXX", "X", "XX"]; const correct = { word: "XXXX", score: scoreWord("XXXX") }; - throw "Complete test by adding an assertion"; + expect(highestScoreFrom(words)).toEqual(correct); }); describe("in case of tied score", () => { diff --git a/test/demo/model.test.js b/test/demo/model.test.js index 49bf9599..52ae8d23 100644 --- a/test/demo/model.test.js +++ b/test/demo/model.test.js @@ -1,7 +1,7 @@ import Model from 'demo/model'; import Adagrams from 'demo/adagrams'; -describe.skip('Game Model', () => { +describe('Game Model', () => { const config = { players: [ 'Player A',