solverforge_solver/heuristic/move/
either.rs1use std::fmt::Debug;
8
9use solverforge_core::domain::PlanningSolution;
10use solverforge_scoring::Director;
11
12use super::{
13 ChangeMove, Move, MoveTabuSignature, PillarChangeMove, PillarSwapMove, RuinRecreateMove,
14 SequentialCompositeMove, SwapMove,
15};
16
17#[allow(clippy::large_enum_variant)]
22pub enum ScalarMoveUnion<S, V> {
23 Change(ChangeMove<S, V>),
24 Swap(SwapMove<S, V>),
25 PillarChange(PillarChangeMove<S, V>),
26 PillarSwap(PillarSwapMove<S, V>),
27 RuinRecreate(RuinRecreateMove<S>),
28 Composite(SequentialCompositeMove<S, ScalarMoveUnion<S, V>>),
29}
30
31impl<S, V> Clone for ScalarMoveUnion<S, V>
32where
33 S: PlanningSolution,
34 V: Clone + PartialEq + Send + Sync + Debug + 'static,
35{
36 fn clone(&self) -> Self {
37 match self {
38 Self::Change(m) => Self::Change(m.clone()),
39 Self::Swap(m) => Self::Swap(*m),
40 Self::PillarChange(m) => Self::PillarChange(m.clone()),
41 Self::PillarSwap(m) => Self::PillarSwap(m.clone()),
42 Self::RuinRecreate(m) => Self::RuinRecreate(m.clone()),
43 Self::Composite(m) => Self::Composite(m.clone()),
44 }
45 }
46}
47
48impl<S, V> Debug for ScalarMoveUnion<S, V>
49where
50 S: PlanningSolution,
51 V: Clone + PartialEq + Send + Sync + Debug + 'static,
52{
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 match self {
55 Self::Change(m) => m.fmt(f),
56 Self::Swap(m) => m.fmt(f),
57 Self::PillarChange(m) => m.fmt(f),
58 Self::PillarSwap(m) => m.fmt(f),
59 Self::RuinRecreate(m) => m.fmt(f),
60 Self::Composite(m) => m.fmt(f),
61 }
62 }
63}
64
65impl<S, V> Move<S> for ScalarMoveUnion<S, V>
66where
67 S: PlanningSolution,
68 V: Clone + PartialEq + Send + Sync + Debug + 'static,
69{
70 fn is_doable<D: Director<S>>(&self, score_director: &D) -> bool {
71 match self {
72 Self::Change(m) => m.is_doable(score_director),
73 Self::Swap(m) => m.is_doable(score_director),
74 Self::PillarChange(m) => m.is_doable(score_director),
75 Self::PillarSwap(m) => m.is_doable(score_director),
76 Self::RuinRecreate(m) => m.is_doable(score_director),
77 Self::Composite(m) => m.is_doable(score_director),
78 }
79 }
80
81 fn do_move<D: Director<S>>(&self, score_director: &mut D) {
82 match self {
83 Self::Change(m) => m.do_move(score_director),
84 Self::Swap(m) => m.do_move(score_director),
85 Self::PillarChange(m) => m.do_move(score_director),
86 Self::PillarSwap(m) => m.do_move(score_director),
87 Self::RuinRecreate(m) => m.do_move(score_director),
88 Self::Composite(m) => m.do_move(score_director),
89 }
90 }
91
92 fn descriptor_index(&self) -> usize {
93 match self {
94 Self::Change(m) => m.descriptor_index(),
95 Self::Swap(m) => m.descriptor_index(),
96 Self::PillarChange(m) => m.descriptor_index(),
97 Self::PillarSwap(m) => m.descriptor_index(),
98 Self::RuinRecreate(m) => m.descriptor_index(),
99 Self::Composite(m) => m.descriptor_index(),
100 }
101 }
102
103 fn entity_indices(&self) -> &[usize] {
104 match self {
105 Self::Change(m) => m.entity_indices(),
106 Self::Swap(m) => m.entity_indices(),
107 Self::PillarChange(m) => m.entity_indices(),
108 Self::PillarSwap(m) => m.entity_indices(),
109 Self::RuinRecreate(m) => m.entity_indices(),
110 Self::Composite(m) => m.entity_indices(),
111 }
112 }
113
114 fn variable_name(&self) -> &str {
115 match self {
116 Self::Change(m) => m.variable_name(),
117 Self::Swap(m) => m.variable_name(),
118 Self::PillarChange(m) => m.variable_name(),
119 Self::PillarSwap(m) => m.variable_name(),
120 Self::RuinRecreate(m) => m.variable_name(),
121 Self::Composite(m) => m.variable_name(),
122 }
123 }
124
125 fn tabu_signature<D: Director<S>>(&self, score_director: &D) -> MoveTabuSignature {
126 match self {
127 Self::Change(m) => m.tabu_signature(score_director),
128 Self::Swap(m) => m.tabu_signature(score_director),
129 Self::PillarChange(m) => m.tabu_signature(score_director),
130 Self::PillarSwap(m) => m.tabu_signature(score_director),
131 Self::RuinRecreate(m) => m.tabu_signature(score_director),
132 Self::Composite(m) => m.tabu_signature(score_director),
133 }
134 }
135}