Skip to content

Commit

Permalink
Release spelling bee changes (#8)
Browse files Browse the repository at this point in the history
* verify puzzle order

same as ConorSheehan1/spelling-bee#28

* keypress handler

same as ConorSheehan1/spelling-bee#29
plus irish translation support

* upgrade to node 16

same as ConorSheehan1/spelling-bee#30
  • Loading branch information
ConorSheehan1 authored Jul 16, 2023
1 parent 840c5ba commit 6f95daf
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 17 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Set up Node 14
- name: Set up Node 16
uses: actions/setup-node@v1
with:
node-version: 14
node-version: 16
- name: Install dependencies
run: |
npm i
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
install_command: yarn install
build_command: yarn build
build_directory: dist
node_version: 14.18.2
node_version: 16
35 changes: 32 additions & 3 deletions data/createFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
// 1. Filters out any invalid words (len < 4, unique letters > 7) and writes them to answers.txt
// 2. Finds pangrams and writes them to pangrams.txt
// 3. Creates unique puzzle starting points and writes them to various allAnswers$N.json
// 4. It will also check if today's and yesterday's puzzles have changed. If they have, it provides the option to quit the script.

import { readFileSync, writeFileSync } from "fs";
import cliProgress from "cli-progress";
import { shuffle } from "../src/utils";
import readlineSync from "readline-sync";
import { generateAnswerObjs, shuffle } from "../src/utils";
// script will fail if allAnswers.json does not already exist. can just create empty file if running for first time.
import currentAnswers from "./allAnswers.json";

// config
const minNumAnswers = 20;
Expand All @@ -14,6 +18,11 @@ const writeSupplementaryFiles = true;
// need to update to use allAnswers2 10 years from now. see you in the future o_0
const numPuzzlesPerFile = 3650;

// TODO: dynamic import in app.vue and here, use variable to ensure script and app use same data
const answerFile = "allAnswers.json" // match App.vue
const gameDate = new Date();
const currentAnswerObj = generateAnswerObjs({ allAnswers: currentAnswers, gameDate });

const data = readFileSync("./data/AllWords.txt");
const words = data
.toString()
Expand All @@ -39,7 +48,6 @@ const uniqueLetterCombinations = pangrams.reduce((acc: Set<string>, pangram: str
acc.add(Array.from(uniqueLetters).join(""));
return acc;
}, new Set());
const numPangrams = pangrams.length;
const numUniqueLetterCombinations = uniqueLetterCombinations.size;
const uniqueLetterCombinationsShuffled = shuffle(Array.from(uniqueLetterCombinations))

Expand Down Expand Up @@ -68,8 +76,27 @@ for (let offset = 0; offset < 7; offset++) {
// }
if (numProcessed % numPuzzlesPerFile === 0) {
let fileNum = numProcessed / numPuzzlesPerFile;

// validation today and yesterdays puzzle hasn't changed
const fileName = `./data/allAnswers${fileNum === 1 ? '' : fileNum}.json`;
if (fileName.endsWith(answerFile)) {
console.log(`\nChecking file currently in use by the game: ${fileName}`);
const newCurrentAnswerObj = generateAnswerObjs({ allAnswers, gameDate });
const jsonNewCurrentAnswerObj = JSON.stringify(newCurrentAnswerObj);
const jsonCurrentAnswerObj = JSON.stringify(currentAnswerObj);
if (jsonNewCurrentAnswerObj !== jsonCurrentAnswerObj) {
console.log(`jsonCurrentAnswerObj: ${jsonCurrentAnswerObj.substring(0, 100)} ...`);
console.log(`jsonNewCurrentAnswerObj: ${jsonNewCurrentAnswerObj.substring(0, 100)} ...`);
if (!readlineSync.keyInYN("Today's and yesterday's puzzles have changed. Continue?")) {
process.exit();
}
} else {
console.log(`Checks passed. Today's and yesterday's puzzles have not changed.`);
}
}

writeFileSync(
`./data/allAnswers${fileNum === 1 ? '' : fileNum}.json`,
fileName,
`${JSON.stringify(allAnswers, null, 2)}`
);
allAnswers = [];
Expand All @@ -78,3 +105,5 @@ for (let offset = 0; offset < 7; offset++) {
}

createPuzzleBar.stop();
console.log(`Processed ${numProcessed} puzzles, and ${Math.floor(numProcessed / numPuzzlesPerFile)} files.`)
console.log(`${Math.floor(numProcessed / 365)} years of puzzles.`)
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^5.0.0",
"@types/cli-progress": "^3.11.0",
"@types/readline-sync": "^1.4.4",
"@vitejs/plugin-vue": "^2.3.3",
"@vue/test-utils": "^2.0.2",
"cli-progress": "^3.11.2",
"happy-dom": "^6.0.4",
"pre-commit": "^1.2.2",
"prettier": "^2.7.1",
"readline-sync": "^1.4.10",
"ts-node": "^10.9.1",
"typescript": "^4.7.4",
"vite": "^2.9.16",
Expand Down
33 changes: 32 additions & 1 deletion src/components/Hive.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<script setup lang="ts">
import { ref } from "vue";
import { onMounted, onUnmounted, ref } from "vue";
import { useMainStore } from "../store";
import { shuffle } from "../utils";
import { useI18n } from "vue-i18n";
import en from "../locales/en.json";
import ga from "../locales/ga.json";
const { t } = useI18n({
inheritLocale: true,
messages: {
en,
ga,
},
});
// `defineProps` is a compiler macro and no longer needs to be imported.
defineProps({
Expand All @@ -16,10 +26,31 @@ const otherLetters = ref(
);
let userGuess = ref("");
const onKeyPress = (e: KeyboardEvent) => {
const pressedKey = e.key.toLowerCase();
if (pressedKey === "enter")
return submitGuess({ $t: t, guess: userGuess.value });
if (["backspace", "delete"].includes(pressedKey)) {
userGuess.value = userGuess.value.slice(0, -1);
return false;
}
if (pressedKey.length === 1 && store.availableLetters.includes(pressedKey)) {
userGuess.value += pressedKey;
return true;
}
};
const submitGuess = ({ $t, guess }: { $t: Function; guess: string }) => {
userGuess.value = "";
store.submitGuess({ $t, guess });
};
onMounted(() => {
window.addEventListener("keyup", onKeyPress);
});
onUnmounted(() => {
window.removeEventListener("keyup", onKeyPress);
});
</script>

<template>
Expand Down
14 changes: 5 additions & 9 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import { defineStore } from "pinia";
import { useStorage } from "@vueuse/core";
import { ElMessage } from "element-plus";
import { differenceInDays, isSameDay } from "date-fns";
import { incrementDups } from "./utils";
import { epoch, generateAnswerObjs, incrementDups } from "./utils";
import { Answer } from "./models/answer";

const epoch = new Date("2022-01-01");

export const useMainStore = defineStore({
id: "main",
state: () => ({
Expand Down Expand Up @@ -162,12 +160,10 @@ export const useMainStore = defineStore({
this.gameDate = now;
// new game so reset guesses
this.correctGuesses = new Set([]);
// use days since arbitrary epoch to ensure yesterdays answers is always 1 behind todays.
const daysSinceEpoch = differenceInDays(this.gameDate, epoch);
// pick next puzzle input, % len puzzles to restart if out of index (circular)
const todaysAnswerObj = allAnswers[daysSinceEpoch % allAnswers.length];
const yesterdaysAnswerObj =
allAnswers[(daysSinceEpoch - 1) % allAnswers.length];
const { todaysAnswerObj, yesterdaysAnswerObj } = generateAnswerObjs({
allAnswers,
gameDate: this.gameDate,
});

this.setYesterdaysAnswersAndLastGameDate({ yesterdaysAnswerObj });

Expand Down
32 changes: 31 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { differenceInDays } from "date-fns";
import { Answer } from "./models/answer";

// generic js functions
// https://levelup.gitconnected.com/lodash-methods-that-can-be-easily-implemented-in-plain-javascript-bbe22509827e
const chunk = ({
Expand Down Expand Up @@ -74,4 +77,31 @@ const incrementDups = (arr: Array<number>): Array<number> => {
});
};

export { chunk, gridify, incrementDups, shuffle, zip };
// year game started, not released until mid-year so no issue using as epoch
const epoch = new Date("2022-01-01");

const generateAnswerObjs = ({
allAnswers,
gameDate,
}: {
allAnswers: Array<Answer>;
gameDate: Date;
}): { todaysAnswerObj: Answer; yesterdaysAnswerObj: Answer } => {
// use days since arbitrary epoch to ensure yesterdays answers is always 1 behind todays.
const daysSinceEpoch = differenceInDays(gameDate, epoch);
// pick next puzzle input, % len puzzles to restart if out of index (circular)
const todaysAnswerObj = allAnswers[daysSinceEpoch % allAnswers.length];
const yesterdaysAnswerObj =
allAnswers[(daysSinceEpoch - 1) % allAnswers.length];
return { todaysAnswerObj, yesterdaysAnswerObj };
};

export {
chunk,
epoch,
generateAnswerObjs,
gridify,
incrementDups,
shuffle,
zip,
};
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==

"@types/readline-sync@^1.4.4":
version "1.4.4"
resolved "https://registry.yarnpkg.com/@types/readline-sync/-/readline-sync-1.4.4.tgz#8568292efe4ddd94d0ccee958b29cc3f4e0ea140"
integrity sha512-cFjVIoiamX7U6zkO2VPvXyTxbFDdiRo902IarJuPVxBhpDnXhwSaVE86ip+SCuyWBbEioKCkT4C88RNTxBM1Dw==

"@types/web-bluetooth@^0.0.14":
version "0.0.14"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.14.tgz#94e175b53623384bff1f354cdb3197a8d63cdbe5"
Expand Down Expand Up @@ -1365,6 +1370,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"

readline-sync@^1.4.10:
version "1.4.10"
resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==

resolve@^1.22.0, resolve@^1.22.1:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
Expand Down

0 comments on commit 6f95daf

Please sign in to comment.