Set up SGF reading and start on the game database #47

Merged
savanni merged 20 commits from kifu/sgf into main 2023-07-26 13:54:28 +00:00
2 changed files with 62 additions and 6 deletions
Showing only changes of commit f24fb5eae9 - Show all commits

6
go-sgf/Makefile Normal file
View File

@ -0,0 +1,6 @@
test:
cargo watch -x 'nextest run'
test-oneshot:
cargo nextest run

View File

@ -161,12 +161,6 @@ struct Node {
} }
*/ */
#[derive(Debug, PartialEq)]
pub struct Property {
ident: String,
values: Vec<String>,
}
enum PropType { enum PropType {
Move, Move,
Setup, Setup,
@ -193,11 +187,55 @@ struct Tree {
sub_sequences: Vec<Tree>, sub_sequences: Vec<Tree>,
} }
impl ToString for Tree {
fn to_string(&self) -> String {
let sequence = self
.sequence
.iter()
.map(|node| node.to_string())
.collect::<String>();
let subsequences = self
.sub_sequences
.iter()
.map(|seq| seq.to_string())
.collect::<String>();
format!("({}{})", sequence, subsequences)
}
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
struct Node { struct Node {
properties: Vec<Property>, properties: Vec<Property>,
} }
impl ToString for Node {
fn to_string(&self) -> String {
let props = self
.properties
.iter()
.map(|prop| prop.to_string())
.collect::<String>();
format!(";{}", props)
}
}
#[derive(Debug, PartialEq)]
struct Property {
ident: String,
values: Vec<String>,
}
impl ToString for Property {
fn to_string(&self) -> String {
let values = self
.values
.iter()
.map(|val| format!("[{}]", val))
.collect::<String>();
format!("{}{}", self.ident, values)
}
}
// note: must preserve unknown properties // note: must preserve unknown properties
// note: must fix or preserve illegally formatted game-info properties // note: must fix or preserve illegally formatted game-info properties
// note: must correct or delete illegally foramtted properties, but display a warning // note: must correct or delete illegally foramtted properties, but display a warning
@ -475,6 +513,18 @@ Usually B plays the 3,3 invasion - see variation];W[qo];B[qp]
assert_eq!(ex_tree.sub_sequences[0].sub_sequences.len(), 2); assert_eq!(ex_tree.sub_sequences[0].sub_sequences.len(), 2);
} }
#[test]
fn it_can_regenerate_the_tree() {
let (_, tree1) = parse_tree(EXAMPLE_1).unwrap();
println!("{}", tree1.to_string());
assert_eq!(
tree1.to_string(),
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e]))(;C[f](;C[g];C[h];C[i])(;C[j])))"
);
let (_, tree2) = parse_tree(&tree1.to_string()).unwrap();
assert_eq!(tree1, tree2);
}
/* /*
fn with_examples(f: impl FnOnce(GameTree, GameTree)) { fn with_examples(f: impl FnOnce(GameTree, GameTree)) {
let (example_1, _) = parse_sgf(EXAMPLE_1).unwrap(); let (example_1, _) = parse_sgf(EXAMPLE_1).unwrap();