Example #1
0
int main() {
	
	srand(time(NULL));
	int randNum = rand();
	int status;
	int testNum = 1;
	int player = 1;
	
	struct gameState gs;
    int k[10] = {adventurer, smithy, ambassador, embargo, gardens, 
						great_hall, tribute, steward, sea_hag, minion};
    
    printf("~~~~~BEGIN TESTING village ~~~~~\n");
	
	status = initializeGame(2, k, randNum, &gs); 	
	assert(status == 0);
	
	int initialHand = gs.handCount[player];
	int initialDeck = gs.deckCount[player];
	int initialActions = gs.numActions;
	
	villageEffect(0, player, &gs);
	
	/* Test 1: Check if one card was added to hand */
	status = gs.handCount[player] == initialHand + 1;
	statusCheck(status, testNum);
	testNum++;
	
	/* Test 2: Check if one card was removed from deck */
	status = gs.deckCount[player] == initialDeck - 1;
	statusCheck(status, testNum);
	testNum++;
	
	/* Test 3: Check if number of actions is increased by 2 */
	status = gs.numActions == initialActions + 2;
	statusCheck(status, testNum);
	testNum++;
	
	printf("~~~~~FINISH TESTING village ~~~~~\n");
	
	return 0;
}
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;
}
Example #3
0
int main() {
 
  /* set up game state */
  int i;
  int numPlayer = 2;
  int handCount;
  int k[10] = {adventurer, council_room, feast, gardens, mine, 
    remodel, smithy, village, baron, great_hall};
  struct gameState G;
  int maxHandCount = 5;
  
  /* initialize decks */
  testInitializeGame(2, k, &G);
  
  /* set up hand for Player 0 */
  G.hand[0][0] = copper;
  G.hand[0][1] = copper;
  G.hand[0][2] = copper;
  G.hand[0][3] = copper;
  G.hand[0][4] = village;
  
  G.handCount[0] = 5;
  
  printf("Setup complete.\n");
  
  /* test */
  printf("Testing Village Card...\n");
  
  /* save game state */
  struct gameState Save;
  Save.numActions = G.numActions;
  Save.numBuys = G.numBuys;
  Save.handCount[0] = G.handCount[0];
  
  /* play village */
  int villageResult = villageEffect(&G, 0, 4);
  
  /* confirm village played */
#if (PRINT_TEST == 1)
  printf("Village Result: %d ",villageResult);
  if (villageResult == 0)
    printf("Pass!\n");
  else
    printf("Fail!\n");
#endif
  
#if (ENABLE_ASSERTS == 1)
  assert(villageResult == 0);
#endif
 
  /* confirm +1 card
   * because village has been discarded, the number of cards in hand
   * should be the same */
#if (PRINT_TEST == 1)
  if (G.handCount[0] - Save.handCount[0] == 0)
    printf("+1 card: Pass!\n");
  else
    printf("+1 card: Fail!\n");
#endif
  
#if (ENABLE_ASSERTS == 1)
  assert(G.handCount[0] - Save.handCount[0] == 0);
#endif
  
  /* confirm +2 Actions */
#if (PRINT_TEST == 1)
  if (G.numActions - Save.numActions == 2)
    printf("+2 Actions: Pass!\n");
  else
    printf("+2 Actions: Fail!\n");
#endif
  
#if (ENABLE_ASSERTS == 1)
  assert(G.numActions - Save.numActions == 2);
#endif
  
#if (ENABLE_ASSERTS == 1)
  printf("All tests passed!\n");
#endif
  
  return 0;
}
Example #4
0
int main()
{
    int k[10] = { adventurer, gardens, embargo, village, minion, mine, cutpurse,
            sea_hag, tribute, smithy };

    int i = 0, player = 0, players = 0, seed = 0;
    int the_test = 0, handCount = 0;
    int numActions = 0;
#ifdef SEG_FAULT
    int currentPlayer = 0, handPos = 0;
#endif
    struct gameState *aGame = NULL;

    srand(time(NULL));          // init libc random seed
    for (i = 0; i < MAX_TESTS; i++)
    {
        // set up game state
        aGame = newGame();          // allocate new memory
        seed = rand();              // any value will do
        players = (rand() % 3) + 2; // 2 to 4 players
        player = rand() % players;  // randomly pick a player to play

        initializeGame(players, k, seed, aGame);
        aGame->whoseTurn = player;  // set player as active player
        aGame->hand[player][0] = village;

        // set up player hand to between a minimum of 5 and max hand;
        do
        {
            handCount = rand() % (MAX_HAND + 1);
        }
        while( (handCount < 5));
        aGame->handCount[player] = handCount;

#ifdef SEG_FAULT
        currentPlayer = rand();
        handPos = rand();
#endif
        printf("Test %d: ", i);
#ifdef SEG_FAULT
        if (currentPlayer > player)
            fprintf(stderr, "current player out of bounds, likely seg fault...\n");
        if (handPos > handCount)
            fprintf(stderr, "hand position out of bounds, likely seg fault...\n");
#endif
        numActions = aGame->numActions;
#ifdef SEG_FAULT
        villageEffect(currentPlayer, aGame, handPos);
#endif
        villageEffect(player, aGame, 0);

        the_test = (handCount == aGame->handCount[player]);
        printf("drew a card, discarded a card...");
        test(the_test, "hand size changed incorrectly");

        the_test = ((numActions + 2) == aGame->numActions);
        printf("...actions increased by two...");
        test(the_test, "number actions did not change by two.");

        printf("\n");

        //clean up
        free(aGame);
        player = 0, players = 0; seed = 0; the_test = 0, numActions = 0;
        handCount = 0;
    }

    return EXIT_SUCCESS;
}
Example #5
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:
      adventurerEffect(state, currentPlayer);
	  break;
			
    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:
	  smithyEffect(state, currentPlayer, handPos);
	  break;
		
    case village:
      villageEffect(state, currentPlayer, handPos);
	  break;
		
    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:
      greathallEffect(state, currentPlayer, handPos);
	  break;
		
    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: 
		embargoEffect(state, currentPlayer, handPos, choice1);
		break;
		
    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;
}
Example #6
0
int main(int argc, char *argv[]) {
	struct gameState state,		// initialized game state for testing
					 backup;	// backup game state for comparisons
	// array of kingdom cards for game initialization
	int kingdomCards[10] = {adventurer, gardens, embargo, village, minion, mine, 
							cutpurse, sea_hag, tribute, smithy};
	int randomSeed = 10000,
		numTests = 1000,
		numPlayers = 2,
		isValidDraw = 1,
		isValidActions = 1,
		isValidDiscard = 1,
		currentPlayer = 0,
		handpos,
		i = 0,
		j = 0,
		numPassed = 0,
		numFailed = 0;

	for (i = 0; i < numTests; i++) {
		// reset validation check to 1, 0 if test fails
		isValidDraw = 1;
		isValidActions = 1;
		isValidDiscard = 1;
		// setup working copy of game
		initializeGame(numPlayers, kingdomCards, randomSeed, &state);
		// randomize number of cards in player's hand
		state.handCount[currentPlayer] = (rand() % 10) + 1;
		// randomize position of village card and place it in hand
		handpos = rand() % state.handCount[currentPlayer];
		// randomize the player's deck count
		state.deckCount[currentPlayer] = rand() % 5;
		// fill in the rest of the cards in the player's hand
		for (j = 0; j < state.handCount[currentPlayer]; j++) {
			if (j != handpos)
				state.hand[currentPlayer][j] = rand() % 26;
			else
				state.hand[currentPlayer][j] = village;
		}
		// copy game state to backup for error detection
		memcpy(&backup, &state, sizeof(struct gameState));
		// call village card effect
		villageEffect(currentPlayer, &state, handpos);
		// check drawcard component
		if (state.handCount[currentPlayer] != (backup.handCount[currentPlayer]))
			isValidDraw = 0;
		if (state.deckCount[currentPlayer] != backup.deckCount[currentPlayer] - 1) {
			isValidDraw = 0;
		}
		if (state.hand[currentPlayer][state.handCount[currentPlayer] - 1] == -1) {
			isValidDraw = 0;
		}
		// check additional actions
		if (state.numActions != backup.numActions + 2) {
			isValidActions = 0;
		}	
		// check village card is discarded
		if (state.playedCards[state.playedCardCount - 1] != village) {
			isValidDiscard = 0;
		}	
		// print test conditions if the test failed
		if (isValidDraw == 0 || isValidActions == 0 || isValidDiscard == 0) {
			printf("TEST %i\n", i + 1);
			printf("Function Used: villageEffect(%i, &state, %i);\n", currentPlayer, handpos);
			printf("Position of village card: %i\n", handpos);
			printf("Number of Cards in Hand: %i\n", backup.handCount[currentPlayer]);
			printf("Starting deck count: %i\n", backup.deckCount[currentPlayer]);
			printf("Cards in hand: ");
			for (j = 0; j < backup.handCount[currentPlayer]; j++) {
				printf("%i, ", backup.hand[currentPlayer][j]);
			}
			printf("\n");
			printf("Random Seed: %i\n", randomSeed);
			printf("Failed Item(s): \n");
			if (isValidDraw == 0)
				printf("Invalid draw card operation\n");
			if (isValidActions == 0)
				printf("Invalid number of actions\n");
			if (isValidDiscard == 0)
				printf("Invalid discard operation\n");	
			numFailed++;
		} else {
			numPassed++;
		}
	
		randomSeed++;
	}

	printf("\nTotal Tests: %i\n", numTests);
	printf("Total Passed: %i\n", numPassed);
	printf("Total Failed: %i\n", numFailed);

	return 0;
}
Example #7
0
/*Village card unit tests*/
int testVillageCard(){
	int numPlayer = 2; //players in the game 2-4
	int player = 0; //current player
	int handCount = 5; //Number of cards player starts with
	int i; //counting index for loops
	int hasVillage = 0; //Determines if Village card is in player's hand or not.
	char cardName[20]; //name of card
	
	/*Kingdom cards in this game*/
	int k[10] = {adventurer, council_room, feast, gardens, mine
				, remodel, smithy, village, baron, great_hall};
			   
	/*starts new game*/
	struct gameState state;
	
	/*create hand*/
	int hand[handCount];
	hand[0] = copper;
	hand[1] = silver;
	hand[2] = gold;
	hand[3] = estate;
	hand[4] = village;
	
	printf ("Testing villageEffect():\n");

	initializeGame(numPlayer, k, 1000, &state); //initialize a new game
	state.handCount[player] = handCount; //set the number of cards in hand
	memcpy(state.hand[player], hand, sizeof(int) * handCount); //give hand to player

	/*checks if village is in player's hand*/
	for(i = 0; i < state.handCount[player]; i++){
		cardNumToName(state.hand[player][i], cardName); //get name from card num
		printf("%s ", name);
		if(strcmp(name, "village") == 0){
			hasVillage = 1; //village card is in player's hand
		}
	}
	
	if (hasVillage == 1){
		printf ("Player has village\n");
		printf ("Using village card\n");
		villageEffect(player, state, i); //uses village card
		
		/*Village adds 1 card and discards itself*/
		if (state.handCount[player] == 5)
			printf ("Player has the correct number of cards!\n");
		else
			printf("Player has the incorrect number of cards.\n");
		
		/*Village takes one action to play and gives 2 actions 1-1+2=2*/
		if (state.numActions == 2)
			printf("Player has the correct number of actions!\n");
		else
			printf("Player has the incorrect number of actions.\n");
	}
	else{
		printf ("Player does not have village\n");
	}
	
	return 0;
}