~keith-penguin/kdegames/trunk

« back to all changes in this revision

Viewing changes to kpat/patsolve/golf.cpp

  • Committer: Keith Worrell
  • Date: 2009-03-18 05:35:28 UTC
  • Revision ID: keith.worrell@gmail.com-20090318053528-mx6x9c0ngmg0kg6p
imported project

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Common routines & arrays. */
 
2
 
 
3
#include "golf.h"
 
4
#include "../golf.h"
 
5
#include "../pile.h"
 
6
#include "../deck.h"
 
7
 
 
8
#include <cstdio>
 
9
#include <cstdlib>
 
10
#include <cstring>
 
11
#include <cctype>
 
12
#include <cmath>
 
13
#include <sys/types.h>
 
14
#include <cstdarg>
 
15
 
 
16
#include <kdebug.h>
 
17
 
 
18
#define PRINT 0
 
19
#define PRINT2 0
 
20
 
 
21
void GolfSolver::make_move(MOVE *m)
 
22
{
 
23
#if PRINT
 
24
    if ( m->totype == O_Type )
 
25
        fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
 
26
    else
 
27
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
 
28
    print_layout();
 
29
#else
 
30
    //print_layout();
 
31
#endif
 
32
 
 
33
    int from = m->from;
 
34
    int to = m->to;
 
35
 
 
36
    Q_ASSERT( to == 7 );
 
37
    Q_ASSERT( from != 7 );
 
38
 
 
39
    // move to pile
 
40
    if ( from == 8 && to == 7 )
 
41
    {
 
42
        card_t card = *Wp[8];
 
43
        Wp[8]--;
 
44
        Wlen[8]--;
 
45
        card = ( SUIT( card ) << 4 ) + RANK( card );
 
46
        Wp[7]++;
 
47
        *Wp[7] = card;
 
48
        Wlen[7]++;
 
49
        hashpile( 7 );
 
50
        hashpile( 8 );
 
51
#if PRINT
 
52
        print_layout();
 
53
#endif
 
54
        return;
 
55
    }
 
56
 
 
57
    card_t card = *Wp[from];
 
58
    Wp[from]--;
 
59
    Wlen[from]--;
 
60
 
 
61
    Wp[to]++;
 
62
    *Wp[to] = card;
 
63
    Wlen[to]++;
 
64
 
 
65
    hashpile(from);
 
66
    hashpile(to);
 
67
#if PRINT
 
68
    print_layout();
 
69
#endif
 
70
}
 
71
 
 
72
void GolfSolver::undo_move(MOVE *m)
 
73
{
 
74
#if PRINT
 
75
    if ( m->totype == O_Type )
 
76
        fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
 
77
    else
 
78
        fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
 
79
    print_layout();
 
80
 
 
81
#endif
 
82
 
 
83
    int from = m->from;
 
84
    int to = m->to;
 
85
 
 
86
    Q_ASSERT( to == 7 );
 
87
    Q_ASSERT( from != 7 );
 
88
 
 
89
    // move to pile
 
90
    if ( from == 8 && to == 7 )
 
91
    {
 
92
        card_t card = *Wp[7];
 
93
        Wp[7]--;
 
94
        Wlen[7]--;
 
95
        card = ( SUIT( card ) << 4 ) + RANK( card ) + ( 1 << 7 );
 
96
        Wp[8]++;
 
97
        *Wp[8] = card;
 
98
        Wlen[8]++;
 
99
        hashpile( 7 );
 
100
        hashpile( 8 );
 
101
#if PRINT
 
102
        print_layout();
 
103
#endif
 
104
        return;
 
105
    }
 
106
 
 
107
    card_t card = *Wp[to];
 
108
    Wp[to]--;
 
109
    Wlen[to]--;
 
110
 
 
111
    Wp[from]++;
 
112
    *Wp[from] = card;
 
113
    Wlen[from]++;
 
114
 
 
115
    hashpile(from);
 
116
    hashpile(to);
 
117
#if PRINT
 
118
    print_layout();
 
119
#endif
 
120
}
 
121
 
 
122
/* Get the possible moves from a position, and store them in Possible[]. */
 
123
 
 
124
int GolfSolver::get_possible_moves(int *a, int *numout)
 
