Enum open_ttt_lib::ai::Difficulty [−][src]
Expand description
Selects the difficulty used by the Opponent
.
The exact behavior of Easy
, Medium
, and Hard
difficulties are set via
play testing and are subject to adjustment in future library versions.
Variants
The Opponent
picks random positions and does not actually evaluate the
game.
Intended for players who are new to tic-tac-toe to learn the rules of
the game. The Opponent
mostly picks random squares, but occasionally
goes for the win or blocks the player from winning.
Medium difficulty is for players who have some experience with tic-tac-toe. The AI provides a challenge to the player but games are still winnable, especially if the player plans several moves ahead.
At hard difficulty the computer plays almost perfect games. The player must capitalize on rare mistakes made by the computer to win. This is the recommended difficulty for experienced tic-tac-toe players.
The Opponent
plays perfect games and cannot be defeated. The best outcome
for the player is a cat’s game.
Provides full control over the Opponent
’s difficulty via the provided
function.
The AI algorithm selects a free position then traverses the tree of all
possible moves looking for one of the end game conditions: win, loss,
or cat’s game. The provided function is invoked before processing each
node in the outcome tree. Return true
to evaluate the node. Return
false
to stop processing the node, and all child nodes thus preventing
the algorithm from considering the outcomes from that branch of the tree.
The depth of the node being considered is provided as the function’s
parameter so the custom difficulty can take into account how many moves
ahead the Opponent
is looking. E.g. the Opponent
could be more
likely to make mistakes the farther ahead it looks. The depth starts at
zero.
Notes
- The number of nodes to evaluate for a game can be large resulting in the provided function being invoked many times when evaluating a game.
- The AI algorithms contain speed optimizations that might skip evaluating part or all of the outcome tree. In these cases the provided function is not called.
Examples
Implement custom difficulties with the same behavior as the None
and
Unbeatable
variants:
use open_ttt_lib::ai; let same_as_none = ai::Difficulty::Custom(|_| false); let same_as_unbeatable = ai::Difficulty::Custom(|_| true);
Create a custom difficulty that is perfect when looking at the current move and has a fixed probability of failing to consider deeper parts of the tree.
use rand::Rng; use open_ttt_lib::ai; fn should_evaluate_node(depth: i32) -> bool { if depth == 0 { true } else { let evaluate_node_probability = 0.8; rand::thread_rng().gen_bool(evaluate_node_probability) } } let custom_difficulty = ai::Difficulty::Custom(should_evaluate_node);
Trait Implementations
impl Clone for Difficulty
[src]
impl Clone for Difficulty
[src]fn clone(&self) -> Difficulty
[src]
fn clone(&self) -> Difficulty
[src]Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]Performs copy-assignment from source
. Read more
impl Debug for Difficulty
[src]
impl Debug for Difficulty
[src]impl Hash for Difficulty
[src]
impl Hash for Difficulty
[src]impl PartialEq<Difficulty> for Difficulty
[src]
impl PartialEq<Difficulty> for Difficulty
[src]fn eq(&self, other: &Difficulty) -> bool
[src]
fn eq(&self, other: &Difficulty) -> bool
[src]This method tests for self
and other
values to be equal, and is used
by ==
. Read more
fn ne(&self, other: &Difficulty) -> bool
[src]
fn ne(&self, other: &Difficulty) -> bool
[src]This method tests for !=
.
impl Copy for Difficulty
[src]
impl StructuralPartialEq for Difficulty
[src]
Auto Trait Implementations
impl RefUnwindSafe for Difficulty
impl Send for Difficulty
impl Sync for Difficulty
impl Unpin for Difficulty
impl UnwindSafe for Difficulty
Blanket Implementations
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]pub fn borrow_mut(&mut self) -> &mut T
[src]
pub fn borrow_mut(&mut self) -> &mut T
[src]Mutably borrows from an owned value. Read more
impl<T> ToOwned for T where
T: Clone,
[src]
impl<T> ToOwned for T where
T: Clone,
[src]type Owned = T
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn to_owned(&self) -> T
[src]Creates owned data from borrowed data, usually by cloning. Read more
pub fn clone_into(&self, target: &mut T)
[src]
pub fn clone_into(&self, target: &mut T)
[src]🔬 This is a nightly-only experimental API. (toowned_clone_into
)
recently added
Uses borrowed data to replace owned data, usually by cloning. Read more
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,