1 // This file is part of Freecell Solver. It is subject to the license terms in
2 // the COPYING.txt file found in the top-level directory of this distribution
3 // and at http://fc-solve.shlomifish.org/docs/distro/COPYING.html . No part of
4 // Freecell Solver, including this file, may be copied, modified, propagated,
5 // or distributed except according to the terms contained in the COPYING file.
6 //
7 // Copyright (c) 2000 Shlomi Fish
8 
9 #pragma once
10 #include "freecell.h"
11 #include "meta_move_funcs_helpers.h"
12 
13 #ifdef FCS_ZERO_FREECELLS_MODE
DECLARE_MOVE_FUNCTION(fc_solve_sfs_zerofc_0AB_atomic_all_moves)14 DECLARE_MOVE_FUNCTION(fc_solve_sfs_zerofc_0AB_atomic_all_moves)
15 {
16     MOVE_FUNCS__define_common();
17     STACKS__SET_PARAMS();
18 
19     for (stack_i stack_idx = 0; stack_idx < LOCAL_STACKS_NUM; stack_idx++)
20     {
21         var_AUTO(col, fcs_state_get_col(state_key, stack_idx));
22         const size_t cards_num = fcs_col_len(col);
23         if (!cards_num)
24         {
25             continue;
26         }
27         // Get the top card in the stack
28         const fcs_card card = fcs_col_get_card(col, cards_num - 1);
29         for (size_t deck = 0; deck < INSTANCE_DECKS_NUM; deck++)
30         {
31             if (fcs_foundation_value(state_key,
32                     deck * 4 + fcs_card_suit(card)) != fcs_card_rank(card) - 1)
33             {
34                 continue;
35             }
36             sfs_check_state_begin();
37 
38             my_copy_stack(stack_idx);
39             fcs_state_pop_col_top(&new_state_key, stack_idx);
40             fcs_increment_foundation(
41                 new_state_key, deck * 4 + fcs_card_suit(card));
42 
43             fcs_move_stack_non_seq_push(moves,
44                 FCS_MOVE_TYPE_STACK_TO_FOUNDATION, stack_idx,
45                 deck * 4 + fcs_card_suit(card));
46 
47             sfs_check_state_end();
48             break;
49         }
50     }
51     const int num_cards_in_col_threshold = CALC_num_cards_in_col_threshold();
52     if (IS_FILLED_BY_NONE())
53     {
54         goto after_empty;
55     }
56     if (soft_thread->num_vacant_stacks == 0)
57     {
58         goto after_empty;
59     }
60     SET_empty_stack_idx(empty_stack_idx);
61 
62     for (stack_i stack_idx = 0; stack_idx < LOCAL_STACKS_NUM; stack_idx++)
63     {
64         var_AUTO(col, fcs_state_get_col(state_key, stack_idx));
65         const int cards_num = fcs_col_len(col);
66 
67         // Bug fix: if there's only one card in a column, there's no
68         // point moving it to a new empty column.
69         if (cards_num <= 1)
70         {
71             continue;
72         }
73         const fcs_card card = fcs_col_get_card(col, cards_num - 1);
74 
75         if (IS_FILLED_BY_KINGS_ONLY() && (!fcs_card_is_king(card)))
76         {
77             continue;
78         }
79         sfs_check_state_begin();
80         copy_two_stacks(stack_idx, empty_stack_idx);
81         fcs_state_pop_col_top(&new_state_key, stack_idx);
82         fcs_state_push(&new_state_key, empty_stack_idx, card);
83         fcs_push_1card_seq(moves, stack_idx, empty_stack_idx);
84 
85         sfs_check_state_end();
86     }
87 after_empty:
88 
89     for (stack_i stack_idx = 0; stack_idx < LOCAL_STACKS_NUM; stack_idx++)
90     {
91         var_AUTO(col, fcs_state_get_col(state_key, stack_idx));
92         const int cards_num = fcs_col_len(col);
93 
94         if (cards_num <= num_cards_in_col_threshold)
95         {
96             continue;
97         }
98         const fcs_card card = fcs_col_get_card(col, cards_num - 1);
99 
100         for (int ds = 0; ds < LOCAL_STACKS_NUM; ds++)
101         {
102             if ((stack_i)ds == stack_idx)
103             {
104                 continue;
105             }
106 
107             var_AUTO(dest_col, fcs_state_get_col(state_key, ds));
108             const int dest_cards_num = fcs_col_len(dest_col);
109 
110             if (!dest_cards_num)
111             {
112                 continue;
113             }
114             const fcs_card dest_card =
115                 fcs_col_get_card(dest_col, fcs_col_len(dest_col) - 1);
116             if (!fcs_is_parent_card(card, dest_card))
117             {
118                 continue;
119             }
120             sfs_check_state_begin();
121             copy_two_stacks(stack_idx, ds);
122             fcs_state_pop_col_top(&new_state_key, stack_idx);
123             fcs_state_push(&new_state_key, (stack_i)ds, card);
124             fcs_push_1card_seq(moves, stack_idx, (stack_i)ds);
125 
126             sfs_check_state_end();
127         }
128     }
129 }
130 #endif
131