125
{
 
126
    int n = 0;
 
127
    MOVE *mp = Possible;
 
128
 
 
129
    *a = false;
 
130
    *numout = 0;
 
131
 
 
132
    card_t top = *Wp[7];
 
133
    for (int w = 0; w < 7; w++) {
 
134
        if (Wlen[w] > 0) {
 
135
            card_t card = *Wp[w];
 
136
            if (RANK(card) == RANK(top) - 1 ||
 
137
                RANK(card) == RANK(top) + 1 )
 
138
            {
 
139
                mp->card_index = 0;
 
140
                mp->from = w;
 
141
                mp->to = 7;
 
142
                mp->totype = W_Type;
 
143
                mp->pri = 13;
 
144
                if ( RANK( card ) == PS_ACE || RANK( card ) == PS_KING )
 
145
                    mp->pri = 30;
 
146
                mp->turn_index = -1;
 
147
                n++;
 
148
                mp++;
 
149
            }
 
150
        }
 
151
    }
 
152
 
 
153
    /* check for deck->pile */
 
154
    if ( !n && Wlen[8] ) {
 
155
        mp->card_index = 1;
 
156
        mp->from = 8;
 
157
        mp->to = 7;
 
158
        mp->totype = W_Type;
 
159
        mp->pri = 5;
 
160
        mp->turn_index = 0;
 
161
        n++;
 
162
        mp++;
 
163
    }
 
164
 
 
165
    return n;
 
166
}
 
167
 
 
168
void GolfSolver::unpack_cluster( int )
 
169
{
 
170
}
 
171
 
 
172
bool GolfSolver::isWon()
 
173
{
 
174
    //kDebug() << "isWon" << Wlen[7];
 
175
    return Wlen[7] == 52 ;
 
176
}
 
177
 
 
178
int GolfSolver::getOuts()
 
179
{
 
180
    return Wlen[7];
 
181
}
 
182
 
 
183
GolfSolver::GolfSolver(const Golf *dealer)
 
184
    : Solver()
 
185
{
 
186
    setNumberPiles( 9 );
 
187
    deal = dealer;
 
188
}
 
189
 
 
190
/* Read a layout file.  Format is one pile per line, bottom to top (visible
 
191
card).  Temp cells and Out on the last two lines, if any. */
 
192
 
 
193
void GolfSolver::translate_layout()
 
194
{
 
195
    /* Read the workspace. */
 
196
 
 
197
    int total = 0;
 
198
    for ( int w = 0; w < 7; ++w ) {
 
199
        int i = translate_pile(deal->stack[w], W[w], 52);
 
200
        Wp[w] = &W[w][i - 1];
 
201
        Wlen[w] = i;
 
202
        total += i;
 
203
    }
 
204
 
 
205
    int i = translate_pile( deal->waste, W[7], 52 );
 
206
    Wp[7] = &W[7][i-1];
 
207
    Wlen[7] = i;
 
208
    total += i;
 
209
 
 
210
    i = translate_pile( Deck::deck(), W[8], 52 );
 
211
    Wp[8] = &W[8][i-1];
 
212
    Wlen[8] = i;
 
213
    total += i;
 
214
 
 
215
    for ( int i = 0; i < 9; i++ )
 
216
    {
 
217
        for ( int l = 0; l < Wlen[i]; l++ )
 
218
        {
 
219
            card_t card = W[i][l];
 
220
            if ( DOWN( card ) )
 
221
                card = RANK( card ) + PS_SPADE + ( 1 << 7 );
 
222
            else
 
223
                card = RANK( card ) + PS_SPADE;
 
224
            W[i][l] = card;
 
225
        }
 
226
    }
 
227
}
 
228
 
 
229
int GolfSolver::getClusterNumber()
 
230
{
 
231
    return Wlen[8] / 8;
 
232
}
 
233
 
 
234
MoveHint *GolfSolver::translateMove( const MOVE &m )
 
235
{
 
236
    if ( m.from >= 7 )
 
237
        return 0;
 
238
    Pile *frompile = deal->stack[m.from];
 
239
 
 
240
    Card *card = frompile->at( frompile->cardsLeft() - m.card_index - 1);
 
241
 
 
242
    return new MoveHint( card, deal->waste, m.pri );
 
243
}
 
244
 
 
245
void GolfSolver::print_layout()
 
246
{
 
247
    fprintf(stderr, "print-layout-begin\n");
 
248
    for (int w = 0; w < 9; w++) {
 
249
        if ( w == 8 )
 
250
            fprintf( stderr, "Deck: " );
 
251
        else if ( w == 7 )
 
252
            fprintf( stderr, "Pile: " );
 
253
        else
 
254
            fprintf( stderr, "Play%d: ", w );
 
255
        for (int i = 0; i < Wlen[w]; i++) {
 
256
            printcard(W[w][i], stderr);
 
257
        }
 
258
        fputc('\n', stderr);
 
259
    }
 
260
    fprintf(stderr, "print-layout-end\n");
 
261
}