Slightly cleaner stub exit coherence logic
This commit is contained in:
parent
3d90917f65
commit
fed6d2581d
|
@ -1,5 +1,6 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
@ -79,10 +80,19 @@ pub(super) fn check_scene_coherence<'a>(scene: &'a Scene) -> Vec<CoherenceFailur
|
|||
|
||||
pub fn reverse_direction(direction: &str) -> String {
|
||||
match direction.to_lowercase().as_ref() {
|
||||
// compass directions
|
||||
"north" => "south".to_string(),
|
||||
"south" => "north".to_string(),
|
||||
"east" => "west".to_string(),
|
||||
"west" => "east".to_string(),
|
||||
|
||||
// more compass directions
|
||||
"northwest" => "southeast".to_string(),
|
||||
"northeast" => "southwest".to_string(),
|
||||
"southeast" => "northwest".to_string(),
|
||||
"southwest" => "northeast".to_string(),
|
||||
|
||||
// abstract directions
|
||||
"up" => "down".to_string(),
|
||||
"down" => "up".to_string(),
|
||||
"in" => "out".to_string(),
|
||||
|
@ -91,53 +101,11 @@ pub fn reverse_direction(direction: &str) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_exit_by_connection(exit: &Exit, connected_scene: &Scene) -> bool {
|
||||
let connected_key = connected_scene._key.as_deref().unwrap();
|
||||
Some(exit.scene_key.as_ref()) == connected_scene._key.as_deref()
|
||||
|| exit.scene_id.as_deref() == connected_scene._id.as_deref()
|
||||
|| exit.name.to_lowercase() == connected_scene.name.to_lowercase()
|
||||
|| exit.name == connected_key
|
||||
}
|
||||
|
||||
fn find_exit_by_direction(exit: &Exit, direction_from: &str) -> bool {
|
||||
exit.direction == reverse_direction(direction_from)
|
||||
}
|
||||
|
||||
// fn yoink<'a>(
|
||||
// //exits: Vec<&'a mut Exit>,
|
||||
// mut exits: Vec<&'a mut Exit>,
|
||||
// direction_from: &'a str,
|
||||
// connected_scene: &'a Scene,
|
||||
// ) -> Option<&'a mut Exit> {
|
||||
// if exits.len() > 1 {
|
||||
// exits
|
||||
// .iter()
|
||||
// .find_map(|exit| match find_exit_by_direction(*exit, direction_from) {
|
||||
// true => Some(&mut **exit),
|
||||
// _ => None,
|
||||
// })
|
||||
// .or_else(|| {
|
||||
// exits.iter().find_map(|&exit| {
|
||||
// match find_exit_by_connection(exit, connected_scene) {
|
||||
// true => Some(&mut *exit),
|
||||
// _ => None,
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
// } else if exits.len() == 1 {
|
||||
// Some(exits[0])
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Attempt to reconnect back to the connected scene. The model is
|
||||
/// not always good at this. Here, we correct it by attempting to
|
||||
/// find the exit by name, and also making sure the direction is
|
||||
/// coherently reversed.
|
||||
/// Attempt to reconnect back to the connected scene. The model is not
|
||||
/// always good at this. Here, we correct it by attempting to find the
|
||||
/// exit and making sure the direction is coherently reversed. A
|
||||
/// linkback exit is created from scratch if one cannot be found.
|
||||
pub fn make_scene_from_stub_coherent(content: &mut ContentContainer, connected_scene: &Scene) {
|
||||
// TODO we need to perhaps also make the exit from scratch if the
|
||||
// LLM did not generate it at all.
|
||||
let new_scene = content.owner.as_scene_mut();
|
||||
let connected_key = connected_scene._key.as_deref().unwrap();
|
||||
let connected_id = connected_scene._id.as_deref().unwrap();
|
||||
|
@ -151,46 +119,38 @@ pub fn make_scene_from_stub_coherent(content: &mut ContentContainer, connected_s
|
|||
|
||||
let reversed_direction = reverse_direction(direction_from);
|
||||
|
||||
// Rethink this.
|
||||
// 1. Delete any exits that have the same direction as the reversed direction_from
|
||||
// AND do not point to connected scene ID.
|
||||
// 2. Find potential connected exit and modify as normal.
|
||||
new_scene.exits.retain(|exit| {
|
||||
(exit.direction == reversed_direction && exit.scene_key == connected_key)
|
||||
|| exit.direction != reversed_direction
|
||||
});
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
// It is possible we have an exit that leads in the direction of
|
||||
// the way back, or one exit that is created to go back to the connected scene.
|
||||
let exit_to_change = new_scene.exits.iter_mut().find(|exit| {
|
||||
exit.direction == reverse_direction(direction_from)
|
||||
// 1. Delete any exit that is from the reversed direction, or
|
||||
// has the name/ID/key of the connected scene.
|
||||
let mut stubs_to_delete = vec![];
|
||||
let keep_exit = |exit: &Exit| {
|
||||
!(exit.direction == reversed_direction
|
||||
|| Some(exit.scene_key.as_ref()) == connected_scene._key.as_deref()
|
||||
|| exit.scene_id.as_deref() == connected_scene._id.as_deref()
|
||||
|| exit.name.to_lowercase() == connected_scene.name.to_lowercase()
|
||||
|| exit.name == connected_key
|
||||
|| exit.name == connected_id
|
||||
|| exit.name == connected_id)
|
||||
};
|
||||
|
||||
new_scene.exits.retain_mut(|exit| {
|
||||
let keep = keep_exit(exit);
|
||||
if !keep {
|
||||
stubs_to_delete.push(mem::take(&mut exit.scene_key));
|
||||
}
|
||||
keep
|
||||
});
|
||||
|
||||
if let Some(exit) = exit_to_change {
|
||||
// Delete the stub that was this exit, and update the exit
|
||||
content.contained.retain(|c| match &c.content {
|
||||
Content::SceneStub(stub) => stub._id != exit.scene_id,
|
||||
// Delete corresponding stubs
|
||||
content.contained.retain(|c| match &c.content {
|
||||
Content::SceneStub(stub) => match stub._key.as_ref() {
|
||||
Some(key) => !stubs_to_delete.contains(key),
|
||||
_ => true,
|
||||
});
|
||||
},
|
||||
_ => true,
|
||||
});
|
||||
|
||||
// Fix up exit to point back to connected scene.
|
||||
exit.scene_id = connected_scene._id.clone();
|
||||
exit.scene_key = connected_scene._key.as_ref().unwrap().clone();
|
||||
exit.direction = reverse_direction(direction_from);
|
||||
} else {
|
||||
println!("WARNING: could not correct stub exit - creating manually");
|
||||
|
||||
// Could not find a connected exit at all. Create one manually
|
||||
let exit = Exit::from_connected_scene(connected_scene, &reversed_direction);
|
||||
new_scene.exits.push(exit);
|
||||
}
|
||||
// Add new linkback exit
|
||||
let exit = Exit::from_connected_scene(connected_scene, &reversed_direction);
|
||||
new_scene.exits.push(exit);
|
||||
}
|
||||
|
||||
pub async fn make_scene_coherent(
|
||||
|
|
Loading…
Reference in New Issue