@@ -5,6 +5,7 @@ use super::action::advance::Advance;
55use super :: action:: eat_salad:: EatSalad ;
66use super :: action:: exchange_carrots:: ExchangeCarrots ;
77use super :: action:: fall_back:: FallBack ;
8+ use super :: action:: card:: Card ;
89use super :: action:: Action ;
910use super :: board:: Board ;
1011use super :: constants:: PluginConstants ;
@@ -105,6 +106,17 @@ impl GameState {
105106 player_one_in_goal || player_two_in_goal && both_had_last_chance || rounds_exceeded
106107 }
107108
109+ pub fn possible_moves_old ( & self ) -> Vec < Move > {
110+ let mut moves = Vec :: new ( ) ;
111+
112+ moves. append ( & mut self . possible_advance_moves_old ( ) ) ;
113+ moves. append ( & mut self . possible_eat_salad_moves ( ) ) ;
114+ moves. append ( & mut self . possible_exchange_carrots_moves ( ) ) ;
115+ moves. append ( & mut self . possible_fall_back_moves ( ) ) ;
116+
117+ moves
118+ }
119+
108120 pub fn possible_moves ( & self ) -> Vec < Move > {
109121 let mut moves = Vec :: new ( ) ;
110122
@@ -146,7 +158,8 @@ impl GameState {
146158 . collect ( )
147159 }
148160
149- fn possible_advance_moves ( & self ) -> Vec < Move > {
161+ fn possible_advance_moves_old ( & self ) -> Vec < Move > {
162+
150163 let current_player = self . clone_current_player ( ) ;
151164 let max_distance =
152165 ( ( ( -1.0 + ( 1 + 8 * current_player. carrots ) as f64 ) . sqrt ( ) ) / 2.0 ) as usize ;
@@ -189,6 +202,79 @@ impl GameState {
189202 . collect ( )
190203 }
191204
205+ fn possible_advance_moves ( & self ) -> Vec < Move > {
206+
207+ let current_player = self . clone_current_player ( ) ;
208+ let max_distance =
209+ ( ( ( -1.0 + ( 1 + 8 * current_player. carrots ) as f64 ) . sqrt ( ) ) / 2.0 ) as usize ;
210+
211+
212+ let mut card_permutations = Vec :: new ( ) ;
213+
214+ for k in 0 ..=current_player. cards . len ( ) {
215+ for permutation in current_player. cards . iter ( ) . permutations ( k) . unique ( ) {
216+
217+ // change permutation cards to owned
218+ let owned_permutation: Vec < Card > = permutation. iter ( ) . map ( |& card| * card) . collect ( ) ;
219+
220+ // if minimum one card in permutation, save permutation and add all market cards to it
221+ if !owned_permutation. is_empty ( ) {
222+ card_permutations. push ( owned_permutation. clone ( ) ) ;
223+
224+ for card in PluginConstants :: MARKET_SELECTION {
225+ let mut extended_permutation = owned_permutation. clone ( ) ;
226+ extended_permutation. push ( card) ; // card is already owned
227+ card_permutations. push ( extended_permutation) ;
228+ }
229+ }
230+ }
231+ }
232+
233+ let mut moves: Vec < Move > = Vec :: new ( ) ;
234+
235+ for distance in 1 ..=max_distance {
236+ // destination of advance
237+ let target_pos: usize = current_player. position + distance;
238+
239+ // out of range, skip
240+ if target_pos > self . board . track . len ( ) - 1 {
241+ continue ;
242+ }
243+
244+ // destination field of advance
245+ let target_field: Field = self . board . track [ target_pos] ;
246+
247+ // add card / no card advances for each field type
248+ match target_field {
249+ Field :: Hare => {
250+ for permutation in & card_permutations {
251+ moves. push ( Move :: new ( Action :: Advance ( Advance :: new (
252+ distance,
253+ permutation. to_vec ( ) ,
254+ ) ) ) ) ;
255+ }
256+ } ,
257+ Field :: Market => {
258+ for card in PluginConstants :: MARKET_SELECTION {
259+ moves. push ( Move :: new ( Action :: Advance ( Advance :: new (
260+ distance,
261+ vec ! [ card] ,
262+ ) ) ) ) ;
263+ }
264+ } ,
265+ _ => {
266+ moves. push ( Move :: new ( Action :: Advance ( Advance :: new ( distance, vec ! [ ] ) ) ) ) ;
267+ }
268+ }
269+ }
270+
271+ moves
272+ . into_iter ( )
273+ . unique ( )
274+ . filter ( |m| m. perform ( & mut self . clone ( ) ) . is_ok ( ) )
275+ . collect ( )
276+ }
277+
192278 pub fn __repr__ ( & self ) -> String {
193279 format ! ( "{:?}" , self )
194280 }
0 commit comments