Surn commited on
Commit
fd702c9
·
1 Parent(s): c004d56

- 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 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.15"
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 '?' of length letters_display."""
148
- return "?" * letters_display
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
- tooltip_text = "Recent incorrect guesses:\n" + "\n".join(recent_incorrect)
 
 
 
1026
  else:
1027
- tooltip_text = "No incorrect guesses yet"
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", False) and recent_incorrect:
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 \">?</td>"
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