improve hangman
This commit is contained in:
parent
070b404bf4
commit
28527e6113
@ -18,3 +18,4 @@ crossbeam = "0.8"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# For examples and testing
|
# For examples and testing
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
||||||
|
dialog = "*"
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Run with: `cargo run --package turtle-lib --example hangman_threaded`
|
//! Run with: `cargo run --package turtle-lib --example hangman_threaded`
|
||||||
|
|
||||||
use std::io::{self, Write};
|
use dialog::DialogBox;
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use turtle_lib::*;
|
use turtle_lib::*;
|
||||||
|
|
||||||
@ -68,10 +67,6 @@ async fn main() {
|
|||||||
println!("Game ended. Goodbye!");
|
println!("Game ended. Goodbye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
enum GameMessage {
|
|
||||||
GameOver { won: bool, word: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_game_logic(
|
fn run_game_logic(
|
||||||
hangman_tx: TurtleCommandSender,
|
hangman_tx: TurtleCommandSender,
|
||||||
lines_tx: TurtleCommandSender,
|
lines_tx: TurtleCommandSender,
|
||||||
@ -81,6 +76,15 @@ fn run_game_logic(
|
|||||||
println!("Starting hangman game...");
|
println!("Starting hangman game...");
|
||||||
println!("Secret word has {} letters", secret.len());
|
println!("Secret word has {} letters", secret.len());
|
||||||
|
|
||||||
|
// hide the smiley at start
|
||||||
|
{
|
||||||
|
let mut plan = create_turtle_plan();
|
||||||
|
plan.hide();
|
||||||
|
smiley_tx.send(plan.build()).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_smiley(&smiley_tx, true);
|
||||||
|
|
||||||
// Setup: Position hangman turtle and draw base (hill)
|
// Setup: Position hangman turtle and draw base (hill)
|
||||||
{
|
{
|
||||||
let mut plan = create_turtle_plan();
|
let mut plan = create_turtle_plan();
|
||||||
@ -139,12 +143,34 @@ fn choose_word() -> &'static str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ask_for_letter() -> String {
|
fn ask_for_letter() -> String {
|
||||||
print!("Guess a letter: ");
|
loop {
|
||||||
io::stdout().flush().ok();
|
match dialog::Input::new("Enter a single letter to guess")
|
||||||
|
.title("Hangman - Letter Guess")
|
||||||
let mut guess = String::new();
|
.show()
|
||||||
io::stdin().read_line(&mut guess).ok();
|
{
|
||||||
guess.trim().to_string()
|
Ok(Some(input)) => {
|
||||||
|
let trimmed = input.trim();
|
||||||
|
if trimmed.len() == 1 && trimmed.chars().all(|c| c.is_alphabetic()) {
|
||||||
|
return trimmed.to_lowercase();
|
||||||
|
} else {
|
||||||
|
// Invalid input, show error and retry
|
||||||
|
let _ = dialog::Message::new("Please enter exactly one letter (a-z).")
|
||||||
|
.title("Invalid Input")
|
||||||
|
.show();
|
||||||
|
// Loop continues to ask again
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
// User cancelled - ask again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// Dialog system failed - exit game
|
||||||
|
eprintln!("Dialog error: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_hangman(plan: &mut TurtlePlan) {
|
fn setup_hangman(plan: &mut TurtlePlan) {
|
||||||
@ -243,35 +269,16 @@ fn draw_lines_state(tx: &TurtleCommandSender, secret: &str, all_guesses: &str) {
|
|||||||
.go_to(vec2(-100.0, 100.0))
|
.go_to(vec2(-100.0, 100.0))
|
||||||
.pen_down();
|
.pen_down();
|
||||||
|
|
||||||
// Print word state in console
|
// Draw underscores/circles for each letter with text labels
|
||||||
print!("Word: ");
|
|
||||||
for letter in secret.chars() {
|
|
||||||
if all_guesses.contains(letter) {
|
|
||||||
print!("{} ", letter);
|
|
||||||
} else {
|
|
||||||
print!("_ ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
|
|
||||||
// Draw underscores/circles for each letter
|
|
||||||
for letter in secret.chars() {
|
for letter in secret.chars() {
|
||||||
if all_guesses.contains(letter) {
|
if all_guesses.contains(letter) {
|
||||||
// Draw green circle for revealed letter
|
// Draw green circle for revealed letter
|
||||||
plan.pen_up()
|
plan.set_pen_color(GREEN)
|
||||||
.right(90.0)
|
.write_text(&letter.to_uppercase().to_string(), 32u16)
|
||||||
.forward(2.5)
|
.forward(15.0);
|
||||||
.set_pen_color(GREEN)
|
|
||||||
.pen_down()
|
|
||||||
.circle_left(7.5, 360.0, 24)
|
|
||||||
.pen_up()
|
|
||||||
.backward(2.5)
|
|
||||||
.left(90.0)
|
|
||||||
.set_pen_color(BLACK)
|
|
||||||
.pen_down();
|
|
||||||
} else {
|
} else {
|
||||||
// Draw black underscore
|
// Draw black underscore
|
||||||
plan.forward(15.0);
|
plan.set_pen_color(BLACK).forward(15.0);
|
||||||
}
|
}
|
||||||
plan.pen_up().forward(15.0).pen_down();
|
plan.pen_up().forward(15.0).pen_down();
|
||||||
}
|
}
|
||||||
@ -281,27 +288,29 @@ fn draw_lines_state(tx: &TurtleCommandSender, secret: &str, all_guesses: &str) {
|
|||||||
|
|
||||||
fn draw_smiley(tx: &TurtleCommandSender, won: bool) {
|
fn draw_smiley(tx: &TurtleCommandSender, won: bool) {
|
||||||
let mut plan = create_turtle_plan();
|
let mut plan = create_turtle_plan();
|
||||||
plan.hide()
|
plan.reset()
|
||||||
|
.hide()
|
||||||
.set_speed(1001) // Instant mode
|
.set_speed(1001) // Instant mode
|
||||||
.pen_up()
|
.pen_up()
|
||||||
.go_to(vec2(100.0, 0.0)) // Right side of screen
|
.go_to(vec2(100.0, -100.0)) // Right side of screen
|
||||||
.pen_down()
|
.pen_down()
|
||||||
.set_pen_color(if won { GREEN } else { RED });
|
.set_pen_color(if won { GREEN } else { RED })
|
||||||
|
.left(90.);
|
||||||
|
|
||||||
// Face
|
// Face
|
||||||
plan.circle_left(50.0, 360.0, 72);
|
plan.circle_right(50.0, 360.0, 72);
|
||||||
|
|
||||||
// Left eye
|
// Left eye
|
||||||
plan.pen_up()
|
plan.pen_up()
|
||||||
.forward(27.5)
|
.forward(10.0)
|
||||||
.right(90.0)
|
.right(90.0)
|
||||||
.forward(20.0)
|
.forward(27.5)
|
||||||
.pen_down()
|
.pen_down()
|
||||||
.circle_left(3.0, 360.0, 24);
|
.circle_left(3.0, 360.0, 24);
|
||||||
|
|
||||||
// Right eye
|
// Right eye
|
||||||
plan.pen_up()
|
plan.pen_up()
|
||||||
.forward(42.5)
|
.forward(45.0)
|
||||||
.pen_down()
|
.pen_down()
|
||||||
.circle_left(3.0, 360.0, 24);
|
.circle_left(3.0, 360.0, 24);
|
||||||
|
|
||||||
@ -309,7 +318,7 @@ fn draw_smiley(tx: &TurtleCommandSender, won: bool) {
|
|||||||
plan.pen_up()
|
plan.pen_up()
|
||||||
.backward(42.5)
|
.backward(42.5)
|
||||||
.left(90.0)
|
.left(90.0)
|
||||||
.backward(40.0)
|
.backward(30.0)
|
||||||
.right(90.0)
|
.right(90.0)
|
||||||
.pen_down();
|
.pen_down();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user