int main() { int totalFail = 0; int totalPass = 0; int seed = -1; struct gameState G; int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy}; int NUM_TEST_CARDS = 3; int testCards[NUM_TEST_CARDS]; int i, x; int priorSupply, postSupply; int priorHand, postHand; int priorDeck, postDeck; int priorDiscard, postDiscard; SelectStream(1); PutSeed(-1); Random(); for (i = 0; i < NUM_TEST_CARDS; i++) { testCards[i] = k[(int)floor(Random() * 10)]; } initializeGame(2, k, seed, &G); //Begin testing-------------------------------------------------------------- printf("------------------------------------------------------------\n"); printf("-----------------BEGIN TESTING FOR gainCard()---------------\n"); printf("------------------------------------------------------------\n"); //Test out of bounds input for card to get ie. card that does not exist if (gainCard(treasure_map + 2, &G, 0, 0) == -1) { printf("gainCard(): PASS -> handles non existent card.\n\n"); totalPass++; } else { printf("gainCard(): FAIL -> does not handle non existent card.\n\n"); totalFail++; } //test empty supply pile ie. all cards are gone of that type G.supplyCount[curse] = 0; if (gainCard(curse, &G, 0, 0) == -1) { printf("gainCard(): PASS -> handles empty supply pile.\n\n"); totalPass++; } else { printf("gainCard(): FAIL -> does not handle empty supply pile.\n\n"); totalFail++; } //Test for out of bounds player if (gainCard(copper, &G, 0, MAX_PLAYERS + 1) == -1) { printf("gainCard(): PASS -> handles out of bounds player.\n\n"); totalPass++; } else { printf("gainCard(): FAIL -> does not exit on out of bounds player.\n\n"); totalFail++; } //Test to make sure anything other than 1 or 2 adds card to discard pile priorSupply = G.supplyCount[copper]; priorDiscard = G.discardCount[0]; gainCard(copper, &G, 3, 0); postSupply = G.supplyCount[copper]; postDiscard = G.discardCount[0]; if (postSupply == (priorSupply - 1)) { printf("gainCard(): PASS -> decrements supply count on flag not equal to 1 or 2.\n\n"); totalPass++; } else { printf("gainCard(): FAIL -> does not decrement supply count on flag not equal to 1 or 2.\n\n"); totalFail++; } if ( postDiscard == (priorDiscard + 1) && G.discard[0][postDiscard - 1] == copper ) { printf("gainCard(): PASS -> correctly discards card on flag not equal to 1 or 2.\n\n"); totalPass++; } else { printf("gainCard(): FAIL -> did not discard card on flag not equal to 1 or 2.\n\n"); totalFail++; } //Test scenario of adding card to the discard pile //test scenario of adding card to the deck //test scenario of adding card to the hand //The following uses NUM_TEST_CARDS number of random cards to test to make //sure that the cards are gained in either the discard, deck or hand for (x = 0; x < NUM_TEST_CARDS; x++) { //testing gaining card x and adding it to the deck priorSupply = G.supplyCount[testCards[x]]; priorDeck = G.deckCount[0]; gainCard(testCards[x], &G, 1, 0); //add card to deck postSupply = G.supplyCount[testCards[x]]; postDeck = G.deckCount[0]; if ( postDeck == (priorDeck + 1) ) { if ( G.deck[0][postDeck - 1] == testCards[x] ) { printf("gainCard(): PASS -> Test card %d gained correctly to deck.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d incremented deck count but was not correctly added to deck.\n\n", testCards[x]); totalFail++; } } else { if ( G.deck[0][postDeck - 1] == testCards[x] ) { printf("gainCard(): FAIL -> Test card %d was added to deck but did not increment deck count.\n\n", testCards[x]); totalFail++; } else { printf("gainCard(): FAIL -> Test card %d was not added to deck and did not increment deck count.\n\n", testCards[x]); totalFail++; } } if ( postSupply == (priorSupply - 1) ) { printf("gainCard(): PASS -> Test card %d decreased supply pile after added to deck.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d did not decrease supply pile after added to deck.\n\n", testCards[x]); totalFail++; } //testing gaining card x and adding it to the hand priorSupply = G.supplyCount[testCards[x]]; priorHand = G.handCount[0]; gainCard(testCards[x], &G, 2, 0); //add card to hand postSupply = G.supplyCount[testCards[x]]; postHand = G.handCount[0]; if ( postHand == (priorHand + 1) ) { if ( G.hand[0][postHand - 1] == testCards[x] ) { printf("gainCard(): PASS -> Test card %d gained correctly to hand.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d incremented hand count but was not correctly added to hand.\n\n", testCards[x]); totalFail++; } } else { if ( G.hand[0][postHand - 1] == testCards[x] ) { printf("gainCard(): FAIL -> Test card %d was added to hand but did not increment hand count.\n\n", testCards[x]); totalFail++; } else { printf("gainCard(): FAIL -> Test card %d was not added to hand and did not increment hand count.\n\n", testCards[x]); totalFail++; } } if ( postSupply == (priorSupply - 1) ) { printf("gainCard(): PASS -> Test card %d decreased supply pile after added to hand.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d did not decrease supply pile after added to deck.\n\n", testCards[x]); totalFail++; } //testing gaining card x and adding it to discard priorSupply = G.supplyCount[testCards[x]]; priorDiscard = G.discardCount[0]; gainCard(testCards[x], &G, 0, 0); //add card to discard postSupply = G.supplyCount[testCards[x]]; postDiscard = G.discardCount[0]; if ( postDiscard == (priorDiscard + 1) ) { if ( G.discard[0][postDiscard - 1] == testCards[x] ) { printf("gainCard(): PASS -> Test card %d gained correctly to discard.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d incremented discard count but was not correctly added to discard.\n\n", testCards[x]); totalFail++; } } else { if ( G.discard[0][postDiscard - 1] == testCards[x] ) { printf("gainCard(): FAIL -> Test card %d was added to discard but did not increment discard count.\n\n", testCards[x]); totalFail++; } else { printf("gainCard(): FAIL -> Test card %d was not added to discard and did not increment discard count.\n\n", testCards[x]); totalFail++; } } if ( postSupply == (priorSupply - 1) ) { printf("gainCard(): PASS -> Test card %d decreased supply pile after added to discard.\n\n", testCards[x]); totalPass++; } else { printf("gainCard(): FAIL -> Test card %d did not decrease supply pile after added to deck.\n\n", testCards[x]); totalFail++; } } printf("------------------------------------------------------------\n"); printf("----------------RESULTS of gainCard() testing---------------\n"); printf("Tests Passed: %d\tTests Failed: %d\n", totalPass, totalFail); printf("------------------------------------------------------------\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 k; 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 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 adventurerFunc(state, currentPlayer, temphand, drawntreasure, z); 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: return feastFunc(state, currentPlayer, temphand, choice1); 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: return baronFunc(state, currentPlayer, 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 minionFunc(state, currentPlayer, handPos, choice1, choice2); 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: return ambassadorFunc(state, currentPlayer, choice1, choice2, handPos); 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 main(){ int testresult; int k[10] = {adventurer, feast, gardens, mine, remodel, smithy, village, baron, sea_hag, great_hall}; int numPlayers = 2; struct gameState G; memset(&G, 0, sizeof(struct gameState)); // clear the game state initializeGame(numPlayers, k, 10, &G); //initialize game printf ("------------------TESTING gainCard():--------------------\n\n"); //test when pile of cards that is attempt to be gained is empty printf ("Test when supply pile of adventure cards is empty.\n"); G.supplyCount[adventurer] = 0; testresult = gainCard(adventurer, &G, 0, 1); if(testresult == -1){ printf ("PASS. EXPECTED: Cannot gain an adventure card. ACTUAL: Cannot gain an adventure card.\n"); } else{ printf ("FAIL. EXPECTED: Cannot gain an adventure card. ACTUAL: Can gain an adventure card.\n"); } //test when card is not used in the game printf ("Test when card is not in the game.\n"); testresult = gainCard(council_room, &G, 0, 1); if(testresult == -1){ printf ("PASS. EXPECTED: Cannot gain a council_room card. ACTUAL: Cannot gain a council_room card.\n\n"); } else{ printf ("FAIL. EXPECTED: Cannot gain a council_room card. ACTUAL: Can gain a council_room card.\n\n"); } //test when flag set to add card to deck printf ("Test when card must be moved to deck.\n"); int deckCount1 = G.deckCount[1]; //save current number of deck cards for player 1 int deckCount2 = G.deckCount[2]; //save current number of deck cards for player 2 G.supplyCount[adventurer] = 5; gainCard(adventurer, &G, 1, 1); //check that deck count is incremented for 1st player if(G.deckCount[1] == deckCount1+1){ printf ("PASS. EXPECTED: Deck count for player 1 is incremented. ACTUAL: Deck count for player 1 is incremented.\n"); } else{ printf ("PASS. EXPECTED: Deck count for player 1 is not incremented. ACTUAL: Deck count for player 1 is not incremented.\n"); } //check that right card was added to the deck of 1st player if(G.deck[1][deckCount1] == adventurer){ printf ("PASS. EXPECTED: Adventurer is added to the end of deck. ACTUAL: Adventurer is added to the end of deck.\n"); } else{ printf ("FAIL. EXPECTED: Adventurer is added to the end of deck. ACTUAL: Adventurer is not at the end of deck.\n"); } //check that deck count for player 2 is not changed if(G.deckCount[2] == deckCount2){ printf ("PASS. EXPECTED: Deck count for player 2 is not changed. ACTUAL: Deck count for player 2 is not changed.\n"); } else{ printf ("PASS. EXPECTED: Deck count for player 2 is not changed. ACTUAL: Deck count for player 2 is changed.\n"); } //test supply count of adventurer is decremented if(G.supplyCount[adventurer] == 4){ printf ("PASS. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } else{ printf ("FAIL. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } //test when flag set to add card to hand printf ("Test when card must be moved to hand.\n"); int handCount1 = G.handCount[1]; //save current number of hand cards for player 1 int handCount2 = G.handCount[2]; //save current number of hand cards for player 2 G.supplyCount[adventurer] = 5; gainCard(adventurer, &G, 2, 1); //check that hand count is incremented for 1st player if(G.handCount[1] == handCount1+1){ printf ("PASS. EXPECTED: Hand count for player 1 is incremented. ACTUAL: Hand count for player 1 is incremented.\n"); } else{ printf ("PASS. EXPECTED: Hand count for player 1 is not incremented. ACTUAL: Hand count for player 1 is not incremented.\n"); } //check that right card was added to the hand of 1st player if(G.hand[1][handCount1] == adventurer){ printf ("PASS. EXPECTED: Adventurer is added to the end of hand. ACTUAL: Adventurer is added to the end of hand.\n"); } else{ printf ("FAIL. EXPECTED: Adventurer is added to the end of hand. ACTUAL: Adventurer is not at the end of hand.\n"); } //check that hand count for player 2 is not changed if(G.handCount[2] == handCount2){ printf ("PASS. EXPECTED: Hand count for player 2 is not changed. ACTUAL: Hand count for player 2 is not changed.\n"); } else{ printf ("PASS. EXPECTED: Hand count for player 2 is not changed. ACTUAL: Hand count for player 2 is changed.\n"); } //test supply count of adventurer is decremented if(G.supplyCount[adventurer] == 4){ printf ("PASS. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } else{ printf ("FAIL. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } //test when flag set to add card to discard printf ("Test when card must be moved to discard.\n"); int discardCount1 = G.discardCount[1]; //save current number of discard cards for player 1 int discardCount2 = G.discardCount[2]; //save current number of discard cards for player 2 G.supplyCount[adventurer] = 5; gainCard(adventurer, &G, 0, 1); //check that discard count is incremented for 1st player if(G.discardCount[1] == discardCount1+1){ printf ("PASS. EXPECTED: Discard count for player 1 is incremented. ACTUAL: Discard count for player 1 is incremented.\n"); } else{ printf ("PASS. EXPECTED: Discard count for player 1 is not incremented. ACTUAL: Discard count for player 1 is not incremented.\n"); } //check that right card was added to the discard of 1st player if(G.discard[1][discardCount1] == adventurer){ printf ("PASS. EXPECTED: Adventurer is added to the end of discard. ACTUAL: Adventurer is added to the end of discard.\n"); } else{ printf ("FAIL. EXPECTED: Adventurer is added to the end of discard. ACTUAL: Adventurer is not at the end of discard.\n"); } //check that discard count for player 2 is not changed if(G.discardCount[2] == discardCount2){ printf ("PASS. EXPECTED: Discard count for player 2 is not changed. ACTUAL: Discard count for player 2 is not changed.\n"); } else{ printf ("PASS. EXPECTED: Discard count for player 2 is not changed. ACTUAL: Discard count for player 2 is changed.\n"); } //test supply count of adventurer is decremented if(G.supplyCount[adventurer] == 4){ printf ("PASS. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } else{ printf ("FAIL. EXPECTED: Supply count for adventurer is 4. ACTUAL: Supply count for adventurer is %d.\n\n", G.supplyCount[adventurer]); } printf("---------------------------------------------------------\n"); return 0; }
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus) { int i = 0; int j = 0; 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 adventurerCard(currentPlayer, handPos, state, drawntreasure, cardDrawn, temphand); //Edit **************************************** case council_room: council_room_func(card, state, handPos, bonus, currentPlayer); return 0; case feast: //Checking supply and cost requirements if(supplyCount(choice1, state) <= 0 || getCost(choice1) > 5) return -1; //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"); return -1; } } if (DEBUG){ printf("Coins: %d < %d\n", state->coins, getCost(choice1)); } else{ //Add new card to discard gainCard(choice1, state, 0, currentPlayer); //remove feast! discardCard(handPos, currentPlayer, state, 1); return 0; case gardens: return -1; //Edit 2 ********************************************************************************************************************* case mine: i = mine_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer); return i; //Edit 3 ********************************************************************************************************************* case remodel: i=remodel_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer); return i; case smithy: smithy_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer); return 0; case village: village_func(card, i, j, choice1, choice2, state, handPos, bonus, currentPlayer); return 0; case baron: //increment purchase number state->numBuys++; if(choice1) //Checking bool if we going to discard victory card { for( i = 0; i < state->handCount[currentPlayer]; ++i) { if(state->hand[currentPlayer][i] == estate) { //increamenting coins state->coins += 4; //discard victory card discardCard(i, currentPlayer, state, 0); //discard baron discardCard(baron, currentPlayer, state, 0); return 0; } } } //No estate found, going to get one gainCard(estate, state, 0, currentPlayer); //try to get estate discardCard(handPos, currentPlayer, state, 0); //discard baron 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 = (currentPlayer+1)%state->numPlayers; i != currentPlayer; i = (i+1)%state->numPlayers) { if (drawCard(i, state) != 1){ PUSH(discard, i, POP_R(hand, i)); } gainCard(curse, state, 1, i); } discardCard(handPos, currentPlayer, 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) { //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: 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; }
int main() { struct gameState G1, G2; int numPlayers = 2; int seed = 1; int player1 = 0; int result = -1; int kingdomCards[10] = { adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy }; initializeGame(numPlayers, kingdomCards, seed, &G1); memcpy(&G2, &G1, sizeof(struct gameState)); printf("Testing gainCard():\n"); printf("\nTest card is not gained if supply count equals zero...\n"); G2.supplyCount[smithy] = 0; result = gainCard(smithy, &G2, 1, player1); printf("Return value = %d, expected -1...", result); if (result == -1) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } memcpy(&G2, &G1, sizeof(struct gameState)); printf("\nTest card gained is added to deck...\n"); gainCard(smithy, &G2, 1, player1); int lastDeckCard = G2.deck[player1][G2.deckCount[player1] - 1]; printf("Last card in deck = %d, expected 13 (smithy)...", lastDeckCard); if (lastDeckCard == smithy) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } printf("Player 1 deck count = %d, expected %d...", G2.deckCount[player1], G1.deckCount[player1] + 1); if (G2.deckCount[player1] == G1.deckCount[player1] + 1) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } memcpy(&G2, &G1, sizeof(struct gameState)); printf("\nTest card gained is added to hand...\n"); gainCard(smithy, &G2, 2, player1); int lastHandCard = G2.hand[player1][G2.handCount[player1] - 1]; printf("Last card in hand = %d, expected 13 (smithy)...", lastHandCard); if (lastHandCard == smithy) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } printf("P1 hand count = %d, expected %d...", G2.handCount[player1], G1.handCount[player1] + 1); if (G2.handCount[player1] == G1.handCount[player1] + 1) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } memcpy(&G2, &G1, sizeof(struct gameState)); printf("\nTest card gained is added to discard...\n"); gainCard(smithy, &G2, 0, player1); int lastDiscardCard = G2.discard[player1][G2.discardCount[player1] - 1]; printf("Last card in hand = %d, expected %d...", lastDiscardCard, smithy); if (lastDiscardCard == smithy) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } printf("Player 1 discard count = %d, expected 1...", G2.discardCount[player1]); if (G2.discardCount[player1] == 1) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } printf("\nTest supply pile count is decremented...\n"); printf("Supply count = %d, expected %d...", G2.supplyCount[smithy], G1.supplyCount[smithy] - 1); if (G2.supplyCount[smithy] == G1.supplyCount[smithy] - 1) { printf("PASSED.\n"); } else { printf("FAILED.\n"); } return 0; }
//baron int main(int argc, char* args[]) { int kCards[10] = {adventurer, gardens, embargo, village, minion, baron, cutpurse, sea_hag, tribute, smithy}; struct gameState g, orig; int r; if(argc != 3) { printf("Usage: randomtestcard1 seed secondsToRun\n"); return -1; } int seed = atoi(args[1]); int secondsLeft = atoi(args[2]); srand(seed); initializeGame(2, kCards, seed, &orig); printf("Running randomtestcard1 for %d seconds\n", secondsLeft); clock_t start = clock(); while(1) { clock_t totalTime = (clock() - start) / CLOCKS_PER_SEC; if(totalTime >= secondsLeft) break; memcpy(&g, &orig, sizeof(struct gameState)); int numHand = rand() % 10; for(int i = 0; i < numHand; ++i) { int randCard = rand() % (treasure_map+1); g.hand[0][i] = randCard; } g.handCount[0] = numHand; gainCard(baron, &g, 2, 0); int numEstates = 0; for(int i = 0; i < numHandCards(&g); ++i) if(handCard(i, &g) == estate) numEstates++; int oldTotalCards = fullDeckCount(0, &g); int totalCoins = updateCoins(0, &g); int estateSupp = supplyCount(estate, &g); int randOption = rand() % 2; r = playCard(numHandCards(&g)-1, randOption, 0, 0, &g); int newCoins = updateCoins(0, &g); myAssert(r == 0, "Played card failed", __LINE__); myAssert(g.numBuys == 2, "Did not get a buy", __LINE__); int newEstates = 0; for(int i = 0; i < numHandCards(&g); ++i) if(handCard(i, &g) == estate) newEstates++; //move playedCards into discard endTurn(&g); //wants to discard and has estates if(randOption && numEstates) { myAssert(newEstates == numEstates-1, "Did not discard estate when had/wanted to", __LINE__); myAssert(newCoins == totalCoins+4, "Did not get 4 coins for discarding estate", __LINE__); r = myAssert(oldTotalCards == fullDeckCount(0, &g), "Lost cards", __LINE__); } //wants to discard but has no estates else if(randOption && !numEstates) { myAssert(estateSupp-1 == supplyCount(estate, &g), "Did not gain estate when had none to discard", __LINE__); myAssert(newCoins == totalCoins, "Coins are not the same after forced to gain an estate", __LINE__); r = myAssert(oldTotalCards+1 == fullDeckCount(0, &g), "Incorrect total card count", __LINE__); } //did not want to discard else { myAssert(estateSupp-1 == supplyCount(estate, &g), "Did not gain estate", __LINE__); myAssert(newCoins == totalCoins, "Coins are not the same after gaining estate", __LINE__); r = myAssert(oldTotalCards+1 == fullDeckCount(0, &g), "Incorrect total card count", __LINE__); } if(r != 0) break; } r = myAssert(1, "", __LINE__); if(r == 0) printf("Tests completed successfully\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; }
void testGainCard() { int i; int r; int player = 1; struct gameState state; /*Add cards to the stack*/ for(i = 0; i <= treasure_map; i++) { state.supplyCount[i] = 5; } /*run tests for five players, one more than max*/ for(i = 0; i < 5; i++) { /*Test trying to get card from an empty stack*/ state.supplyCount[village] = 0; r = gainCard(village, &state, 1, i); if(r == -1) printf("gainCard: PASS empty stack, player %d.\n", i); else printf("gainCard: FAIL empty stack, player %d.\n", i); /*Test trying to get card from stack*/ state.supplyCount[village] = 5; r = gainCard(village, &state, 1, i); if(r == 0) printf("gainCard: PASS gain card, player %d.\n", i); else printf("gainCard: FAIL gain card, player %d.\n", i); /*Test adding card to player deck*/ state.supplyCount[village] = 5; state.deckCount[i] = 0; gainCard(village, &state, 1, i); if(state.deckCount[i] == 1) printf("gainCard: PASS add card to player %d deck.\n", i); else printf("gainCard: FAIL add card to player %d deck.\n", i); /*Test adding card to player hand*/ state.supplyCount[village] = 5; state.handCount[i] = 0; gainCard(village, &state, 2, i); if(state.handCount[i] == 1) printf("gainCard: PASS add card to player %d hand.\n", i); else printf("gainCard: FAIL add card to player %d hand.\n", i); /*Test adding card to player discard, positive flag*/ state.supplyCount[village] = 5; state.discardCount[i] = 0; gainCard(village, &state, 3, i); if(state.discardCount[i] == 1) printf("gainCard: PASS add card to player %d discard, positive flag.\n", i); else printf("gainCard: FAIL add card to player %d discard, positive flag.\n", i); /*Test adding card to player discard, negative flag*/ state.supplyCount[village] = 5; state.discardCount[i] = 0; gainCard(village, &state, -1, i); if(state.discardCount[i] == 1) printf("gainCard: PASS add card to player %d discard, negative flag.\n", i); else printf("gainCard: FAIL add card to player %d discard, negative flag.\n", i); } /*Test card is removed from supply stack*/ state.supplyCount[village] = 5; gainCard(village, &state, 1, player); if(state.supplyCount[village] == 4) printf("gainCard: PASS remove from supply stack.\n"); else printf("gainCard: FAIL remove from supply stack.\n"); /*Test using invalid card*/ state.supplyCount[27] = 5; gainCard(27, &state, 1, player); if(state.supplyCount[27] == 4) printf("gainCard: PASS using invalid card.\n"); else printf("gainCard: FAIL using invalid card.\n"); }
int main(){ struct gameState G; int k[10] = {village, smithy, great_hall, gardens, embargo, minion, mine, cutpurse, sea_hag, tribute}; initializeGame(2, k, 1, &G); int player = G.whoseTurn; G.handCount[player] = 0; G.hand[player][0] = k[0]; int i; for(i = 0; i < 5; i++){ if(i < 5) gainCard(1, &G, 1, player); else gainCard(i+1, &G, 1, G.whoseTurn); } drawCard(G.whoseTurn, &G); printf("######################################################c3\n"); printf("Testing Village card functionality.\n"); printf("Before tests:\n"); printf(" Player hand count: %d\n", G.handCount[player]); printf(" Player action count: %d\n", G.numActions); printf(" Player deck Count: %d\n", G.deckCount[player]); printf(" player discard Count: %d\n", G.discardCount[player]); int test1 = G.numActions + 2; int test2 = G.handCount[player]; int test3 = G.deckCount[player] - 1; int test4 = G.discardCount[player] + 1; cardEffect(village, 1, 1, 1, &G, 0, 0); printf("After test 1: cards in hand and cards in deck\n"); printf(" Player hand count: %d\n", G.handCount[player]); if(test2 != G.handCount[player]) printf("Bug!:\n Hand count should be: %d\n", test2); printf(" Player action count: %d\n", G.numActions); if(test1 != G.numActions) printf("Bug!:\n Action count should be: %d\n", test1); printf(" Player deck Count: %d\n", G.deckCount[player]); if(test3 != G.deckCount[player]) printf("Bug!:\n Deck count should be: %d\n", test3); printf(" player discard Count: %d\n", G.discardCount[player]); if(test4 != G.discardCount[player]) printf("Bug!:\n Discard count should be: %d\n", test4); //deck initialization might be bugged. G.deckCount[player] was returning a number while in //a for loop then a different number while outside of the for loop. My speculation is that //there is an issue with draw card that some times keeps the deck count the same. while(0 != G.deckCount[player]){ drawCard(G.whoseTurn, &G); } G.handCount[player] = 1; test1 = G.numActions + 2; test2 = G.handCount[player] - 1; test3 = G.deckCount[player]; test4 = test4 + 1; cardEffect(village, -1, -1, -1, &G, 0, 0); printf("After test 2: no cards in hand and no cards in deck\n"); if(test2 != G.handCount[player]) printf("Bug!:\n Hand count should be: %d\n", test2); printf(" Player action count: %d\n", G.numActions); if(test1 != G.numActions) printf("Bug!:\n Action count should be: %d\n", test1); printf(" Player deck Count: %d\n", G.deckCount[player]); if(test3 != G.deckCount[player]) printf("Bug!:\n Deck count should be: %d\n", test3); printf(" player discard Count: %d\n", G.discardCount[player]); if(test4 != G.discardCount[player]) printf("Bug!:\n Discard count should be: %d\n", test4); printf("After tests: The rest of the game state variables\n"); printf(" Number of players: %d\n", G.numPlayers); printf(" Supply Counter: %d\n", G.supplyCount[treasure_map+1]); printf(" Embargo Tokens: %d\n", G.embargoTokens[treasure_map+1]); printf(" Outpost check: %d\n", G.outpostPlayed); printf(" Outpost turn: %d\n", G.outpostTurn); printf(" Current player: %d\n", G.whoseTurn); printf(" Phase check: %d\n", G.phase); printf(" Number of Coins: %d\n", G.coins); printf(" Number of buys: %d\n", G.numBuys); printf(" Number of cards played: %d\n", G.playedCardCount); printf("\n"); printf("----------------------------------------------------------------\n"); printf("\n"); return 0; }
int playFeast(int choice1, struct gameState *state) { int player = whoseTurn(state); int i; int x; int tempHand[MAX_HAND]; // Gain card with cost up to 5 // Backup hand for (i = 0; i <= state->handCount[player]; i++) { tempHand[i] = state->hand[player][i]; // Backup card state->hand[player][i] = -1; // Set to nothing } // Backup hand // Update Coins for Buy updateCoins(player, 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[player] + state->deckCount[player] + state->discardCount[player] ); } gainCard(choice1, state, 0, player); // Gain the card x = 0; // No more buying cards if (DEBUG) { printf( "Deck Count: %d\n", state->handCount[player] + state->deckCount[player] + state->discardCount[player] ); } } } // Reset Hand for (i = 0; i <= state->handCount[player]; i++) { state->hand[player][i] = tempHand[i]; tempHand[i] = -1; } // Reset Hand return 0; }
//------------------------------------------------------------- int playAmbassador(struct gameState *state, int choice1, int choice2, int handPos) { int j; int i; int currentPlayer = whoseTurn(state); 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; }
int main() { int i, n, deckCount = 0, error1 = 0, error2 = 0, error3 = 0, error4 = 0, error5 = 0; int handPos = 0; int seed = 2000; int numPlayers = floor(Random() * MAX_PLAYERS); int player; int numBefore; int numAfter; int coinsBefore; int coinsAfter; int card = 0; int bonus = 0; struct gameState G, testG, oldG; int k[10] = {adventurer, embargo, village, minion, mine, cutpurse, sea_hag, gardens, smithy, council_room}; printf("----------------- Random Testing for %s Begin----------------\n", TESTCARD); for(n = 0; n < seed; n++){ player = floor(Random() * 2); G.deckCount[player] = floor(Random() * MAX_DECK); G.discardCount[player] = floor(Random() * MAX_DECK); G.handCount[player] = floor(Random() * MAX_HAND); numPlayers = floor(Random() * MAX_PLAYERS); // initialize a game state and player cards initTestGame(numPlayers, k, seed, &G); /*************** TEST 1: Two treasure cards are revealed ***********/ // copy the game state to a test case memcpy(&testG, &G, sizeof(struct gameState)); player = testG.whoseTurn; // make sure the player has treasure cards gainCard(copper,&testG,1,player); gainCard(silver,&testG,1,player); gainCard(gold,&testG,1,player); // record coin amount before card is played updateCoins(player, &testG, 0); coinsBefore = testG.coins; // fill players deck with gardens cards for (i = deckCount; i < (deckCount + 5); i++) { gainCard(k[rand() % 9 + 1],&testG,1,player); } // give player an adventurer card and play it gainCard(adventurer,&testG,2,player); cardEffect(card, 0, 0, 0, &testG, handPos, &bonus); // get coin amounts after card is played updateCoins(player, &testG, 0); coinsAfter = testG.coins; endTurn(&testG); // this will fail due to the altered dominion.c code if(coinsAfter != 5) { printf("Error 1 'Two treasure cards in deck' Expected: 5, Actual: %d\n", coinsAfter); error1++; } if(numHandCards(&testG) != (numHandCards(&G) + 1)) { printf("Error 5 'Number of cards in hand updated' Expected: %d, Actual: %d\n", (numHandCards(&G) + 1), numHandCards(&testG)); error5++; } /*************** TEST 2: No treasure cards in deck ***********/ // copy the game state to a test case memcpy(&testG, &G, sizeof(struct gameState)); player = testG.whoseTurn; // record coin amount before card is played updateCoins(player, &testG, 0); coinsBefore = testG.coins; // fill players deck with gardens cards for (i = deckCount; i < (deckCount + 5); i++) { gainCard(k[rand() % 9 + 1],&testG,1,player); } // give player an adventurer card and play it gainCard(adventurer,&testG,2,player); cardEffect(card, 0, 0, 0, &testG, handPos, &bonus); // get coin amounts after card is played updateCoins(player, &testG, 0); coinsAfter = testG.coins; endTurn(&testG); // test fails if player gains coins from playing the adventurer card if(coinsAfter != 0) { printf("Error 2 'No treasure cards in deck' Expected: 0, Actual: %d\n", coinsAfter); error2++;//printf("PASS: No treasure cards in deck\n\n\n"); } if(numHandCards(&testG) != numHandCards(&G)) { printf("Error 5 'Number of cards in hand updated' Expected: %d, Actual: %d\n", numHandCards(&G), numHandCards(&testG)); error5++; } /*************** TEST 3: One treasure card in deck ***********/ // copy the game state to a test case memcpy(&testG, &G, sizeof(struct gameState)); player = testG.whoseTurn; // record coin amount before card is played gainCard(copper,&testG,1,player); updateCoins(player, &testG, 0); coinsBefore = testG.coins; // fill players deck with gardens cards for (i = deckCount; i < (deckCount + 5); i++) { gainCard(k[rand() % 9 + 1],&testG,1,player); } // give player an adventurer card and play it gainCard(adventurer,&testG,2,player); cardEffect(card, 0, 0, 0, &testG, handPos, &bonus); // get coin amounts after card is played updateCoins(player, &testG, 0); coinsAfter = testG.coins; endTurn(&testG); // test fails if player gains no coins from playing the adventurer card // will fail due to altered dominion.c code if(coinsAfter == 0) { printf("Error 3 'One treasure card in deck' Expected: 1, Actual: %d\n", coinsAfter); error3++;//printf("PASS: One treasure card in deck\n\n\n"); } if(numHandCards(&testG) != numHandCards(&G)) { printf("Error 5 'Number of cards in hand updated' Expected: %d, Actual: %d\n", numHandCards(&G), numHandCards(&testG)); error5++; } /*************** TEST 4: All revealed non-treasure cards are discarded ***********/ // copy the game state to a test case memcpy(&testG, &G, sizeof(struct gameState)); player = testG.whoseTurn; // give player treasure cards and record card amounts before card is played gainCard(silver,&testG,1,player); gainCard(silver,&testG,1,player); gainCard(silver,&testG,1,player); numBefore = numHandCards(&testG); // fill players deck with gardens cards for (i = deckCount; i < (deckCount + 5); i++) { gainCard(k[rand() % 9 + 1],&testG,1,player); } // give player an adventurer card and play it gainCard(adventurer,&testG,2,player); cardEffect(card, 0, 0, 0, &testG, handPos, &bonus); // get card amounts after card is played oldG = testG; endTurn(&testG); numAfter = numHandCards(&oldG); // test passes if player's hand cointains only the adventurer card if(numAfter != (numBefore + 1)) { printf("Error 4 'All revealed non-treasure cards discarded' failed. Expected: %d, actual: %d\n", (numBefore+1), numAfter); error4++; } } printf("\n >>>>> SUCCESS: Random Testing Complete for %s <<<<<\n\n", TESTCARD); printf("Error 1 'Two treasure cards in deck' failed %d of %d times\n", error1, seed); printf("Error 2 'No treasure cards in deck' failed %d of %d times\n", error2, seed); printf("Error 3 'One treasure card in deck' failed %d of %d times\n", error3, seed); printf("Error 4 'All revealed non-treasure cards discarded' failed %d of %d times\n", error4, seed); printf("Error 5 'Number of cards in hand updated' failed %d of %d times\n\n\n\n", error5, (seed * 3)); return 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 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 main() { //initialize game struct gameState game, testgame; int playerNumber = 2; int player = 1; int kCards[10] = {adventurer, council_room, feast, gardens, mine, smithy, village, baron, great_hall, minion}; int rSeed = 50; int returnValue; int numberLeft; initializeGame(playerNumber, kCards, rSeed, &game); printf("----------TESTING gainCard()----------\n\n"); printf("----------Testing if card is not in game or is no longer available----------\n"); //sea_hag card is not in game //when the card is not in the game it should return -1 returnValue = gainCard(sea_hag, &game, 0, player); if(returnValue == -1) { printf("Test 1 (card not being used in game) passed.\n"); } else { printf("Test 1 (card not being used in game) failed.\n"); } //make card no longer available in game by setting it to zero game.supplyCount[council_room] = 0; returnValue = gainCard(council_room, &game, 0, player); if(returnValue == -1) { printf("Test 2 (card no longer available in game) passed.\n"); } else { printf("Test 2 (card no longer available in game) failed.\n"); } printf("----------Testing where card goes when it is gained----------\n"); //toFlag = 0 means gained card goes to discard memcpy(&testgame,&game,sizeof(struct gameState)); //save game state gainCard(feast, &game, 0, player); testgame.discard[player][testgame.discardCount[player]] = feast; testgame.discardCount[player]++; if(testgame.discard[player][testgame.discardCount[player] -1] == game.discard[player][game.discardCount[player] - 1] && testgame.discardCount[player] == game.discardCount[player]) { printf("Test 3 (toFlag=0) passed.\n"); } else { printf("Test 3 (toFlag=0) failed.\n"); } //toflag = 1 means card is added to deck memcpy(&testgame,&game,sizeof(struct gameState)); //save game state gainCard(adventurer, &game, 1, player); testgame.deck[player][testgame.deckCount[player]] = adventurer; testgame.deckCount[player]++; if(testgame.deck[player][testgame.deckCount[player] - 1] == game.deck[player][game.deckCount[player] - 1] && testgame.deckCount[player] == game.deckCount[player]) { printf("Test 4 (toFlag=1) passed.\n"); } else { printf("Test 4 (toFlag=1) failed.\n"); } //toflag= 2 means card is added to hand memcpy(&testgame,&game,sizeof(struct gameState)); //save game state gainCard(gardens, &game, 2, player); testgame.hand[player][testgame.handCount[player]] = gardens; testgame.handCount[player]++; if(testgame.hand[player][testgame.handCount[player] - 1] == game.hand[player][testgame.handCount[player] - 1] && testgame.handCount[player] == game.handCount[player]) { printf("Test 5 (toFlag=2) passed.\n"); } else { printf("Test 5 (toFlag=2) failed.\n"); } printf("----------Testing to make sure supply count is updated----------\n"); memcpy(&testgame,&game,sizeof(struct gameState)); //save game state numberLeft = game.supplyCount[village]; gainCard(village, &game, 2, player); testgame.supplyCount[village]--; if(testgame.supplyCount[village] == game.supplyCount[village]) { printf("Test 6 (supply count updated) passed.\n"); } else { printf("Test 6 (supply count updated) failed.\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 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) ) { /* MUTANT (del_stmt) */ /* 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 feastCard(int currentPlayer, int choice1, struct gameState* state, int handPos){ //Gain a card up to 5 cost //Backup hand int i; int x; int temphand[MAX_HAND]; for (i = 0; i <= state->handCount[currentPlayer]; i++){ //Backup card temphand[i] = state->hand[currentPlayer][i]; //Set to nothing state->hand[currentPlayer][i] = -1; } //Backup hand //Update coins for buy updateCoins(currentPlayer, state, 5); //Condition to loop on x = 1; //Buy 1 card while(x == 1) { if (supplyCount(choice1, state) <= 0){ if (DEBUG){ printf("No cards remaining!\n"); } if(DEBUG){ printf("Cards remaining: %d\n", supplyCount(choice1,state)); } } else if (state->coins < getCost (choice1)) { printf ("Not enough coins to purchase card!\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]); } //Gain the card gainCard(choice1, state, 0, currentPlayer); //No buys remaining x=0; 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; } return 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: 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; }
/* 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; }