int handCard(int handPos, struct gameState *state) {
	int currentPlayer = whoseTurn(state);
	return state->hand[currentPlayer][handPos];
}
int getWinners(int players[MAX_PLAYERS], struct gameState *state) {
	int i;	
	int j;
	int highScore;
	int currentPlayer;

	//get score for each player
	for (i = 0; i < MAX_PLAYERS; i++)
		{
			//set unused player scores to -9999
			if (i >= state->numPlayers)
				{
					players[i] = -9999;
				}
			else
				{
					players[i] = scoreFor (i, state);
				}
		}

	//find highest score
	j = 0;
	for (i = 0; i < MAX_PLAYERS; i++)
		{
			if (players[i] > players[j])
				{
					j = i;
				}
		}
	highScore = players[j];

	//add 1 to players who had less turns
	currentPlayer = whoseTurn(state);
	for (i = 0; i < MAX_PLAYERS; i++)
		{
 /* MUTANT (rep_op) */			if ( players[i] == highScore && i == currentPlayer )
				{
					players[i]++;
				}
		}

	//find new highest score
	j = 0;
	for (i = 0; i < MAX_PLAYERS; i++)
		{
			if ( players[i] > players[j] )
				{
					j = i;
				}
		}
	highScore = players[j];

	//set winners in array to 1 and rest to 0
	for (i = 0; i < MAX_PLAYERS; i++)
		{
			if ( players[i] == highScore )
				{
					players[i] = 1;
				}
			else
				{
					players[i] = 0;
				}
		}

	return 0;
}
int numHandCards(struct gameState *state) {
	return state->handCount[ whoseTurn(state) ];
}
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 f_adventurer(state,currentPlayer);
	    case council_room:
		return f_concil_room(state,currentPlayer,handPos);	

    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:
	return f_remodel(state,currentPlayer,choice1,choice2,handPos); 
    case smithy:
	return f_smithy(state,currentPlayer,handPos);
    case village:
	return f_village(state,currentPlayer,handPos);	
	
    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);
/* XXX: original code was : 	      state->supplyCount[estate]--;//Decrement estates */
	      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 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 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++;
			}
		}
		while (z > 0) {
			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 main(int argc, char** argv) {
	struct gameState G;
	struct gameState *p = &G;

	int k[10] = { adventurer, gardens, embargo, village, minion, mine, cutpurse,
		sea_hag, tribute, smithy };

	printf("Starting game.\n");

	initializeGame(2, k, atoi(argv[1]), p);

	int money = 0;
	int smithyPos = -1;
	int adventurerPos = -1;
	int i = 0;

	int numSmithies = 0;
	int numAdventurers = 0;

	while (!isGameOver(p)) {
		money = 0;
		smithyPos = -1;
		adventurerPos = -1;
		for (i = 0; i < numHandCards(p); i++) {
			if (handCard(i, p) == copper)
				money++;
			else if (handCard(i, p) == silver)
				money += 2;
			else if (handCard(i, p) == gold)
				money += 3;
			else if (handCard(i, p) == smithy)
				smithyPos = i;
			else if (handCard(i, p) == adventurer)
				adventurerPos = i;
		}

		if (whoseTurn(p) == 0) {
			if (smithyPos != -1) {
				printf("0: smithy played from position %d\n", smithyPos);
				playCard(smithyPos, -1, -1, -1, p);
				printf("smithy played.\n");
				money = 0;
				i = 0;
				while (i < numHandCards(p)){
					if (handCard(i, p) == copper){
						playCard(i, -1, -1, -1, p);
						money++;
					}
					else if (handCard(i, p) == silver){
						playCard(i, -1, -1, -1, p);
						money += 2;
					}
					else if (handCard(i, p) == gold){
						playCard(i, -1, -1, -1, p);
						money += 3;
					}
					i++;
				}
			}

			if (money >= 8) {
				printf("0: bought province\n");
				buyCard(province, p);
			}
			else if (money >= 6) {
				printf("0: bought gold\n");
				buyCard(gold, p);
			}
			else if ((money >= 4) && (numSmithies < 2)) {
				printf("0: bought smithy\n");
				buyCard(smithy, p);
				numSmithies++;
			}
			else if (money >= 3) {
				printf("0: bought silver\n");
				buyCard(silver, p);
			}

			printf("0: end turn\n");
			endTurn(p);
		}
		else {
			if (adventurerPos != -1) {
				printf("1: adventurer played from position %d\n", adventurerPos);
				playCard(adventurerPos, -1, -1, -1, p);
				money = 0;
				i = 0;
				while (i < numHandCards(p)){
					if (handCard(i, p) == copper){
						playCard(i, -1, -1, -1, p);
						money++;
					}
					else if (handCard(i, p) == silver){
						playCard(i, -1, -1, -1, p);
						money += 2;
					}
					else if (handCard(i, p) == gold){
						playCard(i, -1, -1, -1, p);
						money += 3;
					}
					i++;
				}
			}

			if (money >= 8) {
				printf("1: bought province\n");
				buyCard(province, p);
			}
			else if ((money >= 6) && (numAdventurers < 2)) {
				printf("1: bought adventurer\n");
				buyCard(adventurer, p);
				numAdventurers++;
			}
			else if (money >= 6){
				printf("1: bought gold\n");
				buyCard(gold, p);
			}
			else if (money >= 3){
				printf("1: bought silver\n");
				buyCard(silver, p);
			}
			printf("1: endTurn\n");

			endTurn(p);
		}

		printf("Player 0: %d\nPlayer 1: %d\n", scoreFor(0, p), scoreFor(1, p));

	} // end of While

	printf("Finished game.\n");
	printf("Player 0: %d\nPlayer 1: %d\n", scoreFor(0, p), scoreFor(1, p));

	return 0;
}