uci: start working on interface
This commit is contained in:
parent
7d83efe953
commit
d72042e455
95
Cargo.lock
generated
95
Cargo.lock
generated
|
@ -8,6 +8,14 @@ dependencies = [
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -25,7 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -47,7 +55,7 @@ name = "getrandom"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -60,11 +68,44 @@ dependencies = [
|
||||||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexical-core"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.71"
|
version = "0.2.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nodrop"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "5.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lexical-core 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -107,6 +148,37 @@ dependencies = [
|
||||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -130,6 +202,7 @@ name = "vatu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -138,6 +211,11 @@ name = "vec_map"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
@ -164,22 +242,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
|
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
||||||
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
||||||
"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||||
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||||
"checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
|
"checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
|
||||||
|
"checksum lexical-core 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f86d66d380c9c5a685aaac7a11818bdfa1f733198dfd9ec09c70b762cd12ad6f"
|
||||||
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
||||||
|
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||||
|
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
"checksum nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
|
||||||
"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||||
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||||
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||||
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||||
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
|
@ -6,4 +6,5 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
|
nom = "5"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
|
60
src/board.rs
60
src/board.rs
|
@ -75,6 +75,7 @@ pub fn pos(s: &str) -> Pos {
|
||||||
/// defining the state of the square.
|
/// defining the state of the square.
|
||||||
pub type Board = [u8; 64];
|
pub type Board = [u8; 64];
|
||||||
|
|
||||||
|
/// Generate the board of a new game.
|
||||||
pub fn new() -> Board {
|
pub fn new() -> Board {
|
||||||
[
|
[
|
||||||
/* 1 2 3 4 5 6 7 8 */
|
/* 1 2 3 4 5 6 7 8 */
|
||||||
|
@ -89,10 +90,47 @@ pub fn new() -> Board {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate an empty board.
|
||||||
pub fn new_empty() -> Board {
|
pub fn new_empty() -> Board {
|
||||||
[SQ_E; 64]
|
[SQ_E; 64]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FEN_START: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
||||||
|
|
||||||
|
/// Generate a board from a FEN string.
|
||||||
|
///
|
||||||
|
/// This will only parse the first FEN field.
|
||||||
|
pub fn new_from_fen(fen: &str) -> Board {
|
||||||
|
let mut board = [SQ_E; 64];
|
||||||
|
let mut f = 0;
|
||||||
|
let mut r = 7;
|
||||||
|
for c in fen.chars() {
|
||||||
|
match c {
|
||||||
|
'r' => { set_square(&mut board, &(f, r), SQ_BL_R); f += 1 }
|
||||||
|
'n' => { set_square(&mut board, &(f, r), SQ_BL_N); f += 1 }
|
||||||
|
'b' => { set_square(&mut board, &(f, r), SQ_BL_B); f += 1 }
|
||||||
|
'q' => { set_square(&mut board, &(f, r), SQ_BL_Q); f += 1 }
|
||||||
|
'k' => { set_square(&mut board, &(f, r), SQ_BL_K); f += 1 }
|
||||||
|
'p' => { set_square(&mut board, &(f, r), SQ_BL_P); f += 1 }
|
||||||
|
'R' => { set_square(&mut board, &(f, r), SQ_WH_R); f += 1 }
|
||||||
|
'N' => { set_square(&mut board, &(f, r), SQ_WH_N); f += 1 }
|
||||||
|
'B' => { set_square(&mut board, &(f, r), SQ_WH_B); f += 1 }
|
||||||
|
'Q' => { set_square(&mut board, &(f, r), SQ_WH_Q); f += 1 }
|
||||||
|
'K' => { set_square(&mut board, &(f, r), SQ_WH_K); f += 1 }
|
||||||
|
'P' => { set_square(&mut board, &(f, r), SQ_WH_P); f += 1 }
|
||||||
|
'/' => { f = 0; r -= 1; }
|
||||||
|
d if d.is_digit(10) => { f += d.to_digit(10).unwrap() as i8 }
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
board
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true of both boards are equal.
|
||||||
|
pub fn eq(b1: &Board, b2: &Board) -> bool {
|
||||||
|
b1.iter().zip(b2.iter()).all(|(a, b)| a == b)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_square(board: &Board, coords: &Pos) -> u8 {
|
pub fn get_square(board: &Board, coords: &Pos) -> u8 {
|
||||||
board[(coords.0 * 8 + coords.1) as usize]
|
board[(coords.0 * 8 + coords.1) as usize]
|
||||||
|
@ -109,7 +147,9 @@ pub fn clear_square(board: &mut Board, coords: &Pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_empty(board: &Board, coords: &Pos) -> bool { get_square(board, coords) == SQ_E }
|
pub fn is_empty(board: &Board, coords: &Pos) -> bool {
|
||||||
|
get_square(board, coords) == SQ_E
|
||||||
|
}
|
||||||
|
|
||||||
/// Count number of pieces on board
|
/// Count number of pieces on board
|
||||||
pub fn num_pieces(board: &Board) -> u8 {
|
pub fn num_pieces(board: &Board) -> u8 {
|
||||||
|
@ -192,6 +232,24 @@ mod tests {
|
||||||
assert_eq!(pos("h8"), (7, 7));
|
assert_eq!(pos("h8"), (7, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_from_fen() {
|
||||||
|
let b1 = new();
|
||||||
|
let b2 = new_from_fen(FEN_START);
|
||||||
|
assert!(eq(&b1, &b2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_eq() {
|
||||||
|
let mut b1 = new();
|
||||||
|
let b2 = new();
|
||||||
|
assert!(eq(&b1, &b2));
|
||||||
|
set_square(&mut b1, &pos("a1"), SQ_E);
|
||||||
|
assert!(!eq(&b1, &b2));
|
||||||
|
set_square(&mut b1, &pos("a1"), SQ_WH_R);
|
||||||
|
assert!(eq(&b1, &b2));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_square() {
|
fn test_get_square() {
|
||||||
let b = new();
|
let b = new();
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -5,6 +5,7 @@ use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
pub mod board;
|
pub mod board;
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod rules;
|
pub mod rules;
|
||||||
|
pub mod uci;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("Vatu")
|
let matches = App::new("Vatu")
|
||||||
|
@ -15,10 +16,16 @@ fn main() {
|
||||||
.help("Color for the player")
|
.help("Color for the player")
|
||||||
.short("c").long("color").takes_value(true).required(false)
|
.short("c").long("color").takes_value(true).required(false)
|
||||||
.possible_values(&["w", "white", "b", "black"])))
|
.possible_values(&["w", "white", "b", "black"])))
|
||||||
|
.subcommand(SubCommand::with_name("uci")
|
||||||
|
.about("Start engine in UCI mode")
|
||||||
|
.arg(Arg::with_name("output")
|
||||||
|
.help("Log file path")
|
||||||
|
.short("o").long("output").takes_value(true).required(false)))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
process::exit(match matches.subcommand() {
|
process::exit(match matches.subcommand() {
|
||||||
("cli", Some(a)) => cmd_cli(a),
|
("cli", Some(a)) => cmd_cli(a),
|
||||||
|
("uci", Some(a)) => cmd_uci(a),
|
||||||
_ => 0,
|
_ => 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -39,3 +46,9 @@ fn cmd_cli(args: &ArgMatches) -> i32 {
|
||||||
cli::start_game(color);
|
cli::start_game(color);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmd_uci(args: &ArgMatches) -> i32 {
|
||||||
|
let output = args.value_of("output");
|
||||||
|
uci::start(output);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
17
src/notation.rs
Normal file
17
src/notation.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//! Functions using various notations.
|
||||||
|
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
/// FEN notation for positions, split into fields.
|
||||||
|
pub struct Fen {
|
||||||
|
placement: String,
|
||||||
|
color: String,
|
||||||
|
castling: String,
|
||||||
|
en_passant: String,
|
||||||
|
halfmove: String,
|
||||||
|
fullmove: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_fen(i: &str) -> IResult<&str, Fen> {
|
||||||
|
|
||||||
|
}
|
146
src/uci.rs
Normal file
146
src/uci.rs
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
//! UCI management.
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
use nom::IResult;
|
||||||
|
use nom::branch::alt;
|
||||||
|
use nom::character::is_space;
|
||||||
|
use nom::bytes::complete::{tag, take_while};
|
||||||
|
|
||||||
|
use crate::board;
|
||||||
|
|
||||||
|
const VATU_NAME: &str = env!("CARGO_PKG_NAME");
|
||||||
|
const VATU_AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
|
||||||
|
|
||||||
|
/// Hold some values related to UCI comms.
|
||||||
|
pub struct Uci {
|
||||||
|
state: State,
|
||||||
|
board: board::Board,
|
||||||
|
logfile: Option<fs::File>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Internal UCI state.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum State {
|
||||||
|
Init,
|
||||||
|
Ready,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UCI remote commands, received by engine.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum RemoteCmd {
|
||||||
|
Uci,
|
||||||
|
IsReady,
|
||||||
|
UciNewGame,
|
||||||
|
Stop,
|
||||||
|
Position(String),
|
||||||
|
Quit,
|
||||||
|
Unknown(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Uci {
|
||||||
|
fn listen(&mut self) {
|
||||||
|
loop {
|
||||||
|
if let Some(cmd) = self.receive() {
|
||||||
|
match parse_command(&cmd) {
|
||||||
|
Ok((_, cmd)) => {
|
||||||
|
if !self.handle_command(&cmd) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.log(format!("Unknown command: {}", cmd))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&mut self, s: String) {
|
||||||
|
match self.logfile.as_ref() {
|
||||||
|
Some(mut f) => {
|
||||||
|
f.write_all(s.as_bytes()).ok();
|
||||||
|
f.write_all("\n".as_bytes()).ok();
|
||||||
|
f.flush().ok();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
eprintln!("{}", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a command from the interface.
|
||||||
|
fn receive(&mut self) -> Option<String> {
|
||||||
|
let mut s = String::new();
|
||||||
|
match io::stdin().read_line(&mut s) {
|
||||||
|
Ok(_) => { self.log(format!(">>> {}", s.trim_end())); Some(s.trim().to_string()) }
|
||||||
|
Err(e) => { self.log(format!("Failed to read input: {:?}", e)); None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send replies to the interface.
|
||||||
|
fn send(&mut self, s: &str) {
|
||||||
|
self.log(format!("<<< {}", s));
|
||||||
|
println!("{}", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle a remote command, return false if engine should stop listening.
|
||||||
|
fn handle_command(&mut self, cmd: &RemoteCmd) -> bool {
|
||||||
|
match cmd {
|
||||||
|
RemoteCmd::Uci => if self.state == State::Init { self.identify(); },
|
||||||
|
RemoteCmd::IsReady => if self.state == State::Ready { self.ready() },
|
||||||
|
RemoteCmd::UciNewGame => if self.state == State::Ready { /* Nothing to do. */ },
|
||||||
|
RemoteCmd::Stop => if self.state == State::Ready { /* Nothing to do. */ },
|
||||||
|
RemoteCmd::Quit => return false,
|
||||||
|
_ => { self.log(format!("Unknown command: {:?}", cmd)); }
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send IDs to interface.
|
||||||
|
fn identify(&mut self) {
|
||||||
|
self.send(&format!("id name {}", VATU_NAME));
|
||||||
|
self.send(&format!("id author {}", VATU_AUTHORS));
|
||||||
|
self.send("uciok");
|
||||||
|
self.state = State::Ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ready(&mut self) {
|
||||||
|
self.send("readyok");
|
||||||
|
self.state = State::Ready;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start UCI I/O.
|
||||||
|
pub fn start(output: Option<&str>) {
|
||||||
|
let mut uci = Uci {
|
||||||
|
state: State::Init,
|
||||||
|
board: board::new_empty(),
|
||||||
|
logfile: None
|
||||||
|
};
|
||||||
|
if let Some(output) = output {
|
||||||
|
match fs::File::create(output) {
|
||||||
|
Ok(f) => { uci.logfile = Some(f) }
|
||||||
|
Err(e) => { eprintln!("Could not open log file: {}", e) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uci.listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take_non_space(i: &str) -> IResult<&str, &str> {
|
||||||
|
take_while(|c| c != ' ')(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_command(i: &str) -> IResult<&str, RemoteCmd> {
|
||||||
|
let (i, cmd) = take_non_space(i)?;
|
||||||
|
match cmd {
|
||||||
|
"uci" => Ok((i, RemoteCmd::Uci)),
|
||||||
|
"isready" => Ok((i, RemoteCmd::IsReady)),
|
||||||
|
"ucinewgame" => Ok((i, RemoteCmd::UciNewGame)),
|
||||||
|
"stop" => Ok((i, RemoteCmd::Stop)),
|
||||||
|
"position" => Ok((i, RemoteCmd::Position(i.trim().to_string()))),
|
||||||
|
"quit" => Ok((i, RemoteCmd::Quit)),
|
||||||
|
c => Ok((i, RemoteCmd::Unknown(c.to_string()))),
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue