sunrise-sunset: tidy streak calculation

This commit is contained in:
Thomas 2023-02-01 22:31:56 +00:00
parent daf73c797e
commit 0eb59d948a
3 changed files with 50 additions and 45 deletions

View file

@ -82,7 +82,7 @@
return; return;
} }
currentStreakLength = streakCalculator.getStreakLength( currentStreakLength = streakCalculator.getCurrentStreakLengthForCorrectDays(
$guessingHistory.correctDays $guessingHistory.correctDays
); );
localStorage.setItem(localStorageKey, JSON.stringify(value)); localStorage.setItem(localStorageKey, JSON.stringify(value));

View file

@ -9,7 +9,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const correctDays = []; const correctDays = [];
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(anyDay).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(anyDay).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(0); expect(currentStreakLength).toBe(0);
@ -21,7 +23,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const today = '2023-01-29'; const today = '2023-01-29';
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(today).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(today).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(1); expect(currentStreakLength).toBe(1);
@ -33,7 +37,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const today = '2023-01-29'; const today = '2023-01-29';
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(today).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(today).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(2); expect(currentStreakLength).toBe(2);
@ -45,7 +51,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const today = '2023-01-28'; const today = '2023-01-28';
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(today).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(today).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(1); expect(currentStreakLength).toBe(1);
@ -56,7 +64,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const correctDays = ['2023-01-26', '2023-01-27', '2023-01-31']; const correctDays = ['2023-01-26', '2023-01-27', '2023-01-31'];
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator('2023-01-31').getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(
'2023-01-31'
).getCurrentStreakLengthForCorrectDays(correctDays);
// THEN // THEN
expect(currentStreakLength).toBe(1); expect(currentStreakLength).toBe(1);
@ -68,7 +78,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const today = '2023-01-28'; const today = '2023-01-28';
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(today).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(today).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(2); expect(currentStreakLength).toBe(2);
@ -80,7 +92,9 @@ describe('SunriseSunsetStreakCalculator', () => {
const today = '2023-01-28'; const today = '2023-01-28';
// WHEN // WHEN
const currentStreakLength = new SunriseSunsetStreakCalculator(today).getStreakLength(correctDays); const currentStreakLength = new SunriseSunsetStreakCalculator(today).getCurrentStreakLengthForCorrectDays(
correctDays
);
// THEN // THEN
expect(currentStreakLength).toBe(3); expect(currentStreakLength).toBe(3);

View file

@ -1,4 +1,4 @@
import { parse, format as formatDate, differenceInCalendarDays } from 'date-fns'; import { parse, format as formatDate, differenceInCalendarDays, isSameDay } from 'date-fns';
import { SunriseSunsetDayGuess } from './SunriseSunsetDayGuess.js'; import { SunriseSunsetDayGuess } from './SunriseSunsetDayGuess.js';
import { SunriseSunsetDayGuessSet } from './SunriseSunsetGuessSet.js'; import { SunriseSunsetDayGuessSet } from './SunriseSunsetGuessSet.js';
import { GuessType } from './GuessType.js'; import { GuessType } from './GuessType.js';
@ -9,7 +9,10 @@ class SunriseSunsetStreak {
readonly mostRecentStreak: number; readonly mostRecentStreak: number;
constructor(correctDays: Date[], today = new Date()) { constructor(correctDays: Date[], today = new Date()) {
if (correctDays.length === 0) { const isCorrectDaysEmpty = correctDays.length === 0;
if (isCorrectDaysEmpty) {
console.log(`No correct days recorded.`);
this.longestStreak = 0; this.longestStreak = 0;
this.mostRecentStreak = 0; this.mostRecentStreak = 0;
this.allStreaks = []; this.allStreaks = [];
@ -47,17 +50,26 @@ class SunriseSunsetStreak {
[1] [1]
); );
// The streaks are in reverse order, so the most recent streak is the last one.
console.log('allStreaks', allStreaks);
this.mostRecentStreak = allStreaks[0] ?? 0;
this.longestStreak = allStreaks.length > 0 ? Math.max(...allStreaks) : 0; this.longestStreak = allStreaks.length > 0 ? Math.max(...allStreaks) : 0;
this.allStreaks = allStreaks; this.allStreaks = allStreaks;
const isTodayMissingFromCorrectDays = !correctDays.some((day) => isSameDay(day, today));
// The streaks are in reverse order, so the most recent streak is the last one.
if (allStreaks[0] === undefined) {
this.mostRecentStreak = 0;
} else if (isTodayMissingFromCorrectDays) {
this.mostRecentStreak = 0;
} else {
this.mostRecentStreak = allStreaks[0];
}
} }
} }
export class SunriseSunsetStreakCalculator { export class SunriseSunsetStreakCalculator {
private readonly todayDate: Date; private readonly todayDate: Date;
constructor(private readonly today: string) {
constructor(today: string) {
this.todayDate = parse(today, 'yyyy-MM-dd', new Date()); this.todayDate = parse(today, 'yyyy-MM-dd', new Date());
} }
@ -77,11 +89,18 @@ export class SunriseSunsetStreakCalculator {
return streak; return streak;
} }
getCurrentStreakLengthForCorrectDays(correctDays: string[]): number {
const streak = new SunriseSunsetStreak(this.daysAsDates(correctDays), this.todayDate);
return streak.mostRecentStreak;
}
getShareableStatement(correctDays: string[], incorrectDays: string[], today: Date, joiningString = '\n'): string { getShareableStatement(correctDays: string[], incorrectDays: string[], today: Date, joiningString = '\n'): string {
const emoji = this.getEmojiForHistory(correctDays, incorrectDays);
const todayFormatted = formatDate(today, 'yyyy-MM-dd');
const streak = new SunriseSunsetStreak(this.daysAsDates(correctDays)); const streak = new SunriseSunsetStreak(this.daysAsDates(correctDays));
const currentStreak = this.getStreakLength(correctDays); const todayFormatted = formatDate(today, 'yyyy-MM-dd');
const emoji = this.getEmojiForHistory(correctDays, incorrectDays);
const currentStreak = this.getCurrentStreakLengthForCorrectDays(correctDays);
return [ return [
`Sunrise, Sunset?`, `Sunrise, Sunset?`,
@ -91,32 +110,4 @@ export class SunriseSunsetStreakCalculator {
`Longest Streak: ${streak.longestStreak}`, `Longest Streak: ${streak.longestStreak}`,
].join(joiningString); ].join(joiningString);
} }
getStreakLength(correctDays: string[]): number {
if (correctDays.length === 0) {
console.log(`No correct days, returning 0.`);
return 0;
} else if (!correctDays.some((day) => day === this.today)) {
console.log(`Today is not in the list of correct days`);
return 0;
}
const daysAsDates = this.daysAsDates(correctDays);
const sortedDaysWithoutToday = correctDays
.filter((day) => day !== this.today)
.map((day) => parse(day, 'yyyy-MM-dd', new Date()))
.sort((a, b) => b.getTime() - a.getTime());
const daysBetweenTodayAndMostRecentDay = differenceInCalendarDays(this.todayDate, sortedDaysWithoutToday[0]);
if (daysBetweenTodayAndMostRecentDay > 1) {
console.log(`Today is more than one day after the most recent correct day`);
return 1;
}
const streaks = new SunriseSunsetStreak(daysAsDates);
return streaks.mostRecentStreak;
}
} }