mancala 0.1.0

Play a variant of mancala
Documentation
# mancala [![Build Status]https://travis-ci.org/fifth-postulate/mancala.svg?branch=master]https://travis-ci.org/fifth-postulate/mancala
Reinforcement learning Mancala, in Rust.

## What is
This section will define the terms in the description of this project.

### Mancala
[Mancala][mancala] is a

> generic name for a family of two-player turn-based strategy board games played with small stones, beans, or seeds and rows of holes or pits in the earth, a board or other playing surface. The objective is usually to capture all or some set of the opponent's pieces.

### Rust
[Rust][rust] is a programming language that

> is fundamentally about empowerment: no matter what kind of code you are writing now, Rust empowers you to reach farther, to program with confidence in a wider variety of domains than you did before.

### Reinforcement learning
[Reinforcement learning][rl] is an

> area of machine learning concerned with how software agents ought to take actions in an environment so as to maximize some notion of cumulative reward. The problem, due to its generality, is studied in many other disciplines, such as game theory, control theory, operations research, information theory, simulation-based optimization, multi-agent systems, swarm intelligence, statistics and genetic algorithms.

## Usage
### Who will win?
Let's say we are interested in a game of mancala where each player has only one bowl. Players do not have a real choice. They can only play their single bowl. So determining who wins should not be that hard. Let's use `mancala` for that.

Start with announcing the `mancala` crate.

```rust
extern crate mancala;
```

Since we will be using `Position` directly import it now.

```rust
use mancala::game::Position;
```

Let's agree to start out with 8 stones each. We can create a starting position from a array in the following manner

```rust
let mut position = Position::from([8; 2]);
```

This array represents the bowls with their stones, one bowl for each player.

No we want to play from the only bowl until the game is over.

```rust
while !position.finished() {
    position = position.play(0).unwrap();
}
```

With the game finished, we can determine the score.

```rust
println!("score {}", position.score().unwrap());
```

Now we know who is going to win. You can see a similar [program][position2] in `examples/position2`.

### Play the computer
If you want to play Mancala against the computer this crate has got you covered as well.

Since we are going to use this crate we should better announce that.

```rust
extern crate mancala;
```

Next we need a few imports that will help us setup the game. the `std::ops::Neg` is used to show the correct score.

```rust
use std::ops::Neg;
use mancala::bout::Bout;
use mancala::game::{GameBuilder, Player};
use mancala::strategy::tree::Depth;
use mancala::strategy::{AlphaBeta, User};
```

Since this is a program, we need a `main` function.

```rust
fn main() {
    ...
}
```

We first need two strategies. One `User` strategy and a `AlphaBeta` strategy limited to a depth of 10. Changing this parameter will influence how strong the computer plays and the amount of time the computer takes to come up with an play. With these two strategies we are ready to create a `Bout`.

```rust
    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);
```

Next, we create a game with 6 bowls each and 4 stones per bowl.

```rust
    let game = GameBuilder::new().bowls(6).stones(4).build();
```

and start the bout between the strategies.

```rust
    let result = bout.start(game).expect("a finished game with score");
```

The result is a position which can be asked for the score. We will show the score for the start player, which is `Red` and need to negate the score if the position is `Blue`, since this is a [zero-sum game][zero-sum].

```rust
    let mut score = result.score().expect("a defined score");
    if result.turn() != Player::Red {
        score = score.neg();
    }
    println!("{:?}", score);
```

A variant of the above is already made into a [program][play] in `src/bin/play.rs`.

## Strategies
A strategy is an algorithm that determines what to play in a given situation. A strategy can have a profound impact. For example below there is a comparison between the strategies [`MinMax`][minmax] en [`AlphaBeta`][alphabeta].

Both strategies are used to determine which player will win for a mancala game with two bowls and a number of stones between 1 and 14.

| number of stones | Score |
|------------------|-------|
|                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 |

The time it took to produce these result are found below

| Algorithm   |  Time |
|-------------|-------|
| `MinMax`    | 25.21 |
| `AlphaBeta` |  0.59 |

Which is quit impressive.

[mancala]: https://en.wikipedia.org/wiki/Mancala
[rust]: https://www.rust-lang.org/
[rl]: https://en.wikipedia.org/wiki/Reinforcement_learning
[position2]: https://github.com/fifth-postulate/mancala/blob/master/examples/position2.rs
[zero-sum]: https://en.wikipedia.org/wiki/Zero-sum_game
[play]: https://github.com/fifth-postulate/mancala/blob/master/src/bin/play.rs
[minmax]: https://en.wikipedia.org/wiki/Minimax
[alphabeta]: https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning