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 2bf0b3d782
commit 349f71fc81
2 changed files with 66 additions and 35 deletions

View File

@ -268,7 +268,7 @@ pub struct MoveNode {
name: Option<String>, name: Option<String>,
evaluation: Option<Evaluation>, evaluation: Option<Evaluation>,
value: Option<f64>, value: Option<f64>,
comments: Vec<String>, comments: Option<String>,
annotation: Option<Annotation>, annotation: Option<Annotation>,
unknown_props: Vec<(String, String)>, unknown_props: Vec<(String, String)>,
} }
@ -286,7 +286,7 @@ impl MoveNode {
name: None, name: None,
evaluation: None, evaluation: None,
value: None, value: None,
comments: vec![], comments: None,
annotation: None, annotation: None,
unknown_props: vec![], unknown_props: vec![],
} }
@ -309,7 +309,14 @@ impl TryFrom<&parser::Node> for MoveNode {
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> { fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
match n.move_() { 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), None => Err(ConversionError::IncompatibleNodeType),
} }
} }
@ -419,16 +426,8 @@ mod test {
let n = parser::Node { let n = parser::Node {
properties: vec![ properties: vec![
parser::Property::Move((Color::White, "dp".to_owned())), parser::Property::Move((Color::White, "dp".to_owned())),
/* parser::Property::TimeLeft((Color::White, Duration::from_secs(176))),
parser::Property { parser::Property::Comment("Comments in the game".to_owned()),
ident: "WL".to_owned(),
values: vec!["176.099".to_owned()],
},
parser::Property {
ident: "C".to_owned(),
values: vec!["Comments in the game".to_owned()],
},
*/
], ],
next: vec![], next: vec![],
}; };
@ -461,16 +460,8 @@ mod move_node_tests {
let n = parser::Node { let n = parser::Node {
properties: vec![ properties: vec![
parser::Property::Move((Color::White, "dp".to_owned())), parser::Property::Move((Color::White, "dp".to_owned())),
/* parser::Property::TimeLeft((Color::White, Duration::from_secs(176))),
parser::Property { parser::Property::Comment("Comments in the game".to_owned()),
ident: "WL".to_owned(),
values: vec!["176.099".to_owned()],
},
parser::Property {
ident: "C".to_owned(),
values: vec!["Comments in the game".to_owned()],
},
*/
], ],
next: vec![], next: vec![],
}; };
@ -479,7 +470,7 @@ mod move_node_tests {
assert_eq!(node.position, "dp".to_owned()); assert_eq!(node.position, "dp".to_owned());
assert_eq!(node.children, vec![]); assert_eq!(node.children, vec![]);
assert_eq!(node.time_left, Some(Duration::from_secs(176))); 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}, multi::{many0, many1, separated_list1},
IResult, Parser, IResult, Parser,
}; };
use std::num::ParseIntError; use std::{num::ParseIntError, time::Duration};
impl From<ParseSizeError> for Error { impl From<ParseSizeError> for Error {
fn from(_: ParseSizeError) -> Self { fn from(_: ParseSizeError) -> Self {
@ -240,13 +240,31 @@ pub struct Node {
impl Node { impl Node {
pub fn move_(&self) -> Option<(Color, String)> { pub fn move_(&self) -> Option<(Color, String)> {
self.properties self.find_by(|prop| match prop {
.iter()
.filter_map(|prop| match prop {
Property::Move(val) => Some(val.clone()), Property::Move(val) => Some(val.clone()),
_ => None, _ => 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 // SL
// SQ // SQ
// TR // TR
// BL
// OB // OB
// OW // OW
// WL
// FG // FG
// PM // PM
// VW // VW
@ -414,7 +430,7 @@ pub enum Property {
Source(String), Source(String),
// TM // TM
TimeLimit(std::time::Duration), TimeLimit(Duration),
// US // US
User(String), User(String),
@ -425,6 +441,9 @@ pub enum Property {
// WT // WT
WhiteTeam(String), WhiteTeam(String),
// BL, WL
TimeLeft((Color, Duration)),
Unknown(UnknownProperty), Unknown(UnknownProperty),
} }
@ -440,6 +459,9 @@ impl ToString for Property {
Property::Move((color, position)) => { Property::Move((color, position)) => {
format!("{}[{}]", color.abbreviation(), position) format!("{}[{}]", color.abbreviation(), position)
} }
Property::TimeLeft((color, time)) => {
format!("{}[{}]", color.abbreviation(), time.as_secs())
}
Property::Comment(value) => format!("C[{}]", value), Property::Comment(value) => format!("C[{}]", value),
Property::BadMove => "BM[]".to_owned(), Property::BadMove => "BM[]".to_owned(),
Property::DoubtfulMove => "DO[]".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)?, "W" => parse_propval(parse_move(Color::White))(input)?,
"B" => parse_propval(parse_move(Color::Black))(input)?, "B" => parse_propval(parse_move(Color::Black))(input)?,
"C" => parse_propval(parse_comment())(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)?, "BM" => discard_propval().map(|_| Property::BadMove).parse(input)?,
"DO" => discard_propval() "DO" => discard_propval()
.map(|_| Property::DoubtfulMove) .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>>( fn parse_propval<'a, E: nom::error::ParseError<&'a str>>(
mut parser: impl Parser<&'a str, Property, E>, mut parser: impl Parser<&'a str, Property, E>,
) -> impl FnMut(&'a str) -> IResult<&'a str, Property, E> { ) -> impl FnMut(&'a str) -> IResult<&'a str, Property, E> {