2 个不稳定版本

0.2.0 2022年6月17日
0.1.0 2021年3月20日

#988游戏开发

MIT 许可证

19KB
328 代码行

arbor

此包提供了一个到蒙特卡洛树搜索算法的通用接口。它允许开发者实现一个两人游戏的AI代理,无需描述特定于游戏的启发式或策略。

GitHub上提供了使用arbor的示例,包括

  • 翻转棋
  • 四子棋
  • 曼卡拉
  • 井字棋

这些示例使用Yew在Arbor GitHub.io上进行了图形演示。

文档

文档提供在 Docs.rs

示例

arbor 添加到您的 Cargo.toml 的依赖项中

[dependencies]
arbor = "0.2.0"

然后在您的 rust 文件中

use arbor::*;

#[derive(Copy,Clone,Debug,PartialEq)]
enum Grid {
    TL,TM,TR,
    ML,MM,MR,
    BL,BM,BR
}

#[derive(Copy,Clone,Debug)]
struct TicTacToe {
    space: [Mark;9],
    turn: usize,
    side: Mark,
}

impl Action for Grid {}
impl Player for Mark {}

impl GameState<Mark,Grid> for TicTacToe {

    fn actions<F>(&self,f: &mut F) where F: FnMut(Grid){
        debug_assert!(self.gameover().is_none());
        
        for mark in ALLMOVES.iter() {
            let i = *mark as usize;
            if self.space[i] == Mark::N {
                f(ALLMOVES[i])
            }
        }
    }
    
    fn make(&self, action: Grid) -> Self {
        debug_assert!(self.gameover().is_none(),"Make called while gameover\n{}",self);
        debug_assert!(self.space[action as usize] == Mark::N,"Make called on invalid space {:?}\n{}",action,self);

        let mut next = TicTacToe {
            space: self.space,
            turn: self.turn + 1,
            side: if self.side == Mark::X {Mark::O} else {Mark::X},
        };

        next.space[action as usize] = self.side;

        next
    }
    
    fn gameover(&self) -> Option<GameResult> {
        let winner = self.winner();
        if (self.turn == 9) || (winner != Mark::N) {
            return match winner {
                Mark::N => Some(GameResult::Draw),

                // Side to play last always wins
                _ => Some(GameResult::Lose),
            }
        } else {
            None
        }
    }

    fn player(&self) -> Mark {
        self.side
    }
}

依赖项

~3MB
~61K SLoC