Example #1
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:
		zzzadventurercardplay(drawntreasure, currentPlayer, cardDrawn, temphand, z,
				state);
      return 0;
			
    case council_room:
      //+4 Cards
		zzzcouncilroomcardplay(i, currentPlayer, handPos, state);
      return 0;
			
    case feast:
      //gain card with cost up to 5
      //Backup hand
		zzzfeastcardplay(i, currentPlayer, temphand, x, choice1, state);
      //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:
      //+3 Cards
		zzzsmithycardplay(i, currentPlayer, handPos, state);
      return 0;
		
    case village:
      //+1 Card
		zzzvillagecardplay(currentPlayer, handPos, state);
      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:
      //+1 Card     
      //+1 Actions  	
      //discard card from hand      
	  zzzgreathallcardplay(currentPlayer, handPos, state);
      return 0;
		
    case minion:
      zzzminioncardplay(i, j, choice1, choice2, currentPlayer, handPos, 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   
			
      //discard card
      zzzoutpostcardplay(currentPlayer, handPos, state);
      return 0;
		
    case salvager:
      //+1 buy      
	  //gain coins equal to trashed card	  
	  //trash card			
      //discard card
      zzzsalvagercardplay(choice1, currentPlayer, handPos, state);
      return 0;
		
    case sea_hag:
      zzzseahagcardplay(i, currentPlayer, state);
      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;
}
int main(){
	SelectStream(2);
	PutSeed(time(NULL));

	int num_tests = 5000;
	struct gameState state, previous;
#if(NOISY_TEST == 1)
	printf("Testing Adventurer against %d random gamestates\n", num_tests);
#endif
	for(int test = 0; test < num_tests; test++){
		for(int p = 0; p < MAX_PLAYERS; p++){
			//start adventurer specific counters
			int drawnTreasure = 0;
			int cardDrawn = 0;
			int tempHand[MAX_HAND];
			int z = 0;
			//end adventurer specific counters
			int treasures_in_deck = 0;
			int treasures_in_hand = 0;
			int prev;
			random_gamestate(&state);
			int adventurer_pos = (int)(Random()*state.handCount[p]);	//random adventurer position
			state.hand[p][adventurer_pos] = adventurer;
			int d = state.deckCount[p];
			previous = state;
		
			//count treasures in deck
			for(int i = 0; i < state.deckCount[p]; i++)
				if(state.deck[p][i] == copper || state.deck[p][i] == silver || state.deck[p][i] == gold)
					treasures_in_deck+=1;
			
#if(NOISY_TEST == 1)
			printf("Randomly generated deck contains %d treasure cards\n", treasures_in_deck);
#endif
			
			//count treasures in hand
			for(int i = 0; i < state.handCount[p]; i++)
				if(state.hand[p][i] == copper || state.hand[p][i] == silver || state.hand[p][i] == gold)
					treasures_in_hand+=1;
#if(NOISY_TEST == 1)
			printf("Randomly generated hand contains %d treasure cards\n", treasures_in_hand);
#endif
			zzzadventurercardplay(drawnTreasure, p, cardDrawn, tempHand, z, &state);


			//check hand size
			if(d<2){
				if(treasures_in_deck >= d){
#if(NOISY_TEST == 1)
					printf("Hand Size: %d, Expected: %d\n", state.handCount[p], previous.handCount[p] -1 + d);
#endif
#if(ASSERTS == 1)
					assert(state.handCount[p] == previous.handCount[p] - 1 + d);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Hand Size: %d, Expected: %d\n", state.handCount[p], previous.handCount[p] -1 + treasures_in_deck);
#endif
#if(ASSERTS == 1)
					assert(state.handCount[p] == previous.handCount[p] - 1 + treasures_in_deck);
#endif
			}}
			else{
				if(treasures_in_deck < 2){
#if(NOISY_TEST == 1)
					printf("Hand Size: %d, Expected: %d\n", state.handCount[p], previous.handCount[p] -1 + treasures_in_deck);
#endif
#if(ASSERTS == 1)
					assert(state.handCount[p] == previous.handCount[p] -1 + treasures_in_deck);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Hand Size: %d, Expected: %d\n", state.handCount[p], previous.handCount[p] +1);
#endif
#if(ASSERTS == 1)
					assert(state.handCount[p] == previous.handCount[p] +1);
#endif
			}}		

			//check deck size
			if(d<2){
				if(treasures_in_deck >= d){
#if(NOISY_TEST == 1)
					printf("Deck + Discard + Played: %d, Expected: %d\n", state.discardCount[p] + state.playedCardCount + state.deckCount[p], previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - d );
#endif
#if(ASSERTS == 1)
					assert(state.discardCount[p] + state.playedCardCount + state.deckCount[p] == previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - d);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Deck + Discard + Played: %d, Expected: %d\n", state.discardCount[p] + state.playedCardCount + state.deckCount[p], previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - treasures_in_deck );	
#endif
#if(ASSERTS == 1)
					assert(state.discardCount[p] + state.playedCardCount + state.deckCount[p] == previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - treasures_in_deck);
#endif
			}}
			else{
				if(treasures_in_deck < 2){
#if(NOISY_TEST == 1)
					printf("Deck + Discard + Played: %d, Expected: %d\n", state.discardCount[p] + state.playedCardCount + state.deckCount[p], previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - treasures_in_deck);	
#endif
#if(ASSERTS == 1)
					assert(state.discardCount[p] + state.playedCardCount + state.deckCount[p] == previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] + 1 - treasures_in_deck);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Deck + Discard + Played: %d, Expected: %d\n", state.discardCount[p] + state.playedCardCount + state.deckCount[p], previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] -1);	
#endif
#if(ASSERTS == 1)
					assert(state.discardCount[p] + state.playedCardCount + state.deckCount[p] == previous.discardCount[p] + previous.playedCardCount + previous.deckCount[p] -1);
#endif
					
			}}		

			//check treasures in hand
			prev = treasures_in_hand;
			treasures_in_hand = 0;
			for(int i = 0; i < state.handCount[p]; i++)
				if(state.hand[p][i] == copper || state.hand[p][i] == silver || state.hand[p][i] == gold)
					treasures_in_hand++;
			
			if(d<2){
				if(treasures_in_deck >= d){
#if(NOISY_TEST == 1)
					printf("Treasures in Hand: %d, Expected: %d\n", treasures_in_hand, prev + d);
#endif
#if(ASSERTS == 1)
					assert(treasures_in_hand == prev + d);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Treasures in Hand: %d, Expected: %d\n", treasures_in_hand, prev + treasures_in_deck);
#endif
#if(ASSERTS == 1)
					assert(treasures_in_hand == prev+treasures_in_deck);
#endif
			}}
			else{
				if(treasures_in_deck < 2){
#if(NOISY_TEST == 1)
					printf("Treasures in Hand: %d, Expected: %d\n", treasures_in_hand, prev + treasures_in_deck);
#endif
#if(ASSERTS == 1)
					assert(treasures_in_hand == prev+treasures_in_deck);
#endif
				}else{
#if(NOISY_TEST == 1)
					printf("Treasures in Hand: %d, Expected: %d\n", treasures_in_hand, prev + 2);
#endif
#if(ASSERTS == 1)
					assert(treasures_in_hand == prev + 2);
#endif
			}}		
			
		}//end players loop
	}//end tests loop

#if(NOISY_TEST == 1)
	printf("Finished testing adventurer on %d random gamestates\n", num_tests);
#endif
#if(ASSERTS == 1)
	printf("Tests passed.\n");
#endif
}//end main