use crate::scope::SolverScope;
use solverforge_core::domain::{PlanningSolution, SolutionDescriptor};
use solverforge_core::score::SoftScore;
use solverforge_scoring::director::score_director::ScoreDirector;
use std::any::TypeId;
pub use solverforge_test::nqueens::{
calculate_conflicts, create_nqueens_descriptor, get_queen_row, set_queen_row, NQueensSolution,
Queen,
};
#[derive(Clone, Debug)]
pub struct TestSolution {
pub score: Option<SoftScore>,
}
impl TestSolution {
pub fn new() -> Self {
Self { score: None }
}
pub fn with_score(score: SoftScore) -> Self {
Self { score: Some(score) }
}
}
impl Default for TestSolution {
fn default() -> Self {
Self::new()
}
}
impl PlanningSolution for TestSolution {
type Score = SoftScore;
fn score(&self) -> Option<Self::Score> {
self.score
}
fn set_score(&mut self, score: Option<Self::Score>) {
self.score = score;
}
}
pub type TestDirector = ScoreDirector<TestSolution, ()>;
pub fn create_minimal_descriptor() -> SolutionDescriptor {
SolutionDescriptor::new("TestSolution", TypeId::of::<TestSolution>())
}
pub fn create_minimal_director() -> TestDirector {
let solution = TestSolution::new();
let descriptor = create_minimal_descriptor();
ScoreDirector::simple(solution, descriptor, |_, _| 0)
}
pub fn create_nqueens_director(rows: &[i64]) -> ScoreDirector<NQueensSolution, ()> {
let solution = NQueensSolution::with_rows(rows);
let descriptor = create_nqueens_descriptor();
ScoreDirector::simple(solution, descriptor, |s, _| s.queens.len())
}
pub fn create_simple_nqueens_director(n: usize) -> ScoreDirector<NQueensSolution, ()> {
let solution = NQueensSolution::uninitialized(n);
let descriptor = create_nqueens_descriptor();
ScoreDirector::simple(solution, descriptor, |s, _| s.queens.len())
}
pub fn create_scope() -> SolverScope<'static, TestSolution, TestDirector> {
let desc = create_minimal_descriptor();
let director = ScoreDirector::simple(TestSolution::new(), desc, |_, _| 0);
SolverScope::new(director)
}
pub fn create_test_scope() -> SolverScope<'static, TestSolution, TestDirector> {
create_scope()
}
pub fn create_scope_with_score(
score: SoftScore,
) -> SolverScope<'static, TestSolution, TestDirector> {
let desc = create_minimal_descriptor();
let solution = TestSolution::with_score(score);
let director = ScoreDirector::simple(solution.clone(), desc, |_, _| 0);
let mut scope = SolverScope::new(director);
scope.set_best_solution(solution, score);
scope
}
pub fn create_test_scope_with_score(
score: SoftScore,
) -> SolverScope<'static, TestSolution, TestDirector> {
create_scope_with_score(score)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_solution_creation() {
let s1 = TestSolution::new();
assert!(s1.score.is_none());
let s2 = TestSolution::with_score(SoftScore::of(-5));
assert_eq!(s2.score, Some(SoftScore::of(-5)));
}
#[test]
fn test_create_scope() {
let scope = create_scope();
assert_eq!(scope.total_step_count(), 0);
}
#[test]
fn test_create_test_scope_alias() {
let scope = create_test_scope();
assert_eq!(scope.total_step_count(), 0);
}
#[test]
fn test_create_scope_with_score() {
let scope = create_scope_with_score(SoftScore::of(-10));
assert!(scope.best_solution().is_some());
assert_eq!(scope.best_score(), Some(&SoftScore::of(-10)));
}
#[test]
fn test_create_test_scope_with_score_alias() {
let scope = create_test_scope_with_score(SoftScore::of(-10));
assert!(scope.best_solution().is_some());
assert_eq!(scope.best_score(), Some(&SoftScore::of(-10)));
}
}