Skip to content

Sapphire - Hannah Chandley Wohllaib #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
165 changes: 161 additions & 4 deletions src/adagrams.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,172 @@
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_VALUE = {
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,
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love to see the two constants LETTER_VALUE and LETTER_POOL up top! 🧡


const getRandomInt = (max) => {
return Math.floor(Math.random() * max);
}
Comment on lines +59 to +61

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great helper function!


export const drawLetters = () => {
// Implement this method for wave 1
const alphabet = Object.keys(LETTER_POOL);
const drawnLetters = [];

while (drawnLetters.length < 10) {
const randomLetter = alphabet[getRandomInt(26)];
const quantity = LETTER_POOL[randomLetter];
let counter = 0;

for (let i = 0; i < drawnLetters.length; i++) {
if (drawnLetters[i] === randomLetter) {
counter += 1;
}
}
if (counter < quantity) {
drawnLetters.push(randomLetter);
}
Comment on lines +68 to +79

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't quite mimic the action of pulling out a random letter form a bag of properly weighted letters (here, there's an equal chance of pulling out a E as a Z due to L28, despite E being much more likely to be drawn) but it's a good start!

}
return drawnLetters;
};

export const usesAvailableLetters = (input, lettersInHand) => {
// Implement this method for wave 2
const lettersInHandMap = new Map()
lettersInHand.forEach(letter => lettersInHandMap.set(letter));
const inputUpper = input.toUpperCase();

for (const letter of inputUpper) {
if (lettersInHandMap.has(letter) === true) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor to:

if (lettersInHandMap.has(letter)) {

lettersInHandMap.delete(letter);
} else {
return false;
}
}
return true;
};

export const scoreWord = (word) => {
// Implement this method for wave 3
const wordUpper = word.toUpperCase();
let score = 0;

for (const letter of wordUpper) {
score += LETTER_VALUE[letter];
}

if (wordUpper.length > 6) {
score += 8;
}

return score;
};

const tieBreaker = (potentialWinningWords) => {
const tenLetterWords = [];
const shortestWords = [];
let shortestWordLength = 11

for (const word of potentialWinningWords) {
if (word.length === 10) {
tenLetterWords.push(word)
} else if (word.length < shortestWordLength) {
shortestWordLength = word.length;
}
}

for (const word of potentialWinningWords) {
if (word.length === shortestWordLength) {
shortestWords.push(word);
}
}

if (tenLetterWords.length > 0) {
return tenLetterWords[0];
} else {
return shortestWords[0];
}
};
Comment on lines +114 to 138

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great tiebreaker logic in a neat helper function!


export const highestScoreFrom = (words) => {
// Implement this method for wave 4
const wordsScores = new Map();
let scoreCounter = 0;
const potentialWinners = [];

for (const word of words) {
wordsScores.set(word, scoreWord(word));
if (wordsScores.get(word) > scoreCounter) {
scoreCounter = wordsScores.get(word);
}
}

for (const word of wordsScores.keys()) {
if (wordsScores.get(word) === scoreCounter) {
potentialWinners.push(word);
}
}

if (potentialWinners.length === 1) {
const winningWord = {
'word': potentialWinners[0],
'score': wordsScores.get(potentialWinners[0]),
};
return winningWord;
} else {
const tieBreakerWinner = tieBreaker(potentialWinners);
const winningWord = {
'word': tieBreakerWinner,
'score': wordsScores.get(tieBreakerWinner),
};
return winningWord;
}
};
8 changes: 5 additions & 3 deletions test/adagrams.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ describe("Adagrams", () => {
});

it("returns a score of 0 if given an empty input", () => {
throw "Complete test";
expectScores({
'': 0,
});
});

it("adds an extra 8 points if word is 7 or more characters long", () => {
Expand All @@ -133,7 +135,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") };
Expand All @@ -145,7 +147,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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

});

describe("in case of tied score", () => {
Expand Down
2 changes: 1 addition & 1 deletion test/demo/model.test.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down