mirror of
https://github.com/Noratrieb/monte-carlo-tree-search.git
synced 2026-01-17 08:45:05 +01:00
game
This commit is contained in:
parent
fdba35e4ac
commit
f95aeffef7
2 changed files with 30 additions and 63 deletions
|
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rand = "0.8.4"
|
||||||
|
|
|
||||||
92
src/lib.rs
92
src/lib.rs
|
|
@ -1,8 +1,31 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
pub struct Node<T> {
|
use rand::Rng;
|
||||||
value: T,
|
|
||||||
children: Vec<Node<T>>,
|
mod basic_search;
|
||||||
|
|
||||||
|
pub trait GameState {
|
||||||
|
fn points(&self) -> i32;
|
||||||
|
|
||||||
|
fn next(&self) -> Box<dyn Iterator<Item = Self>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameState for i32 {
|
||||||
|
fn points(&self) -> i32 {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&self) -> Box<dyn Iterator<Item = Self>> {
|
||||||
|
let child_amount = rand::thread_rng().gen_range(0..10);
|
||||||
|
let mut i = 0;
|
||||||
|
Box::new(std::iter::from_fn(move || {
|
||||||
|
if i < child_amount {
|
||||||
|
Some(rand::random())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
@ -15,67 +38,10 @@ macro_rules! tree {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
mod search {
|
mod mcts {}
|
||||||
use crate::Node;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
pub fn breadth_first_search<T: Eq>(tree: &Node<T>, searched: &T) -> bool {
|
|
||||||
let mut candidates = VecDeque::new();
|
|
||||||
candidates.push_back(tree);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if let Some(candidate) = candidates.pop_front() {
|
|
||||||
if candidate.value == *searched {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
candidates.extend(candidate.children.iter());
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn depth_first_search<T: Eq>(tree: &Node<T>, searched: &T) -> bool {
|
|
||||||
if tree.value == *searched {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for child in &tree.children {
|
|
||||||
if depth_first_search(&child, searched) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod test {
|
||||||
use crate::search;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dfs() {
|
fn t() {}
|
||||||
let tree = tree!(1, tree!(6, tree!(5), tree!(4)), tree!(6));
|
|
||||||
|
|
||||||
let has_seven = search::depth_first_search(&tree, &7);
|
|
||||||
let has_five = search::depth_first_search(&tree, &5);
|
|
||||||
|
|
||||||
assert!(!has_seven);
|
|
||||||
assert!(has_five);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn bfs() {
|
|
||||||
let tree = tree!(1, tree!(6, tree!(5), tree!(4)), tree!(6));
|
|
||||||
|
|
||||||
let has_seven = search::breadth_first_search(&tree, &7);
|
|
||||||
let has_five = search::breadth_first_search(&tree, &5);
|
|
||||||
|
|
||||||
assert!(!has_seven);
|
|
||||||
assert!(has_five);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue