From f4168c449b1ac4de9af77526962127820c8b7475 Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Sat, 28 Jun 2025 16:45:33 +0800 Subject: [PATCH] added final victory message --- rdraught-ui/src/main.rs | 170 +++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 74 deletions(-) diff --git a/rdraught-ui/src/main.rs b/rdraught-ui/src/main.rs index 5451381..dfe1191 100644 --- a/rdraught-ui/src/main.rs +++ b/rdraught-ui/src/main.rs @@ -1,6 +1,6 @@ use gdk4::cairo::{Context as CairoContext, Matrix, Rectangle}; use gtk4::cairo::Error; -use gtk4::glib::Propagation; +use gtk4::glib::{MainContext, Propagation}; use gtk4::{self as gtk, gdk::ffi::GDK_BUTTON_PRIMARY}; use gtk4::{Application, DrawingArea, prelude::*}; use rdraught::draughts::{DraughtsBoard, DraughtsGame, Move, Piece, Player}; @@ -12,6 +12,7 @@ use rsvg::SvgHandle; use std::thread; const SQUARE_SIZE: f64 = 1.0; +mod final_dialog; mod greeting_dialog; mod types; @@ -161,30 +162,45 @@ fn draw_piece( } } -fn draw_score_bar(cr: &CairoContext, board: &Rectangle, draughts_game: &DraughtsGame) { +fn draw_score_bar( + cr: &CairoContext, + board: &Rectangle, + draughts_game: &DraughtsGame, + current_player: Player, +) { + fn modulate_score(relative_score: f64) -> f64 { + let x = relative_score; + f64::atan(8.0 * x - 4.0) / f64::atan(4.0) / 2.0 + 0.5 + } let score_bar = Rectangle::new( board.tl().x() - board.width() / 10.0, board.tl().y(), board.width() / 16.0, board.height(), ); - let score_percentage = draughts_game.relative_score(Player::White) as f64; + let score_percentage = modulate_score(draughts_game.relative_score(current_player) as f64); let tl = score_bar.tl(); cr.save().unwrap(); - cr.set_source_rgb(1.0, 1.0, 1.0); + match current_player { + Player::White => cr.set_source_rgb(1.0, 0.0, 0.0), + Player::Red => cr.set_source_rgb(1.0, 1.0, 1.0), + } cr.rectangle( score_bar.tl().x(), score_bar.tl().y(), score_bar.width(), - score_bar.height() * score_percentage, + score_bar.height() * (1.0 - score_percentage), ); cr.fill().unwrap(); - cr.set_source_rgb(1.0, 0.0, 0.0); + match current_player { + Player::White => cr.set_source_rgb(1.0, 1.0, 1.0), + Player::Red => cr.set_source_rgb(1.0, 0.0, 0.0), + } cr.rectangle( tl.x(), - tl.y() + score_bar.height() * score_percentage, + tl.y() + score_bar.height() * (1.0 - score_percentage), score_bar.width(), - score_bar.height() * (1.0 - score_percentage), + score_bar.height() * score_percentage, ); cr.fill().unwrap(); cr.restore().unwrap(); @@ -374,7 +390,7 @@ fn create_game_window(application: &Application, current_player: Player) { cr.restore().unwrap(); } } - draw_score_bar(cr, &board, &draughts_game.borrow()); + draw_score_bar(cr, &board, &draughts_game.borrow(), current_player); }); } let gesture = gtk::GestureClick::new(); @@ -386,75 +402,81 @@ fn create_game_window(application: &Application, current_player: Player) { { let drawing_area = drawing_area.clone(); let available_moves = available_moves.clone(); + let window = window.clone(); gesture.connect_pressed(move |gesture, _, x, y| { gesture.set_state(gtk::EventSequenceState::Claimed); - let xform = xform.borrow(); - let inverse = { - let mut m = *xform; - m.invert(); - m - }; - let p = transform_point(&Point::new(x, y), &inverse); - if board_clone.contains(&p) { - let p = &p - &board_clone.tl(); - // println!("Point: {:?}", p); - let position = match current_player { - Player::White => Position::new( - (8.0 - (p.y() / SQUARE_SIZE)) as u8, - (p.x() / SQUARE_SIZE) as u8, - ), - Player::Red => { - Position::new((p.y() / SQUARE_SIZE) as u8, (p.x() / SQUARE_SIZE) as u8) - } - }; - // println!("Selected position: {:?}", position); - let mut draughts_game = draughts_game.borrow_mut(); - let piece = draughts_game.piece_at(position); - // println!("Selected piece: {:?}", piece); - let mut am = available_moves.borrow_mut(); - let mut move_applied = false; - if !am.is_empty() { - for mv in am.iter() { - if mv.get_end_position() == position { - draughts_game.apply_move(mv).unwrap(); - let game_copy = draughts_game.clone(); - thread::spawn(move || { - if let (Some(mv), analyzed_moves) = game_copy.get_best_move(10) { - println!( - "Next best move: {:?}, analyzed moves: {}", - mv, analyzed_moves - ); - } - }); - move_applied = true; - break; - } - } - if move_applied { - selected_piece.set(None); - am.clear(); - } - } - if !move_applied { - match piece.player() { - Some(Player::Red) => selected_piece.set(Some(position)), - Some(Player::White) => selected_piece.set(Some(position)), - None => selected_piece.set(None), - } - am.clear(); - if piece.player().is_none() { - selected_piece.set(None) - } else { - selected_piece.set(Some(position)); - for mv in draughts_game.moves_for_piece(position) { - am.push(mv); - } - } - } + if let Some(winner) = draughts_game.borrow().winner() { + MainContext::default() + .spawn_local(final_dialog::create_dialog(window.clone(), winner)); } else { - selected_piece.set(None); + let xform = xform.borrow(); + let inverse = { + let mut m = *xform; + m.invert(); + m + }; + let p = transform_point(&Point::new(x, y), &inverse); + if board_clone.contains(&p) { + let p = &p - &board_clone.tl(); + // println!("Point: {:?}", p); + let position = match current_player { + Player::White => Position::new( + (8.0 - (p.y() / SQUARE_SIZE)) as u8, + (p.x() / SQUARE_SIZE) as u8, + ), + Player::Red => { + Position::new((p.y() / SQUARE_SIZE) as u8, (p.x() / SQUARE_SIZE) as u8) + } + }; + // println!("Selected position: {:?}", position); + let mut draughts_game = draughts_game.borrow_mut(); + let piece = draughts_game.piece_at(position); + // println!("Selected piece: {:?}", piece); + let mut am = available_moves.borrow_mut(); + let mut move_applied = false; + if !am.is_empty() { + for mv in am.iter() { + if mv.get_end_position() == position { + draughts_game.apply_move(mv).unwrap(); + let game_copy = draughts_game.clone(); + // thread::spawn(move || { + // if let (Some(mv), analyzed_moves) = game_copy.get_best_move(10) { + // println!( + // "Next best move: {:?}, analyzed moves: {}", + // mv, analyzed_moves + // ); + // } + // }); + move_applied = true; + break; + } + } + if move_applied { + selected_piece.set(None); + am.clear(); + } + } + if !move_applied { + match piece.player() { + Some(Player::Red) => selected_piece.set(Some(position)), + Some(Player::White) => selected_piece.set(Some(position)), + None => selected_piece.set(None), + } + am.clear(); + if piece.player().is_none() { + selected_piece.set(None) + } else { + selected_piece.set(Some(position)); + for mv in draughts_game.moves_for_piece(position) { + am.push(mv); + } + } + } + } else { + selected_piece.set(None); + } + drawing_area.queue_draw(); } - drawing_area.queue_draw(); }); } // Assign the gesture to the treeview