///|
/// Exact targets must be nonempty, in-bounds occupancies.
pub(all) enum Goal {
AnySingle
Exact(Position)
} derive(Debug, Eq)
///|
pub fn Board::validate_goal(self : Board, goal : Goal) -> Unit raise PegError {
match goal {
AnySingle => ()
Exact(p) =>
if p.bits == 0UL || (p.bits & self.mask) != p.bits {
raise InvalidGoal
}
}
}
///|
fn Goal::matches(self : Goal, p : Position) -> Bool {
match self {
AnySingle => p.count() == 1
Exact(q) => p == q
}
}
///|
pub fn Board::is_goal(
self : Board,
p : Position,
goal : Goal,
) -> Bool raise PegError {
self.validate(p)
self.validate_goal(goal)
goal.matches(p)
}
///|
pub fn Board::is_terminal(self : Board, p : Position) -> Bool raise PegError {
self.legal_moves(p).is_empty()
}
///|
/// Construct an exact singleton goal using public grid coordinates.
pub fn Board::goal_at(self : Board, x : Int, y : Int) -> Goal raise PegError {
match self.index(x, y) {
Some(i) => Exact({ bits: bit(i) })
None => raise InvalidGoal
}
}