Skip to content

Instantly share code, notes, and snippets.

@trdthg
Created September 8, 2022 08:44
Show Gist options
  • Save trdthg/7b1d997500049a19746b654f536a53ea to your computer and use it in GitHub Desktop.
Save trdthg/7b1d997500049a19746b654f536a53ea to your computer and use it in GitHub Desktop.
wheretoeat_v0.0.1
use rand::prelude::*;
struct Node {
name: String,
children: Vec<Node>,
}
impl Node {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
children: vec![],
}
}
pub fn add<F>(&mut self, name: &str, f: F) -> &mut Self
where
F: FnOnce(&mut Self) + Copy,
{
let mut n = Node::new(name);
f(&mut n);
self.children.push(n);
self
}
pub fn add_node(mut self, node: Node) -> Self {
self.children.push(node);
self
}
pub fn execute<F>(&mut self, f: F)
where
F: FnOnce(&mut Self) + Copy,
{
f(self);
}
}
fn random_select(node: &mut Node) {
println!("{}", node.name);
if node.children.is_empty() {
return;
}
let mut rng = thread_rng();
let random_index = rng.gen_range(0..node.children.len());
if let Some(child) = node.children.get_mut(random_index) {
child.execute(random_select);
};
}
fn main() {
Node::new("Where to eat: ")
.add("东苑", |东苑| {
东苑.add("东 1", |东1| {
东1.add("一层", |一层| {
一层
.add("1 窗", |_| {})
.add("1 窗", |_| {})
.add("1 窗", |_| {});
});
});
})
.add("西苑", |_| {})
.execute(random_select);
Node::new("Where to eat: ")
.add_node(
Node::new("东苑")
.add_node(Node::new("东 1"))
.add_node(Node::new("东 2"))
.add_node(Node::new("东 3")),
)
.add_node(Node::new("西苑"))
.execute(random_select);
}
#[cfg(test)]
mod test {
use rand::{thread_rng, Rng};
#[test]
fn test() {
let mut rng = thread_rng();
let y = rng.gen_range(0..0);
println!("{}", y);
}
}
@trdthg
Copy link
Author

trdthg commented Sep 9, 2022

extern crate core;

use std::any::Any;

trait Node: AnyExt {
    fn add(self: Box<Self>, n: Box<dyn Node>) -> Box<dyn Node>;
    fn exec(&self, func: fn(n: &dyn Node)) -> &dyn Node;
}

trait AnyExt {
    fn to_any(self: Box<Self>) -> Box<dyn Any>;
    fn as_any(self: &Self) -> &dyn Any;
}
impl<T: Any> AnyExt for T {
    fn to_any(self: Box<Self>) -> Box<dyn Any> {
        self
    }

    fn as_any(self: &Self) -> &dyn Any {
        self
    }
}

struct SimpleNode {
    name: String,
    children: Vec<Box<SimpleNode>>,
}

impl SimpleNode {
    fn new(name: &str) -> SimpleNode {
        SimpleNode {
            name: name.to_string(),
            children: Vec::new(),
        }
    }
}

impl Node for SimpleNode {
    fn add(mut self: Box<Self>, n: Box<dyn Node>) -> Box<dyn Node> {
        if let Ok(sim_node) = n.to_any().downcast::<SimpleNode>() {
            self.children.push(sim_node);
        } else {
            panic!("error")
        }
        self
    }

    fn exec(&self, func: fn(&dyn Node)) -> &dyn Node {
        func(self);
        self
    }
}

fn random_select(n: &dyn Node) {
    if let Some(sim_node) = n.as_any().downcast_ref::<SimpleNode>() {
        println!(
            "{:?} and children {:?}",
            sim_node.name,
            sim_node.children.len()
        );
        let mut cnt = 0;
        while cnt < sim_node.children.len() {
            sim_node.children[cnt].exec(random_select);
            cnt += 1;
        }
    }
}

fn main() {
    Box::new(SimpleNode::new("where to eat :"))
        .add(
            Box::new(SimpleNode::new("东苑"))
                .add(Box::new(SimpleNode::new("东一")))
                .add(Box::new(SimpleNode::new("东二"))),
        )
        .add(
            Box::new(SimpleNode::new("西苑"))
                .add(Box::new(SimpleNode::new("西一")))
                .add(Box::new(SimpleNode::new("西二"))),
        )
        .add(
            Box::new(SimpleNode::new("软件园"))
                .add(Box::new(SimpleNode::new("一楼")))
                .add(Box::new(SimpleNode::new("二楼"))),
        )
        .exec(random_select);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment