Skip to content

Commit

Permalink
simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
hiimsergey authored Oct 6, 2023
1 parent aac11b4 commit 72dc80b
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 142 deletions.
181 changes: 100 additions & 81 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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()),
);
}

Expand All @@ -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"),
);
}

Expand All @@ -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();
}),
);
}

Expand All @@ -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();
}),
);
}
63 changes: 36 additions & 27 deletions src/logic.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -18,17 +12,25 @@ pub fn check_guess(s: &mut Cursive, guess: &str, digit_num: u8, code: &Vec<u8>)
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()
Expand Down Expand Up @@ -90,28 +92,35 @@ fn get_guess_status(guess: &str, digit_num: u8, code: &Vec<u8>) -> Result<(), Fo
fn print_feedback(s: &mut Cursive, guess: &str, feedback: String) {
s.call_on_name("list", |v: &mut ScrollView<ListView>| {
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();
}),
);
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ fn main() {
let mut siv = cursive::default();
mastermind_rs::menu(&mut siv);
siv.run();
}
}
Loading

0 comments on commit 72dc80b

Please sign in to comment.