/* libass/ass_switch.c * * Copyright (C) 1997 Timothy M. Vanderhoek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Tim Vanderhoek * ac199@hwcn.org */ #include "ass.h" #include "ass_err.h" #include #include #include static int comp (const void *, const void *); /* * This will take the two highest cards from the ASS and give them * to the PREZ, and the highest cards from the VICEASS and give it * to the VICE. Should everyone be an ASS, it will do nothing. * It returns a statically allocated hand_t (BEWARE!). The first * two cards in the hand_t are from the ass, the third and fourth * are from the PREZ, the fifth is from the VICEASS, and the sixth * is from the VICE. The values of the others are undefined. * * If some player doesn't have any cards to give away (ie. they have * too many NAC cards), ass_switch() will return 0. This is an error. * Don't do it. :) */ hand_t ass_switch ( game_t game /* In what game? */ ) { static struct hand_s ret; card_t *a1, *a2, *p1, *p2, *va, *vp; /* Cards to switch */ position_t j; int i, ii; card_t x; for (i=0; i<6; i++) ret.cards[i] = NAC; j = ASS; for (i=0; i<4; i++) if (game->ppl[i].pos == j) break; assert (i != 4); /* Must always be at least one ASS */ /* Find the ASS's two highest cards... */ for (a1=a2=NULL, ii=0; ii<15; ii++) if (!a1 || game->ppl[i].hand.cards[ii] > *a1) { a2 = a1; a1 = &(game->ppl[i].hand.cards[ii]); } else if (!a2 || game->ppl[i].hand.cards[ii] > *a2) a2 = &(game->ppl[i].hand.cards[ii]); j = VICEASS; for (i=0; i<4; i++) if (game->ppl[i].pos == j) break; if (i == 4) { /* Couldn't find a VICEASS. That means everyone should * be an ass. Let's check, eh... */ for (i=0; i<4; i++) assert (game->ppl[i].pos == ASS); /* Okay, return nicely... */ for (i=0; i<54; i++) ret.cards[i] = NAC; return &ret; } /* Find highest card... */ for (va=NULL, ii=0; ii<15; ii++) if (!va || game->ppl[i].hand.cards[ii] > *va) va = &(game->ppl[i].hand.cards[ii]); j = VICE; for (i=0; i<4; i++) if (game->ppl[i].pos == j) break; assert (i != 4); /* Must be at least one VICE at this point... */ /* Find lowest card... */ for (vp=NULL, ii=0; ii<15; ii++) if (!vp || (game->ppl[i].hand.cards[ii] < *vp && game->ppl[i].hand.cards[ii] != NAC)) vp = &(game->ppl[i].hand.cards[ii]); j = PREZ; for (i=0; i<4; i++) if (game->ppl[i].pos == j) break; assert (i != 4); /* Must be at least one PREZ at this point... */ /* Find two lowest cards... */ for (p1=p2=NULL, ii=0; ii<15; ii++) if (!p1 || (game->ppl[i].hand.cards[ii] < *p1 && game->ppl[i].hand.cards[ii] != NAC)) { p2 = p1; p1 = &(game->ppl[i].hand.cards[ii]); } else if (!p2 || (game->ppl[i].hand.cards[ii] < *p2 && game->ppl[i].hand.cards[ii] != NAC)) p2 = &(game->ppl[i].hand.cards[ii]); if (ass_err (!a1 || !a2 || !va || !vp || !p1 || !p2, "libass: ass_switch(): Couldn't find cards to give away!\n")) return 0; ret.cards[0] = *a1; ret.cards[1] = *a2; ret.cards[2] = *p1; ret.cards[3] = *p2; ret.cards[4] = *va; ret.cards[5] = *vp; x = *a1; *a1 = *p1; *p1 = x; /* Switch first ASS<->PREZ card */ x = *a2; *a2 = *p2; *p2 = x; /* Switch second ASS<->PREZ card */ x = *va; *va = *vp; *vp = x; /* Switch VICEASS<->VICE card */ /* Better resort each hand... */ for (i=0; i<4; i++) qsort (game->ppl[i].hand.cards, 14, sizeof(card_t), comp); return &ret; } /* * qsort()'s comparison function. */ static int comp ( const void * first, /* item #1 */ const void * second /* item #2 */ ) { if (*(const card_t *) first >= *(const card_t *) second) return 1; return -1; }