Start on a second-level representation for the game tree
This commit is contained in:
parent
d6c2a9519b
commit
0700f13429
|
@ -2309,6 +2309,7 @@ dependencies = [
|
|||
"serde",
|
||||
"thiserror",
|
||||
"typeshare",
|
||||
"uuid 1.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2726,6 +2727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -11,6 +11,7 @@ nom = { version = "7" }
|
|||
serde = { version = "1", features = [ "derive" ] }
|
||||
thiserror = { version = "1"}
|
||||
typeshare = { version = "1" }
|
||||
uuid = { version = "1.4", features = ["v4", "serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
cool_asserts = { version = "2" }
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
use crate::{Color, Position};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub trait Node {
|
||||
fn path_to_node<'a>(&'a self, id: Uuid) -> Vec<&'a GameNode>;
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode;
|
||||
fn add_annotation(&mut self, label: String, note: String);
|
||||
}
|
||||
|
||||
pub enum GameNode {
|
||||
MoveNode(MoveNode),
|
||||
SetupNode(SetupNode),
|
||||
}
|
||||
|
||||
impl GameNode {
|
||||
fn id(&self) -> Uuid {
|
||||
match self {
|
||||
GameNode::MoveNode(node) => node.id,
|
||||
GameNode::SetupNode(node) => node.id,
|
||||
}
|
||||
}
|
||||
|
||||
fn children<'a>(&'a self) -> Vec<&'a GameNode> {
|
||||
unimplemented!("GameNode::children")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for GameNode {
|
||||
fn path_to_node<'a>(&'a self, id: Uuid) -> Vec<&'a GameNode> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_annotation(&mut self, label: String, note: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
// Root node
|
||||
pub struct GameTree {
|
||||
children: Vec<GameNode>,
|
||||
}
|
||||
|
||||
impl GameTree {
|
||||
fn new() -> Self {
|
||||
Self { children: vec![] }
|
||||
}
|
||||
|
||||
fn nodes<'a>(&'a self) -> impl Iterator<Item = &'a GameNode> {
|
||||
vec![].into_iter()
|
||||
}
|
||||
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode {
|
||||
// self.children.push(node);
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for GameTree {
|
||||
fn path_to_node<'a>(&'a self, id: Uuid) -> Vec<&'a GameNode> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_annotation(&mut self, label: String, note: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MoveNode {
|
||||
id: Uuid,
|
||||
|
||||
color: Color,
|
||||
position: Position,
|
||||
annotations: Vec<(String, String)>,
|
||||
children: Vec<GameNode>,
|
||||
}
|
||||
|
||||
impl MoveNode {
|
||||
pub fn new(color: Color, position: Position) -> Self {
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
|
||||
color,
|
||||
position,
|
||||
annotations: Vec::new(),
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for MoveNode {
|
||||
fn path_to_node<'a>(&'a self, id: Uuid) -> Vec<&'a GameNode> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_annotation(&mut self, label: String, note: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetupNode {
|
||||
id: Uuid,
|
||||
|
||||
positions: Vec<(Color, Position)>,
|
||||
annotations: Vec<(String, String)>,
|
||||
children: Vec<GameNode>,
|
||||
}
|
||||
|
||||
impl SetupNode {
|
||||
pub fn new(positions: Vec<(Color, Position)>) -> Self {
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
positions,
|
||||
annotations: Vec::new(),
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for SetupNode {
|
||||
fn path_to_node<'a>(&'a self, id: Uuid) -> Vec<&'a GameNode> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_child<'a>(&'a mut self, node: GameNode) -> &'a GameNode {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_annotation(&mut self, label: String, note: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path_to_node<'a>(node: &'a GameNode, id: Uuid) -> Vec<&'a GameNode> {
|
||||
if node.id() == id {
|
||||
return vec![node];
|
||||
}
|
||||
|
||||
for child in node.children() {
|
||||
let mut path = path_to_node(child, id);
|
||||
if path.len() > 1 {
|
||||
path.push(child);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_can_create_an_empty_game_tree() {
|
||||
let tree = GameTree::new();
|
||||
assert_eq!(tree.nodes().count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_add_moves_to_a_game() {
|
||||
let mut tree = GameTree::new();
|
||||
|
||||
let node = MoveNode::new(Color::Black, Position {});
|
||||
let mut node = tree.add_child(GameNode::MoveNode(node));
|
||||
let new_node = MoveNode::new(Color::White, Position {});
|
||||
node.add_child(new_node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_set_up_a_game() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_load_tree_from_sgf() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod root_node_tests {
|
||||
#[test]
|
||||
fn it_rejects_move_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_rejects_setup_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_parse_a_root_sgf() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod move_node_tests {
|
||||
#[test]
|
||||
fn it_rejects_setup_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_rejects_root_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_parse_an_sgf_move_node() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_rejects_an_sgf_setup_node() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod setup_node_tests {
|
||||
#[test]
|
||||
fn it_rejects_move_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_rejects_root_properties() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_parse_an_sgf_setup_node() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_rejects_an_sgf_move_node() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod path_test {
|
||||
#[test]
|
||||
fn returns_empty_list_if_no_game_nodes() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_empty_list_if_node_not_found() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_excludes_root_node() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ pub mod go;
|
|||
mod tree;
|
||||
use tree::parse_collection;
|
||||
|
||||
mod game;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -16,6 +18,13 @@ pub enum Error {
|
|||
InvalidSgf(VerboseNomError),
|
||||
}
|
||||
|
||||
pub enum Color {
|
||||
Black,
|
||||
White,
|
||||
}
|
||||
|
||||
pub struct Position {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VerboseNomError(nom::error::VerboseError<String>);
|
||||
|
||||
|
|
Loading…
Reference in New Issue