Skip to main content

ProblemBuilder

Struct ProblemBuilder 

Source
pub struct ProblemBuilder<P: PieceKind, C: ColorKind> { /* private fields */ }
Expand description

Fluent builder for Problem.

Construct via Problem::builder. Every method consumes self and returns the updated builder, so calls chain. Finalise with ProblemBuilder::build.

The builder is an alternative to direct struct-literal construction of Problem; both produce the same value.

use chess_startpos_rs::{Constraint, CountOp, Problem, SquareColor};

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
enum Card { Ace, King, Queen }

let problem: Problem<Card> = Problem::builder()
    .squares(6)
    .alternating_colors(SquareColor::Light, SquareColor::Dark)
    .pieces([Card::Ace, Card::King, Card::Queen])
    .constraint(Constraint::Count { piece: Card::Ace,   op: CountOp::Eq, value: 2 })
    .constraint(Constraint::Count { piece: Card::King,  op: CountOp::Eq, value: 2 })
    .constraint(Constraint::Count { piece: Card::Queen, op: CountOp::Eq, value: 2 })
    .build();

assert_eq!(problem.count(), 90); // 6! / (2! · 2! · 2!)

Implementations§

Source§

impl<P: PieceKind, C: ColorKind> ProblemBuilder<P, C>

Source

pub fn new() -> Self

Returns a fresh empty builder.

Source

pub fn squares(self, n: usize) -> Self

Sets the board size.

Source

pub fn colors(self, colors: Vec<C>) -> Self

Sets square_colors to colors. The slice’s length should match num_squares; mismatch isn’t a build-time error but will produce empty results from the solver.

Source

pub fn alternating_colors(self, first: C, second: C) -> Self
where C: Copy,

Sets square_colors to a length-num_squares sequence alternating between first (even indices) and second (odd indices). Call after .squares(n); otherwise produces an empty colour vector.

Source

pub fn uniform_colors(self, c: C) -> Self
where C: Copy,

Sets square_colors to a length-num_squares sequence with every square coloured c. Call after .squares(n).

Source

pub fn colors_fn<F>(self, f: F) -> Self
where F: FnMut(usize) -> C,

Sets square_colors to (0..num_squares).map(f).collect(). The closure receives each 0-based square index and returns its colour. Call after .squares(n).

use chess_startpos_rs::{Problem, SquareColor};

// 6-square board split into halves: first 3 Light, last 3 Dark.
let problem: Problem<u8> = Problem::builder()
    .squares(6)
    .colors_fn(|i| if i < 3 { SquareColor::Light } else { SquareColor::Dark })
    .build();
assert_eq!(problem.square_colors.len(), 6);
Source

pub fn pieces<I: IntoIterator<Item = P>>(self, alphabet: I) -> Self

Replaces the alphabet with alphabet. Duplicates are silently deduplicated by the solver.

Source

pub fn piece(self, p: P) -> Self

Appends p to the alphabet.

Source

pub fn constraint(self, c: Constraint<P, C>) -> Self

Appends a constraint. Multiple calls AND-compose at build time.

Source

pub fn build(self) -> Problem<P, C>

Finalises into a Problem without validating it. The accumulated constraints are wrapped in Constraint::And (a single constraint is stored bare; zero constraints become And(vec![]), which is always satisfied).

To check internal consistency before solving, use try_build instead, or call Problem::validate on the returned value.

Source

pub fn try_build(self) -> Result<Problem<P, C>, ValidationError>

Like build but runs Problem::validate on the result, returning the validation error instead of the problem if it fails.

use chess_startpos_rs::{chess, Problem, SquareColor, ValidationError};

// Builder forgot to call `.alternating_colors(...)` after
// `.squares(8)`; `square_colors` ends up length 0.
// That's allowed iff no constraint references colours — but
// here we omit colours *and* don't add any constraints, so
// it's fine. Now break it by mismatching the colour vec:
let bad: Result<Problem<chess::Piece>, _> = Problem::builder()
    .squares(8)
    .colors(vec![SquareColor::Light]) // length 1, not 8
    .pieces([chess::Piece::King])
    .try_build();
assert!(matches!(
    bad,
    Err(ValidationError::ColorLengthMismatch { expected: 8, actual: 1 }),
));

Trait Implementations§

Source§

impl<P: Clone + PieceKind, C: Clone + ColorKind> Clone for ProblemBuilder<P, C>

Source§

fn clone(&self) -> ProblemBuilder<P, C>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<P: Debug + PieceKind, C: Debug + ColorKind> Debug for ProblemBuilder<P, C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<P: PieceKind, C: ColorKind> Default for ProblemBuilder<P, C>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<P, C> Freeze for ProblemBuilder<P, C>

§

impl<P, C> RefUnwindSafe for ProblemBuilder<P, C>

§

impl<P, C> Send for ProblemBuilder<P, C>
where C: Send, P: Send,

§

impl<P, C> Sync for ProblemBuilder<P, C>
where C: Sync, P: Sync,

§

impl<P, C> Unpin for ProblemBuilder<P, C>
where C: Unpin, P: Unpin,

§

impl<P, C> UnsafeUnpin for ProblemBuilder<P, C>

§

impl<P, C> UnwindSafe for ProblemBuilder<P, C>
where C: UnwindSafe, P: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.