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:
      while(drawntreasure<2){
	if (state->deckCount[currentPlayer] <1){//if the deck is empty we need to shuffle discard and add to deck
	  shuffle(currentPlayer, state);
	}
	drawCard(currentPlayer, state);
	cardDrawn = state->hand[currentPlayer][state->handCount[currentPlayer]-1];//top card of hand is most recently drawn card.
	if (cardDrawn == copper || cardDrawn == silver || cardDrawn == gold)
	  drawntreasure++;
	else{
	  temphand[z]=cardDrawn;
	  state->handCount[currentPlayer]--; //this should just remove the top card (the most recently drawn one).
	  z++;
	}
      }
      while(z-1>=0){
	state->discard[currentPlayer][state->discardCount[currentPlayer]++]=temphand[z-1]; // discard all cards in play that have been drawn
	z=z-1;
      }
      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:
      //+3 Cards
      for (i = 0; i < 3; i++)
	{
	  drawCard(currentPlayer, state);
	}
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
      return 0;
		
    case village:
      //+1 Card
      drawCard(currentPlayer, state);
			
      //+2 Actions
      state->numActions = state->numActions + 2;
			
      //discard played card from hand
      discardCard(handPos, currentPlayer, state, 0);
      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
      drawCard(currentPlayer, state);
			
      //+1 Actions
      state->numActions++;
			
      //discard card from hand
      discardCard(handPos, currentPlayer, state, 0);
      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:
      for (i = 0; i < state->numPlayers; i++){
	if (i != currentPlayer){
	  state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--];			    state->deckCount[i]--;
	  state->discardCount[i]++;
	  state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse
	}
      }
      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 cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
{
	int i;
	int j;
	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:
		playedCard(handPos, NULL, NULL, state);
		while (drawntreasure < 2) {
			if (drawCard(currentPlayer, state) == -1)
				break;
			cardDrawn = state->hand[currentPlayer][state->handCount[currentPlayer] - 1];//top card of hand is most recently drawn card.
			if (cardDrawn == copper || cardDrawn == silver || cardDrawn == gold)
				drawntreasure++;
			else {
				temphand[z] = cardDrawn;
				state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1;
				state->handCount[currentPlayer]--; //this should just remove the top card (the most recently drawn one).
				z++;
			}
		}
 /* MUTANT (rep_const) */		while (z > -1) {
			state->discard[currentPlayer][state->discardCount[currentPlayer]++] = temphand[z - 1]; // discard all cards in play that have been drawn
			z--;
		}
		endPlayed(state, 0);
		return 0;

	case council_room:
		return councilRoomEffect(currentPlayer, handPos, state);

	case feast:
		if (choice1 < curse || choice1 > treasure_map)
			return -1;

		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));
			}
			return -1;
		}
		else if (5 < getCost(choice1)) {
			if (DEBUG) {
				printf("That card is too expensive!\n");
				printf("Coins: %d < %d\n", state->coins, getCost(choice1));
			}
			return -1;
		}	

		playedCard(handPos, NULL, NULL, state);

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

		gainCard(choice1, state, 0, currentPlayer);//Gain the card

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

		//trash feast
		endPlayed(state, 1);

		return 0;

	case gardens:
		return -1;

	case mine:
		if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos)
			return -1;

		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 > gold || choice2 < copper)
		{
			return -1;
		}

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

		playedCard(handPos, &choice1, NULL, state);

		//trash old treasure
		discardCard(choice1, currentPlayer, state, 1);

		//gain new treasure
		gainCard(choice2, state, 2, currentPlayer);

		endPlayed(state, 0);

		return 0;

	case remodel:
		if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos)
			return -1;

		if (choice2 < curse || choice2 > treasure_map)
			return -1;

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

		playedCard(handPos, &choice1, NULL, state);

		//trash choice
		discardCard(choice1, currentPlayer, state, 1);

		//gain new card
		gainCard(choice2, state, 0, currentPlayer);

		endPlayed(state, 0);
		return 0;

	case smithy:
		return smithyEffect(currentPlayer, handPos, state);

	case village:
		return villageEffect(currentPlayer, handPos, state);

	case baron:
		if (!(choice1 == 1 || choice1 == 2))
			return -1;

		if (choice1 == 1) {//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 (p >= state->handCount[currentPlayer]) {
					if (DEBUG) {
						printf("No estate cards in your hand, invalid choice\n");						
					}
					return -1;
				}
				else if (state->hand[currentPlayer][p] == estate) {//Found an estate card!
					playedCard(handPos, &p, NULL, state);
					*bonus += 4;//Add 4 coins to the amount of coins
					discardCard(p, currentPlayer, state, 0);
					card_not_discarded = 0;//Exit the loop
				}
				else {
					p++;//Next card
				}
			}
		}

		else {
			playedCard(handPos, NULL, NULL, state);
			gainCard(estate, state, 0, currentPlayer);//Gain an estate	
		}
		state->numBuys++;//Increase buys by 1!
		endPlayed(state, 0);
		return 0;

	case great_hall:
		return greatHallEffect(currentPlayer, handPos, state);

	case minion:
		if (!(choice1 == 1 || choice1 == 2))
			return -1;

		playedCard(handPos, NULL, NULL, state);

		//+1 action
		state->numActions++;

		if (choice1 == 1)      //+2 coins
		{
			*bonus += 2;
		}

		else if (choice1 == 2)     //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
		{
			//discard hand
			while (numHandCards(state) > 0)
			{
				discardCard(0, 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(0, i, state, 0);
						}

						//draw 4
						for (j = 0; j < 4; j++)
						{
							drawCard(i, state);
						}
					}
				}
			}

		}
		endPlayed(state, 0);
		return 0;

	case steward:
		if (!(choice1 == 1 || choice1 == 2 || choice1 == 3))
			return -1;
		if (choice1 == 3 && ((choice2 >= state->handCount[currentPlayer] || choice2 < 0) || (choice3 >= state->handCount[currentPlayer] || choice3 < 0) || choice2 == choice3 || (choice2 == handPos || choice3 == handPos)))
			return -1;

		if (choice1 == 1)
		{
			playedCard(handPos, NULL, NULL, state);
			//+2 cards
			drawCard(currentPlayer, state);
			drawCard(currentPlayer, state);
		}
		else if (choice1 == 2)
		{
			//+2 coins
			playedCard(handPos, NULL, NULL, state);
			*bonus += 2;
		}
		else
		{
			playedCard(handPos, &choice2, &choice3, state);
			//trash 2 cards in hand
			if (choice2 < choice3) {
				int tmp = choice2;
				choice2 = choice3;
				choice3 = tmp;
			}

			//discard order matters, must discard max to min for correct effect
			discardCard(choice2, currentPlayer, state, 1);
			discardCard(choice3, currentPlayer, state, 1);			
		}
		endPlayed(state, 0);
		return 0;

	case tribute:
		playedCard(handPos, NULL, NULL, state);
		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]--;
				state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[0];
				state->discardCount[nextPlayer]++;
			}
			else if (state->discardCount[nextPlayer] > 0) {
				tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer] - 1];
			}
			else {
				//No Card to Reveal
				if (DEBUG) {
					printf("No cards to reveal\n");
				}
				endPlayed(state, 0);
				return 0;
			}
		}

		else {
			if (state->deckCount[nextPlayer] == 0) {
				j = state->discardCount[nextPlayer];
				for (i = 0; i < j; 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] = -1;
			state->deckCount[nextPlayer]--;

			if (state->deckCount[nextPlayer] == 0) {
				j = state->discardCount[nextPlayer];
				for (i = 0; i < j; 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
			}

			state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[0];
			state->discardCount[nextPlayer]++;

			tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer] - 1];
			state->deck[nextPlayer][state->deckCount[nextPlayer] - 1] = -1;
			state->deckCount[nextPlayer]--;
			state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[1];
			state->discardCount[nextPlayer]++;
		}

		if (tributeRevealedCards[0] == tributeRevealedCards[1]) {//If we have a duplicate card, just drop one 
			tributeRevealedCards[1] = -1;
		}

		for (i = 0; i < 2; i++) {
			if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) {//Treasure cards
				*bonus += 2;
			}

			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);
			}
			if (tributeRevealedCards[i] >= adventurer && tributeRevealedCards[i] <= treasure_map){//Action Card
				state->numActions = state->numActions + 2;
			}
		}

		endPlayed(state, 0);

		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 || choice1 >= numHandCards(state) || choice1 < 0)
		{
			return -1;
		}

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

		playedCard(handPos, &choice1, NULL, state);

		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);
			}
		}

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

		endPlayed(state, 0);

		return 0;

	case cutpurse:
		return cutpurseEffect(currentPlayer, handPos, state, bonus);

	case embargo:
		if (choice1 < curse || choice1 > treasure_map)
			return -1;
		//see if selected pile is in play
		if (state->supplyCount[choice1] == -1)
		{
			return -1;
		}

		playedCard(handPos, NULL, NULL, state);

		//+2 Coins
		*bonus += 2;

		//add embargo token to selected supply pile
		state->embargoTokens[choice1]++;

		//trash card
		endPlayed(state, 1);
		return 0;

	case outpost:
		if (state->outpostTurn == 1)
			return -1;
		
		playedCard(handPos, NULL, NULL, state);
		//set outpost flag
		state->outpostPlayed = 1;

		//we actually don't call endPlayed() here on purpose
		return 0;

	case salvager:
		if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos)
			return -1;

		playedCard(handPos, &choice1, NULL, state);

		//+1 buy
		state->numBuys++;
		
		//gain coins equal to trashed card
		*bonus += getCost(handCard(choice1, state));
		
		//trash card
		discardCard(choice1, currentPlayer, state, 1);
		
		endPlayed(state, 0);
		return 0;

	case sea_hag:
		playedCard(handPos, NULL, NULL, state);
		for (i = 0; i < state->numPlayers; i++) {
			if (i != currentPlayer) {
				if (state->deckCount[i] + state->discardCount[i] > 0) {
					if (state->deckCount[i] == 0) {
						j = state->discardCount[i];
						for (index = 0; index < j; index++) {
							state->deck[i][index] = state->discard[i][index];//Move to deck
							state->deckCount[i]++;
							state->discard[i][index] = -1;
							state->discardCount[i]--;
						}

						shuffle(i, state);//Shuffle the deck
					}
					state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i] - 1];
					state->discardCount[i]++;
					//conveniently, this happens to add it to the top of the deck
					gainCard(curse, state, 1, i);
				}
				else { //literally no cards in their deck or discard, so they just get a curse in their deck
					gainCard(curse, state, 1, i);
				}				
			}
		}
		endPlayed(state, 0);
		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){
			playedCard(handPos, &index, NULL, state);
			//trash other treasure_map
			discardCard(index, currentPlayer, state, 1);

			//gain 4 Gold cards
			for (i = 0; i < 4; i++)
			{
				gainCard(gold, state, 1, currentPlayer);
			}
		}
		else {
			return -1;
		}
		endPlayed(state, 1);
		return 0;
		
	}

	return -1;
}
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
{
	int i;
	int j;
	int k;
	int index;
	int currentPlayer = whoseTurn(state);
	int nextPlayer = currentPlayer + 1;

	int tributeRevealedCards[2] = {-1, -1};
	int drawntreasure=0;
	if (nextPlayer > (state->numPlayers - 1)){
		nextPlayer = 0;
	}
  
	
	//uses switch to select card and perform actions
	switch( card ) 
		{
		case adventurer:
			return adventurerCard (drawntreasure, state, currentPlayer);
		case council_room:
			return councilRoomCard (currentPlayer, state, handPos);
		case feast:
			return feastCard (currentPlayer, state, choice1);			
		case gardens:
			return -1;			
		case mine:
			return mineCard (currentPlayer, state, choice1, choice2, handPos);
		case remodel:
			return remodelCard (currentPlayer, state, choice1, choice2, handPos);
		case smithy:
			//+3 Cards
			for (i = 0; i < 3; i++)
				{
					drawCard(currentPlayer, state);
				}
			
			//discard card from hand
			discardCard(handPos, currentPlayer, state, 0);
			return 0;
		
		case village:
			//+1 Card
			drawCard(currentPlayer, state);
			
			//+2 Actions
			state->numActions = state->numActions + 2;
			
			//discard played card from hand
			discardCard(handPos, currentPlayer, state, 0);
			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
			drawCard(currentPlayer, state);
			
			//+1 Actions
			state->numActions++;
			
			//discard card from hand
			discardCard(handPos, currentPlayer, state, 0);
			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:
			for (i = 0; i < state->numPlayers; i++){
				if (i != currentPlayer){
					state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]-1];
					state->discardCount[i]++;
					state->deck[i][state->deckCount[i]-1] = curse;//Top card now a curse
				}
			}
			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 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:
                return adventurerEffect(state, drawntreasure, z, temphand);

        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:
                return smithyEffect(state, handPos);

        case village:
                //+1 Card
                drawCard(currentPlayer, state);

                //+2 Actions
                state->numActions = state->numActions + 2;

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

        case baron:
                return baronEffect(state, choice1);

        case great_hall:
                //+1 Card
                drawCard(currentPlayer, state);

                //+1 Actions
                state->numActions++;

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

        case minion:
                return minionEffect(state, handPos, choice1, choice2);

        case steward:
                return stewardEffect(state, handPos, choice1, choice2, choice3);

        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:
                return ambassadorEffect(state, handPos, choice1, choice2);

        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:
                return embargoEffect(state, handPos, choice1);

        case outpost:
                //set outpost flag
                state->outpostPlayed++;

                //discard card
                discardCard(handPos, state->whoseTurn, 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:
                for (i = 0; i < state->numPlayers; i++) {
                        if (i != currentPlayer) {
                                state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--];          state->deckCount[i]--;
                                state->discardCount[i]++;
                                state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse
                        }
                }
                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(int argc, char**argv){

   struct gameState Game;
   struct gameState *Ga = &Game;
   int players, ranCard, i;
   int money, cardPos, curPlayer, useCard, returnCard, buyCa;
   int k[10];
   int pool[20] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall, minion, steward, tribute, ambassador, cutpurse, embargo, outpost, salvager, sea_hag, treasure_map};

   srand(atoi(argv[1]));
   players = rand()% 3 + 2;
   ranCard = rand() % 20;

   for(i=0;i<10;i++){
      k[i] = pool[(ranCard+i)%20];
   }

   printf("Starting Game\n");
   initializeGame(players,k,atoi(argv[1]),Ga);
   printf("Number of player %d\n",players);

   while(!isGameOver(Ga)){
      money = 0;
      cardPos = -1;
      curPlayer = whoseTurn(Ga);
      for(i=0;i<numHandCards(Ga);i++){
	 if (handCard(i,Ga) == copper)
	    money++;
	 else if(handCard(i,Ga) == silver)
	    money += 2;
	 else if(handCard(i,Ga) == gold)
	    money += 3;
	 else if(handCard(i,Ga) > 6)
	    cardPos = i;
      }
      if(cardPos != -1){
     	useCard = handCard(cardPos,Ga);
      	printf("Player %d: is playing card %d\n",curPlayer,useCard);
      	returnCard = playCard(cardPos,1,1,1,Ga);
      	if(returnCard== -1)
		 printf("Playing card Failed\n",useCard);
      	else
		 printf("Playing card %d Succeded\n",useCard);
      }
      buyCa = k[rand()%10];
      printf("Player %d has %d coins\n",curPlayer,money);

      if (money >= 8){
	 printf("Player %d is trying to buy province\n",curPlayer);
	 if(buyCard(province,Ga)==-1){
	    printf("Buying Province Failed\n");}
      }
      else if (money >= getCost(buyCa)){
	 printf("Player %d is trying to by card %d \n"layer,buyCa);
	 if(buyCard(buyCa,Ga)==-1){
	    printf("Buying %d Failed\n", buyCa);}
      }
      else if (money >= 6){
	 printf("Player %d is trying to buy gold\n",curPlayer);
	 if(buyCard(gold,Ga)==-1){
	    printf("Buying Gold Faile\n");}
      }
      else if (money >= 3){
	 printf("Player %d is trying to buy silver\n",curPlayer);
	 if (buyCard(silver,Ga)==-1){
	    printf("Buying Silver Failed\n");}
      }
      printf("Player %d has %d Cards in hand\n",curPlayer,numHandCards(Ga));
      printf("Player %d ends turn\n",curPlayer);
      endTurn(Ga);


   };
   
   for(i=0;i<players;i++){
      printf("Player %d Score: %d\n",i,scoreFor(i,Ga));
   }


   return 0;
}
Example #6
0
	void FixEdgeInserterCore::findWeightedShortestPath(const CombinatorialEmbedding &E, edge eOrig, SList<adjEntry> &crossed)
	{
		node s = m_pr.copy(eOrig->source());
		node t = m_pr.copy(eOrig->target());
		OGDF_ASSERT(s != t);

		int eSubgraph = (m_pSubgraph != nullptr) ? (*m_pSubgraph)[eOrig] : 0;

		EdgeArray<int> costDual(m_dual, 0);
		int maxCost = 0;
		for(edge eDual : m_dual.edges) {
			int c = getCost(m_primalAdj[eDual]->theEdge(), eSubgraph);
			costDual[eDual] = c;
			if (c > maxCost)
				maxCost = c;
		}

		++maxCost;
		Array<SListPure<edge> > nodesAtDist(maxCost);

		NodeArray<edge> spPred(m_dual,nullptr);

		int oldIdCount = m_dual.maxEdgeIndex();

		// augment dual by edges from s to all adjacent faces of s ...
		for(adjEntry adj : s->adjEdges) {
			// starting edges of bfs-search are all edges leaving s
			edge eDual = m_dual.newEdge(m_vS, m_nodeOf[E.rightFace(adj)]);
			m_primalAdj[eDual] = adj;
			nodesAtDist[0].pushBack(eDual);
		}

		// ... and from all adjacent faces of t to t
		for(adjEntry adj : t->adjEdges) {
			edge eDual = m_dual.newEdge(m_nodeOf[E.rightFace(adj)], m_vT);
			m_primalAdj[eDual] = adj;
		}

		// actual search (using extended bfs on directed dual)
		int currentDist = 0;

		for( ; ; )
		{
			// next candidate edge
			while(nodesAtDist[currentDist % maxCost].empty())
				++currentDist;

			edge eCand = nodesAtDist[currentDist % maxCost].popFrontRet();
			node v = eCand->target();

			// leads to an unvisited node?
			if (spPred[v] == nullptr)
			{
				// yes, then we set v's predecessor in search tree
				spPred[v] = eCand;

				// have we reached t ...
				if (v == m_vT)
				{
					// ... then search is done.
					// constructed list of used edges (translated to crossed
					// adjacency entries in PG) from t back to s (including first
					// and last!)

					do {
						edge eDual = spPred[v];
						crossed.pushFront(m_primalAdj[eDual]);
						v = eDual->source();
					} while(v != m_vS);

					break;
				}

				// append next candidate edges to queue (all edges leaving v)
				appendCandidates(nodesAtDist, costDual, maxCost, v, currentDist);
			}
		}

		// remove augmented edges again
		adjEntry adj;
		while ((adj = m_vS->firstAdj()) != nullptr)
			m_dual.delEdge(adj->theEdge());

		while ((adj = m_vT->firstAdj()) != nullptr)
			m_dual.delEdge(adj->theEdge());

		m_dual.resetEdgeIdCount(oldIdCount);
	}
