mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-28 08:53:26 +03:00
start structuring the UI for selecting and running a challenge
This commit is contained in:
parent
d35d0c1b41
commit
53bd77332e
91
game/src/challenges.rs
Normal file
91
game/src/challenges.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use crate::game::{State, Transition, WizardState};
|
||||||
|
use crate::ui::UI;
|
||||||
|
use ezgui::{
|
||||||
|
hotkey, Choice, EventCtx, GfxCtx, HorizontalAlignment, Key, Line, ModalMenu, Text,
|
||||||
|
VerticalAlignment,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Also have some kind of screenshot to display for each challenge
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Challenge {
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
map_name: String,
|
||||||
|
scenario_name: String,
|
||||||
|
}
|
||||||
|
impl abstutil::Cloneable for Challenge {}
|
||||||
|
|
||||||
|
fn all_challenges() -> Vec<Challenge> {
|
||||||
|
vec![
|
||||||
|
Challenge {
|
||||||
|
title: "Speed up route 980".to_string(),
|
||||||
|
description:
|
||||||
|
"Decrease the average waiting time between all of 980's stops by at least 30s"
|
||||||
|
.to_string(),
|
||||||
|
map_name: "montlake".to_string(),
|
||||||
|
scenario_name: "weekday_typical_traffic_from_psrc".to_string(),
|
||||||
|
},
|
||||||
|
Challenge {
|
||||||
|
title: "Speed up route 27 along Yesler".to_string(),
|
||||||
|
description:
|
||||||
|
"Decrease the average waiting time between all of 27's stops by at least 30s"
|
||||||
|
.to_string(),
|
||||||
|
map_name: "23rd".to_string(),
|
||||||
|
scenario_name: "weekday_typical_traffic_from_psrc".to_string(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn challenges_picker() -> Box<dyn State> {
|
||||||
|
WizardState::new(Box::new(move |wiz, ctx, _| {
|
||||||
|
let (_, challenge) = wiz.wrap(ctx).choose("Play which challenge?", || {
|
||||||
|
all_challenges()
|
||||||
|
.into_iter()
|
||||||
|
.map(|c| Choice::new(c.title.clone(), c))
|
||||||
|
.collect()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut summary = Text::from(Line(&challenge.description));
|
||||||
|
summary.add(Line(""));
|
||||||
|
summary.add(Line("Proposals:"));
|
||||||
|
summary.add(Line(""));
|
||||||
|
summary.add(Line("- bus lane fix (untested)"));
|
||||||
|
summary.add(Line("- signal retiming (score 500)"));
|
||||||
|
|
||||||
|
Some(Transition::Replace(Box::new(ChallengeSplash {
|
||||||
|
summary,
|
||||||
|
menu: ModalMenu::new(
|
||||||
|
&challenge.title,
|
||||||
|
vec![
|
||||||
|
(hotkey(Key::Escape), "back to challenges"),
|
||||||
|
(hotkey(Key::S), "start challenge"),
|
||||||
|
(hotkey(Key::L), "load existing proposal"),
|
||||||
|
],
|
||||||
|
ctx,
|
||||||
|
),
|
||||||
|
})))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChallengeSplash {
|
||||||
|
menu: ModalMenu,
|
||||||
|
summary: Text,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State for ChallengeSplash {
|
||||||
|
fn event(&mut self, ctx: &mut EventCtx, _: &mut UI) -> Transition {
|
||||||
|
self.menu.event(ctx);
|
||||||
|
if self.menu.action("back to challenges") {
|
||||||
|
return Transition::Replace(challenges_picker());
|
||||||
|
}
|
||||||
|
Transition::Keep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||||
|
g.draw_blocking_text(
|
||||||
|
&self.summary,
|
||||||
|
(HorizontalAlignment::Center, VerticalAlignment::Center),
|
||||||
|
);
|
||||||
|
self.menu.draw(g);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
mod abtest;
|
mod abtest;
|
||||||
|
mod challenges;
|
||||||
mod common;
|
mod common;
|
||||||
mod debug;
|
mod debug;
|
||||||
mod edit;
|
mod edit;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::abtest::setup::PickABTest;
|
use crate::abtest::setup::PickABTest;
|
||||||
|
use crate::challenges::challenges_picker;
|
||||||
use crate::debug::DebugMode;
|
use crate::debug::DebugMode;
|
||||||
use crate::edit::EditMode;
|
use crate::edit::EditMode;
|
||||||
use crate::game::{State, Transition};
|
use crate::game::{State, Transition};
|
||||||
@ -123,6 +124,7 @@ fn splash_screen(
|
|||||||
) -> Option<Transition> {
|
) -> Option<Transition> {
|
||||||
let mut wizard = raw_wizard.wrap(ctx);
|
let mut wizard = raw_wizard.wrap(ctx);
|
||||||
let sandbox = "Sandbox mode";
|
let sandbox = "Sandbox mode";
|
||||||
|
let challenge = "Challenge mode";
|
||||||
let load_map = "Load another map";
|
let load_map = "Load another map";
|
||||||
let edit = "Edit map";
|
let edit = "Edit map";
|
||||||
let abtest = "A/B Test Mode";
|
let abtest = "A/B Test Mode";
|
||||||
@ -142,6 +144,7 @@ fn splash_screen(
|
|||||||
.choose("Welcome to A/B Street!", || {
|
.choose("Welcome to A/B Street!", || {
|
||||||
vec![
|
vec![
|
||||||
Choice::new(sandbox, ()).key(Key::S),
|
Choice::new(sandbox, ()).key(Key::S),
|
||||||
|
Choice::new(challenge, ()).key(Key::C),
|
||||||
Choice::new(load_map, ()).key(Key::L),
|
Choice::new(load_map, ()).key(Key::L),
|
||||||
Choice::new(edit, ()).key(Key::E),
|
Choice::new(edit, ()).key(Key::E),
|
||||||
Choice::new(abtest, ()).key(Key::A),
|
Choice::new(abtest, ()).key(Key::A),
|
||||||
@ -156,6 +159,7 @@ fn splash_screen(
|
|||||||
.as_str()
|
.as_str()
|
||||||
{
|
{
|
||||||
x if x == sandbox => Some(Transition::Push(Box::new(SandboxMode::new(ctx, ui)))),
|
x if x == sandbox => Some(Transition::Push(Box::new(SandboxMode::new(ctx, ui)))),
|
||||||
|
x if x == challenge => Some(Transition::Push(challenges_picker())),
|
||||||
x if x == load_map => {
|
x if x == load_map => {
|
||||||
if let Some(name) = wizard.choose_string("Load which map?", || {
|
if let Some(name) = wizard.choose_string("Load which map?", || {
|
||||||
let current_map = ui.primary.map.get_name();
|
let current_map = ui.primary.map.get_name();
|
||||||
|
Loading…
Reference in New Issue
Block a user