Implement dummy chess solver
It chooses a random available move ¯\_(ツ)_/¯
This commit is contained in:
78
rs/Cargo.lock
generated
78
rs/Cargo.lock
generated
@@ -2,6 +2,84 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.112"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
"rand_hc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schach"
|
name = "schach"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rand = "0.8.4"
|
||||||
|
|||||||
@@ -247,6 +247,9 @@ impl Board {
|
|||||||
state: Default::default(),
|
state: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn occupied(&self, position: &Position) -> bool {
|
||||||
|
self.state.contains_key(position)
|
||||||
|
}
|
||||||
pub fn get_at(&self, position: &Position) -> Option<&Piece> {
|
pub fn get_at(&self, position: &Position) -> Option<&Piece> {
|
||||||
self.state.get(position)
|
self.state.get(position)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::board;
|
use crate::board;
|
||||||
|
use rand::seq::IteratorRandom;
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
board: board::Board,
|
board: board::Board,
|
||||||
@@ -21,23 +22,47 @@ impl Engine {
|
|||||||
pub fn get_legal_moves(
|
pub fn get_legal_moves(
|
||||||
&self,
|
&self,
|
||||||
position: &board::Position,
|
position: &board::Position,
|
||||||
) -> Result<Vec<board::Position>, ()> {
|
) -> Result<impl Iterator<Item = board::Position> + '_, ()> {
|
||||||
Ok(self
|
if self.board.occupied(position) {
|
||||||
.board
|
Ok(self
|
||||||
.find_moves(position)?
|
.board
|
||||||
.chain(self.board.find_captures(position)?)
|
.find_moves(position)
|
||||||
.collect())
|
.unwrap()
|
||||||
|
.chain(self.board.find_captures(position).unwrap()))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn make_move(
|
pub fn make_move(
|
||||||
&mut self,
|
&mut self,
|
||||||
source: &board::Position,
|
source: &board::Position,
|
||||||
target: board::Position,
|
target: board::Position,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
if !self.get_legal_moves(source)?.contains(&target) {
|
if !self.get_legal_moves(source)?.any(|pos| pos == target) {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
// We checked that there is a piece at source in get_legal_moves
|
// We checked that there is a piece at source in get_legal_moves
|
||||||
self.board.relocate(source, target)
|
self.board.relocate(source, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn choose_move(
|
||||||
|
&self,
|
||||||
|
color: &board::Color,
|
||||||
|
) -> Option<(board::Position, board::Position)> {
|
||||||
|
self.board
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(source, piece)| {
|
||||||
|
if &piece.color == color {
|
||||||
|
if let Ok(targets) = self.get_legal_moves(source) {
|
||||||
|
Some(targets.map(|target| (source.clone(), target)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.choose(&mut rand::thread_rng())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
extern crate rand;
|
||||||
mod board;
|
mod board;
|
||||||
mod engine;
|
mod engine;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|||||||
31
rs/src/ui.rs
31
rs/src/ui.rs
@@ -182,10 +182,9 @@ impl Ui {
|
|||||||
let error = format!("No moves possible from {}", position);
|
let error = format!("No moves possible from {}", position);
|
||||||
Err(error)
|
Err(error)
|
||||||
}
|
}
|
||||||
Ok(positions) => Ok(positions
|
Ok(positions) => {
|
||||||
.iter()
|
Ok(positions.map(|pos| format!("{}", pos)).collect())
|
||||||
.map(|pos| format!("{}", pos))
|
}
|
||||||
.collect()),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err("get_moves takes 1 arg".to_owned())
|
Err("get_moves takes 1 arg".to_owned())
|
||||||
@@ -208,6 +207,29 @@ impl Ui {
|
|||||||
Err("make_move takes 2 args".to_owned())
|
Err("make_move takes 2 args".to_owned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn choose_move(&self, args: &[&str]) -> Result<String, String> {
|
||||||
|
if let [color_str] = args {
|
||||||
|
if let [color_char] = color_str.chars().collect::<Vec<char>>()[..]
|
||||||
|
{
|
||||||
|
match self.engine.choose_move(
|
||||||
|
&board::Color::parse(color_char).map_err(|_| {
|
||||||
|
format!("Couldn't parse color code {}", color_char)
|
||||||
|
})?,
|
||||||
|
) {
|
||||||
|
Some((source, target)) => {
|
||||||
|
Ok(format!("{},{}", source, target))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
Err(format!("No move possible for {}", color_char))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(format!("Invalid color string {}", color_str))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err("choose_move takes 1 arg".to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
fn handle_command(&mut self, s: &str) -> Result<String, String> {
|
fn handle_command(&mut self, s: &str) -> Result<String, String> {
|
||||||
let mut cmd = s.split(',');
|
let mut cmd = s.split(',');
|
||||||
// There will be at least an empty string => otherwise panic
|
// There will be at least an empty string => otherwise panic
|
||||||
@@ -218,6 +240,7 @@ impl Ui {
|
|||||||
"get_moves" => self.get_moves(&args),
|
"get_moves" => self.get_moves(&args),
|
||||||
"make_move" => self.make_move(&args),
|
"make_move" => self.make_move(&args),
|
||||||
"set_state" => self.set_state(&args),
|
"set_state" => self.set_state(&args),
|
||||||
|
"choose_move" => self.choose_move(&args),
|
||||||
"" => Err("No command given".to_owned()),
|
"" => Err("No command given".to_owned()),
|
||||||
_ => Err("Invalid command".to_owned()),
|
_ => Err("Invalid command".to_owned()),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user