Exemplo n.º 1
0
void testDeckShuffle(struct gameState* G){
    
    int deckCount;
    int player= G->whoseTurn;
    int empty_deck[MAX_DECK];
    int i;
   
    for (i = 0; i < MAX_DECK; i++)
    { 
        empty_deck[i]="";
    }
    int j;
    
        G->discardCount[player]=G->deckCount[player];
    for(j=0;j<G->discardCount[player]; j++){
       
        G->discard[player][j]= j;
    }



    printf("Test 1) Testing when deck is empty, discard pile is shuffled, then added to deck\npreconditions: deck is empty, discard is full of unique cards (to check shuffle)\npostconditions: deck has cards\n");
    deckCount=G->deckCount[player]; //deck count stored
    G->deckCount[player]=0;                 // deck count in state set to zero
    G->hand[player][0]=7;                       // adventurer card put in player's hand at pos zero
    memcpy(G->deck[player], empty_deck, sizeof(int) * deckCount);   // player's deck is emptied
    printf("\n(before function call, to compare with deck cards post function call)\n");   
   printDiscard(player,G);                     

    printf("\n(deckCount before calling play_adventurer: %d)\n",G->deckCount[player]);
    printf("results: \n");
    play_adventurer(player,G,0);           //takes player, game ptr, and hand position of adventurer card
    printf("(deck count after calling play_adventurer)\n - Expected: at least 1 Actual: %d\n\n", G->deckCount[player]);
    
    printf("(Visual check to see that new cards in deck are shuffled)\n");
    printDeck(player,G);
    
    
         
}
int main() {
    int newCards = 2;
    int discarded = 0;		// no discard in play_adventurer card
    int xtraCoins = 0;

    int newTreas1, newTreas2;
    int G_totalcount, testG_totalcount;
    int pass_count=0, fail_count=0;
    int tcc_hand, tcc_deck, tcc_discard, tcc_total;	//tcc = treasure card count

	int i, r;
	int temphand[MAX_HAND];// moved above the if statement
	int drawntreasure=0;
	int cardDrawn=0;
    int seed = 1000;
    int numPlayers = 2;
    int thisPlayer = 0;
	struct gameState G, testG;

	int NUMCARDS = 27;
	int NUMCARDS_IN_PLAY = 17;
	int TOT_KCARDS = 20;
	int KCARD_FIRSTINDEX = adventurer;
	int MAX_KCARDS = 10;
	int MIN_STARTING_CARDS = 2;
	int MAX_STARTING_CARDS = 15;
	int k[MAX_KCARDS];					// array storing 10 cards to use in a single game
	int NUMTREASURECARDS = 3;
	int TREASURE_FIRSTINDEX = copper;

	// list of cards
	char* card[] = {"curse", "estate", "duchy", "province", "copper",
			"silver", "gold", "adventurer", "council_room", "feast",
			"gardens", "mine", "remodel", "smithy", "village",
			"baron", "great_hall", "minion", "steward", "tribute",
			"ambassador", "cutpurse", "embargo", "outpost", "salvager",
			"sea_hag", "treasure_map"};

	// declare random test variables
	int rand_kcard[MAX_KCARDS];			// adventurer and 9 other randomly selected kingdom cards
	int rand_numhandcards;				// starting number of cards in hand from 2 to 10
	int rand_numdeckcards;				// starting number of cards in deck from 2 to 10
	int rand_numdiscards;				// starting number of cards in discard from 2 to 10
	int rand_thiscard;					// 1 of 17 cardtypes in play (1 curse, 3 victory 3 treasure, 10 kingdom)
	int rand_isTreasure;				// boolean determining whether a card is a Treasure card

	int cardtype[NUMCARDS];				// counts of each card type in deck and discard (potential discards)
	int kcardcount = 0;					// count of numnber of kcards types established
	int repeat_flag;					// true if repeat was found

	printf("\t----------------- Random Testing Card: %s ----------------\n", TESTCARD);

	printf("\t***BUG FOUND: play_adventurer does not discard original adventurer card -- disregarding discard***\n");
	printf("\t***BUG FOUND: play_adventurer does not update coins -- disregarding coin update***\n");
	printf("\t  >> Initial tests perform as expected; continue only exception reporting <<\n");

	for (i=0; i<NUMCARDS; i++) { cardtype[i] = 0; }

	for (r=0; r<NUM_RUNS; r++) {
		kcardcount = 0;
		tcc_hand=0; tcc_deck=0; tcc_discard=0; tcc_total=0;

		// establish parameters of a single test case

		//		establish 10 kingdom cards to use for this game
		rand_kcard[0] = adventurer;
		kcardcount++;
		while (kcardcount < MAX_KCARDS) {
			repeat_flag = FALSE;
			rand_kcard[kcardcount] = (rand() % TOT_KCARDS) + KCARD_FIRSTINDEX;
			for (i=0; i<kcardcount; i++) {
				if (rand_kcard[kcardcount] == rand_kcard[i])
					repeat_flag = TRUE;
			}
			if (!repeat_flag)
				kcardcount++;
		}
		for (i=0; i<MAX_KCARDS; i++)
			k[i] = rand_kcard[i];
		//for (i=0; i<MAX_KCARDS; i++) printf("\trand_kcard[%d] = %s\n", i, card[k[i]]); 			printf("\n");
		//for (i=0; i<MAX_KCARDS; i++) printf("\trand_kcard[%d] = %s\n", i, card[rand_kcard[i]]); 	printf("\n");

		// initialize a game state and player cards
		initializeGame(numPlayers, k, seed, &G);

		//		establish number of cards in hand from 2 to 10
		rand_numhandcards = (rand() % (MAX_STARTING_CARDS - MIN_STARTING_CARDS + 1)) + MIN_STARTING_CARDS;
		//printf("\tstarting cards in hand: %d\n", rand_numhandcards);
		G.handCount[thisPlayer] = rand_numhandcards;
		G.hand[thisPlayer][0] = adventurer;

		//		establish number of cards in deck from 2 to 10
		rand_numdeckcards = (rand() % (MAX_STARTING_CARDS - MIN_STARTING_CARDS + 1)) + MIN_STARTING_CARDS;
		//printf("\tstarting cards in deck: %d\n", rand_numdeckcards);
		G.deckCount[thisPlayer] = rand_numdeckcards;

		//		establish number of cards in discard from 2 to 10
		rand_numdiscards = (rand() % (MAX_STARTING_CARDS - MIN_STARTING_CARDS + 1)) + MIN_STARTING_CARDS;
		//printf("\tstarting cards in discard: %d\n", rand_numdiscards);
		G.discardCount[thisPlayer] = rand_numdiscards;

		//		establish each card
		//			cards in hand
		G.hand[thisPlayer][0] = adventurer;
		for (i=1; i<rand_numhandcards; i++) {
			rand_isTreasure = rand() % 2;
			if (rand_isTreasure) {
				G.hand[thisPlayer][i] = (rand() % NUMTREASURECARDS) + TREASURE_FIRSTINDEX;
				tcc_hand++;
			}
			else {
				rand_thiscard = rand() % (NUMCARDS_IN_PLAY - NUMTREASURECARDS);
				if (rand_thiscard < TREASURE_FIRSTINDEX)
					G.hand[thisPlayer][i] = rand_thiscard;
				else {
					G.hand[thisPlayer][i] = k[rand_thiscard - TREASURE_FIRSTINDEX];
				}
			}
		}
		//for (i=0; i<rand_numhandcards; i++) printf("\t\thandcard[%d] = %s\n", i, card[G.hand[thisPlayer][i]]);

		//			cards in deck
		for (i=0; i<rand_numdeckcards; i++) {
			rand_isTreasure = rand() % 2;
			if (rand_isTreasure) {
				G.deck[thisPlayer][i] = (rand() % NUMTREASURECARDS) + TREASURE_FIRSTINDEX;
				tcc_deck++;
			}
			else {
				rand_thiscard = rand() % (NUMCARDS_IN_PLAY - NUMTREASURECARDS);
				if (rand_thiscard < TREASURE_FIRSTINDEX)
					G.deck[thisPlayer][i] = rand_thiscard;
				else
					G.deck[thisPlayer][i] = k[rand_thiscard - TREASURE_FIRSTINDEX];
			}
		}
		for (i=0; i<rand_numdeckcards; i++) cardtype[G.deck[thisPlayer][i]]++;
		//for (i=0; i<rand_numdeckcards; i++) printf("\t\tdeckcard[%d] = %s\n", i, card[G.deck[thisPlayer][i]]);

		//			cards in discard
		for (i=0; i<rand_numdiscards; i++) {
			rand_isTreasure = rand() % 2;
			if (rand_isTreasure) {
				G.discard[thisPlayer][i] = (rand() % NUMTREASURECARDS) + TREASURE_FIRSTINDEX;
				tcc_discard++;
			}
			else {
				rand_thiscard = rand() % (NUMCARDS_IN_PLAY - NUMTREASURECARDS);
				if (rand_thiscard < TREASURE_FIRSTINDEX)
					G.discard[thisPlayer][i] = rand_thiscard;
				else
					G.discard[thisPlayer][i] = k[rand_thiscard - TREASURE_FIRSTINDEX];
			}
		}
		for (i=0; i<rand_numdiscards; i++) cardtype[G.discard[thisPlayer][i]]++;
		//for (i=0; i<rand_numdiscards; i++) printf("\t\tdiscard[%d] = %s\n", i, card[G.deck[thisPlayer][i]]);

		tcc_total = tcc_hand + tcc_deck + tcc_discard;

		// -------- TEST: execute a single test case ---------------

		// copy the game state to a test case
		memcpy(&testG, &G, sizeof(struct gameState));
		play_adventurer(thisPlayer, drawntreasure, cardDrawn, temphand, &testG);

		G_totalcount = G.handCount[thisPlayer] + G.deckCount[thisPlayer] + G.discardCount[thisPlayer];
		testG_totalcount = testG.handCount[thisPlayer] + testG.deckCount[thisPlayer] + testG.discardCount[thisPlayer];
		newTreas1 = testG.hand[thisPlayer][testG.handCount[thisPlayer]-1];
		newTreas2 = testG.hand[thisPlayer][testG.handCount[thisPlayer]-2];

		discarded = 0; // modifying because BUG FOUND - play adventurer does not discard orig adventurer
		xtraCoins = 0; // modifying because BUG FOUND - play_adventurer does not update coins.
		newCards = (tcc_deck + tcc_discard >= 2)? 2: tcc_deck + tcc_discard;	// lower of 2 or #Treasures in deck+discard

		if (testG.handCount[thisPlayer] != G.handCount[thisPlayer] + newCards - discarded) { fail_count++;
			printf("\n\tTEST %d: orig {handcount, deckcount, discardcount, total} = {%d, %d, %d, %d}\n",
					r, G.handCount[thisPlayer], G.deckCount[thisPlayer], G.discardCount[thisPlayer], G_totalcount);
			printf("\tnew {handcount, deckcount, discardcount, total} = {%d, %d, %d, %d}\n",
					testG.handCount[thisPlayer], testG.deckCount[thisPlayer], testG.discardCount[thisPlayer], testG_totalcount);
			printf("\torig treasure card count {handcount, deckcount, discardcount, total} = {%d, %d, %d, %d}\n",
					tcc_hand, tcc_deck, tcc_discard, tcc_total);
			printf("\thand count = %d, expected = %d\n", testG.handCount[thisPlayer], G.handCount[thisPlayer] + newCards - discarded);
			printf("\torig last 2 card: %s, %s\n", card[G.hand[thisPlayer][G.handCount[thisPlayer]-1]],
					card[G.hand[thisPlayer][G.handCount[thisPlayer]-2]]);
			printf("\tnew last 2 cards: %s, %s\n", card[newTreas1], card[newTreas2]);
			printf("\tCoin before: %d, Coin after: %d\n", G.coins, testG.coins);

			//printf("\t\tdeck count = %d, expected = %d\n", testG.deckCount[thisPlayer], G.deckCount[thisPlayer] - newCards + shuffledCards);
			//printf("\t\tcoins = %d, expected = %d\n\n", testG.coins, G.coins + xtraCoins);
			//assert(testG.handCount[thisPlayer] == G.handCount[thisPlayer] + newCards - discarded);
			//assert(testG.deckCount[thisPlayer] == G.deckCount[thisPlayer] - newCards + shuffledCards);
			//assert(testG.coins == G.coins + xtraCoins);
		} else pass_count++;
	}

	// output the counts of initialized deck and discard cards
	printf("\n\tNumber of test cases: %d.  PASS=%d  FAIL=%d\n\n", NUM_RUNS, pass_count, fail_count);
	for (i=0; i<NUMCARDS; i++)
		printf("\tcard %-15s==> # times in either deck or discard count: %d\n", card[i], cardtype[i]);



	return 0;
}
Exemplo n.º 3
0
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
{
  int i;
  int j;
  int k;
  int x;
  int index;
  int currentPlayer = whoseTurn(state);
  int nextPlayer = currentPlayer + 1;

  int tributeRevealedCards[2] = {-1, -1};
  int temphand[MAX_HAND];// moved above the if statement
  int drawntreasure=0;
  int cardDrawn;
  int z = 0;// this is the counter for the temp hand
  if (nextPlayer > (state->numPlayers - 1)){
    nextPlayer = 0;
  }

	
  //uses switch to select card and perform actions
  switch( card ) 
  {
    case adventurer:

      play_adventurer(&currentPlayer, state, &cardDrawn, drawntreasure, &z, temphand);
      
      return 0;
			
    case council_room:
      //+4 Cards
      for (i = 0; i < 4; i++)
	{
	  drawCard(currentPlayer, state);
	}
			
      //+1 Buy
      state->numBuys++;
			
      //Each other player draws a card
      for (i = 0; i < state->numPlayers; i++)
	{
	  if ( i != currentPlayer )
	    {
	      drawCard(i, state);
	    }
	}
			
      //put played card in played card pile
      discardCard(handPos, currentPlayer, state, 0);
			
      return 0;
			
    case feast:
      //gain card with cost up to 5
      //Backup hand
      for (i = 0; i <= state->handCount[currentPlayer]; i++){
	temphand[i] = state->hand[currentPlayer][i];//Backup card
	state->hand[currentPlayer][i] = -1;//Set to nothing
      }
      //Backup hand

      //Update Coins for Buy
      updateCoins(currentPlayer, state, 5);
      x = 1;//Condition to loop on
      while( x == 1) {//Buy one card
	if (supplyCount(choice1, state) <= 0){
	  if (DEBUG)
	    printf("None of that card left, sorry!\n");

	  if (DEBUG){
	    printf("Cards Left: %d\n", supplyCount(choice1, state));
	  }
	}
	else if (state->coins < getCost(choice1)){
	  printf("That card is too expensive!\n");

	  if (DEBUG){
	    printf("Coins: %d < %d\n", state->coins, getCost(choice1));
	  }
	}
	else{

	  if (DEBUG){
	    printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]);
	  }

	  gainCard(choice1, state, 0, currentPlayer);//Gain the card
	  x = 0;//No more buying cards

	  if (DEBUG){
	    printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]);
	  }

	}
      }     

      //Reset Hand
      for (i = 0; i <= state->handCount[currentPlayer]; i++){
	state->hand[currentPlayer][i] = temphand[i];
	temphand[i] = -1;
      }
      //Reset Hand
      			
      return 0;
			
    case gardens:
      return -1;
			
    case mine:
      j = state->hand[currentPlayer][choice1];  //store card we will trash

      if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold)
	{
	  return -1;
	}
		
      if (choice2 > treasure_map || choice2 < curse)
	{
	  return -1;
	}

      if ( (getCost(state->hand[currentPlayer][choice1]) + 3) > getCost(choice2) )
	{
	  return -1;
	}

      gainCard(choice2, state, 2, currentPlayer);

      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);

      //discard trashed card
      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (state->hand[currentPlayer][i] == j)
	    {
	      discardCard(i, currentPlayer, state, 0);			
	      break;
	    }
	}
			
      return 0;
			
    case remodel:
      j = state->hand[currentPlayer][choice1];  //store card we will trash

      if ( (getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2) )
	{
	  return -1;
	}

      gainCard(choice2, state, 0, currentPlayer);

      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);

      //discard trashed card
      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (state->hand[currentPlayer][i] == j)
	    {
	      discardCard(i, currentPlayer, state, 0);			
	      break;
	    }
	}


      return 0;
		
    case smithy:
      
      play_smithy(&currentPlayer, state, &handPos);
      return 0;
		
    case village:
      play_village(&currentPlayer, state, &handPos);
      return 0;
		
    case baron:
      state->numBuys++;//Increase buys by 1!
      if (choice1 > 0){//Boolean true or going to discard an estate
	int p = 0;//Iterator for hand!
	int card_not_discarded = 1;//Flag for discard set!
	while(card_not_discarded){
	  if (state->hand[currentPlayer][p] == estate){//Found an estate card!
	    state->coins += 4;//Add 4 coins to the amount of coins
	    state->discard[currentPlayer][state->discardCount[currentPlayer]] = state->hand[currentPlayer][p];
	    state->discardCount[currentPlayer]++;
	    for (;p < state->handCount[currentPlayer]; p++){
	      state->hand[currentPlayer][p] = state->hand[currentPlayer][p+1];
	    }
	    state->hand[currentPlayer][state->handCount[currentPlayer]] = -1;
	    state->handCount[currentPlayer]--;
	    card_not_discarded = 0;//Exit the loop
	  }
	  else if (p > state->handCount[currentPlayer]){
	    if(DEBUG) {
	      printf("No estate cards in your hand, invalid choice\n");
	      printf("Must gain an estate if there are any\n");
	    }
	    if (supplyCount(estate, state) > 0){
	      gainCard(estate, state, 0, currentPlayer);
	      state->supplyCount[estate]--;//Decrement estates
	      if (supplyCount(estate, state) == 0){
		isGameOver(state);
	      }
	    }
	    card_not_discarded = 0;//Exit the loop
	  }
			    
	  else{
	    p++;//Next card
	  }
	}
      }
			    
      else{
	if (supplyCount(estate, state) > 0){
	  gainCard(estate, state, 0, currentPlayer);//Gain an estate
	  state->supplyCount[estate]--;//Decrement Estates
	  if (supplyCount(estate, state) == 0){
	    isGameOver(state);
	  }
	}
      }
	    
      
      return 0;
		
    case great_hall:
      play_great_hall(&currentPlayer, state, &handPos);
      return 0;
		
    case minion:
      //+1 action
      state->numActions++;
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
			
      if (choice1)		//+2 coins
	{
	  state->coins = state->coins + 2;
	}
			
      else if (choice2)		//discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
	{
	  //discard hand
	  while(numHandCards(state) > 0)
	    {
	      discardCard(handPos, currentPlayer, state, 0);
	    }
				
	  //draw 4
	  for (i = 0; i < 4; i++)
	    {
	      drawCard(currentPlayer, state);
	    }
				
	  //other players discard hand and redraw if hand size > 4
	  for (i = 0; i < state->numPlayers; i++)
	    {
	      if (i != currentPlayer)
		{
		  if ( state->handCount[i] > 4 )
		    {
		      //discard hand
		      while( state->handCount[i] > 0 )
			{
			  discardCard(handPos, i, state, 0);
			}
							
		      //draw 4
		      for (j = 0; j < 4; j++)
			{
			  drawCard(i, state);
			}
		    }
		}
	    }
				
	}
      return 0;
		
    case steward:
      if (choice1 == 1)
	{
	  //+2 cards
	  drawCard(currentPlayer, state);
	  drawCard(currentPlayer, state);
	}
      else if (choice1 == 2)
	{
	  //+2 coins
	  state->coins = state->coins + 2;
	}
      else
	{
	  //trash 2 cards in hand
	  discardCard(choice2, currentPlayer, state, 1);
	  discardCard(choice3, currentPlayer, state, 1);
	}
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case tribute:
      if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){
	if (state->deckCount[nextPlayer] > 0){
	  tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	  state->deckCount[nextPlayer]--;
	}
	else if (state->discardCount[nextPlayer] > 0){
	  tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1];
	  state->discardCount[nextPlayer]--;
	}
	else{
	  //No Card to Reveal
	  if (DEBUG){
	    printf("No cards to reveal\n");
	  }
	}
      }
	    
      else{
	if (state->deckCount[nextPlayer] == 0){
	  for (i = 0; i < state->discardCount[nextPlayer]; i++){
	    state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck
	    state->deckCount[nextPlayer]++;
	    state->discard[nextPlayer][i] = -1;
	    state->discardCount[nextPlayer]--;
	  }
			    
	  shuffle(nextPlayer,state);//Shuffle the deck
	} 
	tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
	state->deckCount[nextPlayer]--;
	tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
	state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
	state->deckCount[nextPlayer]--;
      }    
		       
      if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one 
	state->playedCards[state->playedCardCount] = tributeRevealedCards[1];
	state->playedCardCount++;
	tributeRevealedCards[1] = -1;
      }

      for (i = 0; i <= 2; i ++){
	if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards
	  state->coins += 2;
	}
		    
	else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found
	  drawCard(currentPlayer, state);
	  drawCard(currentPlayer, state);
	}
	else{//Action Card
	  state->numActions = state->numActions + 2;
	}
      }
	    
      return 0;
		
    case ambassador:
      j = 0;		//used to check if player has enough cards to discard

      if (choice2 > 2 || choice2 < 0)
	{
	  return -1;				
	}

      if (choice1 == handPos)
	{
	  return -1;
	}

      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1)
	    {
	      j++;
	    }
	}
      if (j < choice2)
	{
	  return -1;				
	}

      if (DEBUG) 
	printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]);

      //increase supply count for choosen card by amount being discarded
      state->supplyCount[state->hand[currentPlayer][choice1]] += choice2;
			
      //each other player gains a copy of revealed card
      for (i = 0; i < state->numPlayers; i++)
	{
	  if (i != currentPlayer)
	    {
	      gainCard(state->hand[currentPlayer][choice1], state, 0, i);
	    }
	}

      //discard played card from hand
      discardCard(handPos, currentPlayer, state, 0);			

      //trash copies of cards returned to supply
      for (j = 0; j < choice2; j++)
	{
	  for (i = 0; i < state->handCount[currentPlayer]; i++)
	    {
	      if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1])
		{
		  discardCard(i, currentPlayer, state, 1);
		  break;
		}
	    }
	}			

      return 0;
		
    case cutpurse:

      updateCoins(currentPlayer, state, 2);
      for (i = 0; i < state->numPlayers; i++)
	{
	  if (i != currentPlayer)
	    {
	      for (j = 0; j < state->handCount[i]; j++)
		{
		  if (state->hand[i][j] == copper)
		    {
		      discardCard(j, i, state, 0);
		      break;
		    }
		  if (j == state->handCount[i])
		    {
		      for (k = 0; k < state->handCount[i]; k++)
			{
			  if (DEBUG)
			    printf("Player %d reveals card number %d\n", i, state->hand[i][k]);
			}	
		      break;
		    }		
		}
					
	    }
				
	}				

      //discard played card from hand
      discardCard(handPos, currentPlayer, state, 0);			

      return 0;

		
    case embargo: 
      //+2 Coins
      state->coins = state->coins + 2;
			
      //see if selected pile is in play
      if ( state->supplyCount[choice1] == -1 )
	{
	  return -1;
	}
			
      //add embargo token to selected supply pile
      state->embargoTokens[choice1]++;
			
      //trash card
      discardCard(handPos, currentPlayer, state, 1);		
      return 0;
		
    case outpost:
      //set outpost flag
      state->outpostPlayed++;
			
      //discard card
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case salvager:
      //+1 buy
      state->numBuys++;
			
      if (choice1)
	{
	  //gain coins equal to trashed card
	  state->coins = state->coins + getCost( handCard(choice1, state) );
	  //trash card
	  discardCard(choice1, currentPlayer, state, 1);	
	}
			
      //discard card
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case sea_hag:
      play_sea_hag(state, &currentPlayer);
      return 0;
		
    case treasure_map:
      //search hand for another treasure_map
      index = -1;
      for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
	  if (state->hand[currentPlayer][i] == treasure_map && i != handPos)
	    {
	      index = i;
	      break;
	    }
	}
      if (index > -1)
	{
	  //trash both treasure cards
	  discardCard(handPos, currentPlayer, state, 1);
	  discardCard(index, currentPlayer, state, 1);

	  //gain 4 Gold cards
	  for (i = 0; i < 4; i++)
	    {
	      gainCard(gold, state, 1, currentPlayer);
	    }
				
	  //return success
	  return 1;
	}
			
      //no second treasure_map found in hand
      return -1;
    }
	
  return -1;
}