1 个不稳定版本
0.1.0 | 2019 年 10 月 27 日 |
---|
#358 in 游戏
38KB
836 行
mancala 
Rust 中的强化学习曼卡拉。
什么是
本节将定义本项目中描述中的术语。
曼卡拉
曼卡拉是一组
双人轮流策略棋类游戏的通称,使用小石头、豆子或种子,以及地面、棋盘或其他游戏表面的凹槽或坑进行游戏。目标通常是捕获对手的所有或部分棋子。
Rust
Rust 是一种编程语言,它
从根本上来说是关于赋能:无论你现在正在编写什么类型的代码,Rust 都能让你走得更远,让你能够在比之前更广泛的领域中自信地编程。
强化学习
强化学习是
机器学习的一个领域,研究软件代理在环境中如何采取行动以最大化某种累积奖励的概念。由于它的通用性,该问题在其他许多学科中都有研究,如博弈论、控制论、运筹学、信息论、基于模拟的优化、多智能体系统、群体智能、统计学和遗传算法。
用法
谁会赢?
假设我们感兴趣的是一种只有一个碗的曼卡拉游戏,每个玩家都没有选择。他们只能玩他们的单个碗。所以确定谁会赢不应该很难。让我们用 mancala
来表示。
首先宣布 mancala
包。
extern crate mancala;
由于我们将直接使用 Position
,现在让我们导入它。
use mancala::game::Position;
我们同意从每个玩家8个石头开始。
let mut position = Position::from([8; 2]);
这个数组表示每个玩家的碗和它们的石头,每个玩家一个碗。
现在我们只想从一个碗开始玩,直到游戏结束。
while !position.finished() {
position = position.play(0).unwrap();
}
游戏结束后,我们可以确定分数。
println!("score {}", position.score().unwrap());
现在我们知道谁将获胜。您可以在 examples/position2
中看到一个类似的 程序。
与计算机对战
如果您想与计算机玩曼卡拉,这个库也为您提供了相应的支持。
由于我们将使用这个库,我们最好宣布一下。
extern crate mancala;
接下来,我们需要一些导入,以帮助我们设置游戏。使用 std::ops::Neg
来显示正确的分数。
use std::ops::Neg;
use mancala::bout::Bout;
use mancala::game::{GameBuilder, Player};
use mancala::strategy::tree::Depth;
use mancala::strategy::{AlphaBeta, User};
由于这是一个程序,我们需要一个 main
函数。
fn main() {
...
}
我们首先需要两种策略。一个是 User
策略,另一个是深度限制为 10 的 AlphaBeta
策略。更改此参数将影响计算机的强度和思考时间。有了这两种策略,我们就可以创建一个 Bout
。
lt mut red_strategy = user();
let mut blue_strategy = AlphaBeta::limited_to(Depth::Limit(10));
let mut bout = Bout::new(&mut red_strategy, &mut blue_strategy);
接下来,我们创建一个包含 6 个碗和每个碗 4 个石子的游戏。
let game = GameBuilder::new().bowls(6).stones(4).build();
然后启动策略之间的对决。
let result = bout.start(game).expect("a finished game with score");
结果是可以通过询问分数来得到的位置。我们将显示起始玩家的分数,即 Red
,如果位置是 Blue
,则需要取反,因为这是一个 零和游戏。
let mut score = result.score().expect("a defined score");
if result.turn() != Player::Red {
score = score.neg();
}
println!("{:?}", score);
上述变体已经在一个名为 src/bin/play.rs
的 程序 中实现。
策略
策略是一种算法,用于确定在特定情况下应该玩什么。策略可以产生深远的影响。例如,下面是对策略 MinMax
和 AlphaBeta
的比较。
这两种策略都用于确定在两个碗和 1 到 14 个石子之间进行曼卡拉游戏的哪个玩家会获胜。
石子数量 | 分数 |
---|---|
1 | 2 |
2 | -2 |
3 | -4 |
4 | -10 |
5 | 6 |
6 | 8 |
7 | 12 |
8 | 4 |
9 | -10 |
10 | -6 |
11 | 6 |
12 | 14 |
13 | 6 |
14 | 4 |
产生以下结果所需的时间如下
算法 | 时间 |
---|---|
MinMax |
25.21 |
AlphaBeta |
0.59 |
这是相当令人印象深刻的。
依赖关系
~750KB