Skip to content
138 changes: 126 additions & 12 deletions src/adagrams.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,129 @@
export const drawLetters = () => {
// Implement this method for wave 1
};
export default class Adagrams {

Choose a reason for hiding this comment

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

OOP!

constructor() {
// this.score = 0;
// this.hand = [];
}

export const usesAvailableLetters = (input, lettersInHand) => {
// Implement this method for wave 2
};
drawLetters() {
const letterPool = {
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 letters = Object.keys(letterPool);
let hand = [];
let i = 0;

export const scoreWord = (word) => {
// Implement this method for wave 3
};
while (i < 10) {

Choose a reason for hiding this comment

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

This loops makes sense, and I don't think you really have to worry about it here, but when I see while loops like this, I think about adding some other kind of guard condition- like limiting the number of attempts, for example-- to catch a possible infinite loop if there weren't enough letters to be picked.

let drawnLetter = letters[Math.floor(Math.random() * letters.length)];
if (letterPool[drawnLetter] > 0) {
hand.push(drawnLetter);
letterPool[drawnLetter]--;
i++;
}
}

export const highestScoreFrom = (words) => {
// Implement this method for wave 4
};
return hand;
}

usesAvailableLetters(input, lettersInHand) {
let usesOnlyAvailableLetters = true;
[...input].forEach((letter) => {
const index = lettersInHand.indexOf(letter);
// indexOf method return -1 if letter not found

Choose a reason for hiding this comment

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

I appreciate the comment

if (index != -1) {
// for splice, need to specify only 1 letter should be removed
lettersInHand.splice(index, 1);

Choose a reason for hiding this comment

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

concise-- nice usage of splice

} else {
usesOnlyAvailableLetters = false;
}
});
return usesOnlyAvailableLetters;
}

scoreWord(word) {
// stored letterScores as a dict so code is flexible and changes can easily be made
const letterScores = {
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,
};
let score = 0;

[...word].forEach((letter) => {

Choose a reason for hiding this comment

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

nice use of spread syntax

score += letterScores[letter.toUpperCase()];
});
if (word.length >= 7) {
score += 8;
}
return score;
}

highestScoreFrom(words) {
let max = 0;
let winner;
for (let i = 0; i < words.length; i++) {
let score = this.scoreWord(words[i]);
if (score > max) {
winner = { word: words[i], score: score };
max = score;
} else if (score == max) {
if (winner.word.length == 10) {
return winner;
} else if (words[i].length == 10) {
winner = { word: words[i], score: score };
return winner;
} else if (words[i].length < winner.word.length) {
winner = { word: words[i], score: score };
}
}
}
return winner;
}
}
18 changes: 4 additions & 14 deletions src/demo/adagrams.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import {
drawLetters,
usesAvailableLetters,
scoreWord,
highestScoreFrom,
} from "adagrams";

const Real = {
drawLetters,
usesAvailableLetters,
scoreWord,
highestScoreFrom,
};
import Adagrams from "../adagrams";

const Real = new Adagrams();

const Stub = {
drawLetters() {
Expand All @@ -28,7 +18,7 @@ const Stub = {
return Real.usesAvailableLetters(input, lettersInHand);
}

return true;
return null;
},

scoreWord(word) {
Expand Down
51 changes: 29 additions & 22 deletions src/demo/model.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Adagrams from 'demo/adagrams';
import Adagrams from "demo/adagrams";

class Model {
constructor(config) {
if(!config) {
throw new Error('Model requires a config parameter.');
if (!config) {
throw new Error("Model requires a config parameter.");
}

this.config = config;
Expand Down Expand Up @@ -33,7 +33,7 @@ class Model {
}

currentPlayerName() {
if(this.currentPlayer === null) return null;
if (this.currentPlayer === null) return null;

return this._playerName(this.currentPlayer);
}
Expand All @@ -44,7 +44,7 @@ class Model {
this.currentPlayer = 0;

const gameOver = this.round > this.config.rounds;
if(gameOver) {
if (gameOver) {
return { gameOver, winner: this._gameWinner() };
}

Expand All @@ -71,15 +71,15 @@ class Model {
playWord(word) {
word = word.toUpperCase();

if(!this._valid(word)) return null;
if (!this._valid(word)) return null;

this._recordPlay(word);

return Adagrams.scoreWord(word);
}

_valid(word, letterBank = this.letterBank) {
if(word.length < 1) return false;
if (word.length < 1) return false;
return Adagrams.usesAvailableLetters(word, letterBank);
}

Expand All @@ -93,7 +93,7 @@ class Model {

_bestPlay(round, player) {
const plays = this.plays[player][round - 1];
if(plays.length < 1) {
if (plays.length < 1) {
return null;
}

Expand All @@ -102,38 +102,45 @@ class Model {

_roundWinner(round) {
const bestPlays = this.config.players
.map((player) => ({ player, ...this._bestPlay(round, player) }))
.filter(({ player, word, score }) => word !== undefined);
.map((player) => ({ player, ...this._bestPlay(round, player) }))

Choose a reason for hiding this comment

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

Ooh, nice use of map for looping through the players

.filter(({ player, word, score }) => word !== undefined);

if(bestPlays.length < 1) {
return { player: '<NOBODY>', word: '<NONE>', score: 0 };
if (bestPlays.length < 1) {
return { player: "<NOBODY>", word: "<NONE>", score: 0 };
}

const { word: winningWord } = Adagrams.highestScoreFrom(bestPlays.map(({ word }) => word));
const { word: winningWord } = Adagrams.highestScoreFrom(
bestPlays.map(({ word }) => word)
);
return bestPlays.find(({ word }) => word === winningWord);
}

_gameWinner() {
// Add up the scores for each player, counting only the rounds where they won
const roundWinners = [];
for(let round = 1; round <= this.config.rounds; round++) {
for (let round = 1; round <= this.config.rounds; round++) {
const winner = this._roundWinner(round);
const existing = roundWinners.find(({ player }) => player === winner.player);
const existing = roundWinners.find(
({ player }) => player === winner.player
);

if(existing) {
if (existing) {
existing.score += winner.score;
} else {
roundWinners.push(winner);
}
}

return roundWinners.reduce((gameWinner, roundWinner) => {
if(roundWinner.score > gameWinner.score) {
gameWinner = roundWinner;
}
return roundWinners.reduce(
(gameWinner, roundWinner) => {
if (roundWinner.score > gameWinner.score) {
gameWinner = roundWinner;
}

return gameWinner;
}, { player: '<NOBODY>', score: 0 });
return gameWinner;
},
{ player: "<NOBODY>", score: 0 }
);
}
}

Expand Down
Loading