1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! This crate provides a framework for writing chess engines.
//!
//! # Why chess engines?
//!
//! Simple! Chess is the greatest thing humans have
//! invented. Computers follow closely ;)
//!
//! # Why a framework?
//!
//! There is lots of knowledge out there about how to write a chess
//! engine, and there is a lot of room for innovation also. Writing a
//! chess engine is fun, but even for the simplest engine there is a
//! lot of complex (and boring) things that have to be implemented
//! first: the UCI protocol communication, the rules, the static
//! exchange evaluator, and many more. Thousands of programmers have
//! been re-implementing those things over and over again.
//!
//! So, if you want to write your own chess engine, you face an
//! unpleasant choice: You either roll up your sleeves and implement
//! all the hard stuff from scratch, or you take someone else's chess
//! engine and struggle to understand its cryptic, undocumented source
//! code, hoping that it will be general enough to allow
//! modification. This unfortunate situation stifles innovation.
//!
//! # Features
//!
//! * Modular design. Users can write their own implementations for
//!   every part of the chess engine.
//!
//! * Very good default implementations — move generation,
//!   quiescence search, static exchange evaluation, time management,
//!   iterative deepening, multi-PV, aspiration windows, generic
//!   transposition table.
//!
//! * Very complete UCI support (including "searchmoves").
//!
//! # Usage
//!
//! This crate is [on crates.io](https://crates.io/crates/alcibiades)
//! and can be used by adding `alcibiades` to your dependencies in
//! your project's `Cargo.toml`.
//!
//! ```toml
//! [dependencies]
//! alcibiades = "0.3.0"
//! ```
//!
//! and this to your crate root:
//!
//! ```rust
//! extern crate alcibiades;
//! ```
//!
//! Here is how simple it is to create a chess engine using this crate:
//!
//! ```rust,no_run
//! extern crate alcibiades;
//! use alcibiades::stock::*;
//! use alcibiades::engine::run_uci;
//!
//! fn main() {
//!     type Ttable = StdTtable<StdTtableEntry>;
//!     type SearchNode = StdSearchNode<StdQsearch<StdMoveGenerator<SimpleEvaluator>>>;
//!     type SearchExecutor = Deepening<SimpleSearch<Ttable, SearchNode>>;
//!     run_uci::<SearchExecutor, StdTimeManager>("My engine", "John Doe", vec![]);
//! }
//! ```
//!
//! This engine is assembled from the "in stock" implementations of
//! the different framework traits.
//!
//! In reality, you will probably want to write your own
//! implementations for some of the framework traits. Thanks to Rust's
//! incredible generic programming capabilities, you are not limited
//! to implementing only the methods required by the traits. For
//! example you may write your own static position evaluator which has
//! a `consult_endgame_table` method. Then you will be able to write a
//! search algorithm that uses this method.
//!
//! # Speed and safety
//!
//! This crate tries to be fast *and* memory-safe.

#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate regex;
extern crate rand;

pub mod utils;
pub mod engine;
pub mod stock;
pub mod squares;
pub mod files;
pub mod ranks;
pub mod bitsets;
mod board;
mod moves;
mod value;
mod depth;
mod evaluator;
mod search_node;
mod search;
mod ttable;
mod move_generator;
mod qsearch;
mod time_manager;
mod uci;

pub use board::*;
pub use moves::*;
pub use value::*;
pub use depth::*;
pub use evaluator::*;
pub use search_node::*;
pub use search::*;
pub use ttable::*;
pub use move_generator::*;
pub use qsearch::*;
pub use time_manager::*;
pub use uci::{SetOption, OptionDescription};


use std::sync::RwLock;
use std::collections::HashMap;

lazy_static! {
    static ref CONFIGURATION: RwLock<HashMap<&'static str, String>> = RwLock::new(HashMap::new());
}

/// Returns the current value for a given configuration option.
///
/// # Panics
///
/// Panics if given invalid configuration option name.
pub fn get_option(name: &'static str) -> String {
    CONFIGURATION
        .read()
        .unwrap()
        .get(name)
        .unwrap()
        .clone()
}