Add as command line tool
This commit is contained in:
@@ -353,6 +353,36 @@ impl Board {
|
||||
fn create_move(start: &Square, target: Square) -> Move {
|
||||
Move::new(start.clone(), target)
|
||||
}
|
||||
|
||||
pub(crate) fn from_string(board_string: String) -> Option<Board> {
|
||||
if board_string.chars().count() != 16 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut board = Board::new();
|
||||
let mut file = 0;
|
||||
let mut rank = 0;
|
||||
let mut chars = board_string.chars();
|
||||
for r in 0..4 {
|
||||
for f in 0..4 {
|
||||
let c = chars.next().unwrap();
|
||||
let piece = match c {
|
||||
'K' => Piece::King,
|
||||
'Q' => Piece::Queen,
|
||||
'B' => Piece::Bishop,
|
||||
'N' => Piece::Knight,
|
||||
'R' => Piece::Rook,
|
||||
'P' => Piece::Pawn,
|
||||
'.' => continue,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let square = Square::Occupied(piece, Coord::new(f, r));
|
||||
board.set(square);
|
||||
}
|
||||
}
|
||||
Some(board)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+5
-1
@@ -12,7 +12,11 @@ impl Move {
|
||||
}
|
||||
|
||||
pub(crate) fn notation(&self) -> String {
|
||||
format!("{} -> {}", self.from.notation(), self.to.notation())
|
||||
format!(
|
||||
"{} -> {}",
|
||||
self.from.notation(),
|
||||
self.to.coord_ref().notation
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
};
|
||||
use rand::{seq::*, Rng};
|
||||
|
||||
pub(crate) fn generate() -> Option<Board> {
|
||||
pub(crate) fn generate(num_pieces: u32) -> Option<Board> {
|
||||
let mut rand = rand::thread_rng();
|
||||
let candidate_pieces = vec![
|
||||
Piece::Pawn,
|
||||
@@ -17,7 +17,6 @@ pub(crate) fn generate() -> Option<Board> {
|
||||
Piece::King,
|
||||
Piece::Queen,
|
||||
];
|
||||
let num_pieces = 7;
|
||||
let attempts = 1000;
|
||||
for i in 0..attempts {
|
||||
let board = try_generate(num_pieces, candidate_pieces.clone(), rand.clone());
|
||||
|
||||
+74
-12
@@ -7,26 +7,44 @@ mod solver;
|
||||
#[allow(unused)]
|
||||
mod generator;
|
||||
|
||||
use argh::FromArgs;
|
||||
use engine::board::Board;
|
||||
|
||||
use crate::generator::generator::generate;
|
||||
use crate::solver::solver::Solver;
|
||||
|
||||
fn main() {
|
||||
let start = std::time::Instant::now();
|
||||
let board = generate();
|
||||
let elapsed = start.elapsed();
|
||||
let args: Args = argh::from_env();
|
||||
if args.generate {
|
||||
let puzzle = generate_puzzle(args.num_pieces);
|
||||
let Some(board) = puzzle else {
|
||||
return;
|
||||
};
|
||||
|
||||
println!("Generated a problem in {} ms", elapsed.as_millis());
|
||||
println!("{}", board.print());
|
||||
|
||||
let Some(board) = board else {
|
||||
println!(
|
||||
"Failed to generate a board after {} ms, Try again",
|
||||
elapsed.as_millis()
|
||||
);
|
||||
return;
|
||||
};
|
||||
if args.print {
|
||||
solve_puzzle(board);
|
||||
}
|
||||
} else if let Some(board_string) = args.solve {
|
||||
let board = Board::from_string(board_string);
|
||||
let Some(board) = board else {
|
||||
println!("Invalid board string");
|
||||
return;
|
||||
};
|
||||
println!("{}", board.print());
|
||||
solve_puzzle(board);
|
||||
} else {
|
||||
println!("Use --help to see available options");
|
||||
}
|
||||
}
|
||||
|
||||
println!("{}", board.print());
|
||||
fn solve_puzzle(board: Board) {
|
||||
let solutions = Solver::new(board).solve();
|
||||
if solutions.len() == 0 {
|
||||
println!("No solutions found");
|
||||
return;
|
||||
}
|
||||
println!("Found {} solutions", solutions.len());
|
||||
let solution = solutions.first().unwrap();
|
||||
let mut idx = 0;
|
||||
@@ -35,3 +53,47 @@ fn main() {
|
||||
println!("{}. {}", idx, m.notation());
|
||||
});
|
||||
}
|
||||
|
||||
fn generate_puzzle(num_pieces: Option<u32>) -> Option<Board> {
|
||||
let start = std::time::Instant::now();
|
||||
let num_pieces = num_pieces.unwrap_or(5);
|
||||
let board = generate(num_pieces);
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
let Some(board) = board else {
|
||||
println!(
|
||||
"Failed to generate a puzzle with {} pieces after {} ms, Try again",
|
||||
num_pieces,
|
||||
elapsed.as_millis()
|
||||
);
|
||||
return None;
|
||||
};
|
||||
|
||||
println!(
|
||||
"Generated a puzzle with {} pieces after {} ms",
|
||||
num_pieces,
|
||||
elapsed.as_millis()
|
||||
);
|
||||
Some(board)
|
||||
}
|
||||
|
||||
/// Solitaire Chess puzzle generator and solver
|
||||
/// - v0.0.1 cool-mist
|
||||
#[derive(FromArgs)]
|
||||
struct Args {
|
||||
#[argh(switch, short = 'g')]
|
||||
/// generate a puzzle
|
||||
generate: bool,
|
||||
|
||||
#[argh(option, short = 'n')]
|
||||
/// number of pieces to place on the board while generating a puzzle
|
||||
num_pieces: Option<u32>,
|
||||
|
||||
#[argh(switch)]
|
||||
/// print the solution. When solving a puzzle, this is always set to true
|
||||
print: bool,
|
||||
|
||||
#[argh(option, short = 's')]
|
||||
/// the board to solve
|
||||
solve: Option<String>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user