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