Compare commits
4 Commits
3b216000f9
...
9e34b7a1d9
Author | SHA1 | Date | |
---|---|---|---|
9e34b7a1d9 | |||
1472ef1ca3 | |||
afe708d992 | |||
b616b5e324 |
|
@ -110,7 +110,7 @@ class Bagels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFragment(kind) {
|
get fragment() {
|
||||||
return this.word + ',' + this.availableLetters.sort().join('');
|
return this.word + ',' + this.availableLetters.sort().join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html manifest="cache.appcache">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
|
||||||
<meta content="utf-8" http-equiv="encoding">
|
<meta content="utf-8" http-equiv="encoding">
|
||||||
|
@ -72,19 +72,25 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
submitWord() {
|
submitWord(word) {
|
||||||
if (this.won) return;
|
if (this.won) return;
|
||||||
|
let guess;
|
||||||
|
if (word) {
|
||||||
|
guess = word;
|
||||||
|
} else {
|
||||||
if (!this.letters.every(letter => letter != '')) return;
|
if (!this.letters.every(letter => letter != '')) return;
|
||||||
let guess = this.letters.join('');
|
guess = this.letters.join('');
|
||||||
|
}
|
||||||
let results = this.game.makeGuess(guess);
|
let results = this.game.makeGuess(guess);
|
||||||
if (results == null) return;
|
if (results == null) return;
|
||||||
|
this.saveGuess(guess);
|
||||||
|
|
||||||
let resultDisplay = document.createElement('tr');
|
let resultDisplay = document.createElement('tr');
|
||||||
resultDisplay.classList.add('guess');
|
resultDisplay.classList.add('guess');
|
||||||
|
|
||||||
for (let i = 0; i < this.game.numLetters; i++) {
|
for (let i = 0; i < this.game.numLetters; i++) {
|
||||||
let letter = document.createElement('td');
|
let letter = document.createElement('td');
|
||||||
letter.innerText = this.letters[i];
|
letter.innerText = guess[i];
|
||||||
letter.classList.add(getLetterGuessResultClass(results.letters[i]));
|
letter.classList.add(getLetterGuessResultClass(results.letters[i]));
|
||||||
resultDisplay.appendChild(letter);
|
resultDisplay.appendChild(letter);
|
||||||
}
|
}
|
||||||
|
@ -112,17 +118,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newGame() {
|
|
||||||
let settings = this.getSettingsObjectFromForm();
|
|
||||||
if (settings === null) return;
|
|
||||||
|
|
||||||
let game;
|
|
||||||
do {
|
|
||||||
game = Bagels.generateRandom(settings);
|
|
||||||
} while (game === null && window.confirm('Unable to generate puzzle with the given difficulty settings. Try again?'));
|
|
||||||
if (game !== null) this.initialize(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
get defaultSettings() {
|
get defaultSettings() {
|
||||||
let default_settings = {
|
let default_settings = {
|
||||||
'min_word_length': 4,
|
'min_word_length': 4,
|
||||||
|
@ -140,6 +135,8 @@
|
||||||
constructor(game) {
|
constructor(game) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
let ui = this;
|
||||||
|
|
||||||
let difficulty = document.forms['difficulty'];
|
let difficulty = document.forms['difficulty'];
|
||||||
let min_word_length = difficulty.elements['min_word_length'];
|
let min_word_length = difficulty.elements['min_word_length'];
|
||||||
let max_word_length = difficulty.elements['max_word_length'];
|
let max_word_length = difficulty.elements['max_word_length'];
|
||||||
|
@ -179,18 +176,18 @@
|
||||||
ui.saveSettings();
|
ui.saveSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game === null) {
|
this.nextGame(game);
|
||||||
this.newGame();
|
|
||||||
} else {
|
|
||||||
this.initialize(game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get gameClass() {
|
||||||
|
return Bagels;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(game) {
|
initialize(game) {
|
||||||
this.won = false;
|
this.won = false;
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
|
||||||
scrambleString(game.getFragment(), ['A', 'B']).then(fragment => {
|
scrambleString(game.fragment, ['A', 'B']).then(fragment => {
|
||||||
document.getElementById('permalink').href = '#' + fragment;
|
document.getElementById('permalink').href = '#' + fragment;
|
||||||
document.getElementById('permalink_input').value
|
document.getElementById('permalink_input').value
|
||||||
= window.location.href.split('#')[0] + '#' + fragment;
|
= window.location.href.split('#')[0] + '#' + fragment;
|
||||||
|
@ -199,6 +196,8 @@
|
||||||
this.initializeInputs(game.numLetters);
|
this.initializeInputs(game.numLetters);
|
||||||
|
|
||||||
clearElement(document.getElementById('guesses'));
|
clearElement(document.getElementById('guesses'));
|
||||||
|
|
||||||
|
this.doPostInitialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +235,9 @@
|
||||||
<a href="#" target="_blank" id="permalink">Permalink</a>
|
<a href="#" target="_blank" id="permalink">Permalink</a>
|
||||||
to current puzzle:
|
to current puzzle:
|
||||||
<input contenteditable id="permalink_input" />
|
<input contenteditable id="permalink_input" />
|
||||||
<button id="copy_permalink">Copy</button>
|
<button id="copy_permalink">Copy</button><br />
|
||||||
|
<select id="available_games"></select>
|
||||||
|
<button id="switch_game">Switch Game</button>
|
||||||
<h2>Difficulty</h2>
|
<h2>Difficulty</h2>
|
||||||
<form id="difficulty" onsubmit="return false;">
|
<form id="difficulty" onsubmit="return false;">
|
||||||
Word length:
|
Word length:
|
||||||
|
@ -321,7 +322,7 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="endgame">
|
<div id="endgame">
|
||||||
<button id="newgame">New Game</button>
|
<button id="newgame">Next Game</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="available_letters_display">
|
<div id="available_letters_display">
|
||||||
<button id="shuffle"></button>
|
<button id="shuffle"></button>
|
||||||
|
|
|
@ -172,7 +172,7 @@ class Crossword {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFragment() {
|
get fragment() {
|
||||||
let sortedLetters = this.availableLetters.sort();
|
let sortedLetters = this.availableLetters.sort();
|
||||||
return this.minGuessLength + '|' + sortedLetters.join('') + '|'
|
return this.minGuessLength + '|' + sortedLetters.join('') + '|'
|
||||||
+ this.clues.map(clue => clue.toFragment(sortedLetters)).join(';');
|
+ this.clues.map(clue => clue.toFragment(sortedLetters)).join(';');
|
||||||
|
|
|
@ -15,16 +15,22 @@
|
||||||
<script src="../entryui.js"></script>
|
<script src="../entryui.js"></script>
|
||||||
<script >
|
<script >
|
||||||
class CrosswordUI extends AnagramEntryUI {
|
class CrosswordUI extends AnagramEntryUI {
|
||||||
submitWord() {
|
submitWord(word) {
|
||||||
if (this.won) return;
|
if (this.won) return;
|
||||||
|
let guess;
|
||||||
|
if (word) {
|
||||||
|
guess = word;
|
||||||
|
} else {
|
||||||
let seenSpace = false;
|
let seenSpace = false;
|
||||||
for (let idx in this.letters) {
|
for (let idx in this.letters) {
|
||||||
if (this.letters[idx] == '') seenSpace = true;
|
if (this.letters[idx] == '') seenSpace = true;
|
||||||
else if (seenSpace) return;
|
else if (seenSpace) return;
|
||||||
}
|
}
|
||||||
let guess = this.letters.join('');
|
guess = this.letters.join('');
|
||||||
|
}
|
||||||
let results = this.game.makeGuess(guess);
|
let results = this.game.makeGuess(guess);
|
||||||
if (results === null) return;
|
if (results === null) return;
|
||||||
|
this.saveGuess(guess);
|
||||||
|
|
||||||
this.updateCrossword(results);
|
this.updateCrossword(results);
|
||||||
|
|
||||||
|
@ -33,7 +39,7 @@
|
||||||
|
|
||||||
for (let i = 0; i < this.game.numLetters; i++) {
|
for (let i = 0; i < this.game.numLetters; i++) {
|
||||||
let letter = document.createElement('td');
|
let letter = document.createElement('td');
|
||||||
letter.innerText = this.letters[i];
|
letter.innerText = guess[i] || '';
|
||||||
resultDisplay.appendChild(letter);
|
resultDisplay.appendChild(letter);
|
||||||
}
|
}
|
||||||
let link = document.createElement('a');
|
let link = document.createElement('a');
|
||||||
|
@ -122,17 +128,6 @@
|
||||||
return this.mayEnterLetterAt(letter, this.focusedTextbox);
|
return this.mayEnterLetterAt(letter, this.focusedTextbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
newGame() {
|
|
||||||
let settings = this.getSettingsObjectFromForm();
|
|
||||||
if (settings === null) return;
|
|
||||||
|
|
||||||
let game;
|
|
||||||
do {
|
|
||||||
game = Crossword.generateRandom(settings);
|
|
||||||
} while (game === null && window.confirm('Unable to generate puzzle with the given difficulty settings. Try again?'));
|
|
||||||
if (game !== null) this.initialize(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
get defaultSettings() {
|
get defaultSettings() {
|
||||||
let default_settings = {
|
let default_settings = {
|
||||||
'min_word_length': 4,
|
'min_word_length': 4,
|
||||||
|
@ -196,11 +191,11 @@
|
||||||
ui.saveSettings();
|
ui.saveSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game === null) {
|
this.nextGame(game);
|
||||||
this.newGame();
|
|
||||||
} else {
|
|
||||||
this.initialize(game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get gameClass() {
|
||||||
|
return Crossword;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(game) {
|
initialize(game) {
|
||||||
|
@ -208,7 +203,7 @@
|
||||||
this.game = game;
|
this.game = game;
|
||||||
let ui = this;
|
let ui = this;
|
||||||
|
|
||||||
scrambleString(game.getFragment(), ['', 'A', 'B']).then(fragment => {
|
scrambleString(game.fragment, ['', 'A', 'B']).then(fragment => {
|
||||||
document.getElementById('permalink').href = '#' + fragment;
|
document.getElementById('permalink').href = '#' + fragment;
|
||||||
document.getElementById('permalink_input').value
|
document.getElementById('permalink_input').value
|
||||||
= window.location.href.split('#')[0] + '#' + fragment;
|
= window.location.href.split('#')[0] + '#' + fragment;
|
||||||
|
@ -286,6 +281,8 @@
|
||||||
document.getElementById('bonus_words_found').innerText = 0;
|
document.getElementById('bonus_words_found').innerText = 0;
|
||||||
document.getElementById('clues_total').innerText = game.clues.length;
|
document.getElementById('clues_total').innerText = game.clues.length;
|
||||||
document.getElementById('top_words_total').innerText = game.allTopWords.size - game.clues.length;
|
document.getElementById('top_words_total').innerText = game.allTopWords.size - game.clues.length;
|
||||||
|
|
||||||
|
this.doPostInitialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +320,9 @@
|
||||||
<a href="#" target="_blank" id="permalink">Permalink</a>
|
<a href="#" target="_blank" id="permalink">Permalink</a>
|
||||||
to current puzzle:
|
to current puzzle:
|
||||||
<input contenteditable id="permalink_input" />
|
<input contenteditable id="permalink_input" />
|
||||||
<button id="copy_permalink">Copy</button>
|
<button id="copy_permalink">Copy</button><br />
|
||||||
|
<select id="available_games"></select>
|
||||||
|
<button id="switch_game">Switch Game</button>
|
||||||
<h2>Difficulty</h2>
|
<h2>Difficulty</h2>
|
||||||
<form id="difficulty" onsubmit="return false;">
|
<form id="difficulty" onsubmit="return false;">
|
||||||
Word length:
|
Word length:
|
||||||
|
@ -386,7 +385,7 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="endgame">
|
<div id="endgame">
|
||||||
<button id="newgame">New Game</button>
|
<button id="newgame">Next Game</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="available_letters_display">
|
<div id="available_letters_display">
|
||||||
<button id="shuffle"></button>
|
<button id="shuffle"></button>
|
||||||
|
|
136
www/entryui.js
136
www/entryui.js
|
@ -19,7 +19,14 @@ class AnagramEntryUI {
|
||||||
document.getElementById('clear_nonlocked')
|
document.getElementById('clear_nonlocked')
|
||||||
.addEventListener('click', _ => ui.clearUnlocked());
|
.addEventListener('click', _ => ui.clearUnlocked());
|
||||||
document.getElementById('newgame')
|
document.getElementById('newgame')
|
||||||
.addEventListener('click', _ => ui.newGame());
|
.addEventListener('click', _ => ui.nextGame());
|
||||||
|
document.getElementById('switch_game')
|
||||||
|
.addEventListener('click', _ => {
|
||||||
|
let fragment = document.getElementById('available_games').value;
|
||||||
|
if (!ui.game || fragment != ui.game.fragment) {
|
||||||
|
ui.nextGame(ui.gameClass.fromFragment(fragment));
|
||||||
|
}
|
||||||
|
});
|
||||||
document.addEventListener('keyup', event => {
|
document.addEventListener('keyup', event => {
|
||||||
if (!ui.game || document.activeElement.nodeName.toUpperCase() === 'INPUT') {
|
if (!ui.game || document.activeElement.nodeName.toUpperCase() === 'INPUT') {
|
||||||
return;
|
return;
|
||||||
|
@ -76,9 +83,7 @@ class AnagramEntryUI {
|
||||||
document.getElementById('newgame_button')
|
document.getElementById('newgame_button')
|
||||||
.addEventListener('click', _ => {
|
.addEventListener('click', _ => {
|
||||||
if (this.getSettingsObjectFromForm() === null) return;
|
if (this.getSettingsObjectFromForm() === null) return;
|
||||||
if (ui.won || window.confirm('Lose all progress on this puzzle and generate a new one?')) {
|
|
||||||
ui.newGame();
|
ui.newGame();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,13 +302,116 @@ class AnagramEntryUI {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
updateSavedGamesMenu(settings) {
|
||||||
|
let saves = settings['saved_games'];
|
||||||
|
let gameSelect = document.getElementById('available_games');
|
||||||
|
let gameFragment = this.game ? this.game.fragment : null;
|
||||||
|
clearElement(gameSelect);
|
||||||
|
for (let fragment in saves) {
|
||||||
|
let option = document.createElement('option');
|
||||||
|
option.value = fragment;
|
||||||
|
option.selected = fragment == gameFragment;
|
||||||
|
option.innerText = (option.selected ? '[*] ' : '') + new Date(saves[fragment].last_played) + " - [" + saves[fragment].guesses.length + "] " + (saves[fragment].guesses.slice(-1)[0] || "(no guesses yet)");
|
||||||
|
gameSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadSettings() {
|
newGame() {
|
||||||
let default_settings = this.defaultSettings;
|
let settings = this.getSettingsObjectFromForm();
|
||||||
|
if (settings === null) return;
|
||||||
|
|
||||||
|
let game;
|
||||||
|
do {
|
||||||
|
game = this.gameClass.generateRandom(settings);
|
||||||
|
} while (game === null && window.confirm('Unable to generate puzzle with the given difficulty settings. Try again?'));
|
||||||
|
if (game !== null) this.initialize(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
doPostInitialize() {
|
||||||
|
let fragment = this.game.fragment;
|
||||||
|
let currentSettings = this.loadSettingsJson();
|
||||||
|
if (!currentSettings) currentSettings = this.defaultSettings;
|
||||||
|
|
||||||
|
if (!('saved_games' in currentSettings)) {
|
||||||
|
currentSettings['saved_games'] = {};
|
||||||
|
}
|
||||||
|
if (fragment in currentSettings.saved_games) {
|
||||||
|
currentSettings.saved_games[fragment].guesses.forEach(guess => {
|
||||||
|
this.submitWord(guess);
|
||||||
|
});
|
||||||
|
currentSettings.saved_games[fragment].last_played = new Date().toJSON();
|
||||||
|
} else {
|
||||||
|
currentSettings.saved_games[fragment] = {
|
||||||
|
'guesses': [],
|
||||||
|
'last_played': new Date().toJSON()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.saveSettingsJson(currentSettings);
|
||||||
|
this.updateSavedGamesMenu(currentSettings);
|
||||||
|
}
|
||||||
|
getRecentGameFragment() {
|
||||||
|
let currentSettings = this.loadSettingsJson();
|
||||||
|
if (!currentSettings) return null;
|
||||||
|
if (!('saved_games' in currentSettings)) return null;
|
||||||
|
let saves = currentSettings.saved_games;
|
||||||
|
if (!saves) return null;
|
||||||
|
|
||||||
|
let recentDate =
|
||||||
|
Object.keys(saves)
|
||||||
|
.map(fragment => saves[fragment].last_played)
|
||||||
|
.sort()
|
||||||
|
.slice(-1)[0];
|
||||||
|
for (let fragment in saves) {
|
||||||
|
if (saves[fragment].last_played == recentDate) {
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
nextGame(game) {
|
||||||
|
if (this.won) {
|
||||||
|
this.finishGame();
|
||||||
|
}
|
||||||
|
if (!game) {
|
||||||
|
let fragment = this.getRecentGameFragment();
|
||||||
|
game = this.gameClass.fromFragment(fragment);
|
||||||
|
}
|
||||||
|
if (game === null) {
|
||||||
|
this.newGame();
|
||||||
|
} else {
|
||||||
|
this.initialize(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finishGame() {
|
||||||
|
if (this.won) {
|
||||||
|
let fragment = this.game.fragment;
|
||||||
|
let currentSettings = this.loadSettingsJson();
|
||||||
|
delete currentSettings.saved_games[fragment];
|
||||||
|
this.saveSettingsJson(currentSettings);
|
||||||
|
this.updateSavedGamesMenu(currentSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveGuess(guess) {
|
||||||
|
let fragment = this.game.fragment;
|
||||||
|
let currentSettings = this.loadSettingsJson();
|
||||||
|
currentSettings.saved_games[fragment].guesses.push(guess);
|
||||||
|
currentSettings.saved_games[fragment].last_played = new Date().toJSON();
|
||||||
|
this.saveSettingsJson(currentSettings);
|
||||||
|
this.updateSavedGamesMenu(currentSettings);
|
||||||
|
}
|
||||||
|
loadSettingsJson() {
|
||||||
let json = window.localStorage.getItem(this.settingsKey);
|
let json = window.localStorage.getItem(this.settingsKey);
|
||||||
if (json) {
|
if (json) {
|
||||||
try {
|
try {
|
||||||
let obj = JSON.parse(json);
|
return JSON.parse(json);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
loadSettings() {
|
||||||
|
let default_settings = this.defaultSettings;
|
||||||
|
let obj = this.loadSettingsJson();
|
||||||
|
if (obj) {
|
||||||
let settings = {};
|
let settings = {};
|
||||||
for (let key in default_settings) {
|
for (let key in default_settings) {
|
||||||
if (key in obj) {
|
if (key in obj) {
|
||||||
|
@ -315,17 +423,25 @@ class AnagramEntryUI {
|
||||||
if ('auto_submit' in obj) {
|
if ('auto_submit' in obj) {
|
||||||
document.getElementById('auto_submit').checked = obj.auto_submit;
|
document.getElementById('auto_submit').checked = obj.auto_submit;
|
||||||
}
|
}
|
||||||
|
if ('saved_games' in obj) {
|
||||||
|
this.updateSavedGamesMenu(obj);
|
||||||
|
}
|
||||||
this.setSettingsForm(settings);
|
this.setSettingsForm(settings);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
this.setSettingsForm(default_settings);
|
this.setSettingsForm(default_settings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
saveSettings() {
|
saveSettings() {
|
||||||
let settings = this.getSettingsObjectFromForm();
|
let settings = this.getSettingsObjectFromForm();
|
||||||
if (settings === null) return;
|
if (settings === null) return;
|
||||||
settings['auto_submit'] = this.autoSubmit.checked;
|
settings['auto_submit'] = this.autoSubmit.checked;
|
||||||
|
let currentSettings = this.loadSettingsJson();
|
||||||
|
if (currentSettings) {
|
||||||
|
settings['saved_games'] = currentSettings['saved_games'];
|
||||||
|
}
|
||||||
|
this.saveSettingsJson(settings);
|
||||||
|
}
|
||||||
|
saveSettingsJson(settings) {
|
||||||
let json = JSON.stringify(settings);
|
let json = JSON.stringify(settings);
|
||||||
window.localStorage.setItem(this.settingsKey, json);
|
window.localStorage.setItem(this.settingsKey, json);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user