diff --git a/src/components/WordBuilder.js b/src/components/WordBuilder.js
index a3e7e1f..ed0d73c 100644
--- a/src/components/WordBuilder.js
+++ b/src/components/WordBuilder.js
@@ -13,6 +13,8 @@ export function createWordBuilder({ onTileRemoved, onTilesReordered, onSubmitWor
const hasTiles = tileCount > 0;
const tileObjects = state.activeTileIds.map(id => state.boardTiles.find(t => t.id === id)).filter(Boolean);
const pts = tileCount === 4 ? 8 : tileCount === 3 ? 4 : tileCount === 2 ? 2 : 1;
+ const constructedWord = tileObjects.map(t => t.text.toLowerCase()).join('');
+ const isAlreadyFound = hasTiles && state.foundWords.has(constructedWord);
wrapper.innerHTML = `
@@ -35,10 +37,10 @@ export function createWordBuilder({ onTileRemoved, onTilesReordered, onSubmitWor
-
diff --git a/src/main.js b/src/main.js
index 2d4a2db..c71cd8f 100644
--- a/src/main.js
+++ b/src/main.js
@@ -174,8 +174,14 @@ async function initApp() {
const result = gameState.submitWord();
if (!result.success) {
- sound.playError();
- wordBuilder.triggerShake();
+ if (result.reason !== 'empty') {
+ sound.playError();
+ wordBuilder.triggerShake();
+ // Automatically erase selected tiles after shake so player doesn't have to keep hitting backspace/x
+ setTimeout(() => {
+ gameState.clearActive();
+ }, 400);
+ }
return;
}
diff --git a/src/state/game-state.js b/src/state/game-state.js
index c17a6f6..3265a3b 100644
--- a/src/state/game-state.js
+++ b/src/state/game-state.js
@@ -337,9 +337,7 @@ class GameStateManager {
// Check if already found
if (this.foundWords.has(constructedWord)) {
this.notifyToast(`"${constructedWord.toUpperCase()}" already found!`, 'warning');
- this.activeTileIds = [];
- this.notify();
- return { success: false, reason: 'duplicate' };
+ return { success: false, reason: 'duplicate', word: constructedWord };
}
// Look up in current puzzle's valid words list
@@ -347,7 +345,7 @@ class GameStateManager {
if (!match) {
this.notifyToast(`"${constructedWord.toUpperCase()}" is not in the word list`, 'error');
- return { success: false, reason: 'invalid' };
+ return { success: false, reason: 'invalid', word: constructedWord };
}
// Valid word!
diff --git a/src/styles/board.css b/src/styles/board.css
index e2fc5b8..aef0559 100644
--- a/src/styles/board.css
+++ b/src/styles/board.css
@@ -186,6 +186,17 @@
margin-left: 2px;
}
+.btn-submit-tray.is-duplicate {
+ background: linear-gradient(135deg, #f59e0b, #d97706);
+ box-shadow: 0 2px 8px rgba(245, 158, 11, 0.35);
+}
+
+.submit-pts.already-found {
+ background: rgba(0, 0, 0, 0.22);
+ color: #ffffff;
+ font-weight: 800;
+}
+
@media (max-width: 420px) {
.word-builder {
padding: 3px 6px;