Skip to main content

rsnaker/graphics/menus/retro_parameter_table/
customized_with_fruits.rs

1use crate::game_logic::game_options::GameOptions;
2use crate::graphics::menus::retro_parameter_table::generic_logic::{
3    get_default_action_input, CellValue, FooterData, GenericMenu, RowData,
4};
5use crate::graphics::sprites::fruit::{Fruit, FRUITS_SCORES_PROBABILITIES};
6use ratatui::DefaultTerminal;
7use std::time::Duration;
8
9pub fn setup_and_run_fruits_table_parameters(
10    terminal: &mut DefaultTerminal,
11    options: &GameOptions,
12) {
13    //later: extend ActionInput to have a callback for each action (like apply, move, change value)
14    // Callback has a dyn &mut ApplyParameter and a &mut GenericMenu
15    // Goal is to be allowed to reload the menu table with a preset and to move freely between menus.
16    GenericMenu::new(
17        load_fruits_info_in_table(options),
18        &fruits_get_headers(),
19        fruits_get_footer_data(),
20        None,
21    )
22    .run(get_default_action_input(), terminal);
23}
24
25/// Loads fruit information into table rows for display.
26/// Each row contains: Fruit emoji, Base Score, Spawn Chance, Size Effect, and Computed duration.
27#[must_use]
28fn load_fruits_info_in_table(options: &GameOptions) -> Vec<RowData> {
29    let mut rows = vec![];
30    let base_duration = Duration::from_secs(u64::from(options.fruit_duration_seconds));
31
32    for (fruit, score, probability, size_effect) in FRUITS_SCORES_PROBABILITIES {
33        let multiplier = Fruit::duration_multiplier(*size_effect);
34        let computed_duration = Fruit::duration_from_base(base_duration, *size_effect);
35        rows.push(RowData::new(vec![
36            CellValue::new((*fruit).to_string()),
37            CellValue::new(format!("{score}")),
38            CellValue::new(format!("{probability}%")),
39            CellValue::new(size_effect.to_string()),
40            CellValue::new(format!(
41                "{:.1}s ({:.0} x {multiplier:.1})",
42                computed_duration.as_secs_f32(),
43                base_duration.as_secs_f32()
44            )),
45        ]));
46    }
47
48    rows
49}
50
51/// Returns the header labels for fruits information table.
52#[must_use]
53fn fruits_get_headers() -> Vec<String> {
54    vec![
55        "🍎 Fruit".to_string(),
56        "🎯 Score x Speed Modifier".to_string(),
57        "🎲 Chance".to_string(),
58        "📏 Snake Size Effect".to_string(),
59        "⏱ Computed".to_string(),
60    ]
61}
62
63/// Should add an action to the Footer Data (like apply, move, change value).
64#[must_use]
65fn fruits_get_footer_data() -> Vec<FooterData> {
66    vec![
67        FooterData {
68            symbol: "Esc/Tab".into(),
69            text: "Return to home".into(),
70            value: None,
71        },
72        FooterData {
73            symbol: "↕".into(),
74            text: "Move".into(),
75            value: None,
76        },
77    ]
78}