From 72dc80b5f3c57d25475e836a2770319baa2f420b Mon Sep 17 00:00:00 2001 From: serg <91432388+hiimsergey@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:32:31 +0200 Subject: [PATCH] simplify --- src/lib.rs | 181 ++++++++++++++++++++++++++++----------------------- src/logic.rs | 63 ++++++++++-------- src/main.rs | 2 +- src/util.rs | 61 ++++++++--------- 4 files changed, 165 insertions(+), 142 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 578c010..37ee817 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,49 +1,40 @@ mod logic; mod util; use cursive::{ - Cursive, event::Key, - theme::{ BaseColor, Color, }, - view::{ Nameable, Resizable }, + theme::{BaseColor, Color}, + view::{Nameable, Resizable}, views::{ - Button, - Dialog, - DummyView, - EditView, - LinearLayout, - ListView, - OnEventView, - Panel, - ScrollView, - TextView, - } + Button, Dialog, DummyView, EditView, LinearLayout, ListView, OnEventView, Panel, + ScrollView, TextView, + }, + Cursive, }; -use cursive_aligned_view::Alignable; // Spawn menu/main window pub fn menu(s: &mut Cursive) { s.add_global_callback(Key::Esc, |s| quit_window(s)); - s.add_global_callback('q', |s| { s.pop_layer(); }); + s.add_global_callback('q', |s| { + s.pop_layer(); + }); s.add_layer( OnEventView::new( Dialog::around( LinearLayout::vertical() - .child( - TextView::new( - "Game settings" - ).style(Color::Dark(BaseColor::Blue)) - ) + .child(TextView::new("Game settings").style(Color::Dark(BaseColor::Blue))) .child(DummyView) .child(util::setting_digit_num("Digit number: ")) .child(util::setting_pass_len("Code length: ")) .child(DummyView) - .child(Button::new("Start game", game)) - ).title("mastermind-rs") + .child(Button::new("Start game", game)), + ) + .title("mastermind-rs") .button("Rules", rules) .button("About", about) - .button("Quit", |s| s.quit()) - ).on_event('q', |s| s.quit()) - .on_event(Key::Esc, |s| s.quit()) + .button("Quit", |s| s.quit()), + ) + .on_event('q', |s| s.quit()) + .on_event(Key::Esc, |s| s.quit()), ); } @@ -58,78 +49,95 @@ fn about(s: &mut Cursive) { " A little game written for the sake of experience in writing Rust code. Also my first project using any kind of User Interface. - " - ).style(Color::Dark(BaseColor::Blue)) + ", + ) + .style(Color::Dark(BaseColor::Blue)), ) - .child(util::source_button("https://github.com/hiimsergey/mastermind-rs")) + .child(util::source_button( + "https://github.com/hiimsergey/mastermind-rs", + )) .child( TextView::new( " Utilizes the \"cursive\" crate for building TUIs. - " - ).style(Color::Dark(BaseColor::Blue)) + ", + ) + .style(Color::Dark(BaseColor::Blue)), ) .child(util::source_button("https://crates.io/crates/cursive")) .child( - TextView::new(" -v. 0.2.7 - GPLv3 License " - ).style(Color::Dark(BaseColor::Blue)) - ) - ).button("Ok", |s| { s.pop_layer(); }) + TextView::new( + " +v. 0.2.7 - GPLv3 License ", + ) + .style(Color::Dark(BaseColor::Blue)), + ), + ) + .button("Ok", |s| { + s.pop_layer(); + }) .title("About mastermind-rs") - .fixed_width(64) + .fixed_width(64), ); } // Start game and spawn game window fn game(s: &mut Cursive) { - let digit_num: u8 = s.call_on_name("digit_num", |v: &mut TextView| { - let binding = v.get_content(); - binding.source().parse().unwrap() - }).unwrap(); - let pass_len: u8 = s.call_on_name("pass_len", |v: &mut TextView| { - let binding = v.get_content(); - binding.source().parse().unwrap() - }).unwrap(); + let digit_num: u8 = s + .call_on_name("digit_num", |v: &mut TextView| { + let binding = v.get_content(); + binding.source().parse().unwrap() + }) + .unwrap(); + let pass_len: u8 = s + .call_on_name("pass_len", |v: &mut TextView| { + let binding = v.get_content(); + binding.source().parse().unwrap() + }) + .unwrap(); let code = logic::gen_code(digit_num, pass_len); - let settings = TextView::new( - format!(" + let settings = TextView::new(format!( + " Digit number: {digit_num} Code length: {pass_len}" - ) - ).style(Color::Dark(BaseColor::Blue)).align_center(); + )) + .style(Color::Dark(BaseColor::Blue)); let input = LinearLayout::horizontal() .child(TextView::new("Your guess: ")) - .child(EditView::new() - .on_submit(move |s, name: &str| { - logic::check_guess(s, name, digit_num, &code); - }) - .max_content_width(pass_len as usize) - .with_name("input") - .fixed_width(pass_len as usize + 1) - ).align_center(); + .child( + EditView::new() + .on_submit(move |s, name: &str| { + logic::check_guess(s, name, digit_num, &code); + }) + .max_content_width(pass_len as usize) + .with_name("input") + .fixed_width(pass_len as usize + 1), + ); - let list = Panel::new( - ScrollView::new( - ListView::new() - ).with_name("list") - ).fixed_height(12).fixed_width(2 * (pass_len as usize) + 14); + let list = Panel::new(ScrollView::new(ListView::new()).with_name("list")) + .fixed_height(12) + .fixed_width(2 * (pass_len as usize) + 14); let game_sidebar = LinearLayout::vertical() .child(settings) .child(DummyView) .child(input) .child(DummyView.fixed_height(4)) - .child(Button::new("Menu", |s| { s.pop_layer(); }).align_bottom_right()) - .child(Button::new("Ragequit", |s| s.quit() ).align_bottom_right()); + .child( + Button::new("Menu", |s| { + s.pop_layer(); + }), + ) + .child(Button::new("Ragequit", |s| s.quit())); s.add_layer( Dialog::around( LinearLayout::horizontal() .child(list) .child(DummyView) - .child(game_sidebar) - ).title("Game") + .child(game_sidebar), + ) + .title("Game"), ); } @@ -138,14 +146,20 @@ fn quit_window(s: &mut Cursive) { s.add_layer( OnEventView::new( Dialog::around( - TextView::new( - "Do you want to \nquit the game?" - ).style(Color::Dark(BaseColor::Red)) - ).title("Confirm quit") - .button("No", |s| { s.pop_layer(); }) - .button("Yes", |s| s.quit()) - ).on_event(Key::Esc, |s| { s.pop_layer(); }) - .on_event('q', |s| { s.pop_layer(); }) + TextView::new("Do you want to \nquit the game?").style(Color::Dark(BaseColor::Red)), + ) + .title("Confirm quit") + .button("No", |s| { + s.pop_layer(); + }) + .button("Yes", |s| s.quit()), + ) + .on_event(Key::Esc, |s| { + s.pop_layer(); + }) + .on_event('q', |s| { + s.pop_layer(); + }), ); } @@ -154,12 +168,17 @@ fn rules(s: &mut Cursive) { s.add_layer( Dialog::around( LinearLayout::vertical() - .child(TextView::new( -"Use the arrow keys or the mouse to navigate. -Press q to close windows and Esc to quit the game." - ).align_center()) - .child(util::rules()) - ).title("Rules") - .button("Ok", |s| { s.pop_layer(); }) + .child( + TextView::new( + "Use the arrow keys or the mouse to navigate. +Press q to close windows and Esc to quit the game.", + ), + ) + .child(util::rules()), + ) + .title("Rules") + .button("Ok", |s| { + s.pop_layer(); + }), ); } diff --git a/src/logic.rs b/src/logic.rs index 6c97aa2..62bd2b1 100644 --- a/src/logic.rs +++ b/src/logic.rs @@ -1,14 +1,8 @@ use crate::util::FormatError; use cursive::{ + theme::{BaseColor, Color}, + views::{Dialog, EditView, ListView, ScrollView, TextView}, Cursive, - theme::{ BaseColor, Color }, - views::{ - Dialog, - EditView, - TextView, - ListView, - ScrollView - } }; use rand::Rng; @@ -18,17 +12,25 @@ pub fn check_guess(s: &mut Cursive, guess: &str, digit_num: u8, code: &Vec) s.add_layer( Dialog::around( TextView::new(match err { - FormatError::DigitLimit => "The given guess contains \ndigits outside the limit.", + FormatError::DigitLimit => { + "The given guess contains \ndigits outside the limit." + } FormatError::NaN => "The given guess is \nnot a valid number.", - FormatError::Short => "The given guess \nis too short." - }).style(Color::Dark(BaseColor::Red)) - ).title("Invalid input") - .button("Ok", |s| { s.pop_layer(); }) + FormatError::Short => "The given guess \nis too short.", + }) + .style(Color::Dark(BaseColor::Red)), + ) + .title("Invalid input") + .button("Ok", |s| { + s.pop_layer(); + }), ); s.call_on_name("input", |v: &mut EditView| { v.set_content(""); }); - } else { compare_guess(s, guess, code); } + } else { + compare_guess(s, guess, code); + } } // Generate code based on settings given at lib::menu() @@ -90,28 +92,35 @@ fn get_guess_status(guess: &str, digit_num: u8, code: &Vec) -> Result<(), Fo fn print_feedback(s: &mut Cursive, guess: &str, feedback: String) { s.call_on_name("list", |v: &mut ScrollView| { let len = format!("{}.", v.get_inner().len() + 1); - v.get_inner_mut().add_child("", TextView::new( - format!( + v.get_inner_mut().add_child( + "", + TextView::new(format!( "{:<5}{guess}{:>len_fmt$}", len, &feedback, len_fmt = guess.len() + 4 - ) - )); + )), + ); v.scroll_to_bottom(); }); if feedback.chars().all(|c| c == '!') { - s.call_on_name("input", |v: &mut EditView| v.disable() ); + s.call_on_name("input", |v: &mut EditView| v.disable()); s.add_layer( - Dialog::around( - TextView::new( - "Congratulations!" - ).style(Color::Dark(BaseColor::Blue)) - ).title("You won!") - .button("Ok", |s| { s.pop_layer(); }) - .button("Play again", |s| { s.pop_layer(); s.pop_layer(); crate::game(s); } ) - .button("Menu", |s| { s.pop_layer(); s.pop_layer(); }) + Dialog::around(TextView::new("Congratulations!").style(Color::Dark(BaseColor::Blue))) + .title("You won!") + .button("Ok", |s| { + s.pop_layer(); + }) + .button("Play again", |s| { + s.pop_layer(); + s.pop_layer(); + crate::game(s); + }) + .button("Menu", |s| { + s.pop_layer(); + s.pop_layer(); + }), ); } } diff --git a/src/main.rs b/src/main.rs index a986034..390eb15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,4 +2,4 @@ fn main() { let mut siv = cursive::default(); mastermind_rs::menu(&mut siv); siv.run(); -} \ No newline at end of file +} diff --git a/src/util.rs b/src/util.rs index 5b9ee52..12033e2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,45 +1,41 @@ // util.rs - some helper functions for the other files use cursive::{ - theme::{ BaseColor, Color }, + theme::{BaseColor, Color}, view::Nameable, - views::{ - Button, - Dialog, - DummyView, - LinearLayout, - SliderView, - TextView - } + views::{Button, Dialog, DummyView, LinearLayout, SliderView, TextView}, }; use webbrowser; pub enum FormatError { DigitLimit, NaN, - Short + Short, } pub fn source_button(url: &'static str) -> Button { Button::new("source ↗", |s| { if !webbrowser::open(url).is_ok() { - s.add_global_callback('q', |s| { s.pop_layer(); }); - s.add_layer(Dialog::info( -"Couldn't connect to the website. :[ -Check that you have a web browser installed." - ).title("Connection error")); + s.add_global_callback('q', |s| { + s.pop_layer(); + }); + s.add_layer( + Dialog::info( + "Couldn't connect to the website. :[ +Check that you have a web browser installed.", + ) + .title("Connection error"), + ); } }) } pub fn setting_digit_num(desc: &str) -> LinearLayout { - let slider = SliderView::horizontal(8) - .value(2) - .on_change(|s, n| { - s.call_on_name("digit_num", |v: &mut TextView| { - v.set_content(format!("{}", n + 2)) - }); + let slider = SliderView::horizontal(8).value(2).on_change(|s, n| { + s.call_on_name("digit_num", |v: &mut TextView| { + v.set_content(format!("{}", n + 2)) }); + }); LinearLayout::horizontal() .child(TextView::new(desc)) @@ -49,13 +45,11 @@ pub fn setting_digit_num(desc: &str) -> LinearLayout { } pub fn setting_pass_len(desc: &str) -> LinearLayout { - let slider = SliderView::horizontal(8) - .value(2) - .on_change(|s, n| { - s.call_on_name("pass_len", |v: &mut TextView| { - v.set_content(format!("{}", n + 2)) - }); + let slider = SliderView::horizontal(8).value(2).on_change(|s, n| { + s.call_on_name("pass_len", |v: &mut TextView| { + v.set_content(format!("{}", n + 2)) }); + }); LinearLayout::horizontal() .child(TextView::new(desc)) @@ -66,17 +60,17 @@ pub fn setting_pass_len(desc: &str) -> LinearLayout { pub fn banner() -> TextView { TextView::new( -" _ _ _ + " _ _ _ _ __ ___ __ _ ___| |_ ___ _ __ _ __ ___ (_)_ __ __| | | '_ ` _ \\ / _` / __| __/ _ \\ '__| '_ ` _ \\| | '_ \\ / _` | | | | | | | (_| \\__ \\ || __/ | | | | | | | | | | | (_| | -|_| |_| |_|\\__,_|___/\\__\\___|_| |_| |_| |_|_|_| |_|\\__,_|" +|_| |_| |_|\\__,_|___/\\__\\___|_| |_| |_| |_|_|_| |_|\\__,_|", ) } - + pub fn rules() -> TextView { TextView::new( -" + " A random code is generated based on your settings: 1. \"Digit number\" sets the amount of different @@ -92,6 +86,7 @@ The game gives you feedback: 2. A question mark means that one character is featured in the code but on another position. 3. A dot means that a character isn't featured at - all." - ).style(Color::Dark(BaseColor::Blue)) + all.", + ) + .style(Color::Dark(BaseColor::Blue)) }