int playDominion(struct gameState *state, int k[10]) {
	int i;
	int cardPos, curCard, returnCard, toBuyCard, curPlayer, money;
	int numPlayers = state->numPlayers;

	while (!isGameOver(state)) {
    money = 0;
    curPlayer = whoseTurn(state);
    cardPos = -1;

		printf("\nPlayer %d's turn.\n", curPlayer);

		//Check money 
		for (i = 0; i < numHandCards(state); i++) {
			if (handCard(i, state) == copper) {
				money++;
			} else if (handCard(i, state) == silver) {
				money += 2;
			} else if (handCard(i, state) == gold) {
				money += 3;
			} else if (handCard(i, state) > 6) {
				cardPos = i;
			}
		}

		if (cardPos != -1) {
			curCard = handCard(cardPos, state);
			printf("Player %d plays %d\n", curPlayer, curCard);
			returnCard = playCard(cardPos, 1, 1, 1, state);
			if (returnCard == -1) {
				printf("Playing card %d failed\n", curCard);
			} else {
				printf ("Playing card %d succeded\n", curCard);
			}
		}

		toBuyCard = k[rand() % 10];
		printf("Player %d has %d coins\n", curPlayer, money);

		if (money >= 8) {
			printf("Player %d is trying to buy a province\n", curPlayer);
			if(buyCard(province, state) == -1) {
				printf("Failed to buy a province");
			}
		} else if (money >= getCost(toBuyCard)) {
			printf("Player %d is trying to buy card %s\n", curPlayer, getName(toBuyCard));
			if (buyCard(toBuyCard, state) == -1) {
				printf("Buying %s failed\n", getName(toBuyCard));
			}
		} else if (money >= 6) {
			printf("Player %d is trying to buy gold\n", curPlayer);
			if (buyCard(gold, state) == -1) {
				printf("Failed to buy gold\n");
			}
		} else if (money >= 3) {
			printf("Player %d is trying to buy silver\n", curPlayer);
			if (buyCard(silver, state) == -1) {
				printf("Failed to buy silver\n");
			}
		}
  printf("Player %d has %d cards in hand\n", curPlayer, numHandCards(state));
  printf("Player %d ends turn\n", curPlayer);
  endTurn(state);
	}

  for (i = 0; i < numPlayers; i++) {
    printf("Player %d's score: %d\n", i, scoreFor(i, state));
  }

	return 0;

}
Example #8
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
		zzzconsoleroomcardplay(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
		  zzzvilliagecardplay(currentPlayer, handPos, state);
      return 0;
		
    case baron:
      //+1 buy, may discard estate card and get +4coins otherwise gain an estate card
      zzzbaroncardplay(currentPlayer, choice1, state);
      return 0;
		
    case great_hall:
      zzzgreat_hallcardplay(currentPlayer, handPos, state);
      return 0;
		
    case minion:
      //+1 action
      zzzminioncardplay(handPos, choice1, choice2, i, j, currentPlayer, 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:
      zzzoutpostcardplay(currentPlayer, handPos, state);
      return 0;
		
    case salvager:
      zzzsalvagercardplay(currentPlayer, handPos, choice1, state);
      return 0;
		
    case sea_hag:
      for (i = 0; i < state->numPlayers; i++){
      	if (i != currentPlayer){
      	  state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--];			    state->deckCount[i]--;
      	  state->discardCount[i]++;
      	  state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse
      	}
      }
      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;
}
void vpTemplateTrackerMIForwardAdditional::trackNoPyr(const vpImage<unsigned char> &I)
{
  dW=0;

  double erreur=0;
  int Nbpoint=0;
  if(blur)
    vpImageFilter::filter(I, BI,fgG,taillef);
  vpImageFilter::getGradXGauss2D(I, dIx, fgG,fgdG,taillef);
  vpImageFilter::getGradYGauss2D(I, dIy, fgG,fgdG,taillef);

  double MI=0,MIprec=-1000;

  MI_preEstimation=-getCost(I,p);

  double i2,j2;
  double Tij;
  double IW,dx,dy;
  //unsigned
  int cr,ct;
  double er,et;
  double alpha=2.;

  int i,j;
  unsigned int iteration=0;

  initPosEvalRMS(p);
  do
  {
    if(iteration%5==0)
      initHessienDesired(I);
    Nbpoint=0;
    MIprec=MI;
    MI=0;
    erreur=0;

    zeroProbabilities();

    Warp->computeCoeff(p);
#ifdef VISP_HAVE_OPENMP
    int nthreads = omp_get_num_procs() ;
    //std::cout << "file: " __FILE__ << " line: " << __LINE__ << " function: " << __FUNCTION__ << " nthread: " << nthreads << std::endl;
    omp_set_num_threads(nthreads);
#pragma omp parallel for private(Tij,IW,i,j,i2,j2,cr,ct,er,et,dx,dy) default(shared)
#endif
    for(int point=0;point<(int)templateSize;point++)
    {
      i=ptTemplate[point].y;
      j=ptTemplate[point].x;
      X1[0]=j;X1[1]=i;

      Warp->computeDenom(X1,p);
      Warp->warpX(X1,X2,p);

      j2=X2[0];i2=X2[1];

      if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
      {
        Nbpoint++;
        Tij=ptTemplate[point].val;
        //Tij=Iterateurvecteur->val;
        if(!blur)
          IW=I.getValue(i2,j2);
        else
          IW=BI.getValue(i2,j2);

        dx=1.*dIx.getValue(i2,j2)*(Nc-1)/255.;
        dy=1.*dIy.getValue(i2,j2)*(Nc-1)/255.;

        ct=(int)((IW*(Nc-1))/255.);
        cr=(int)((Tij*(Nc-1))/255.);
        et=(IW*(Nc-1))/255.-ct;
        er=((double)Tij*(Nc-1))/255.-cr;

        //calcul de l'erreur
        erreur+=(Tij-IW)*(Tij-IW);

        //Calcul de l'histogramme joint par interpolation bilinÈaire (Bspline ordre 1)
        Warp->dWarp(X1,X2,p,dW);

        //double *tptemp=temp;
        double *tptemp=new double[nbParam];;
        for(unsigned int it=0;it<nbParam;it++)
          tptemp[it] =(dW[0][it]*dx+dW[1][it]*dy);
        //*tptemp++ =dW[0][it]*dIWx+dW[1][it]*dIWy;
        //std::cout<<cr<<"   "<<ct<<"  ; ";
        if(ApproxHessian==HESSIAN_NONSECOND||hessianComputation==vpTemplateTrackerMI::USE_HESSIEN_DESIRE)
          vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);
        else if(ApproxHessian==HESSIAN_0 || ApproxHessian==HESSIAN_NEW)
          vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);

        delete[] tptemp;
      }
    }

    if(Nbpoint==0)
    {
      //std::cout<<"plus de point dans template suivi"<<std::endl;
      diverge=true;
      MI=0;
      deletePosEvalRMS();
      throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
    }
    else
    {
      computeProba(Nbpoint);
      computeMI(MI);
      //std::cout<<iteration<<"\tMI= "<<MI<<std::endl;
      computeHessien(H);
      computeGradient();

      vpMatrix::computeHLM(H,lambda,HLM);
      try
      {
        switch(hessianComputation)
        {
        case vpTemplateTrackerMI::USE_HESSIEN_DESIRE:
          dp=gain*HLMdesireInverse*G;
          break;
        case vpTemplateTrackerMI::USE_HESSIEN_BEST_COND:
          if(HLM.cond()>HLMdesire.cond())
            dp=gain*HLMdesireInverse*G;
          else
            dp=gain*0.2*HLM.inverseByLU()*G;
          break;
        default:
          dp=gain*0.2*HLM.inverseByLU()*G;
          break;
        }
      }
      catch(vpException &e)
      {
        //std::cerr<<"probleme inversion"<<std::endl;
        deletePosEvalRMS();
        throw(e);
      }
    }

    switch(minimizationMethod)
    {
    case vpTemplateTrackerMIForwardAdditional::USE_LMA:
    {
      vpColVector p_test_LMA(nbParam);
      if(ApproxHessian==HESSIAN_NONSECOND)
        p_test_LMA=p-100000.1*dp;
      else
        p_test_LMA=p+1.*dp;
      MI=-getCost(I,p);
      double MI_LMA=-getCost(I,p_test_LMA);
      if(MI_LMA>MI)
      {
        p=p_test_LMA;
        lambda=(lambda/10.<1e-6)?lambda/10.:1e-6;
      }
      else
      {
        lambda=(lambda*10.<1e6)?1e6:lambda*10.;
      }
    }
      break;
    case vpTemplateTrackerMIForwardAdditional::USE_GRADIENT:
    {
      dp=-gain*6.0*G;
      if(useBrent)
      {
        alpha=2.;
        computeOptimalBrentGain(I,p,-MI,dp,alpha);
        dp=alpha*dp;
      }
      p+=1.*dp;
      break;
    }

    case vpTemplateTrackerMIForwardAdditional::USE_QUASINEWTON:
    {
      double s_scal_y;
      if(iterationGlobale!=0)
      {
        vpColVector s_quasi=p-p_prec;
        vpColVector y_quasi=G-G_prec;
        s_scal_y=s_quasi.t()*y_quasi;
        //if(s_scal_y!=0)//BFGS
        //	KQuasiNewton=KQuasiNewton-(s_quasi*y_quasi.t()*KQuasiNewton+KQuasiNewton*y_quasi*s_quasi.t())/s_scal_y+(1.+y_quasi.t()*(KQuasiNewton*y_quasi)/s_scal_y)*s_quasi*s_quasi.t()/s_scal_y;
        //if(s_scal_y!=0)//DFP
        if(std::fabs(s_scal_y) > std::numeric_limits<double>::epsilon())
          KQuasiNewton=KQuasiNewton+0.001*(s_quasi*s_quasi.t()/s_scal_y-KQuasiNewton*y_quasi*y_quasi.t()*KQuasiNewton/(y_quasi.t()*KQuasiNewton*y_quasi));
      }
      dp=-KQuasiNewton*G;
      p_prec=p;
      G_prec=G;
      p-=1.01*dp;
    }
      break;

    default:
    {
      if(ApproxHessian==HESSIAN_NONSECOND)
        dp=-0.1*dp;
      if(useBrent)
      {
        alpha=2.;
        computeOptimalBrentGain(I,p,-MI,dp,alpha);
        //std::cout<<alpha<<std::endl;
        dp=alpha*dp;
      }

      p+=1.*dp;
      break;
    }
    }

    computeEvalRMS(p);
    iteration++;
    iterationGlobale++;

  }
  while( (std::fabs(MI-MIprec) > std::fabs(MI)*std::numeric_limits<double>::epsilon()) &&(iteration< iterationMax)&&(evolRMS>threshold_RMS) );
  //while( (MI!=MIprec) &&(iteration< iterationMax)&&(evolRMS>threshold_RMS) );
  if(Nbpoint==0) {
    //std::cout<<"plus de point dans template suivi"<<std::endl;
    deletePosEvalRMS();
    throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
  }

  nbIteration=iteration;
  MI_postEstimation=-getCost(I,p);
  if(MI_preEstimation>MI_postEstimation)
  {
    MI_postEstimation = -1;
  }
  deletePosEvalRMS();
}
Example #10
0
int main()
{

        printf("This is testing the get cost function\n");
        int seed = 1000;
        int numPlayer = 2;

        int p, r, handCount;

        int k[10] = {adventurer, council_room, feast, gardens, mine
               , remodel, smithy, village, baron, great_hall};
        struct gameState G;

        p =0;
        handCount=1;

        memset(&G, 23, sizeof(struct gameState));

        r = initializeGame(numPlayer, k, seed, &G);
	//initializing a new game

        G.handCount[p] = handCount;

        if(r==-1)
        {
                exit(0);
        }

	//testing for a normal value
	int i;

        i = getCost(2);
        if (i==5)
	{
	printf("This test passed.\n");
	}
        else
	printf("This test failed.\n");
	
	//testing if value is above any card level value

	int v;
	v = getCost(30);
	if (v==-1)
	{
	 printf("This test passed.\n");
        }
        else
        printf("This test failed.\n");
	//testing another value
	v = getCost(10);
	        if (v==4)
        {
         printf("This test passed.\n");
        }
        else
        printf("This test failed.\n");

        //one more test to make sure the correct
        //value is returned 
        v = getCost(25);
        if (v!=6)
        {
         printf("This test passed.\n");
        }
        else
        printf("This test failed.\n");

        return 0;
}
bool VACVariable::averaging()
{
    Cost Top = wcsp->getUb();
    bool change = false;
    EnumeratedVariable* x;
    EnumeratedVariable* y;
    Constraint* ctr = NULL;
    ConstraintList::iterator itc = getConstrs()->begin();
    if (itc != getConstrs()->end())
        ctr = (*itc).constr;
    while (ctr) {
        if (ctr->isBinary() && !ctr->isSep()) {
            BinaryConstraint* bctr = (BinaryConstraint*)ctr;
            x = (EnumeratedVariable*)bctr->getVarDiffFrom((Variable*)this);
            for (iterator it = begin(); it != end(); ++it) {
                Cost cu = getCost(*it);
                Cost cmin = Top;
                for (iterator itx = x->begin(); itx != x->end(); ++itx) {
                    Cost cbin = bctr->getCost(this, x, *it, *itx);
                    if (cbin < cmin)
                        cmin = cbin;
                }
                assert(cmin < Top);
                Double mean = to_double(cmin + cu) / 2.;
                Double extc = to_double(cu) - mean;
                if (abs(extc) >= 1) {
                    Cost costi = (Long)extc;
                    for (iterator itx = x->begin(); itx != x->end(); ++itx) {
                        bctr->addcost(this, x, *it, *itx, costi);
                    }
                    if (mean > to_double(cu))
                        project(*it, -costi);
                    else
                        extend(*it, costi);
                    change = true;
                }
            }
        } else if (ctr->isTernary() && !ctr->isSep()) {
            TernaryConstraint* tctr = (TernaryConstraint*)ctr;
            x = (EnumeratedVariable*)tctr->getVar(0);
            if (x == this)
                x = (EnumeratedVariable*)tctr->getVar(1);
            y = (EnumeratedVariable*)tctr->getVarDiffFrom((Variable*)this, (Variable*)x);
            for (iterator it = begin(); it != end(); ++it) {
                Cost cu = getCost(*it);
                Cost cmin = Top;
                for (iterator itx = x->begin(); itx != x->end(); ++itx) {
                    for (iterator ity = y->begin(); ity != y->end(); ++ity) {
                        Cost ctern = tctr->getCost(this, x, y, *it, *itx, *ity);
                        if (ctern < cmin)
                            cmin = ctern;
                    }
                }
                assert(cmin < Top);
                Double mean = to_double(cmin + cu) / 2.;
                Double extc = to_double(cu) - mean;
                if (abs(extc) >= 1) {
                    Cost costi = (Long)extc;
                    for (iterator itx = x->begin(); itx != x->end(); ++itx) {
                        for (iterator ity = y->begin(); ity != y->end(); ++ity) {
                            tctr->addCost(this, x, y, *it, *itx, *ity, costi);
                        }
                    }
                    if (mean > to_double(cu))
                        project(*it, -costi);
                    else
                        extend(*it, costi);
                    change = true;
                }
            }
        } else if (ctr->isNary() && !ctr->isSep()) {
            NaryConstraint* nctr = (NaryConstraint*)ctr;
            for (iterator it = begin(); it != end(); ++it) {
                Cost cu = getCost(*it);
                Cost cmin = Top;
                int tindex = nctr->getIndex(this);
                String tuple;
                Cost cost;
                Long nbtuples = 0;
                nctr->first();
                while (nctr->next(tuple, cost)) {
                    nbtuples++;
                    if (toValue(tuple[tindex] - CHAR_FIRST) == (*it) && cost < cmin)
                        cmin = cost;
                }
                if (nctr->getDefCost() < cmin && nbtuples < nctr->getDomainSizeProduct() / getDomainSize())
                    cmin = nctr->getDefCost();
                //				assert(cmin < Top);
                Double mean = to_double(cmin + cu) / 2.;
                Double extc = to_double(cu) - mean;
                if (abs(extc) >= 1) {
                    Cost costi = (Cost)extc;
                    nctr->addtoTuples(this, *it, costi);
                    if (mean > to_double(cu))
                        project(*it, -costi);
                    else
                        extend(*it, costi);
                    change = true;
                }
            }
        }
        ++itc;
        if (itc != getConstrs()->end())
            ctr = (*itc).constr;
        else
            ctr = NULL;
    }
    return change;
}
//Testing mine
int main() {
	
	int i, j, r, passes, choice1, choice2;
	int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, 
	       sea_hag, tribute, smithy};
	int supply[16] = {0,1,2,3,4,5,6,7,10,11,13,14,17,19,21,22};
	
	struct gameState G;
	r = initializeGame(2, k, 2, &G);
		assert(r == 0);
	
	//Try upgrading to every card
	for (i = 1; i < 4; i++) {
		for (j = 0; j < 16; j++) {
			r = initializeGame(2, k, 2, &G);
			assert(r == 0);
			
			G.hand[0][0] = mine;
			G.hand[0][1] = copper;
			G.hand[0][2] = silver;
			G.hand[0][3] = gold;
			G.hand[0][4] = smithy;
			G.handCount[0] = 5;
			G.numActions = 1;
			choice1 = i;
			choice2 = supply[j];
			
			//Only allow to upgrade the treasure card
			r = playCard(0, choice1, choice2, 0, &G);
			
			passes = 1;
			if (choice1 == copper &&
				(choice2 != copper || choice2 != silver) &&
				r == 0) {
				printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]);
				printf("Cost of copper is %d, and cost of %d is %d\n", getCost(copper), i, getCost(i));
				passes = 0;
			}
			if (choice1 == silver &&
				(choice2 != silver || choice2 != gold) &&
				r == 0) {
				printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]);
				printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i]));
				passes = 0;
			}
			if (choice1 == silver &&
				(choice2 != silver || choice2 != gold) &&
				r == 0) {
				printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]);
				printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i]));
				passes = 0;
			}
			if (choice1 == gold &&
				choice2 != gold &&
				r == 0) {
				printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]);
				printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i]));
				passes = 0;
			}
		}
	}
	
	myAssert(passes);
	
	return 0;
}
Example #13
0
/*
Feast:  Trash this card. Gain a card costing up to 5 Coins.

Additional Rules: The gained card goes into your Discard pile. It has to be a card from the Supply.
You cannot use coins from Treasures or previous Actions (like the Market) to increase the cost of the card that you gain.
If you use Throne Room on Feast, you will gain two cards, even though you can only trash Feast once.
Gaining the card isn't contingent on trashing Feast; they're just two things that the card tries to make you do.

This adds 5 coins to the player, but does not subtract them should the chosen card be too expensive.
Also the code checks that the player has the coins needed but the rules do not alow using
additional coins to increase the value of the gained card.
*/
int playFeast(int currentPlayer, struct gameState *state, int choice1)
{

	int temphand[MAX_HAND];
	int cardNotBought;
	int i;

	//Backup hand
	for (i = 0; i <= state->handCount[currentPlayer]; i++)
	{
		temphand[i] = state->hand[currentPlayer][i];//Backup card
		state->hand[currentPlayer][i] = EMPTY_CARD;//Set to nothing
	}

	//Update Coins for Buy (adds 5 which is the incorect behavor)
	updateCoins(currentPlayer, state, FEAST_MAX_COST);

	cardNotBought = NOT_BOUGHT;//Condition to loop on

	while( cardNotBought == NOT_BOUGHT) {//Buy one card

		if (supplyCount(choice1, state) <= EMPTY_SUPPLY)
		{
			if (DEBUG)
			{
				printf("None of that card left, sorry!\n");
				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, TO_DISCARD, currentPlayer);//Gain the card
			cardNotBought = BOUGHT;//No more buying cards

	  		if (DEBUG){
	    		printf("Deck Count: %d\n",
				state->handCount[currentPlayer]
				+ state->deckCount[currentPlayer]
				+ state->discardCount[currentPlayer]
				);
			}
		}
//printf("Card not bought feast choice 1: %d\n", choice1);
	}

	//Reset Hand
	for (i = 0; i <= state->handCount[currentPlayer]; i++)
	{
		state->hand[currentPlayer][i] = temphand[i];
		temphand[i] = EMPTY_CARD;
	}

	return EFFECT_SUCCESS;
}
int TakeTurn(FILE* fp, int currPlayer, struct gameState* pre, struct gameState* post, int* pass, int* fail){
	int errCount = 0;
	fprintf(fp,"Starting turn for player %d\n", currPlayer);
	fprintf(fp,"Printing GameState Below\n");
	dumpState(fp,pre);
	
	while(numActionCard(currPlayer,pre))
	{
		if(pre->numActions <= 0){break;}
		int NthActCard = (rand() % numActionCard(currPlayer,pre)) + 1;
		int cardPosToPlay = idxNthActCard(currPlayer,pre,NthActCard);
		int cardToPlay = pre->hand[currPlayer][cardPosToPlay];
		
		//make SURE we did this right--Remove this later if it all works
		if(cardToPlay>=adventurer && cardToPlay <= treasure_map)
		{
		
			//REALLY didn't want to do this, but seems to be the only reasonable way to deal with the choice-based cards.
			switch(cardToPlay)
			{
				case feast: ;
					int cardToBuy;
					cardToBuy = randAffordableCard(5,pre);
					if(cardToBuy == -1)
					{
						if(numActionCard(currPlayer,pre) < 2)
						{
							pre->numActions = 0;
							break;
						}
						break;
					}
					fprintf(fp, "Player %d is playing a feast, to buy a %s\n",currPlayer, cardnames[cardToBuy]);
					errCount += fassert(playCard(cardPosToPlay,cardToBuy,0,0,post) == 0, pass, fail, "PlayCard returned 0");
					break;
				
				case mine:
					if(hasHandCard(currPlayer,silver,pre))
					{
						fprintf(fp, "Player %d is using mine to trash a silver for a gold\n",currPlayer);
						errCount+= fassert(playCard(cardPosToPlay,hasHandCard(currPlayer,silver,pre),gold,0,post) == 0, pass, fail, "PlayCard returned 0");
						break;
					}
					else if(hasHandCard(currPlayer,copper,pre))
					{
						fprintf(fp, "Player %d is using mine to trash a copper for a silver\n",currPlayer);
						errCount+= fassert(playCard(cardPosToPlay,hasHandCard(currPlayer,copper,pre),silver,0,post) == 0,pass,fail,"PlayCard returned 0");
						break;
					}
					else
					{
						//hrmm, if we aren't holding a treasure card, we can't play--dont want to stick us in an infinite loop,
						//so going to cheat a bit here, THIS IS ONLY TO PREVENT INFINITE LOOPS IF MINE IS THE ONLY ACTION CARD IN HAND
						//Also, there is no point in checking to trash a gold for another gold. Totally redundant. This covers both cases
						if(numActionCard(currPlayer,pre) <= 1){pre->numActions = 0;}
						break;
					}
				case remodel:
					if(pre->handCount[currPlayer] > 1)
					{
						int cardToTrash;
						while(1)
						{
							cardToTrash = rand() % pre->handCount[currPlayer];
							if(cardToTrash!=cardPosToPlay){break;}
						}
						int trashValue = getCost(cardToTrash);
						int cardToBuy = randAffordableCard(trashValue+2,pre);
						if(cardToBuy == -1)
						{
							if(numActionCard(currPlayer,pre) < 2)
							{
								pre->numActions = 0;
								break;
							}
							break;
						}
						fprintf(fp, "Player %d is using remodel to trash a %s and gain a %s\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]],cardnames[cardToBuy]);
						errCount += fassert(playCard(cardPosToPlay,cardToTrash,cardToBuy,0,post) == 0,pass,fail,"PlayCard Returned 0");
						break;
					}
					else
					{
						//only card is remodel, so we can't play--set actions to 0
						pre->numActions = 0;
						break;
					}
				case baron:
					if(hasHandCard(currPlayer, estate, pre))
					{
						if(rand()%2)
						{
							fprintf(fp,"Player %d is playing baron, discarding an estate\n",currPlayer);
							errCount+=fassert(playCard(cardPosToPlay,1,0,0,post)==0,pass,fail,"PlayCard returned 0");
							break;
						}
					}
					else
					{
						fprintf(fp,"Player %d is playing baron, not discarding estate\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,0,0,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
				case minion: ;
					int rChoice;
					rChoice = (rand() % 2)+1;
					if(rChoice == 1)
					{
						fprintf(fp, "Player %d is playing minion, chose +2 coin\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,1,0,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
					else
					{
						fprintf(fp, "Player %d is playing minion, chose redraw\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,0,1,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
				case steward:
					rChoice = (rand()%3)+1;
					if(rChoice == 1)
					{
						fprintf(fp, "Player %d is playing steward, chose +2 card\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
					else if(rChoice == 2)
					{
						fprintf(fp, "Player %d is playing steward, chose +2 coin\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
					else
					{
						fprintf(fp, "Player %d is playing steward, chose trash 2\n",currPlayer);
						errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
				case ambassador:
					if(pre->handCount[currPlayer]>1)
					{
						int cardToTrash;
						while(1)
						{
							cardToTrash = rand() % pre->handCount[currPlayer];
							if(cardToTrash!=cardPosToPlay){break;}
						}
						int numToReturn = (rand() % numCardX(currPlayer,pre->hand[currPlayer][cardToTrash],pre))+1;
						fprintf(fp,"Player %d is playing ambassador, trashing a %s, hoping to return %d\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]],numToReturn);
						errCount+=fassert(playCard(cardPosToPlay,cardToTrash,numToReturn,0,post)==0,pass,fail,"PlayCard returned 0");
						break;
					}
					else
					{
						if(numActionCard(currPlayer,pre) < 2)
						{
							pre->numActions = 0;
						}
						break;
					}
				case embargo: ;
					int cardToEmbargo;
					cardToEmbargo = randAffordableCard(999,pre);
					if(cardToBuy == -1)
					{
						if(numActionCard(currPlayer,pre) < 2)
						{
							pre->numActions = 0;
						}
						break;
					}
					fprintf(fp,"Player %d is playing embargo on %s\n",currPlayer,cardnames[cardToEmbargo]);
					errCount+=fassert(playCard(cardPosToPlay,cardToEmbargo,0,0,post)==0,pass,fail,"PlayCard Returned 0");
					break;
				case salvager:
					if(pre->handCount[currPlayer]>1)
					{
						int cardToTrash;
						while(1)
						{
							cardToTrash = rand() % pre->handCount[currPlayer];
							if(cardToTrash!=cardPosToPlay){break;}
						}
						fprintf(fp,"Player %d is playing salvager, trashing %s\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]]);
						errCount+=fassert(playCard(cardPosToPlay,cardToTrash,0,0,post)==0,pass,fail,"PlayCard Returned 0");
						break;
					}
					else
					{
						pre->numActions = 0;
						break;
					}
				default:		//all other cards don't need choices
					fprintf(fp,"Player %d is playing his %s\n",currPlayer,cardnames[cardToPlay]);
					errCount += fassert(playCard(cardPosToPlay,0,0,0, post) == 0, pass, fail, "PlayCard Returned 0");
					break;
			
			}
			errCount += SanityCheck(post,pass,fail,fp);
			if(!errCount)
			{
				fprintf(fp,"Player %d tried to play a card, gamestate is now\n",currPlayer);
				dumpState(fp,post);
				memcpy(pre,post,sizeof(struct gameState));
			}
			else{break;}
		}
		
	}
	
	//OK, now that we played all possible actions, we can try out buying stuff
	while(pre->numBuys > 0 && !errCount)		//doesn't matter how many coins we have, can still buy for ex: copper for 0c
	{
		if(pre->coins < 2)
		{
			int doibuy = rand() % 2;
			if(doibuy){break;}
		}
		
		
		
		int cardToBuy = randAffordableCard(pre->coins,pre);
		if(cardToBuy == -1)
		{
			pre->numBuys = 0;
			break;
		}
		buyCard(cardToBuy,post);
		fprintf(fp,"Player %d tried to buy a %s\n",currPlayer,cardnames[cardToBuy]);
		errCount+=SanityCheck(post,pass,fail,fp);
		if(!errCount)
		{
			//fprintf(fp,"gamestate is now\n");
			//dumpState(fp,post);
			memcpy(pre,post,sizeof(struct gameState));
		}
		else{break;}
	}
	
	
	
	if(!errCount)
	{
		fprintf(fp,"Ending turn for player %d\n", currPlayer);
		errCount += fassert(endTurn(post) == 0, pass, fail, "endTurn Returned 0");
		errCount += SanityCheck(post,pass, fail,fp);
		if(!errCount)
		{
			memcpy(pre,post,sizeof(struct gameState));
		}
	}
	fprintf(fp,"Gamestate at end of turn\n");
	dumpState(fp, post);
	return errCount;
	
	
}
int main(int argc, char* argv[]){


    int i;
    int ret;
    fprintf(stdout, "Testing getCost\n");

    for(i = 0; i < 27; i++){
	ret = getCost(i);
	switch(i){
	    case curse:
		assert(ret == 0);
		break;
	    case estate:
		assert(ret == 2);
		break;
	    case duchy:
		assert(ret == 5);
		break;
	    case province:
		assert(ret == 8);
		break;
	    case copper:
		assert(ret == 0);
		break;
	    case silver:
		assert(ret == 3);
		break;
	    case gold:
		assert(ret == 6);
		break;
	    case adventurer:
		assert(ret == 6);
		break;
	    case council_room:
		assert(ret == 5);
		break;
	    case feast:
		assert(ret == 4);
		break;
	    case gardens:
		assert(ret == 4);
		break;
	    case mine:
		assert(ret == 5);
		break;
	    case remodel:
		assert(ret == 4);
		break;
	    case smithy:
		assert(ret == 4);
		break;
	    case village:
		assert(ret == 3);
		break;
            case baron:
		assert(ret == 4);
		break;
	    case great_hall:
                assert(ret == 3);
		break;
	    case minion:
		assert(ret == 5);
		break;
	    case steward:
		assert(ret == 3);
		break;
	    case tribute:
		assert(ret == 5);
		break;
	    case ambassador:
		assert(ret == 3);
		break;
            case cutpurse:
		assert(ret == 4);
		break;
	    case embargo:
		assert(ret == 2);
		break;
	    case outpost:
		assert(ret == 5);
		break;
	    case salvager:
		assert(ret == 4);
		break;
	    case sea_hag:
		assert(ret == 4);
		break;
	    case treasure_map:
		assert(ret == 4);
		break;
	}
    }




    fprintf(stdout, "Test passed\n");

    return 0;

}