~ubuntu-branches/ubuntu/natty/freecell-solver/natty

« back to all changes in this revision

Viewing changes to tests.h

  • Committer: Bazaar Package Importer
  • Author(s): RISKO Gergely
  • Date: 2009-07-15 17:42:19 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090715174219-2rlyyvse0kezacly
Tags: 2.34.0-1
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * tests.h - header file of the test functions for Freecell Solver.
3
 
 *
4
 
 * The test functions code is found in freecell.c
5
 
 *
6
 
 * Written by Shlomi Fish ( http://www.shlomifish.org/ ), 2000
7
 
 *
8
 
 * This file is in the public domain (it's uncopyrighted).
9
 
 */
10
 
 
11
 
#ifndef FC_SOLVE__TESTS_H
12
 
#define FC_SOLVE__TESTS_H
13
 
 
14
 
#ifdef __cplusplus
15
 
extern "C" {
16
 
#endif
17
 
 
18
 
#include <stdlib.h>
19
 
#include <limits.h>
20
 
#include <string.h>
21
 
 
22
 
#include "fcs_isa.h"
23
 
#include "fcs.h"
24
 
 
25
 
#include "test_arr.h"
26
 
 
27
 
 
28
 
#ifdef FCS_FREECELL_ONLY
29
 
#define calc_max_sequence_move(fc_num, fs_num) (((fc_num)+1)<<(fs_num))
30
 
#else
31
 
/*
32
 
 * The number of cards that can be moved is
33
 
 * (freecells_number + 1) * 2 ^ (free_stacks_number)
34
 
 *
35
 
 * See the Freecell FAQ and the source code of PySol
36
 
 *
37
 
 * */
38
 
#define calc_max_sequence_move(fc_num, fs_num)                    \
39
 
    ((instance->unlimited_sequence_move) ?                         \
40
 
            INT_MAX :                                             \
41
 
    ((instance->empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD) ? \
42
 
                (((fc_num)+1)<<(fs_num))                        : \
43
 
        ((fc_num)+1)                                              \
44
 
    ))
45
 
#endif
46
 
 
47
 
#include "caas.h"
48
 
 
49
 
/*
50
 
 *  These are some macros to make it easier for the programmer.
51
 
 * */
52
 
#define ptr_state_key (ptr_state_key)
53
 
#define ptr_state_val (ptr_state_val)
54
 
#define state_key (*ptr_state_key)
55
 
#define state  (state_key)
56
 
#define state_val (*ptr_state_val)
57
 
#define new_state (*ptr_new_state_key)
58
 
#define new_state_key (new_state)
59
 
#define new_state_val (*ptr_new_state_val)
60
 
 
61
 
#define sfs_check_state_begin()                                                \
62
 
    fcs_state_ia_alloc_into_var(ptr_new_state_val, hard_thread);    \
63
 
    ptr_new_state_key = ptr_new_state_val->key;                     \
64
 
    fcs_duplicate_state(new_state_key, new_state_val, state_key, state_val);       \
65
 
    /* Some A* and BFS parameters that need to be initialized in               \
66
 
     * the derived state.                                                      \
67
 
     * */                                                                      \
68
 
    ptr_new_state_val->parent_val = ptr_state_val;           \
69
 
    ptr_new_state_val->moves_to_parent = moves;                     \
70
 
    /* Make sure depth is consistent with the game graph.                      \
71
 
     * I.e: the depth of every newly discovered state is derived from          \
72
 
     * the state from which it was discovered. */                              \
73
 
    ptr_new_state_val->depth = ptr_new_state_val->depth + 1; \
74
 
    /* Mark this state as a state that was not yet visited */                  \
75
 
    ptr_new_state_val->visited = 0;                                 \
76
 
    /* It's a newly created state which does not have children yet. */         \
77
 
    ptr_new_state_val->num_active_children = 0;                     \
78
 
    memset(ptr_new_state_val->scan_visited, '\0',                   \
79
 
        sizeof(ptr_new_state_val->scan_visited)                     \
80
 
        );                                                                     \
81
 
    fcs_move_stack_reset(moves);                                               \
82
 
 
83
 
#define sfs_check_state_end()                                             \
84
 
/* The last move in a move stack should be FCS_MOVE_TYPE_CANONIZE         \
85
 
 * because it indicates that the order of the stacks and freecells        \
86
 
 * need to be recalculated                                                \
87
 
 * */                                                                     \
88
 
fcs_move_set_type(temp_move,FCS_MOVE_TYPE_CANONIZE);                      \
89
 
fcs_move_stack_push(moves, temp_move);                                    \
90
 
                                                                          \
91
 
{                                                                         \
92
 
    fcs_state_extra_info_t * existing_state_val;                          \
93
 
    check = fc_solve_check_and_add_state(                                 \
94
 
        soft_thread,                                                      \
95
 
        ptr_new_state_val,                                                \
96
 
        &existing_state_val                                               \
97
 
        );                                                                \
98
 
    if ((check == FCS_STATE_BEGIN_SUSPEND_PROCESS) ||                     \
99
 
        (check == FCS_STATE_SUSPEND_PROCESS))                             \
100
 
    {                                                                     \
101
 
        /* This state is not going to be used, so                         \
102
 
         * let's clean it. */                                             \
103
 
        fcs_state_ia_release(hard_thread);                                \
104
 
        return check;                                                     \
105
 
    }                                                                     \
106
 
    else if (check == FCS_STATE_ALREADY_EXISTS)                           \
107
 
    {                                                                     \
108
 
        fcs_state_ia_release(hard_thread);                                \
109
 
        calculate_real_depth(existing_state_val);     \
110
 
        /* Re-parent the existing state to this one.                      \
111
 
         *                                                                \
112
 
         * What it means is that if the depth of the state if it          \
113
 
         * can be reached from this one is lower than what it             \
114
 
         * already have, then re-assign its parent to this state.         \
115
 
         * */                                                             \
116
 
        if (reparent &&                                                   \
117
 
           (existing_state_val->depth > ptr_state_val->depth+1))   \
118
 
        {                                                                 \
119
 
            /* Make a copy of "moves" because "moves" will be destroyed */\
120
 
            existing_state_val->moves_to_parent =                             \
121
 
                fc_solve_move_stack_compact_allocate(              \
122
 
                    hard_thread, moves                                    \
123
 
                    );                                                    \
124
 
            if (!(existing_state_val->visited & FCS_VISITED_DEAD_END))        \
125
 
            {                                                             \
126
 
                if ((--existing_state_val->parent_val->num_active_children) == 0) \
127
 
                {                                                         \
128
 
                    mark_as_dead_end(                                     \
129
 
                        existing_state_val->parent_val                    \
130
 
                        );                                                \
131
 
                }                                                         \
132
 
                ptr_state_val->num_active_children++;          \
133
 
            }                                                             \
134
 
            existing_state_val->parent_val = ptr_state_val;               \
135
 
            existing_state_val->depth = ptr_state_val->depth + 1;  \
136
 
        }                                                                 \
137
 
        fc_solve_derived_states_list_add_state(                                \
138
 
            derived_states_list,                                          \
139
 
            existing_state_val                                            \
140
 
            );                                                            \
141
 
    }                                                                     \
142
 
    else                                                                  \
143
 
    {                                                                     \
144
 
        fc_solve_derived_states_list_add_state(                                \
145
 
            derived_states_list,                                          \
146
 
            ptr_new_state_val                                             \
147
 
            );                                                            \
148
 
   }                                                                      \
149
 
}
150
 
 
151
 
 
152
 
/*
153
 
    This macro checks if the top card in the stack is a flipped card
154
 
    , and if so flips it so its face is up.
155
 
  */
156
 
#define fcs_flip_top_card(stack)                                   \
157
 
{                                                                  \
158
 
    int cards_num;                                                 \
159
 
    cards_num = fcs_stack_len(new_state,stack);                    \
160
 
                                                                   \
161
 
    if (cards_num > 0)                                             \
162
 
    {                                                              \
163
 
        if (fcs_card_get_flipped(                                  \
164
 
                fcs_stack_card(                                    \
165
 
                    new_state,                                     \
166
 
                    stack,                                         \
167
 
                    cards_num-1)                                   \
168
 
                ) == 1                                             \
169
 
           )                                                       \
170
 
        {                                                          \
171
 
            fcs_flip_stack_card(new_state,stack,cards_num-1);      \
172
 
            fcs_move_set_type(temp_move, FCS_MOVE_TYPE_FLIP_CARD); \
173
 
            fcs_move_set_src_stack(temp_move, stack);              \
174
 
                                                                   \
175
 
            fcs_move_stack_push(moves, temp_move);                 \
176
 
        }                                                          \
177
 
    }                                                              \
178
 
}
179
 
 
180
 
 
181
 
/*
182
 
 * dest is the destination stack
183
 
 * source is the source stack
184
 
 * start is the start height
185
 
 * end is the end height
186
 
 * a is the iterator
187
 
 * */
188
 
#define fcs_move_sequence(dest, source, start, end, a)              \
189
 
{                                                                   \
190
 
    for ( a = (start) ; a <= (end) ; a++)                           \
191
 
    {                                                               \
192
 
        fcs_push_stack_card_into_stack(new_state, dest, source, a); \
193
 
    }                                                               \
194
 
                                                                    \
195
 
    for ( a = (start) ; a <= (end) ; a++)                           \
196
 
    {                                                               \
197
 
        fcs_pop_stack_card(new_state, source, temp_card);           \
198
 
    }                                                               \
199
 
                                                                    \
200
 
    fcs_move_set_type(temp_move, FCS_MOVE_TYPE_STACK_TO_STACK);     \
201
 
    fcs_move_set_src_stack(temp_move, source);                      \
202
 
    fcs_move_set_dest_stack(temp_move, dest);                       \
203
 
    fcs_move_set_num_cards_in_seq(temp_move, (end)-(start)+1);      \
204
 
                                                                    \
205
 
    fcs_move_stack_push(moves, temp_move);                          \
206
 
}
207
 
 
208
 
#ifdef FCS_FREECELL_ONLY
209
 
#define tests_declare_accessors_freecell_only()
210
 
#else
211
 
#define tests_declare_accessors_freecell_only() \
212
 
    int sequences_are_built_by;  \
213
 
    int empty_stacks_fill;
214
 
#endif
215
 
 
216
 
/*
217
 
 * This test declares a few access variables that are used in all
218
 
 * the tests.
219
 
 * */
220
 
#define tests_declare_accessors()                              \
221
 
    fc_solve_hard_thread_t * hard_thread;               \
222
 
    fc_solve_instance_t * instance;                     \
223
 
    fcs_state_t * ptr_state_key; \
224
 
    fcs_state_t * ptr_new_state_key; \
225
 
    fcs_state_extra_info_t * ptr_new_state_val; \
226
 
    fcs_move_stack_t * moves;                                  \
227
 
    char * indirect_stacks_buffer;                             \
228
 
    int calc_real_depth;                                       \
229
 
    int scans_synergy;                                         \
230
 
    tests_declare_accessors_freecell_only()
231
 
 
232
 
#ifdef FCS_FREECELL_ONLY
233
 
 
234
 
#define tests_define_accessors_freecell_only() {}
235
 
 
236
 
#define tests__is_filled_by_any_card() 1
237
 
 
238
 
#define tests__is_filled_by_kings_only() 0
239
 
 
240
 
#define tests__is_filled_by_none() 0
241
 
 
242
 
#else
243
 
 
244
 
#define tests_define_accessors_freecell_only() \
245
 
{ \
246
 
    sequences_are_built_by = instance->sequences_are_built_by; \
247
 
    empty_stacks_fill = instance->empty_stacks_fill;           \
248
 
}
249
 
 
250
 
#define tests__is_filled_by_any_card() \
251
 
    (empty_stacks_fill == FCS_ES_FILLED_BY_ANY_CARD)
252
 
 
253
 
#define tests__is_filled_by_kings_only() \
254
 
    (empty_stacks_fill == FCS_ES_FILLED_BY_KINGS_ONLY)
255
 
 
256
 
#define tests__is_filled_by_none() \
257
 
    (empty_stacks_fill == FCS_ES_FILLED_BY_NONE)
258
 
 
259
 
#endif
260
 
 
261
 
/*
262
 
 * This macro defines these accessors to have some value.
263
 
 * */
264
 
#define tests_define_accessors()                                  \
265
 
    ptr_state_key = ptr_state_val->key;                           \
266
 
    hard_thread = soft_thread->hard_thread;                       \
267
 
    instance = hard_thread->instance;                             \
268
 
    moves = hard_thread->reusable_move_stack;                     \
269
 
    indirect_stacks_buffer = hard_thread->indirect_stacks_buffer; \
270
 
    calc_real_depth = instance->calc_real_depth;                  \
271
 
    scans_synergy = instance->scans_synergy;                      \
272
 
    tests_define_accessors_freecell_only()
273
 
 
274
 
extern int fc_solve_sfs_simple_simon_move_sequence_to_founds(
275
 
        fc_solve_soft_thread_t * soft_thread,
276
 
        fcs_state_extra_info_t * ptr_state_val,
277
 
        int num_freestacks,
278
 
        int num_freecells,
279
 
        fcs_derived_states_list_t * derived_states_list,
280
 
        int reparent
281
 
        );
282
 
extern int fc_solve_sfs_simple_simon_move_sequence_to_true_parent(
283
 
        fc_solve_soft_thread_t * soft_thread,
284
 
        fcs_state_extra_info_t * ptr_state_val,
285
 
        int num_freestacks,
286
 
        int num_freecells,
287
 
        fcs_derived_states_list_t * derived_states_list,
288
 
        int reparent
289
 
        );
290
 
 
291
 
extern int fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent(
292
 
        fc_solve_soft_thread_t * soft_thread,
293
 
        fcs_state_extra_info_t * ptr_state_val,
294
 
        int num_freestacks,
295
 
        int num_freecells,
296
 
        fcs_derived_states_list_t * derived_states_list,
297
 
        int reparent
298
 
        );
299
 
 
300
 
extern int fc_solve_sfs_simple_simon_move_sequence_to_true_parent_with_some_cards_above(
301
 
        fc_solve_soft_thread_t * soft_thread,
302
 
        fcs_state_extra_info_t * ptr_state_val,
303
 
        int num_freestacks,
304
 
        int num_freecells,
305
 
        fcs_derived_states_list_t * derived_states_list,
306
 
        int reparent
307
 
        );
308
 
 
309
 
extern int fc_solve_sfs_simple_simon_move_sequence_with_some_cards_above_to_true_parent(
310
 
        fc_solve_soft_thread_t * soft_thread,
311
 
        fcs_state_extra_info_t * ptr_state_val,
312
 
        int num_freestacks,
313
 
        int num_freecells,
314
 
        fcs_derived_states_list_t * derived_states_list,
315
 
        int reparent
316
 
        );
317
 
 
318
 
extern int fc_solve_sfs_simple_simon_move_sequence_with_junk_seq_above_to_true_parent_with_some_cards_above(
319
 
        fc_solve_soft_thread_t * soft_thread,
320
 
        fcs_state_extra_info_t * ptr_state_val,
321
 
        int num_freestacks,
322
 
        int num_freecells,
323
 
        fcs_derived_states_list_t * derived_states_list,
324
 
        int reparent
325
 
        );
326
 
 
327
 
extern int fc_solve_sfs_simple_simon_move_whole_stack_sequence_to_false_parent_with_some_cards_above(
328
 
        fc_solve_soft_thread_t * soft_thread,
329
 
        fcs_state_extra_info_t * ptr_state_val,
330
 
        int num_freestacks,
331
 
        int num_freecells,
332
 
        fcs_derived_states_list_t * derived_states_list,
333
 
        int reparent
334
 
        );
335
 
 
336
 
extern int fc_solve_sfs_simple_simon_move_sequence_to_parent_on_the_same_stack(
337
 
        fc_solve_soft_thread_t * soft_thread,
338
 
        fcs_state_extra_info_t * ptr_state_val,
339
 
        int num_freestacks,
340
 
        int num_freecells,
341
 
        fcs_derived_states_list_t * derived_states_list,
342
 
        int reparent
343
 
        );
344
 
 
345
 
#ifdef __cplusplus
346
 
}
347
 
#endif
348
 
 
349
 
#define my_copy_stack(idx) fcs_copy_stack(new_state_key, new_state_val, idx, indirect_stacks_buffer);
350
 
 
351
 
#endif /* FC_SOLVE__TESTS_H */