Spaces:
Running
Running
0.2.16
Browse files- replace question marks in score panel with underscores
- add option to toggle incorrect guess history display in settings (enabled by default)
- game over popup updated to ensure it is fully visible on screen
- README.md +5 -0
- battlewords/__init__.py +1 -1
- battlewords/logic.py +3 -3
- battlewords/ui.py +36 -11
README.md
CHANGED
|
@@ -106,6 +106,11 @@ docker run -p 8501:8501 battlewords
|
|
| 106 |
|
| 107 |
## Changelog
|
| 108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
-0.2.15
|
| 110 |
- fix music playing after game end
|
| 111 |
- change incorrect guesses icon
|
|
|
|
| 106 |
|
| 107 |
## Changelog
|
| 108 |
|
| 109 |
+
-0.2.16
|
| 110 |
+
- replace question marks in score panel with underscores
|
| 111 |
+
- add option to toggle incorrect guess history display in settings (enabled by default)
|
| 112 |
+
- game over popup updated to ensure it is fully visible on screen
|
| 113 |
+
|
| 114 |
-0.2.15
|
| 115 |
- fix music playing after game end
|
| 116 |
- change incorrect guesses icon
|
battlewords/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
-
__version__ = "0.2.
|
| 2 |
__all__ = ["models", "generator", "logic", "ui"]
|
|
|
|
| 1 |
+
__version__ = "0.2.16"
|
| 2 |
__all__ = ["models", "generator", "logic", "ui"]
|
battlewords/logic.py
CHANGED
|
@@ -143,9 +143,9 @@ def compute_tier(score: int) -> str:
|
|
| 143 |
return "Good"
|
| 144 |
return "Keep practicing"
|
| 145 |
|
| 146 |
-
def hidden_word_display(letters_display: int) -> str:
|
| 147 |
-
"""Return a string of
|
| 148 |
-
return
|
| 149 |
|
| 150 |
def auto_mark_completed_words(state: GameState) -> bool:
|
| 151 |
"""Automatically mark words as found when all their letters are revealed.
|
|
|
|
| 143 |
return "Good"
|
| 144 |
return "Keep practicing"
|
| 145 |
|
| 146 |
+
def hidden_word_display(letters_display: int, character: str = "?") -> str:
|
| 147 |
+
"""Return a string of characters of length letters_display."""
|
| 148 |
+
return character * letters_display
|
| 149 |
|
| 150 |
def auto_mark_completed_words(state: GameState) -> bool:
|
| 151 |
"""Automatically mark words as found when all their letters are revealed.
|
battlewords/ui.py
CHANGED
|
@@ -1021,10 +1021,13 @@ def _render_guess_form(state: GameState):
|
|
| 1021 |
|
| 1022 |
# Prepare tooltip text for native browser tooltip
|
| 1023 |
recent_incorrect = st.session_state.incorrect_guesses[-10:]
|
| 1024 |
-
if recent_incorrect:
|
| 1025 |
-
|
|
|
|
|
|
|
|
|
|
| 1026 |
else:
|
| 1027 |
-
tooltip_text =
|
| 1028 |
|
| 1029 |
# Add CSS for the incorrect guesses display
|
| 1030 |
st.markdown(
|
|
@@ -1037,30 +1040,30 @@ def _render_guess_form(state: GameState):
|
|
| 1037 |
font-style: italic;
|
| 1038 |
}
|
| 1039 |
/* Reposition tooltip anchor under the input */
|
| 1040 |
-
.stTooltipIcon {
|
| 1041 |
position: absolute;
|
| 1042 |
left: 0;
|
| 1043 |
bottom: -22px;
|
| 1044 |
width: auto !important;
|
| 1045 |
}
|
| 1046 |
/* Hide the default SVG info icon */
|
| 1047 |
-
.stTooltipIcon svg.icon {
|
| 1048 |
display: none !important;
|
| 1049 |
}
|
| 1050 |
/* Make the tooltip trigger look like a link reading "incorrect guesses" */
|
| 1051 |
-
.stTooltipIcon .stTooltipHoverTarget {
|
| 1052 |
display: inline-flex;
|
| 1053 |
align-items: center;
|
| 1054 |
width: auto;
|
| 1055 |
}
|
| 1056 |
-
.stTooltipIcon .stTooltipHoverTarget::after {
|
| 1057 |
content: "incorrect guesses";
|
| 1058 |
color: #FFFFFF;
|
| 1059 |
text-decoration: underline;
|
| 1060 |
font-size: 0.8rem;
|
| 1061 |
cursor: help;
|
| 1062 |
}
|
| 1063 |
-
.stTooltipIcon .stTooltipHoverTarget:hover::after {
|
| 1064 |
color: #ff9999;
|
| 1065 |
}
|
| 1066 |
|
|
@@ -1091,7 +1094,7 @@ def _render_guess_form(state: GameState):
|
|
| 1091 |
submitted = st.form_submit_button("OK", disabled=not state.can_guess, width=100, key="guess_submit")
|
| 1092 |
|
| 1093 |
# Show compact list below input if setting is enabled
|
| 1094 |
-
#if st.session_state.get("show_incorrect_guesses",
|
| 1095 |
# st.markdown(
|
| 1096 |
# f'<div class="bw-incorrect-guesses">Recent: {", ".join(recent_incorrect)}</div>',
|
| 1097 |
# unsafe_allow_html=True,
|
|
@@ -1144,9 +1147,9 @@ def _render_score_panel(state: GameState):
|
|
| 1144 |
# Hide unguessed words in classic mode
|
| 1145 |
row_html = (
|
| 1146 |
"<tr>"
|
| 1147 |
-
f"<td class=\"blue-background \">{hidden_word_display(letters_display)}</td>"
|
| 1148 |
f"<td class=\"blue-background \">{letters_display}</td>"
|
| 1149 |
-
f"<td class=\"blue-background \"
|
| 1150 |
"</tr>"
|
| 1151 |
)
|
| 1152 |
rows_html.append(row_html)
|
|
@@ -1336,6 +1339,28 @@ def _game_over_content(state: GameState) -> None:
|
|
| 1336 |
unsafe_allow_html=True,
|
| 1337 |
)
|
| 1338 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1339 |
# Dialog actions
|
| 1340 |
if st.button("Close", key="close_game_over"):
|
| 1341 |
st.session_state["show_gameover_overlay"] = False
|
|
|
|
| 1021 |
|
| 1022 |
# Prepare tooltip text for native browser tooltip
|
| 1023 |
recent_incorrect = st.session_state.incorrect_guesses[-10:]
|
| 1024 |
+
if st.session_state.get("show_incorrect_guesses", True) and recent_incorrect:
|
| 1025 |
+
if recent_incorrect:
|
| 1026 |
+
tooltip_text = "Recent incorrect guesses:\n" + "\n".join(recent_incorrect)
|
| 1027 |
+
else:
|
| 1028 |
+
tooltip_text = "No incorrect guesses yet"
|
| 1029 |
else:
|
| 1030 |
+
tooltip_text = None
|
| 1031 |
|
| 1032 |
# Add CSS for the incorrect guesses display
|
| 1033 |
st.markdown(
|
|
|
|
| 1040 |
font-style: italic;
|
| 1041 |
}
|
| 1042 |
/* Reposition tooltip anchor under the input */
|
| 1043 |
+
.st-key-guess_input .stTooltipIcon {
|
| 1044 |
position: absolute;
|
| 1045 |
left: 0;
|
| 1046 |
bottom: -22px;
|
| 1047 |
width: auto !important;
|
| 1048 |
}
|
| 1049 |
/* Hide the default SVG info icon */
|
| 1050 |
+
.st-key-guess_input .stTooltipIcon svg.icon {
|
| 1051 |
display: none !important;
|
| 1052 |
}
|
| 1053 |
/* Make the tooltip trigger look like a link reading "incorrect guesses" */
|
| 1054 |
+
.st-key-guess_input .stTooltipIcon .stTooltipHoverTarget {
|
| 1055 |
display: inline-flex;
|
| 1056 |
align-items: center;
|
| 1057 |
width: auto;
|
| 1058 |
}
|
| 1059 |
+
.st-key-guess_input .stTooltipIcon .stTooltipHoverTarget::after {
|
| 1060 |
content: "incorrect guesses";
|
| 1061 |
color: #FFFFFF;
|
| 1062 |
text-decoration: underline;
|
| 1063 |
font-size: 0.8rem;
|
| 1064 |
cursor: help;
|
| 1065 |
}
|
| 1066 |
+
.st-key-guess_input .stTooltipIcon .stTooltipHoverTarget:hover::after {
|
| 1067 |
color: #ff9999;
|
| 1068 |
}
|
| 1069 |
|
|
|
|
| 1094 |
submitted = st.form_submit_button("OK", disabled=not state.can_guess, width=100, key="guess_submit")
|
| 1095 |
|
| 1096 |
# Show compact list below input if setting is enabled
|
| 1097 |
+
#if st.session_state.get("show_incorrect_guesses", True) and recent_incorrect:
|
| 1098 |
# st.markdown(
|
| 1099 |
# f'<div class="bw-incorrect-guesses">Recent: {", ".join(recent_incorrect)}</div>',
|
| 1100 |
# unsafe_allow_html=True,
|
|
|
|
| 1147 |
# Hide unguessed words in classic mode
|
| 1148 |
row_html = (
|
| 1149 |
"<tr>"
|
| 1150 |
+
f"<td class=\"blue-background \">{hidden_word_display(letters_display,'_')}</td>"
|
| 1151 |
f"<td class=\"blue-background \">{letters_display}</td>"
|
| 1152 |
+
f"<td class=\"blue-background \">_</td>"
|
| 1153 |
"</tr>"
|
| 1154 |
)
|
| 1155 |
rows_html.append(row_html)
|
|
|
|
| 1339 |
unsafe_allow_html=True,
|
| 1340 |
)
|
| 1341 |
|
| 1342 |
+
# Ensure the popup is in view by scrolling the parent window to the main anchor (or top as fallback)
|
| 1343 |
+
components.html(
|
| 1344 |
+
"""
|
| 1345 |
+
<script>
|
| 1346 |
+
(function() {
|
| 1347 |
+
try {
|
| 1348 |
+
var parentDoc = window.parent && window.parent.document ? window.parent.document : document;
|
| 1349 |
+
var anchor = parentDoc.getElementById('bw-main-anchor');
|
| 1350 |
+
if (anchor && anchor.scrollIntoView) {
|
| 1351 |
+
anchor.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
| 1352 |
+
} else if (window.parent && window.parent.scrollTo) {
|
| 1353 |
+
window.parent.scrollTo({ top: 0, behavior: 'smooth' });
|
| 1354 |
+
} else {
|
| 1355 |
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
| 1356 |
+
}
|
| 1357 |
+
} catch (e) { /* no-op */ }
|
| 1358 |
+
})();
|
| 1359 |
+
</script>
|
| 1360 |
+
""",
|
| 1361 |
+
height=0,
|
| 1362 |
+
)
|
| 1363 |
+
|
| 1364 |
# Dialog actions
|
| 1365 |
if st.button("Close", key="close_game_over"):
|
| 1366 |
st.session_state["show_gameover_overlay"] = False
|