1
0

Compare commits

..

No commits in common. "9e34b7a1d94a8db6a3a8c27f26267c5b96fdc13e" and "3b216000f9d89a92d8d0dfcc0b58a3cebbebd599" have entirely different histories.

5 changed files with 73 additions and 189 deletions

View File

@ -110,7 +110,7 @@ class Bagels {
} }
} }
get fragment() { getFragment(kind) {
return this.word + ',' + this.availableLetters.sort().join(''); return this.word + ',' + this.availableLetters.sort().join('');
} }

View File

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html> <html manifest="cache.appcache">
<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,25 +72,19 @@
}); });
} }
submitWord(word) { submitWord() {
if (this.won) return; if (this.won) return;
let guess; if (!this.letters.every(letter => letter != '')) return;
if (word) { let guess = this.letters.join('');
guess = word;
} else {
if (!this.letters.every(letter => letter != '')) return;
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 = guess[i]; letter.innerText = this.letters[i];
letter.classList.add(getLetterGuessResultClass(results.letters[i])); letter.classList.add(getLetterGuessResultClass(results.letters[i]));
resultDisplay.appendChild(letter); resultDisplay.appendChild(letter);
} }
@ -118,6 +112,17 @@
} }
} }
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,
@ -135,8 +140,6 @@
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'];
@ -176,18 +179,18 @@
ui.saveSettings(); ui.saveSettings();
}); });
this.nextGame(game); if (game === null) {
} this.newGame();
} else {
get gameClass() { this.initialize(game);
return Bagels; }
} }
initialize(game) { initialize(game) {
this.won = false; this.won = false;
this.game = game; this.game = game;
scrambleString(game.fragment, ['A', 'B']).then(fragment => { scrambleString(game.getFragment(), ['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;
@ -196,8 +199,6 @@
this.initializeInputs(game.numLetters); this.initializeInputs(game.numLetters);
clearElement(document.getElementById('guesses')); clearElement(document.getElementById('guesses'));
this.doPostInitialize();
} }
} }
@ -235,9 +236,7 @@
<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><br /> <button id="copy_permalink">Copy</button>
<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:
@ -322,7 +321,7 @@
</label> </label>
</div> </div>
<div id="endgame"> <div id="endgame">
<button id="newgame">Next Game</button> <button id="newgame">New Game</button>
</div> </div>
<div id="available_letters_display"> <div id="available_letters_display">
<button id="shuffle"></button> <button id="shuffle"></button>

View File

@ -172,7 +172,7 @@ class Crossword {
} }
} }
get fragment() { getFragment() {
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(';');

View File

@ -15,22 +15,16 @@
<script src="../entryui.js"></script> <script src="../entryui.js"></script>
<script > <script >
class CrosswordUI extends AnagramEntryUI { class CrosswordUI extends AnagramEntryUI {
submitWord(word) { submitWord() {
if (this.won) return; if (this.won) return;
let guess; let seenSpace = false;
if (word) { for (let idx in this.letters) {
guess = word; if (this.letters[idx] == '') seenSpace = true;
} else { else if (seenSpace) return;
let seenSpace = false;
for (let idx in this.letters) {
if (this.letters[idx] == '') seenSpace = true;
else if (seenSpace) return;
}
guess = this.letters.join('');
} }
let 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);
@ -39,7 +33,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 = guess[i] || ''; letter.innerText = this.letters[i];
resultDisplay.appendChild(letter); resultDisplay.appendChild(letter);
} }
let link = document.createElement('a'); let link = document.createElement('a');
@ -128,6 +122,17 @@
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,
@ -191,11 +196,11 @@
ui.saveSettings(); ui.saveSettings();
}); });
this.nextGame(game); if (game === null) {
} this.newGame();
} else {
get gameClass() { this.initialize(game);
return Crossword; }
} }
initialize(game) { initialize(game) {
@ -203,7 +208,7 @@
this.game = game; this.game = game;
let ui = this; let ui = this;
scrambleString(game.fragment, ['', 'A', 'B']).then(fragment => { scrambleString(game.getFragment(), ['', '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;
@ -281,8 +286,6 @@
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();
} }
} }
@ -320,9 +323,7 @@
<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><br /> <button id="copy_permalink">Copy</button>
<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:
@ -385,7 +386,7 @@
</label> </label>
</div> </div>
<div id="endgame"> <div id="endgame">
<button id="newgame">Next Game</button> <button id="newgame">New Game</button>
</div> </div>
<div id="available_letters_display"> <div id="available_letters_display">
<button id="shuffle"></button> <button id="shuffle"></button>

View File

@ -19,14 +19,7 @@ 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.nextGame()); .addEventListener('click', _ => ui.newGame());
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;
@ -83,7 +76,9 @@ class AnagramEntryUI {
document.getElementById('newgame_button') document.getElementById('newgame_button')
.addEventListener('click', _ => { .addEventListener('click', _ => {
if (this.getSettingsObjectFromForm() === null) return; if (this.getSettingsObjectFromForm() === null) return;
ui.newGame(); if (ui.won || window.confirm('Lose all progress on this puzzle and generate a new one?')) {
ui.newGame();
}
}); });
} }
@ -302,146 +297,35 @@ 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);
}
}
newGame() { loadSettings() {
let settings = this.getSettingsObjectFromForm(); let default_settings = this.defaultSettings;
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 {
return JSON.parse(json); let obj = JSON.parse(json);
} catch (e) {} let settings = {};
} for (let key in default_settings) {
return null; if (key in obj) {
} settings[key] = obj[key];
loadSettings() { } else {
let default_settings = this.defaultSettings; settings[key] = default_settings[key];
let obj = this.loadSettingsJson(); }
if (obj) {
let settings = {};
for (let key in default_settings) {
if (key in obj) {
settings[key] = obj[key];
} else {
settings[key] = default_settings[key];
} }
if ('auto_submit' in obj) {
document.getElementById('auto_submit').checked = obj.auto_submit;
}
this.setSettingsForm(settings);
return;
} }
if ('auto_submit' in obj) { catch (e) {}
document.getElementById('auto_submit').checked = obj.auto_submit;
}
if ('saved_games' in obj) {
this.updateSavedGamesMenu(obj);
}
this.setSettingsForm(settings);
} else {
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);
} }