Process time remaining and promote comments to the game tree layer

This commit is contained in:
Savanni D'Gerinel 2023-09-14 12:30:55 -04:00
parent 52f663264e
commit 6d8ece3d29
2 changed files with 66 additions and 35 deletions

View File

@ -268,7 +268,7 @@ pub struct MoveNode {
name: Option<String>,
evaluation: Option<Evaluation>,
value: Option<f64>,
comments: Vec<String>,
comments: Option<String>,
annotation: Option<Annotation>,
unknown_props: Vec<(String, String)>,
}
@ -286,7 +286,7 @@ impl MoveNode {
name: None,
evaluation: None,
value: None,
comments: vec![],
comments: None,
annotation: None,
unknown_props: vec![],
}
@ -309,7 +309,14 @@ impl TryFrom<&parser::Node> for MoveNode {
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
match n.move_() {
Some((color, position)) => Ok(MoveNode::new(color, position)),
Some((color, position)) => {
let mut s = Self::new(color, position);
s.time_left = n.time_left();
s.comments = n.comments();
Ok(s)
}
None => Err(ConversionError::IncompatibleNodeType),
}
}
@ -419,16 +426,8 @@ mod test {
let n = parser::Node {
properties: vec![
parser::Property::Move((Color::White, "dp".to_owned())),
/*
parser::Property {
ident: "WL".to_owned(),
values: vec!["176.099".to_owned()],
},
parser::Property {
ident: "C".to_owned(),
values: vec!["Comments in the game".to_owned()],
},
*/
parser::Property::TimeLeft((Color::White, Duration::from_secs(176))),
parser::Property::Comment("Comments in the game".to_owned()),
],
next: vec![],
};
@ -461,16 +460,8 @@ mod move_node_tests {
let n = parser::Node {
properties: vec![
parser::Property::Move((Color::White, "dp".to_owned())),
/*
parser::Property {
ident: "WL".to_owned(),
values: vec!["176.099".to_owned()],
},
parser::Property {
ident: "C".to_owned(),
values: vec!["Comments in the game".to_owned()],
},
*/
parser::Property::TimeLeft((Color::White, Duration::from_secs(176))),
parser::Property::Comment("Comments in the game".to_owned()),
],
next: vec![],
};
@ -479,7 +470,7 @@ mod move_node_tests {
assert_eq!(node.position, "dp".to_owned());
assert_eq!(node.children, vec![]);
assert_eq!(node.time_left, Some(Duration::from_secs(176)));
assert_eq!(node.comments, vec!["Comments in the game".to_owned()]);
assert_eq!(node.comments, Some("Comments in the game".to_owned()));
});
}

View File

@ -8,7 +8,7 @@ use nom::{
multi::{many0, many1, separated_list1},
IResult, Parser,
};
use std::num::ParseIntError;
use std::{num::ParseIntError, time::Duration};
impl From<ParseSizeError> for Error {
fn from(_: ParseSizeError) -> Self {
@ -240,13 +240,31 @@ pub struct Node {
impl Node {
pub fn move_(&self) -> Option<(Color, String)> {
self.properties
.iter()
.filter_map(|prop| match prop {
self.find_by(|prop| match prop {
Property::Move(val) => Some(val.clone()),
_ => None,
})
.next()
}
pub fn time_left(&self) -> Option<Duration> {
self.find_by(|prop| match prop {
Property::TimeLeft((_, duration)) => Some(duration.clone()),
_ => None,
})
}
pub fn comments(&self) -> Option<String> {
self.find_by(|prop| match prop {
Property::Comment(c) => Some(c.clone()),
_ => None,
})
}
fn find_by<F, R>(&self, f: F) -> Option<R>
where
F: FnMut(&Property) -> Option<R>,
{
self.properties.iter().filter_map(f).next()
}
}
@ -287,10 +305,8 @@ impl ToString for Node {
// SL
// SQ
// TR
// BL
// OB
// OW
// WL
// FG
// PM
// VW
@ -414,7 +430,7 @@ pub enum Property {
Source(String),
// TM
TimeLimit(std::time::Duration),
TimeLimit(Duration),
// US
User(String),
@ -425,6 +441,9 @@ pub enum Property {
// WT
WhiteTeam(String),
// BL, WL
TimeLeft((Color, Duration)),
Unknown(UnknownProperty),
}
@ -440,6 +459,9 @@ impl ToString for Property {
Property::Move((color, position)) => {
format!("{}[{}]", color.abbreviation(), position)
}
Property::TimeLeft((color, time)) => {
format!("{}[{}]", color.abbreviation(), time.as_secs())
}
Property::Comment(value) => format!("C[{}]", value),
Property::BadMove => "BM[]".to_owned(),
Property::DoubtfulMove => "DO[]".to_owned(),
@ -550,6 +572,8 @@ fn parse_property<'a, E: nom::error::ParseError<&'a str>>(
"W" => parse_propval(parse_move(Color::White))(input)?,
"B" => parse_propval(parse_move(Color::Black))(input)?,
"C" => parse_propval(parse_comment())(input)?,
"WL" => parse_propval(parse_time_left(Color::White))(input)?,
"BL" => parse_propval(parse_time_left(Color::Black))(input)?,
"BM" => discard_propval().map(|_| Property::BadMove).parse(input)?,
"DO" => discard_propval()
.map(|_| Property::DoubtfulMove)
@ -626,6 +650,22 @@ fn parse_move<'a, E: nom::error::ParseError<&'a str>>(
}
}
fn parse_time_left<'a, E: ParseError<&'a str>>(
color: Color,
) -> impl FnMut(&'a str) -> IResult<&'a str, Property, E> {
{
let color = color.clone();
move |input: &'a str| {
let (input, value) = parse_real().parse(input)?;
let (input, _) = tag("]")(input)?;
Ok((
input,
Property::TimeLeft((color.clone(), Duration::from_secs(value as u64))),
))
}
}
}
fn parse_propval<'a, E: nom::error::ParseError<&'a str>>(
mut parser: impl Parser<&'a str, Property, E>,
) -> impl FnMut(&'a str) -> IResult<&'a str, Property, E> {