//! An easily reusable game bot for deterministic games.
//!
//! It is required to implement the trait [`Game`][game] for your game to use this crate.
//!
//! # Examples
//!
//! A game where you win by selecting `10`.
//!
//! ```rust
//! use std::ops::RangeInclusive;
//!
//! #[derive(Clone)]
//! struct ChooseTen;
//!
//! impl rubot::Game for ChooseTen {
//! /// there is only one player, you!
//! type Player = ();
//! type Action = u8;
//! /// did you choose a 10?
//! type Fitness = bool;
//! type Actions = RangeInclusive<u8>;
//!
//! fn actions(&self, _: Self::Player) -> (bool, Self::Actions) {
//! (true, 1..=10)
//! }
//!
//! fn execute(&mut self, action: &u8, _: Self::Player) -> Self::Fitness {
//! *action == 10
//! }
//! }
//!
//! fn main() {
//! use rubot::Bot;
//! use std::time::Duration;
//!
//! let mut bot = Bot::new(());
//! assert_eq!(
//! bot.select(&ChooseTen, Duration::from_secs(1)),
//! Some(10)
//! );
//! }
//! ```
//!
//! Please visit the [examples folder][ex] or the [`trait Game`][game] documentation
//! for more realistic examples.
//!
//! [ab]:alpha_beta/struct.Bot.html
//! [ex]:https://github.com/lcnr/rubot/tree/master/examples
//! [game]:trait.Game.html
use PartialEq;
use ;
use Drop;
use ;
/// An interface required to interact with [`GameBot`s][bot].
///
/// # Examples
///
/// Implementing this trait for `21 flags`. The game has the following rules:
///
/// - at the beginning there are 21 flags.
/// - 2 players draw 1, 2 or 3 flags in alternating turns
/// - the player who removes the last flag wins
///
/// This example is really simplified and should be viewed as such.
/// For more realistic examples visit the [`/examples`][examples] folder of this project.
///
/// ```rust
/// use std::{
/// ops::{Not, RangeInclusive},
/// time::Duration
/// };
///
/// #[derive(Clone)]
/// struct Game {
/// flags: u32,
/// active_player: Player
/// }
///
/// #[derive(Clone, Copy, PartialEq, Eq, Debug)]
/// enum Player {
/// A,
/// B
/// }
///
/// impl Not for Player {
/// type Output = Player;
///
/// fn not(self) -> Player {
/// match self {
/// Player::A => Player::B,
/// Player::B => Player::A,
/// }
/// }
/// }
///
/// impl Game {
/// fn remove_flags(&mut self, flags: u32) {
/// self.flags -= flags;
/// self.active_player = !self.active_player;
/// }
///
/// fn winner(&self) -> Player {
/// assert_eq!(self.flags, 0);
/// !self.active_player
/// }
/// }
///
/// impl rubot::Game for Game {
/// type Player = Player;
/// type Action = u32;
/// /// `true` if the player wins the game, `false` otherwise.
/// type Fitness = bool;
/// type Actions = RangeInclusive<u32>;
///
/// fn actions(&self, player: Self::Player) -> (bool, Self::Actions) {
/// (player == self.active_player, 1..=std::cmp::min(self.flags, 3))
/// }
///
/// fn execute(&mut self, action: &Self::Action, player: Self::Player) -> Self::Fitness {
/// (action, player, &self);
/// self.remove_flags(*action);
/// self.flags == 0 && player == self.winner()
/// }
///
/// /// The fitness is only `true` if the game is won.
/// fn is_upper_bound(&self, fitness: Self::Fitness, player: Self::Player) -> bool {
/// fitness
/// }
/// }
///
/// fn main() {
/// use rubot::{Bot, ToCompletion};
/// let mut player_a = Bot::new(Player::A);
/// let mut player_b = Bot::new(Player::B);
/// let mut game = Game { flags: 21, active_player: Player::A };
/// loop {
/// game.remove_flags(player_a.select(&game, ToCompletion).unwrap());
/// if game.flags == 0 { break }
///
/// game.remove_flags(player_b.select(&game, ToCompletion).unwrap());
/// if game.flags == 0 { break }
/// }
/// // In case both players play perfectly, the player who begins should always win.
/// assert_eq!(game.winner(), Player::A, "players are not playing optimally");
/// }
/// ```
///
/// # Template
///
/// A template which can be used to implement this trait more quickly.
///
/// ```rust
/// #[derive(Clone)]
/// struct PlaceholderGame;
/// #[derive(Clone, Copy)]
/// struct PlaceholderPlayer;
/// #[derive(Clone, PartialEq)]
/// struct PlaceholderAction;
/// #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
/// struct PlaceholderFitness;
///
/// impl rubot::Game for PlaceholderGame {
/// type Player = PlaceholderPlayer;
/// type Action = PlaceholderAction;
/// type Fitness = PlaceholderFitness;
/// type Actions = Vec<Self::Action>;
///
/// fn actions(&self, player: Self::Player) -> (bool, Self::Actions) {
/// unimplemented!();
/// }
///
/// fn execute(&mut self, action: &Self::Action, player: Self::Player) -> Self::Fitness {
/// unimplemented!();
/// }
/// }
/// ```
/// [bot]: trait.GameBot.html
/// [act]: trait.Game.html#associatedtype.Action
/// [player]: trait.Game.html#associatedtype.player
/// [examples]: https://github.com/lcnr/rubot/tree/master/examples
/// Converts a type into a [`RunCondition`][rc] used by [`Bot::select`][sel].
/// It is recommended to mostly use [`Duration`][dur].
///
/// # Examples
///
/// ```rust
/// # struct Game;
/// # struct Bot;
/// # impl Bot {
/// # fn select<U: rubot::IntoRunCondition>(&mut self, state: &Game, condition: U) -> Option<()> {
/// # Some(())
/// # }
/// # }
/// use std::time::Duration;
///
/// let available_time = Duration::from_secs(2);
///
/// let game: Game = // ...
/// # Game;
/// let mut bot: Bot = // ...
/// # Bot;
/// assert!(bot.select(&game, available_time).is_some())
/// ```
///
/// # Implementations
///
/// - [`Duration`][dur]: `select` runs for the specified duration
/// - [`ToCompletion`][complete]: `select` runs until it found the perfect action
/// - [`Depth`][depth]: `select` analyses up the to given depth and returns to best action at that depth
/// - [`Instant`][instant]: `select` runs until the given `Instant` is in the past
/// - [`Logger`][logger]: takes another run condition and stores information about the last call to `select`
///
/// [rc]: trait.RunCondition.html
/// [dur]: https://doc.rust-lang.org/std/time/struct.Duration.html
/// [complete]: struct.ToCompletion.html
/// [depth]: struct.Depth.html
/// [instant]: https://doc.rust-lang.org/std/time/struct.Instant.html
/// [logger]: struct.Logger.html
/// [sel]: alpha_beta/struct.Bot.html#method.select
///
/// Can be converted into [`RunCondition`][rc] which returns `true` for the first `self.0` steps.
/// This should only be used for debugging and testing as unlike `Duration`, `ToCompletion` or `Depth`,
/// the total amount of steps needed is not directly indicative of search depth and can change between minor versions.
///
/// [rc]: trait.RunCondition.html
;
/// The [`RunCondition`][rc] created by [`Steps`][steps]`::into_run_condition`
///
/// [rc]: trait.RunCondition.html
/// [steps]: struct.Steps.html
;
/// Creates a [`RunCondition`][rc] which returns `true` until this `Duration` has passed.
///
/// [rc]: trait.RunCondition.html
/// A condition which indicates if [`Bot::select`][sel] should keep on running.
/// It is recommended to use [`Duration`][dur] for nearly all use cases.
///
/// A list of all already implemented `RunCondition`s can be found [here][into].
///
/// [sel]: alpha_beta/struct.Bot.html#method.select
/// [dur]: https://doc.rust-lang.org/std/time/struct.Duration.html
/// [into]: trait.IntoRunCondition.html#implementations-1
/// Returns `true` while the `Instant` is still in the future
/// A struct implementing [`RunCondition`][rc] which always returns `true`.
///
/// This means that the bot will always run until the best action was found.
///
/// # Examples
///
/// ```rust
/// # use rubot::{Bot, tree::Node, ToCompletion};
/// let tree = Node::root().with_children(&[
/// Node::new(false, 7).with_children(&[
/// Node::new(true, 4),
/// Node::new(true, 2),
/// ]),
/// Node::new(false, 5).with_children(&[
/// Node::new(true, 8),
/// Node::new(true, 9)
/// ]),
/// ]);
///
/// let mut bot = Bot::new(true);
/// assert_eq!(bot.select(&tree, ToCompletion), Some(1));
/// ```
/// [rc]: trait.RunCondition.html
;
/// A struct implementing [`RunCondition`][rc] returning cancelling the computation once the depth `self.0`
/// is reached.
///
/// # Examples
///
/// ```rust
/// # use rubot::{Bot, tree::Node, Depth};
/// let tree = Node::root().with_children(&[
/// Node::new(false, 7).with_children(&[
/// Node::new(true, 4),
/// Node::new(true, 2),
/// ]),
/// Node::new(false, 5).with_children(&[
/// Node::new(true, 8),
/// Node::new(true, 9)
/// ]),
/// ]);
///
/// let mut bot = Bot::new(true);
/// assert_eq!(bot.select(&tree, Depth(0)), Some(0));
/// assert_eq!(bot.select(&tree, Depth(1)), Some(1));
/// ```
/// [rc]: trait.RunCondition.html
;
/// A struct implementing [`IntoRunCondition`] which can be used to log a call to [`select`][sel].
/// For more details you can visit the individual methods.
///
/// # Examples
///
/// ```rust
/// # use rubot::{Bot, tree::Node, ToCompletion, Logger};
/// # use std::time::Duration;
/// let tree = Node::root().with_children(&[
/// Node::new(false, 7).with_children(&[
/// Node::new(true, 4),
/// Node::new(true, 2),
/// ]),
/// Node::new(false, 5).with_children(&[
/// Node::new(true, 8),
/// Node::new(true, 9)
/// ]),
/// ]);
///
/// let mut bot = Bot::new(true);
/// let mut logger = Logger::new(ToCompletion);
/// assert_eq!(bot.select(&tree, &mut logger), Some(1));
///
/// assert_eq!(logger.depth(), 2);
/// // the total duration of `bot.select`
/// assert!(logger.duration() < Duration::from_secs(1));
/// ```
/// [sel]: alpha_beta/struct.Bot.html#method.select
/// The [`RunCondition`][rc] created by [`Logger`][logger]`::into_run_condition`
///
/// [rc]: trait.RunCondition.html
/// [logger]: struct.Logger.html
;
pub use Bot;