survey: the route probe prints the room whole, its people, and the rung at the end
The catch dump prints a small map whole with its people drawn and off the screen, each person's ledger entries and whether a route reaches them; outcomes are keyed by the map they finished on, the trace line carries the seam's bytes (wCurOpponent included), and the drive ends with the rank. How row 58's mechanism was read.
This commit is contained in:
parent
ddf0743395
commit
28bd980e65
1 changed files with 58 additions and 12 deletions
|
|
@ -1355,9 +1355,9 @@ fn dialog_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64
|
||||||
/// [`PokemonPalette`]: flybrain_gb::pokemon_red::macros::PokemonPalette
|
/// [`PokemonPalette`]: flybrain_gb::pokemon_red::macros::PokemonPalette
|
||||||
fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64) {
|
fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64) {
|
||||||
use flybrain_gb::MacroPalette;
|
use flybrain_gb::MacroPalette;
|
||||||
use flybrain_gb::pokemon_red::macros::cartridge::{MacroState, TargetKey};
|
use flybrain_gb::pokemon_red::macros::cartridge::{FACINGS, MacroState, TalkTarget, TargetKey};
|
||||||
use flybrain_gb::pokemon_red::macros::path::Way;
|
use flybrain_gb::pokemon_red::macros::path::Way;
|
||||||
use flybrain_gb::pokemon_red::macros::{PokemonPalette, palette, path};
|
use flybrain_gb::pokemon_red::macros::{PokemonPalette, Tile, palette, path};
|
||||||
|
|
||||||
let budget = env_usize("FLY_PROBE_FRAMES", 240_000);
|
let budget = env_usize("FLY_PROBE_FRAMES", 240_000);
|
||||||
let mut rng = env_usize("FLY_PROBE_RNG", 20_260_923) as u32 | 1;
|
let mut rng = env_usize("FLY_PROBE_RNG", 20_260_923) as u32 | 1;
|
||||||
|
|
@ -1484,7 +1484,12 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some((name, outcome)) = macros.take_finished() {
|
if let Some((name, outcome)) = macros.take_finished() {
|
||||||
*outcomes.entry(format!("{name} {outcome:?}")).or_default() += 1;
|
*outcomes
|
||||||
|
.entry(format!(
|
||||||
|
"{name} {outcome:?} on {:?}",
|
||||||
|
state::player(gb).map(|p| p.map)
|
||||||
|
))
|
||||||
|
.or_default() += 1;
|
||||||
if !matches!(outcome, flybrain_gb::Outcome::Done) {
|
if !matches!(outcome, flybrain_gb::Outcome::Done) {
|
||||||
println!(
|
println!(
|
||||||
"f{frame:<6} {:?} {name} {outcome:?}",
|
"f{frame:<6} {:?} {name} {outcome:?}",
|
||||||
|
|
@ -1495,11 +1500,12 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
since_decision += 1;
|
since_decision += 1;
|
||||||
if frame < trace_frames {
|
if frame < trace_frames {
|
||||||
println!(
|
println!(
|
||||||
" t{frame:<5} {:?} mask {mask:#04x} running {:?} marks {:?} stood {}",
|
" t{frame:<5} {:?} mask {mask:#04x} running {:?} marks {:?} stood {} | {}",
|
||||||
state::player(gb).map(|p| (p.map, p.x, p.y, p.facing)),
|
state::player(gb).map(|p| (p.map, p.x, p.y, p.facing)),
|
||||||
macros.running(),
|
macros.running(),
|
||||||
macros.fences().1,
|
macros.fences().1,
|
||||||
macros.stood()
|
macros.stood(),
|
||||||
|
scene::why_unknown(gb)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
gb.set_buttons(mask);
|
gb.set_buttons(mask);
|
||||||
|
|
@ -1531,6 +1537,11 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("```\n");
|
println!("```\n");
|
||||||
|
let progress = adapter.progress();
|
||||||
|
println!(
|
||||||
|
"- at the end: rank {} ({}), badges {}, unique tiles {}",
|
||||||
|
progress.rank, progress.rank_label, progress.counter, progress.unique_locations
|
||||||
|
);
|
||||||
println!("- refusals: {refusals:?}");
|
println!("- refusals: {refusals:?}");
|
||||||
println!("- outcomes: {outcomes:?}");
|
println!("- outcomes: {outcomes:?}");
|
||||||
let Some(frame) = caught_at else {
|
let Some(frame) = caught_at else {
|
||||||
|
|
@ -1557,11 +1568,13 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
println!("- objective: {:?}", state.objective());
|
println!("- objective: {:?}", state.objective());
|
||||||
println!("- `objective_goals`: {:?}", palette::objective_goals(state));
|
println!("- `objective_goals`: {:?}", palette::objective_goals(state));
|
||||||
println!("- `objective_targets`: {:?}", palette::objective_targets(state));
|
println!("- `objective_targets`: {:?}", palette::objective_targets(state));
|
||||||
for (tile, target) in path::person_targets(state) {
|
let drawn = path::person_targets(state);
|
||||||
|
for (tile, target) in drawn.iter().copied().chain(path::offscreen_person_targets(state)) {
|
||||||
println!(
|
println!(
|
||||||
" - person {target:?} at ({:2},{:2}): talked {}, blocked {}, reached {}",
|
" - person {target:?} at ({:2},{:2}) {}: talked {}, blocked {}, reached {}",
|
||||||
tile.x,
|
tile.x,
|
||||||
tile.y,
|
tile.y,
|
||||||
|
if drawn.contains(&(tile, target)) { "drawn" } else { "off the screen" },
|
||||||
state.talked(target),
|
state.talked(target),
|
||||||
state.blocked(TargetKey::Thing(target)),
|
state.blocked(TargetKey::Thing(target)),
|
||||||
state.reached(TargetKey::Thing(target))
|
state.reached(TargetKey::Thing(target))
|
||||||
|
|
@ -1591,16 +1604,44 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
reach
|
reach
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
println!("\n### The fly's own neighbourhood (pushed = `P`, player = `@`)\n\n```");
|
// A room small enough to print whole is printed whole, with its people on it (row 58:
|
||||||
for y in player.y.saturating_sub(3)..=player.y.saturating_add(3) {
|
// the gym's leader is twelve rows from the door).
|
||||||
let row: String = (player.x.saturating_sub(6)..=player.x.saturating_add(6))
|
let size = state.map_size().expect("a loaded map");
|
||||||
|
let whole = size.width <= 24 && size.height <= 24;
|
||||||
|
let people: Vec<(Tile, TalkTarget)> = path::person_targets(state)
|
||||||
|
.into_iter()
|
||||||
|
.chain(path::offscreen_person_targets(state))
|
||||||
|
.collect();
|
||||||
|
let (rows, columns) = if whole {
|
||||||
|
(0..=size.height - 1, 0..=size.width - 1)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
player.y.saturating_sub(3)..=player.y.saturating_add(3),
|
||||||
|
player.x.saturating_sub(6)..=player.x.saturating_add(6),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let grid = state.map_grid();
|
||||||
|
println!(
|
||||||
|
"\n### The fly's {} (pushed = `P`, player = `@`, a person = `N`; grid {})\n\n```",
|
||||||
|
if whole { "whole map" } else { "own neighbourhood" },
|
||||||
|
grid.is_some()
|
||||||
|
);
|
||||||
|
for y in rows {
|
||||||
|
let row: String = columns
|
||||||
|
.clone()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
|
let walk = match grid.as_deref() {
|
||||||
|
Some(grid) => grid.walkable(x, y),
|
||||||
|
None => state.walkable(x, y),
|
||||||
|
};
|
||||||
if x == player.x && y == player.y {
|
if x == player.x && y == player.y {
|
||||||
'@'
|
'@'
|
||||||
|
} else if people.iter().any(|(tile, _)| *tile == Tile::new(x, y)) {
|
||||||
|
'N'
|
||||||
} else if state.pushed_tile(x, y) {
|
} else if state.pushed_tile(x, y) {
|
||||||
'P'
|
'P'
|
||||||
} else {
|
} else {
|
||||||
match state.walkable(x, y) {
|
match walk {
|
||||||
flybrain_gb::pokemon_red::macros::state::Walkable::Yes => '.',
|
flybrain_gb::pokemon_red::macros::state::Walkable::Yes => '.',
|
||||||
flybrain_gb::pokemon_red::macros::state::Walkable::No => '#',
|
flybrain_gb::pokemon_red::macros::state::Walkable::No => '#',
|
||||||
flybrain_gb::pokemon_red::macros::state::Walkable::Unknown => '?',
|
flybrain_gb::pokemon_red::macros::state::Walkable::Unknown => '?',
|
||||||
|
|
@ -1608,9 +1649,14 @@ fn route_survey(gb: &mut Emulator, adapter: &mut PokemonRedReward, ms: &mut f64)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
println!("y{y:2} x{:2}.. {row}", player.x.saturating_sub(6));
|
println!("y{y:2} x{:2}.. {row}", if whole { 0 } else { player.x.saturating_sub(6) });
|
||||||
}
|
}
|
||||||
println!("```");
|
println!("```");
|
||||||
|
for (tile, target) in &people {
|
||||||
|
let aims: Vec<Tile> = FACINGS.iter().filter_map(|facing| tile.step(*facing)).collect();
|
||||||
|
let reach = path::route(state, &aims).map(|route| route.goal);
|
||||||
|
println!("- a route to {target:?} at ({:2},{:2}): {reach:?}", tile.x, tile.y);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue