Beispiel #1
0
bool is_flush(int* hand)
{
    for (int i =1; i< 5; i++)
        if (SUIT(hand[i]) != SUIT(hand[0]))
            return false;
    return true;
}
Beispiel #2
0
void YukonSolver::make_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();
#else
    //print_layout();
#endif

	int from, to;
	card_t card = NONE;

	from = m->from;
	to = m->to;

        for ( int l = m->card_index; l >= 0; l-- )
        {
            card = W[from][Wlen[from]-l-1];
            Wp[from]--;
            if ( m->totype != O_Type )
            {
                Wp[to]++;
                *Wp[to] = card;
                Wlen[to]++;
            }
        }
        Wlen[from] -= m->card_index + 1;

        if ( m->turn_index == 0 )
        {
            if ( DOWN( card ) )
                card = ( SUIT( card ) << 4 ) + RANK( card );
            else
                card += ( 1 << 7 );
            W[to][Wlen[to]-m->card_index-1] = card;
        } else if ( m->turn_index != -1 )
        {
            card_t card2 = *Wp[from];
            if ( DOWN( card2 ) )
                card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 );
            *Wp[from] = card2;
        }

        hashpile(from);
	/* Add to pile. */

	if (m->totype == O_Type) {
            O[to]++;
            Q_ASSERT( m->card_index == 0 );
        } else {
            hashpile(to);
	}
#if PRINT
        print_layout();
#endif
}
Beispiel #3
0
void YukonSolver::undo_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();

#endif
	int from, to;
	card_t card;

	from = m->from;
	to = m->to;

        /* Add to 'from' pile. */
        if ( m->turn_index > 0 )
        {
            card_t card2 = *Wp[from];
            if ( !DOWN( card2 ) )
                card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 );
            *Wp[from] = card2;
        }

	if (m->totype == O_Type) {
            card = O[to] + Osuit[to];
            O[to]--;
            Wp[from]++;
            *Wp[from] = card;
            Wlen[from]++;
        } else {
            for ( int l = m->card_index; l >= 0; l-- )
            {
                card = W[to][Wlen[to]-l-1];
                Wp[from]++;
                *Wp[from] = card;
                Wlen[from]++;
                *Wp[to]--;
            }
            Wlen[to] -= m->card_index + 1;
            hashpile(to);
	}

        if ( m->turn_index == 0 )
        {
            card_t card = *Wp[from];
            if ( DOWN( card ) )
                card = ( SUIT( card ) << 4 ) + RANK( card );
            else
                card += ( 1 << 7 );
            *Wp[from] = card;
        }

        hashpile(from);
#if PRINT
        print_layout();
#endif
}
Beispiel #4
0
static inline int compareCards (int c0, int c1) {
  int t0 = SUIT(c0), t1 = SUIT(c1);
  int r = t1-t0;
  if (!r) {
    t0 = FACE(c0), t1 = FACE(c1);
    r = t0-t1;
  }
  return r;
}
Beispiel #5
0
bool is_royal(int* hand)
{
    for (int i=0; i<5; i++) {
        if (hand[i] > 20)
            return false;  // contains card lower than 10
        if (SUIT(hand[i]) != SUIT(hand[0]))
            return false;  // contains mismatched suits
    }
    return true;
}
Beispiel #6
0
void SimonSolver::make_move(MOVE *m)
{
#if PRINT
    //qDebug() << "\n\nmake_move\n";
    if ( m->totype == O_Type )
        fprintf( stderr, "move %d from %d out (at %d) Prio: %d\n\n", m->card_index, m->from, m->turn_index, m->pri );
    else
        fprintf( stderr, "move %d from %d to %d (%d) Prio: %d\n\n", m->card_index, m->from, m->to, m->turn_index, m->pri );
    print_layout();
#else
    //print_layout();
#endif

	int from, to;
	card_t card = NONE;

	from = m->from;
	to = m->to;

	if (m->totype == O_Type) {
            O[to] = SUIT( *Wp[from] );
            Wlen[from] -= 13;
            Wp[from] -= 13;
            hashpile( from );
            if ( Wlen[from] && DOWN( *Wp[from] ) )
            {
                *Wp[from] = ( SUIT( *Wp[from] ) << 4 ) + RANK( *Wp[from] );
            }
#if PRINT
            print_layout();
#endif
            return;
        }

        for ( int l = m->card_index; l >= 0; --l )
        {
            card = W[from][Wlen[from]-l-1];
            Wp[from]--;
            if ( m->totype != O_Type )
            {
                Wp[to]++;
                *Wp[to] = card;
                Wlen[to]++;
            }
        }
        Wlen[from] -= m->card_index + 1;

        hashpile(from);
        hashpile(to);
#if PRINT
        print_layout();
#endif
}
static GCC_INLINE void fc_pro_get_board(long gamenumber, Position * pos)
{
    int  i, j;                /*  generic counters */
    int  wLeft = 52;          /*  cards left to be chosen in shuffle */
    CARD deck[52];            /* deck of 52 unique cards */
    int col;
    CARD card, suit;

    memset(pos, '\0', sizeof(*pos));

    /* shuffle cards */

    for (i = 0; i < 52; i++)      /* put unique card in each deck loc. */
    {
        deck[i] = i;
    }

    for (i = 0; i < 52; i++)
    {
        j = microsoft_rand_rand(&gamenumber) % wLeft;
        col = (i%8);
        card = deck[j];
        suit = SUIT(card);
        pos->tableau[col].cards[pos->tableau[col].count++]
            = (Card)((VALUE(card)+1)
            + (((suit == 3) ? suit : ((suit+1)%3))<<4))
            ;
        deck[j] = deck[--wLeft];
    }
}
Beispiel #8
0
int has_suit(int *cl, int b, int e, int s)
{
        int i, r = 0;
        for (i = b; i <= e; i++)
                if (SUIT(cl[i]) == s)
                        r++;
        return r;
}
Beispiel #9
0
inline bool higher( const card_t &c1, const card_t &c2)
{
    // Sanity check.
    if (c1 == c2)
        return false;

    // Must be same suit.
    if ( SUIT( c1 ) != SUIT( c2 ) )
        return false;

    // Aces form a special case.
    if (RANK( c2 ) == PS_ACE)
        return true;
    if (RANK( c1 ) == PS_ACE)
        return false;

    return (RANK( c1 ) < RANK( c2 ));
}
Beispiel #10
0
void SimonSolver::undo_move(MOVE *m)
{
#if PRINT
    //qDebug() << "\n\nundo_move\n";
    if ( m->totype == O_Type )
        fprintf( stderr, "move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();

#endif
	int from, to;
	card_t card;

	from = m->from;
	to = m->to;

        if (m->totype == O_Type) {
            for ( int j = PS_KING; j >= PS_ACE; --j )
            {
                Wp[from]++;
                *Wp[from] = O[to] + j;
                Wlen[from]++;
            }
            O[to] = -1;
            hashpile( from );
#if PRINT
            print_layout();
#endif
            return;
        }

        /* Add to 'from' pile. */
        if ( m->turn_index > 0 )
        {
            card_t card2 = *Wp[from];
            if ( !DOWN( card2 ) )
                card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 );
            *Wp[from] = card2;
        }

        for ( int l = m->card_index; l >= 0; --l )
        {
            card = W[to][Wlen[to]-l-1];
            Wp[from]++;
            *Wp[from] = card;
            Wlen[from]++;
            Wp[to]--;
        }
        Wlen[to] -= m->card_index + 1;
        hashpile(to);
        hashpile(from);
#if PRINT
        print_layout();
#endif
}
Beispiel #11
0
string refresh(int *cl, int b, int e)
{
        string output = "";
        int i, ls, ns;
        if (b < 0 || e < 0)
                return output;
        if (cl[b] < 0 || cl[e] > 51)
                return output;
        output = sprintf("%18s%s:", "", suit_str[ls = ns = SUIT(cl[b])]);
        for (i = b; i <= e; i++) {
                ns = SUIT(cl[i]);
                if (ls == ns) 
                        output += rank_str[RANK(cl[i])] + " ";
                else {
                        output = sprintf("%s\n%18s%s:", output, "",
                                        suit_str[ls = ns]);
                        output += rank_str[RANK(cl[i])] + " ";
                }
        }
        return output + "\n";
}
char * card_to_string(char * s, CARD card, int not_append_ws, int print_ts)
{
    int suit = SUIT(card);
    int v = VALUE(card)+1;

    if (v == 1)
    {
        strcpy(s, "A");
    }
    else if (v < 10)
    {
        sprintf(s, "%i", v);
    }
    else if (v == 10)
    {
        if (print_ts)
        {
            strcpy(s, "T");
        }
        else
        {
            strcpy(s, "10");
        }
    }
    else
    {
        strcpy(s, (v == 11)?"J":((v == 12)?"Q":"K"));
    }

    switch (suit)
    {
        case CLUB:
            strcat(s, "C");
            break;
        case DIAMOND:
            strcat(s, "D");
            break;
        case HEART:
            strcat(s, "H");
            break;
        case SPADE:
            strcat(s, "S");
            break;
    }

    if (!not_append_ws)
    {
        strcat(s, " ");
    }
    
    return s;
}
Beispiel #13
0
void IdiotSolver::make_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();
#else
    //print_layout();
#endif

    int from, to;
    card_t card = NONE;

    from = m->from;
    to = m->to;

    if ( from == 4 )
    {
        Q_ASSERT( Wlen[from] >= 4 );

        for ( int i = 0; i < 4; ++i )
        {
            Wp[i]++;
            card = *Wp[from];
            *Wp[i] = ( SUIT( card ) << 4 ) + RANK( card );
            Wp[from]--;
            Wlen[from]--;
            Wlen[i]++;
            hashpile( i );
        }
        hashpile( from );
    } else {

        card = *Wp[from];
        Wp[from]--;
        Wlen[from]--;
        *Wp[to]++;
        *Wp[to] = card;
        Wlen[to]++;

        hashpile( to );
        hashpile(from);
    }

#if PRINT
    print_layout();
#endif
}
Beispiel #14
0
void GolfSolver::make_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();
#else
    //print_layout();
#endif

    int from = m->from;
    int to = m->to;

    Q_ASSERT( to == 7 );
    Q_ASSERT( from != 7 );

    // move to pile
    if ( from == 8 && to == 7 )
    {
        card_t card = *Wp[8];
        Wp[8]--;
        Wlen[8]--;
        card = ( SUIT( card ) << 4 ) + RANK( card );
        Wp[7]++;
        *Wp[7] = card;
        Wlen[7]++;
        hashpile( 7 );
        hashpile( 8 );
#if PRINT
        print_layout();
#endif
        return;
    }

    card_t card = *Wp[from];
    Wp[from]--;
    Wlen[from]--;

    Wp[to]++;
    *Wp[to] = card;
    Wlen[to]++;

    hashpile(from);
    hashpile(to);
#if PRINT
    print_layout();
#endif
}
Beispiel #15
0
string card_cmp4(mapping cl, int s)
{
        int i, bc;
        string bp;
        string *clkeys = keys(cl);

        if (sizeof(cl) != 4)
                return clkeys[0];
        bc = s * 13;
        for (i = 0; i < 4; i++) 
                if (SUIT(cl[clkeys[i]]) == s && cl[clkeys[i]] >= bc)
                        bc = cl[bp = clkeys[i]];
        return bp;
}       
Beispiel #16
0
char GetSuitChar(unsigned char c)
{
	/*
	*
	*/

	const char suitChars[] = " hdcs";

	if(ISCARDBACK(c))
		return '?';
	if(ISUNKNOWN(c))
		return '_';

	return suitChars[SUIT(c)];
}
Beispiel #17
0
void IdiotSolver::undo_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();

#endif
    int from, to;
    card_t card;

    from = m->from;
    to = m->to;

    if ( from == 4 )
    {
        for ( int i = 3; i >= 0; --i )
        {
            card = *Wp[i];
            Wp[i]--;
            Wlen[i]--;
            Wp[from]++;
            *Wp[from] = ( SUIT( card ) << 4 ) + RANK( card ) + ( 1 << 7 );
            Wlen[from]++;
            hashpile( i );
        }
        hashpile( from );

    } else {

        card = *Wp[to];
        Wp[to]--;
        Wlen[to]--;
        *Wp[from]++;
        *Wp[from] = card;
        Wlen[from]++;

        hashpile( to );
        hashpile(from);
    }

#if PRINT
    print_layout();
#endif
}
Beispiel #18
0
void GypsySolver::make_move(MOVE *m)
{
#if PRINT
    kDebug() << "\n\nmake_move\n";
    if ( m->totype == O_Type )
        fprintf( stderr, "move %d from %d out (at %d) Prio: %d\n\n", m->card_index, m->from, m->turn_index, m->pri );
    else
        fprintf( stderr, "move %d from %d to %d (%d) Prio: %d\n\n", m->card_index, m->from, m->to, m->turn_index, m->pri );
    print_layout();
#else
    //print_layout();
#endif

    int from, to;
    //card_t card = NONE;

    from = m->from;
    to = m->to;

    if ( m->from == deck )
    {
        for ( int i = 0; i < 8; ++i )
        {
            card_t card = *Wp[from];
            card = ( SUIT( card ) << 4 ) + RANK( card );
            ++Wp[i];
            *Wp[i] = card;
            --Wp[from];
            Wlen[i]++;
            hashpile( i );
            Wlen[from]--;
        }
        hashpile( from );
#if PRINT
        print_layout();
#endif
        return;
    }

    card_t card = NONE;
    for ( int l = m->card_index; l >= 0; --l )
    {
        card = W[from][Wlen[from]-l-1];
        Wp[from]--;
        if ( m->totype != O_Type )
        {
            Wp[to]++;
            *Wp[to] = card;
            Wlen[to]++;
        }
    }
    Wlen[from] -= m->card_index + 1;

    if ( m->turn_index == 0 )
    {
        if ( DOWN( card ) )
            card = ( SUIT( card ) << 4 ) + RANK( card );
        else
            card += ( 1 << 7 );
        W[to][Wlen[to]-m->card_index-1] = card;
    } else if ( m->turn_index != -1 )
    {
        card_t card2 = *Wp[from];
        if ( DOWN( card2 ) )
            card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 );
        *Wp[from] = card2;
    }

    hashpile(from);
    /* Add to pile. */

    if (m->totype == O_Type) {
        if ( Wlen[to] )
            *Wp[to] = card;
        else {
            Wp[to]++;
            Wlen[to]++;
            *Wp[to] = card;
        }
        Q_ASSERT( m->card_index == 0 );
    }
    hashpile(to);

#if PRINT
    print_layout();
#endif
}
Beispiel #19
0
int SimonSolver::get_possible_moves(int *a, int *numout)
{
    MOVE *mp;

    /* Check for moves from W to O. */

    int n = 0;
    mp = Possible;
    for (int w = 0; w < 10; ++w) {
        if (Wlen[w] >= 13 && RANK( *Wp[w] ) == PS_ACE )
        {
            int ace_suit = SUIT( *Wp[w] );
            bool stroke = true;
            for ( int l = 0; l < 13; ++l )
            {
                if ( RANK( W[w][Wlen[w]-l-1] ) != l+1 ||
                     SUIT( W[w][Wlen[w]-l-1] ) != ace_suit )
                {
                    stroke = false;
                    break;
                }

            }
            if ( !stroke )
                continue;

            mp->card_index = 12;
            mp->from = w;
            int o = 0;
            while ( O[o] != -1)
                o++; // TODO I need a way to tell spades off from heart off
            mp->to = o;
            mp->totype = O_Type;
            mp->pri = 0;    /* unused */
            mp->turn_index = -1;
            n++;
            mp++;

            return 1;
        }
    }

    /* No more automoves, but remember if there were any moves out. */

    *a = false;
    *numout = n;

    int conti[10];
    for ( int j = 0; j < 10; ++j )
    {
        conti[j] = 0;
        for ( ; conti[j] < Wlen[j]-1; ++conti[j] )
        {
            if ( SUIT( *Wp[j] ) != SUIT( W[j][Wlen[j]-conti[j]-2] ) ||
                 DOWN( W[j][Wlen[j]-conti[j]-2] ))
                break;
            if ( RANK( W[j][Wlen[j]-conti[j]-1] ) !=
                 RANK( W[j][Wlen[j]-conti[j]-2] ) - 1)
                break;
        }
        conti[j]++;
    }

    for(int i=0; i<10; ++i)
    {
        int len = Wlen[i];
        for (int l=0; l < len; ++l )
        {
            card_t card = W[i][Wlen[i]-1-l];
            if ( DOWN( card ) )
                break;

            if ( l > 0 ) {
                card_t card_on_top = W[i][Wlen[i]-l];
                if ( RANK( card ) != RANK( card_on_top ) + 1 )
                    break;
                if ( SUIT( card ) != SUIT( card_on_top ) )
                    break;
            }

            bool wasempty = false;
            for (int j = 0; j < 10; ++j)
            {
                if (i == j)
                    continue;

                bool allowed = false;

                if ( Wlen[j] > 0 &&
                     RANK(card) == RANK(*Wp[j]) - 1 )
                {
                    allowed = true;
                }
                if ( Wlen[j] == 0 && !wasempty )
                {
                    if ( l != Wlen[i]-1  ) {
                        allowed = true;
                        wasempty = true;
                    }
                }
                if ( allowed && Wlen[i] >= l+2 && Wlen[i] > 1 )
                {
                    Q_ASSERT( Wlen[i]-l-2 >= 0 );
                    card_t card_below = W[i][Wlen[i]-l-2];
                    if ( SUIT( card ) == SUIT( card_below ) &&
                         !DOWN( card_below ) &&
                         RANK( card_below ) == RANK( card ) + 1 )
                    {
                        if ( conti[j]+l != 13 || conti[i]>conti[j]+l || SUIT( card ) != SUIT( *Wp[j] ) ) {
                            // fprintf( stderr, "continue\n" );
                            continue;
                        }
                    }
                }

                if ( allowed ) {
                    mp->card_index = l;
                    mp->from = i;
                    mp->to = j;
                    mp->totype = W_Type;
                    mp->turn_index = -1;
                    int cont = conti[j];
                    if ( Wlen[j] )
                        cont++;
                    if ( cont )
                        cont += l;
                    mp->pri = 8 * cont + qMax( 0, 10 - Wlen[i] );
                    if ( Wlen[j] ) {
                        if ( SUIT( card ) != SUIT( *Wp[j] ) ) {
                            mp->pri /= 2;
                        }
                    } else {
                        mp->pri = 2; // TODO: it should depend on the actual stack's order
                    }
                    if ( Wlen[i] == l+1 )
                        mp->pri = qMin( 127, mp->pri + 20 );
                    else
                        mp->pri = qMin( 127, mp->pri + 2 );

                    /* and now check what sequence we open */
                    int conti_pos = l+1;
                    for ( ; conti_pos < Wlen[i]-1; ++conti_pos )
                    {
                        card_t top = W[i][Wlen[i]-l-2];
                        card_t theone = W[i][Wlen[i]-conti_pos-1];
                        card_t below = W[i][Wlen[i]-conti_pos-2];
                        if ( SUIT( top ) != SUIT( below ) || DOWN( below ) )
                            break;
                        if ( RANK( theone ) !=
                             RANK( below ) - 1)
                            break;
                    }
                    mp->pri = qMin( 127, mp->pri + 5 * ( conti_pos - l - 1 ) );

                    n++;
                    mp++;
                }
            }
        }
    }

    return n;
}
Beispiel #20
0
int KlondikeSolver::get_possible_moves(int *a, int *numout)
{
    int w, o, empty;
    card_t card;
    MOVE *mp;

    /* Check for moves from W to O. */

    int n = 0;
    mp = Possible;
    for (w = 0; w < 8; ++w) {
        if (Wlen[w] > 0) {
            card = *Wp[w];
            o = SUIT(card);
            empty = (O[o] == NONE);
            if ((empty && (RANK(card) == PS_ACE)) ||
                (!empty && (RANK(card) == O[o] + 1))) {
                mp->card_index = 0;
                mp->from = w;
                mp->to = o;
                mp->totype = O_Type;
                mp->pri = 3;    /* unused */
                mp->turn_index = -1;
                if ( Wlen[w] > 1 && DOWN( W[w][Wlen[w]-2] ) )
                    mp->turn_index = 1;
                n++;
                mp++;

                /* If it's an automove, just do it. Automoves from the pile are problematic though
		   in draw=3 because automoves can break the offset and break winnable games 
		 */
                if (good_automove(o, RANK(card)) && (w != 7 || m_draw == 1 || Wlen[7] < 3)) {
                    *a = true;
                    mp[-1].pri = 127;
                    if (n != 1) {
                        Possible[0] = mp[-1];
                        return 1;
                    }
                    return n;
                }
            }
        }
    }

    /* No more automoves, but remember if there were any moves out. */

    *a = false;
    *numout = n;

    /* check for deck->pile */
    if ( Wlen[8] ) {
        mp->card_index = qMin( m_draw, Wlen[8] );
        mp->from = 8;
        mp->to = 7;
        mp->totype = W_Type;
        mp->pri = 5;
        mp->turn_index = 0;
        n++;
        mp++;
    }

    // we first check where to put a king, so we don't
    // try each king on each empty pile
    int first_empty_pile = -1;
    for(int i=0; i<8; ++i)
        if ( !Wlen[i] )
        {
            first_empty_pile = i;
            break;
        }

    for(int i=0; i<8; ++i)
    {
        int len = Wlen[i];
        if ( i == 7 && Wlen[i] > 0)
            len = 1;
        for (int l=0; l < len; ++l )
        {
            card_t card = W[i][Wlen[i]-1-l];
            if ( DOWN( card ) )
                break;

            for (int j = 0; j < 7; ++j)
            {
                if (i == j)
                    continue;

                int allowed = 0;

                if ( Wlen[j] > 0 &&
                     RANK(card) == RANK(*Wp[j]) - 1 &&
                     suitable( card, *Wp[j] ) )
                {
                    allowed = 1;
                    if ( Wlen[i] == l + 1 ) {
                        allowed = 2;
                    } else {
                        if ( DOWN( W[i][Wlen[i]-l-2] ) )
                            allowed = 3;
                    }
                }
                if ( RANK( card ) == PS_KING && j == first_empty_pile )
                {
                    if ( l != Wlen[i]-1 || i == 7 )
                        allowed = 4;
                }
                if ( allowed && i == 7 )
                    allowed = 5;

                if ( allowed == 1 )
                {
                    //print_layout();
                    card_t below = W[i][Wlen[i]-2-l];
                    int o = SUIT(below);
                    bool empty = (O[o] == NONE);
                    //fprintf( stderr, "%d %d\n", i, l );
                    //printcard( below, stderr );

                    if ( ( empty && RANK( below ) != PS_ACE ) ||
                         ( !empty && RANK( below ) != O[o] + 1 ) )
                        allowed = 0;
                    //fprintf( stderr, " allowed %d %d %d %d\n",allowed, empty, RANK( below ), PS_ACE);
                }
                if ( allowed ) {
                    mp->card_index = l;
                    mp->from = i;
                    mp->to = j;
                    mp->totype = W_Type;
                    mp->turn_index = -1;
                    if ( Wlen[i] > l+1 && DOWN( W[i][Wlen[i]-l-2] ) )
                        mp->turn_index = 1;
                    if ( i == 7 )
                        mp->pri = 40;
                    else {
                        if ( mp->turn_index > 0 || Wlen[i] == l+1)
                            mp->pri = 30;
                        else
                            mp->pri = 1;
                    }
                    n++;
                    mp++;
                }
            }
        }
    }

    if ( Wlen[8] == 0 && Wlen[7] > 1 )
    {
        mp->card_index = 0;
        mp->from = 7;
        mp->to = 8;
        mp->totype = W_Type;
        mp->turn_index = 0;
        mp->pri = 2;
        n++;
        mp++;
    }
    return n;
}
Beispiel #21
0
void KlondikeSolver::make_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nmake move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();
#else
    //print_layout();
#endif

	int from, to;
	card_t card = NONE;

	from = m->from;
	to = m->to;

	/* Remove from pile. */
        if ( from == 7 && to == 8 )
        {
            while ( Wlen[7] )
            {
                card = W[7][Wlen[7]-1] + ( 1 << 7 );
                Wlen[8]++;
                W[8][Wlen[8]-1] = card;
                Wlen[7]--;
            }
            Wp[7] = &W[7][0];
            Wp[8] = &W[8][Wlen[8]-1];
            hashpile( 7 );
            hashpile( 8 );
#if PRINT
            print_layout();
#endif
            return;
        }

        // move to pile
        if ( from == 8 && to == 7 )
        {
            for ( int i = 0; i < m->card_index; ++i )
            {
                if ( !Wlen[8] )
                    continue;

                card = *Wp[8];
                Wp[8]--;
                Wlen[8]--;
                card = ( SUIT( card ) << 4 ) + RANK( card );
                Wp[7]++;
                *Wp[7] = card;
                Wlen[7]++;
            }
            hashpile( 7 );
            hashpile( 8 );
#if PRINT
            print_layout();
#endif
            return;
        }

        for ( int l = m->card_index; l >= 0; --l )
        {
            card = W[from][Wlen[from]-l-1];
            Wp[from]--;
            if ( m->totype != O_Type )
            {
                Wp[to]++;
                *Wp[to] = card;
                Wlen[to]++;
            }
        }
        Wlen[from] -= m->card_index + 1;

        if ( m->turn_index == 0 )
        {
            if ( DOWN( card ) )
                card = ( SUIT( card ) << 4 ) + RANK( card );
            else
                card += ( 1 << 7 );
            W[to][Wlen[to]-m->card_index-1] = card;
        } else if ( m->turn_index != -1 )
        {
            card_t card2 = *Wp[from];
            if ( DOWN( card2 ) )
                card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 );
            *Wp[from] = card2;
        }

        hashpile(from);
	/* Add to pile. */

	if (m->totype == O_Type) {
            O[to]++;
            Q_ASSERT( m->card_index == 0 );
        } else {
            hashpile(to);
	}
#if PRINT
        print_layout();
#endif
}
Beispiel #22
0
int ClockSolver::get_possible_moves(int *a, int *numout)
{
    MOVE *mp;

    /* Check for moves from W to O. */

    int first_empty = -1;

    int left_in_play = 0;
    int n = 0;
    mp = Possible;
    for (int w = 0; w < 8; ++w)
    {
        left_in_play += Wlen[w];

        if (Wlen[w] > 0)
        {
            card_t card = *Wp[w];
            auto o = SUIT(card);
            for ( int i = 0; i < 12; ++i )
            {
                if ( o != SUIT( W[8][i] ) )
                    continue;

                if ( RANK( card ) == PS_ACE )
                {
                    if ( RANK( W[8][i] ) != PS_KING )
                        continue;
                } else {
                    if ( RANK( W[8][i] ) != RANK( card ) - 1 )
                        continue;
                }
                mp->card_index = 0;
                mp->from = w;
                mp->to = i;
                mp->totype = O_Type;
                mp->pri = 50;
                mp->turn_index = -1;
                n++;
                mp++;
            }
        } else if ( first_empty < 0 )
            first_empty = w;
    }

    /* No more automoves, but remember if there were any moves out. */

    *a = false;
    *numout = n;

    for(int i=0; i<8; ++i)
    {
        if ( !Wlen[i] )
            continue;

        for (int j=0; j < 8; ++j )
        {
            if ( i == j )
                continue;

            card_t card = *Wp[i];

            bool allowed = false;

            if ( Wlen[j] == 0 )
            {
                if ( Wlen[i] > 1 && first_empty == j )
                    allowed = true;
            } else
            {
                card_t below = *Wp[j];

                if ( RANK(card) == RANK( below ) - 1 )
                {
                    allowed = true;
                }
            }

            if ( allowed )
            {
                    mp->card_index = 0;
                    mp->from = i;
                    mp->to = j;
                    mp->totype = W_Type;
                    mp->turn_index = -1;
                    mp->pri = 1;
                    n++;
                    mp++;
            }
        }
    }

    return n;
}
Beispiel #23
0
void KlondikeSolver::undo_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nundo move %d from %d out (at %d)\n\n", m->card_index, m->from, m->turn_index );
    else
        fprintf( stderr, "\nundo move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();

#endif
	int from, to;
	card_t card;

	from = m->from;
	to = m->to;

	/* Remove from 'to' pile. */

        if ( from == 7 && to == 8 )
        {
            while ( Wlen[8] )
            {
                card = W[8][Wlen[8]-1];
                card = ( SUIT( card ) << 4 ) + RANK( card );
                Wlen[7]++;
                W[7][Wlen[7]-1] = card;
                Wlen[8]--;
            }
            Wp[8] = &W[8][0];
            Wp[7] = &W[7][Wlen[7]-1];
            hashpile( 7 );
            hashpile( 8 );
#if PRINT
            print_layout();
#endif
            return;
        }

        // move back to deck
        if ( from == 8 && to == 7 )
        {
            for ( int i = 0; i < m->card_index; ++i )
            {
                card = *Wp[7];
                Wp[7]--;
                Wlen[7]--;
                card = ( SUIT( card ) << 4 ) + RANK( card ) + ( 1 << 7 );
                Wp[8]++;
                *Wp[8] = card;
                Wlen[8]++;
            }
            hashpile( 7 );
            hashpile( 8 );
#if PRINT
            print_layout();
#endif
            return;
        }


        /* Add to 'from' pile. */
        if ( m->turn_index > 0 )
        {
            card_t card2 = *Wp[from];
            if ( !DOWN( card2 ) )
                card2 = ( SUIT( card2 ) << 4 ) + RANK( card2 ) + ( 1 << 7 );
            *Wp[from] = card2;
        }

	if (m->totype == O_Type) {
            card = O[to] + Osuit[to];
            O[to]--;
            Wp[from]++;
            *Wp[from] = card;
            Wlen[from]++;
        } else {
            for ( int l = m->card_index; l >= 0; --l )
            {
                card = W[to][Wlen[to]-l-1];
                Wp[from]++;
                *Wp[from] = card;
                Wlen[from]++;
                Wp[to]--;
            }
            Wlen[to] -= m->card_index + 1;
            hashpile(to);
	}

        if ( m->turn_index == 0 )
        {
            card_t card = *Wp[from];
            if ( DOWN( card ) )
                card = ( SUIT( card ) << 4 ) + RANK( card );
            else
                card += ( 1 << 7 );
            *Wp[from] = card;
        }

        hashpile(from);
#if PRINT
        print_layout();
#endif
}
Beispiel #24
0
/*
 * aLeftPlayer: next in turn
 * aRightPlayer: prev in turn
 * 0, 1th
 * 1th, 2nd
 */
Card *AlphaBetaPlayer::makeMove (Card *lMove, Card *rMove, Player *aLeftPlayer, Player *aRightPlayer, bool isPassOut) {
  qDebug() << type() << "("<< mPlayerNo << ") moves";
  
  card_t hands[3][10];
  card_t desk[3];
  int crdLeft = 0;
  int trumpSuit = 0;
  Player *plst[3];

//again:
  plst[0] = plst[1] = plst[2] = 0;
  plst[mPlayerNo-1] = this;
  plst[aLeftPlayer->number()-1] = aLeftPlayer;
  plst[aRightPlayer->number()-1] = aRightPlayer;

  // build hands
  for (int c = 0; c < 3; c++) {
    Q_ASSERT(plst[c]);
    CardList *clst = &(plst[c]->mCards);
    //for (int f = 0; f < 10; f++) hds[c][f] = hands[c][f] = 0;
    int pos = 0;
    for (int f = 0; f < clst->size(); f++) {
      Card *ct = clst->at(f);
      if (!ct) continue;
      hands[c][pos++] = CARD(ct->face(), ct->suit()-1);
      if (pos > crdLeft) crdLeft = pos;
    }
    for (int f = pos; f < 10; f++) hands[c][f] = 0;
    xsortCards(hands[c], pos);
  }


  if (!lMove && !rMove && crdLeft == 10) { 
    return AiPlayer::makeMove(lMove, rMove, aLeftPlayer, aRightPlayer, isPassOut);
  }


  // find game
  const eGameBid bid = m_model->currentGame();

  gPassOutOrMisere = (bid == g86 || bid == g86catch || bid == raspass);
  trumpSuit = bid%10-1;//(bid-(bid/10)*10)-1;
/*
  if (bid == g86catch || bid == g86 || bid == raspass) {
    return Player::moveSelectCard(lMove, rMove, aLeftPlayer, aRightPlayer);
  }
*/
  if (bid == g86catch || bid == g86 || bid == raspass) {
    trumpSuit = 4;
  }
  if (trumpSuit < 0) trumpSuit = 4;

  fprintf(stderr, "po:%s; lm:%s, rm:%s\n", isPassOut?"y":"n", lMove?"y":"n", rMove?"y":"n");
  if (isPassOut && rMove && !lMove) {
    // это распасы, первый или второй круг, первый ход
    gPassOutSuit = rMove->suit()-1;
    fprintf(stderr, "pass-out: %i\n", gPassOutSuit);
    rMove = 0;
  } else gPassOutSuit = -1;

  // build desk
  int turn = 0;
  if (lMove) {
    desk[turn++] = CARD(lMove->face(), lMove->suit()-1);
    if (rMove) desk[turn++] = CARD(rMove->face(), rMove->suit()-1);
  } else if (rMove) {
    desk[turn++] = CARD(rMove->face(), rMove->suit()-1);
  }

  // build hands
  for (int f = 0; f < 3; f++) {
    xHands[f].suitCount[0] = xHands[f].suitCount[1] = xHands[f].suitCount[2] = xHands[f].suitCount[3] = 0;
    xHands[f].suitStart[0] = xHands[f].suitStart[1] = xHands[f].suitStart[2] = xHands[f].suitStart[3] = 11;
    xHands[f].tricks = plst[f]->tricksTaken();
    int st;
    for (int z = 0; z < 10; z++) {
      if (hands[f][z]) {
        xHands[f].faces[z] = FACE(hands[f][z]);
        st = xHands[f].suits[z] = SUIT(hands[f][z]);
        if (xHands[f].suitCount[st]++ == 0) xHands[f].suitStart[st] = z;
      } else xHands[f].faces[z] = 0;
    }
  }

  // build desk
  for (int f = 0; f < turn; f++) {
    xDeskFaces[f] = FACE(desk[f]);
    xDeskSuits[f] = SUIT(desk[f]);
  }

  int a, b, c, move;
  int me = this->number()-1;
  xCardsLeft = crdLeft;
  gTrumpSuit = trumpSuit;
  gIterations = 0;

  printf("%shand 0:", this->number()==0?"*":" ");
  printHand(&(xHands[0]));
  printf("%shand 1:", this->number()==1?"*":" ");
  printHand(&(xHands[1]));
  printf("%shand 2:", this->number()==2?"*":" ");
  printHand(&(xHands[2]));
  printDesk(turn);

  // оптимизации
/*
  if (turn > 0) {
    // можем вообще взять?
    if (hands[me].suitCount(
  }
*/

  stTime = QTime::currentTime();
  stTime.start();
  abcPrune(turn, me, -666, 666, 666, &a, &b, &c, &move);

  qDebug() <<
    "face:" << FACE(hands[me][move]) <<
    "suit:" << SUIT(hands[me][move])+1 <<
    "move:" << move <<
    "turn:" << turn <<
    "moves:" << crdLeft <<
    "trump:" << trumpSuit <<
    "iters:" << gIterations <<
    "";

/*
  for (int h = 0; h < 3; h++) {
    fprintf(stderr, (h == me)?"*":" ");
    fprintf(stderr, "hand %i:", h);
    for (int f = 0; f < 10; f++) {
      if (hands[h][f]) {
        fprintf(stderr, " %2i.%i(%3i)", FACE(hands[h][f]), SUIT(hands[h][f]), hands[h][f]);
      } else {
        fprintf(stderr, " %2i.%i(%3i)", 0, 0, hands[h][f]);
      }
    }
    fprintf(stderr, "\n");
  }
  fprintf(stderr, "desk:");
  for (int f = 0; f < turn; f++) {
    fprintf(stderr, " %2i.%i(%3i)", FACE(desk[f]), SUIT(desk[f]), desk[f]);
  }
  fprintf(stderr, "\n");
*/
  Q_ASSERT(move >= 0);

  Card *moveCard = getCard(FACE(hands[me][move]), SUIT(hands[me][move])+1);

  qDebug() << "move:" << moveCard->toString();

  mCards.remove(moveCard);
  mCardsOut.insert(moveCard);

  return moveCard;
}
Beispiel #25
0
void Mod3Solver::make_move(MOVE *m)
{
#if PRINT
    if ( m->totype == O_Type )
        fprintf( stderr, "\nmake move %d from %d out %d (at %d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    else
        fprintf( stderr, "\nmake move %d from %d to %d (%d)\n\n", m->card_index, m->from, m->to, m->turn_index );
    print_layout();
#else
    //print_layout();
#endif

    int from, to;
    from = m->from;
    to = m->to;

    if ( from == deck )
    {
        int len = m->card_index;
        if ( len > 8 )
            len = 8;
        for ( int i = 0; i < len; i++ )
        {
            card_t card = *Wp[deck];
            Wlen[deck]--;
            Wp[deck]--;

            card = ( card & PS_SUIT ) + RANK( card );
            Wp[24 + i]++;
            Wlen[24 + i]++;
            *Wp[24 + i] = card;
            hashpile( 24 + i );
        }
        hashpile( deck );
#if PRINT
        print_layout();
#endif
        return;
    }

    card_t card = *Wp[from];
    Wlen[from]--;
    Wp[from]--;
    hashpile( from );

    /* Add to pile. */

    Wp[to]++;
    *Wp[to] = card;
    Wlen[to]++;
    hashpile( to );

    if ( m->turn_index == 1 )
    {
        card_t card2 = *Wp[deck];
        Wlen[deck]--;
        Wp[deck]--;

        hashpile(deck);
        /* Add to pile. */

        Wp[from]++;
        *Wp[from] = RANK( card2 ) + ( SUIT( card2 ) << 4 );
        Wlen[from]++;
    }

    hashpile(from);
#if PRINT
    print_layout();
#endif
}
Beispiel #26
0
int FreecellSolver::get_possible_moves(int *a, int *numout)
{
	int i, n, t, w, o, empty, emptyw;
	card_t card;
	MOVE *mp;

	/* Check for moves from W to O. */

	n = 0;
	mp = Possible;
	for (w = 0; w < Nwpiles + Ntpiles; ++w) {
		if (Wlen[w] > 0) {
			card = *Wp[w];
			o = SUIT(card);
			empty = (O[o] == NONE);
			if ((empty && (RANK(card) == PS_ACE)) ||
			    (!empty && (RANK(card) == O[o] + 1))) {
				mp->card_index = 0;
				mp->from = w;
				mp->to = o;
				mp->totype = O_Type;
                                mp->turn_index = -1;
				mp->pri = 0;    /* unused */
				n++;
				mp++;

				/* If it's an automove, just do it. */

				if (good_automove(o, RANK(card))) {
					*a = true;
                                        mp[-1].pri = 127;
					if (n != 1) {
						Possible[0] = mp[-1];
						return 1;
					}
					return n;
				}
			}
		}
	}

	/* No more automoves, but remember if there were any moves out. */

	*a = false;
	*numout = n;

	/* Check for moves from non-singleton W cells to one of any
	empty W cells. */

	emptyw = -1;
	for (w = 0; w < Nwpiles; ++w) {
		if (Wlen[w] == 0) {
			emptyw = w;
			break;
		}
	}
	if (emptyw >= 0) {
		for (i = 0; i < Nwpiles + Ntpiles; ++i) {
			if (i == emptyw || Wlen[i] == 0) {
				continue;
			}
                        bool allowed = false;
                        if ( i < Nwpiles)
                            allowed = true;
                        if ( i >= Nwpiles )
                            allowed = true;
                        if ( allowed ) {
				card = *Wp[i];
				mp->card_index = 0;
				mp->from = i;
				mp->to = emptyw;
				mp->totype = W_Type;
                                mp->turn_index = -1;
                                if ( i >= Nwpiles )
                                    mp->pri = Xparam[6];
                                else
                                    mp->pri = Xparam[3];
				n++;
				mp++;
			}
		}
	}

	/* Check for moves from W to non-empty W cells. */

	for (i = 0; i < Nwpiles + Ntpiles; ++i) {
		if (Wlen[i] > 0) {
			card = *Wp[i];
			for (w = 0; w < Nwpiles; ++w) {
				if (i == w) {
					continue;
				}
				if (Wlen[w] > 0 &&
				    (RANK(card) == RANK(*Wp[w]) - 1 &&
				     suitable(card, *Wp[w]))) {
					mp->card_index = 0;
					mp->from = i;
					mp->to = w;
					mp->totype = W_Type;
                                        mp->turn_index = -1;
                                        if ( i >= Nwpiles )
                                            mp->pri = Xparam[5];
                                        else
                                            mp->pri = Xparam[4];
					n++;
					mp++;
				}
			}
		}
	}

        /* Check for moves from W to one of any empty T cells. */

        for (t = 0; t < Ntpiles; ++t) {
               if (!Wlen[t+Nwpiles]) {
                       break;
               }
        }

        if (t < Ntpiles) {
               for (w = 0; w < Nwpiles; ++w) {
                       if (Wlen[w] > 0) {
                               card = *Wp[w];
                               mp->card_index = 0;
                               mp->from = w;
                               mp->turn_index = -1;
                               mp->to = t+Nwpiles;
                               mp->totype = W_Type;
                               mp->pri = Xparam[7];
                               n++;
                               mp++;
                       }
               }
       }


	return n;
}
Beispiel #27
0
void FreecellSolver::prioritize(MOVE *mp0, int n)
{
	int i, j, s, w, pile[NNEED], npile;
	card_t card, need[4];
	MOVE *mp;

	/* There are 4 cards that we "need": the next cards to go out.  We
	give higher priority to the moves that remove cards from the piles
	containing these cards. */

	for (i = 0; i < NNEED; ++i) {
		pile[i] = -1;
	}
	npile = 0;

	for (s = 0; s < 4; ++s) {
		need[s] = NONE;
		if (O[s] == NONE) {
			need[s] = Osuit[s] + PS_ACE;
		} else if (O[s] != PS_KING) {
			need[s] = Osuit[s] + O[s] + 1;
		}
	}

	/* Locate the needed cards.  There's room for optimization here,
	like maybe an array that keeps track of every card; if maintaining
	such an array is not too expensive. */

	for (w = 0; w < Nwpiles; ++w) {
		j = Wlen[w];
		for (i = 0; i < j; ++i) {
			card = W[w][i];
			s = SUIT(card);

			/* Save the locations of the piles containing
			not only the card we need next, but the card
			after that as well. */

			if (need[s] != NONE &&
			    (card == need[s] || card == need[s] + 1)) {
				pile[npile++] = w;
				if (npile == NNEED) {
					break;
				}
			}
		}
		if (npile == NNEED) {
			break;
		}
	}

	/* Now if any of the moves remove a card from any of the piles
	listed in pile[], bump their priority.  Likewise, if a move
	covers a card we need, decrease its priority.  These priority
	increments and decrements were determined empirically. */

	for (i = 0, mp = mp0; i < n; ++i, ++mp) {
		if (mp->card_index != -1) {
			w = mp->from;
			for (j = 0; j < npile; ++j) {
				if (w == pile[j]) {
					mp->pri += Xparam[0];
				}
			}
			if (Wlen[w] > 1) {
				card = W[w][Wlen[w] - 2];
				for (s = 0; s < 4; ++s) {
					if (card == need[s]) {
						mp->pri += Xparam[1];
						break;
					}
				}
			}
			if (mp->totype == W_Type) {
				for (j = 0; j < npile; ++j) {
					if (mp->to == pile[j]) {
						mp->pri -= Xparam[2];
					}
				}
			}
		}
	}
}
Beispiel #28
0
static int
board_save_lin(window_board_t *win, char *filename)
{
	int cur;
	FILE *f;
	if ((f = fopen (filename, "w")) == NULL)
		return 0;

	setlocale (LC_NUMERIC, "C");

	if (win->title) {
		fprintf (f, "vg|%s,%s,%s,%d,%d,%s,,%s,|\n",
			win->title,
			win->subtitle ? win->subtitle : "",
			"P", // FIXME
			1, win->n_boards,
			win->team1 ? win->team1 : "",
			win->team2 ? win->team2 : "");

		fprintf (f, "rs|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			fprintf (f, "%s,", lin_contract (b));
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "pw|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			fprintf (f, "%s,%s,%s,%s",
				b->hand_name[south-1]->str, b->hand_name[west-1]->str,
				b->hand_name[north-1]->str, b->hand_name[east-1]->str);
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "mp|");
		for (cur = 0; cur < win->n_boards; cur++) {
			board *b = win->boards[cur];
			if (b->mp[0] == 0 && b->mp[1] == 0)
				fprintf (f, "--,--");
			else {
				if (b->mp[0])
					fprintf (f, "%.2f", b->mp[0] / 100.0);
				fprintf (f, ",");
				if (b->mp[1])
					fprintf (f, "%.2f", b->mp[1] / 100.0);
			}
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "bn|");
		for (cur = 0; cur < win->n_boards; cur++) {
			//board *b = win->boards[cur];
			fprintf (f, "%d", cur + 1); // TODO: original number?
			if (cur != win->n_boards - 1)
				fprintf (f, ",");
		}
		fprintf (f, "|\n");

		fprintf (f, "pg||\n");
	}

	for (cur = 0; cur < win->n_boards; cur++) {
		board *b = win->boards[cur];
		int i;

		if (win->n_boards > 1)
			fprintf (f, "qx|o%d|", cur + 1); // TODO: open/closed, real board number

		fprintf (f, "pn|%s,%s,%s,%s|",
			b->hand_name[south-1]->str, b->hand_name[west-1]->str,
			b->hand_name[north-1]->str, b->hand_name[east-1]->str);
		fprintf (f, "st||");
		fprintf (f, "md|%d%s|", seat_mod(b->dealer + 1), lin_card_string(b)); // TODO: end positions
		fprintf (f, "rh||");
		fprintf (f, "ah|%s|", b->name->str);
		fprintf (f, "sv|%c|", b->vuln[0] ? (b->vuln[1] ? 'b' : 'n')
						: (b->vuln[1] ? 'e' : 'o'));
		for (i = 0; i < b->n_bids; i++) {
			fprintf (f, "mb|%s|", lin_bid(b->bidding[i]));
			if (b->alerts[i])
				fprintf (f, "an|%s|", *b->alerts[i] ? b->alerts[i] : "!");
		}
		for (i = 0; i < 52; i++) {
			if (i % 4 == 0)
				fprintf (f, "pg||");
			card c = b->played_cards[i];
			if (c < 0)
				break;
			if (c == claim_rest) {
				fprintf (f, "mc|%d|",
					b->declarer_tricks >= 0 ? b->declarer_tricks : 0);
				break;
			}
			fprintf (f, "pc|%c%c|", "CDHS"[SUIT(c)], rank_char(RANK(c)));
		}
		fprintf (f, "pg||\n");
	}

	int ret = 1, e = 0;
	if (ferror (f)) {
		ret = 0;
		e = errno;
	}
	fclose(f);
	errno = e;

	setlocale (LC_NUMERIC, "");

	return ret;
}
Beispiel #29
0
void
on_menu_file_web_activate ()
{
	board *b = CUR_BOARD;
	GString *url = g_string_new ("http://www.bridgebase.com/tools/handviewer.html?");

	/* non-lin interface
	int h;

	g_string_append_printf (url, "d=%c", seat_lc[b->dealer]);
	g_string_append_printf (url, "&v=%c", vuln_lc[b->vuln[0] + 2 * b->vuln[1]]);
	g_string_append_printf (url, "&n=%d", b->n + 1); // TODO: real board number

	for (h = west; h <= south; h++) {
		if (*b->hand_name[h - 1]->str)
			g_string_append_printf (url, "&%cn=%s", seat_lc[h], b->hand_name[h - 1]->str);

		g_string_append_printf (url, "&%c=", seat_lc[h]);
		int s;
		for (s = club; s <= spade; s++) {
			g_string_append_printf (url, "%s", trump_str_char[s]);
			int c;
			for (c = s * 13 + 12; c >= (int)s * 13; c--)
				if (b->dealt_cards[c] == h)
					g_string_append_printf(url, "%c", rank_char(RANK(c)));
		}
	}

	if (b->n_bids) {
		g_string_append_printf (url, "&a=");
		int i;
		for (i = 0; i < b->n_bids; i++)
			g_string_append_printf (url, "%s", lin_bid (b->bidding[i]));
	}

	if (b->n_played_cards) {
		g_string_append_printf (url, "&p=");
		int i;
		for (i = 0; i < b->n_played_cards; i++)
			g_string_append_printf (url, "%s%c",
					trump_str_char[SUIT(b->played_cards[i])], rank_char(RANK(b->played_cards[i])));
		if (b->played_cards[b->n_played_cards] = claim_rest)
			g_string_append_printf (url, "&c=%d", b->declarer_tricks);
	}
	*/

	int i;

	// TODO: merge with code from board_save_lin
	g_string_append_printf (url, "lin=pn|%s,%s,%s,%s|",
			b->hand_name[south-1]->str, b->hand_name[west-1]->str,
			b->hand_name[north-1]->str, b->hand_name[east-1]->str);
	g_string_append_printf (url, "st||");
	g_string_append_printf (url, "md|%d%s|", seat_mod(b->dealer + 1), lin_card_string(b)); // TODO: end positions
	g_string_append_printf (url, "rh||");
	g_string_append_printf (url, "ah|%s|", b->name->str);
	g_string_append_printf (url, "sv|%c|", b->vuln[0] ? (b->vuln[1] ? 'b' : 'n')
			: (b->vuln[1] ? 'e' : 'o'));
	for (i = 0; i < b->n_bids; i++) {
		g_string_append_printf (url, "mb|%s|", lin_bid(b->bidding[i]));
		if (b->alerts[i])
			g_string_append_printf (url, "an|%s|", *b->alerts[i] ? b->alerts[i] : "!");
	}
	for (i = 0; i < 52; i++) {
		if (i % 4 == 0)
			g_string_append_printf (url, "pg||");
		card c = b->played_cards[i];
		if (c < 0)
			break;
		if (c == claim_rest) {
			g_string_append_printf (url, "mc|%d|",
					b->declarer_tricks >= 0 ? b->declarer_tricks : 0);
			break;
		}
		g_string_append_printf (url, "pc|%c%c|", "CDHS"[SUIT(c)], rank_char(RANK(c)));
	}
	g_string_append_printf (url, "pg||\n");

	printf ("%s\n", url->str);

	GError *error = NULL;
	gtk_show_uri (gdk_screen_get_default (), url->str, GDK_CURRENT_TIME, &error);
	if (error) {
		printf ("%s\n", error->message);
		g_error_free (error);
	}
	g_string_free (url, TRUE);
}
Beispiel #30
0
int YukonSolver::get_possible_moves(int *a, int *numout)
{
    int w, o, empty;
    card_t card;
    MOVE *mp;

    /* Check for moves from W to O. */

    int n = 0;
    mp = Possible;
    for (w = 0; w < 7; w++) {
        if (Wlen[w] > 0) {
            card = *Wp[w];
            o = SUIT(card);
            empty = (O[o] == NONE);
            if ((empty && (RANK(card) == PS_ACE)) ||
                (!empty && (RANK(card) == O[o] + 1))) {
                mp->card_index = 0;
                mp->from = w;
                mp->to = o;
                mp->totype = O_Type;
                mp->pri = 3;    /* unused */
                mp->turn_index = -1;
                if ( Wlen[w] > 1 && DOWN( W[w][Wlen[w]-2] ) )
                    mp->turn_index = 1;
                n++;
                mp++;

                /* If it's an automove, just do it. */

                if (good_automove(o, RANK(card))) {
                    *a = true;
                    mp[-1].pri = 127;
                    if (n != 1) {
                        Possible[0] = mp[-1];
                        return 1;
                    }
                    return n;
                }
            }
        }
    }

    /* No more automoves, but remember if there were any moves out. */

    *a = false;
    *numout = n;

    for(int i=0; i<7; i++)
    {
        int len = Wlen[i];
        for (int l=0; l < len; ++l )
        {
            card_t card = W[i][Wlen[i]-1-l];
            if ( DOWN( card ) )
                break;

            for (int j = 0; j < 7; j++)
            {
                if (i == j)
                    continue;

                int allowed = 0;

                if ( Wlen[j] > 0 &&
                     RANK(card) == RANK(*Wp[j]) - 1 &&
                     suitable( card, *Wp[j] ) )
                {
                    allowed = 1;
                    if ( Wlen[i] == l + 1 ) {
                        allowed = 2;
                    } else {
                        if ( DOWN( W[i][Wlen[i]-l-2] ) )
                            allowed = 3;
                    }
                }
                if ( RANK( card ) == PS_KING && Wlen[j] == 0 )
                {
                    if ( l != Wlen[i]-1 || i == 7 )
                        allowed = 4;
                }
                // TODO: there is no point in moving if we're not opening anything
                // e.g. if both i and j have perfect runs below the cards
#if 0
                fprintf( stderr, "%d %d %d\n", i, l, j );
                printcard( card, stderr );
                printcard( *Wp[j], stderr );
                fprintf( stderr, " allowed %d\n",allowed );
#endif
                if ( allowed ) {
                    mp->card_index = l;
                    mp->from = i;
                    mp->to = j;
                    mp->totype = W_Type;
                    mp->turn_index = -1;
                    if ( Wlen[i] > l+1 && DOWN( W[i][Wlen[i]-l-2] ) )
                        mp->turn_index = 1;
                    if ( mp->turn_index > 0 || Wlen[i] == l+1)
                         mp->pri = 30;
                    else
                         mp->pri = 1;
                    n++;
                    mp++;
                }
            }
        }
    }

    return n;
}