diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..0ee506f93 Binary files /dev/null and b/.DS_Store differ diff --git a/dominion/.DS_Store b/dominion/.DS_Store new file mode 100644 index 000000000..7b001fc5b Binary files /dev/null and b/dominion/.DS_Store differ diff --git a/dominion/Makefile copy b/dominion/Makefile copy new file mode 100644 index 000000000..e6bef7740 --- /dev/null +++ b/dominion/Makefile copy @@ -0,0 +1,88 @@ +CFLAGS= -Wall -fpic -coverage -lm -std=c99 + +rngs.o: rngs.h rngs.c + gcc -c rngs.c -g $(CFLAGS) + +dominion.o: dominion.h dominion.c rngs.o + gcc -c dominion.c -g $(CFLAGS) + +playdom: dominion.o playdom.c + gcc -o playdom playdom.c -g dominion.o rngs.o $(CFLAGS) +#To run playdom you need to entere: ./playdom like ./playdom 10*/ + +randomtestresults: randomtestcard1.c randomtestcard2.c + echo "randomtestcard1.c:" >> randomtestresults.out + gcc -o randomtestcard1 -g randomtestcard1.c dominion.c rngs.c interface.c $(CFLAGS) + randomtestcard1 >> randomtestresults.out + gcov dominion.c -b -f >> randomtestresults.out + + echo "randomtestcard2.c:" >> randomtestresults.out + gcc -o randomtestcard2 -g randomtestcard2.c dominion.c rngs.c interface.c $(CFLAGS) + randomtestcard2 >> randomtestresults.out + gcov dominion.c -b -f >> randomtestresults.out + + echo "randomtestcard3.c:" >> randomtestresults.out + gcc -o randomtestcard3 -g randomtestcard3.c dominion.c rngs.c interface.c $(CFLAGS) + randomtestcard3 >> randomtestresults.out + gcov dominion.c -b -f >> randomtestresults.out + +randomtestcard1: randomtestcard1.c dominion.o rngs.o interface.o + gcc -o randomtestcard1 -g randomtestcard1.c dominion.o rngs.o interface.o $(CFLAGS) + +randomtestcard2: randomtestcard2.c dominion.o rngs.o interface.o + gcc -o randomtestcard2 -g randomtestcard2.c dominion.o rngs.o interface.o $(CFLAGS) + +randomtestcard3: randomtestcard3.c dominion.o rngs.o interface.o + gcc -o randomtestcard3 -g randomtestcard3.c dominion.o rngs.o interface.o $(CFLAGS) + +unittest1: unittest1.c dominion.o rngs.o + gcc -o unittest1 dominion.c rngs.c unittest1.c interface.c $(CFLAGS) + +unittest2: unittest2.c dominion.o rngs.o + gcc -o unittest2 dominion.c rngs.c unittest2.c interface.c $(CFLAGS) + +unittest3: unittest3.c dominion.o rngs.o + gcc -o unittest3 dominion.c rngs.c unittest3.c interface.c $(CFLAGS) + +unittest4: unittest4.c dominion.o rngs.o + gcc -o unittest4 dominion.c rngs.c unittest4.c interface.c $(CFLAGS) + +unittest5: unittest5.c dominion.o rngs.o + gcc -o unittest5 dominion.c rngs.c unittest5.c interface.c $(CFLAGS) + +unittestresults: unittest1.c unittest2.c unittest3.c unittest4.c unittest5.c dominion.o + echo "unittest1.c:" >> unittestresults.out + gcc -o unittest1 dominion.c rngs.c unittest1.c interface.c $(CFLAGS) + unittest1 >> unittestresults.out + gcov dominion.c -b -f >> unittestresults.out + + echo "unittest2.c:" >> unittestresults.out + gcc -o unittest2 dominion.c rngs.c unittest2.c interface.c $(CFLAGS) + unittest2 >> unittestresults.out + gcov dominion.c -b -f >> unittestresults.out + + echo "unittest3.c:" >> unittestresults.out + gcc -o unittest3 dominion.c rngs.c unittest3.c interface.c $(CFLAGS) + unittest3 >> unittestresults.out + gcov dominion.c -b -f >> unittestresults.out + + echo "unittest4.c:" >> unittestresults.out + gcc -o unittest4 dominion.c rngs.c unittest4.c interface.c $(CFLAGS) + unittest4 >> unittestresults.out + gcov dominion.c -b -f >> unittestresults.out + + echo "unittest5.c:" >> unittestresults.out + gcc -o unittest5 dominion.c rngs.c unittest5.c interface.c $(CFLAGS) + unittest5 >> unittestresults.out + gcov dominion.c -b -f >> unittestresults.out + +interface.o: interface.h interface.c + gcc -c interface.c -g $(CFLAGS) + +player: player.c interface.o + gcc -o player player.c -g dominion.o rngs.o interface.o $(CFLAGS) + +all: playdom player + +clean: + rm -f *.o playdom.exe playdom player player.exe randomtestcard1 randomtestcard2 randomtestcard3 unittest1 unittest2 unittest3 unittest4 unittest5 unittest1.exe *.gcov *.gcda *.gcno *.so *.out \ No newline at end of file diff --git a/dominion/dominion.c b/dominion/dominion.c index c94e2edb9..25e26199f 100644 --- a/dominion/dominion.c +++ b/dominion/dominion.c @@ -889,13 +889,187 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState return 0; case baron: - state->numBuys++;//Increase buys by 1! + baronCard(choice1, 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: + minionCard(choice1, choice2, handPos, state); + return 0; + + case steward: + if (choice1 == 1) + { + //+2 cards + drawCard(currentPlayer, state); + drawCard(currentPlayer, state); + } + else if (choice1 == 2) + { + //+2 coins + state->coins = state->coins + 2; + } + else + { + //trash 2 cards in hand + discardCard(choice2, currentPlayer, state, 1); + discardCard(choice3, currentPlayer, state, 1); + } + + //discard card from hand + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case tribute: + tributeCard(state, nextPlayer, tributeRevealedCards[2]); + return 0; + + case ambassador: + ambassadorCard(choice1, choice2, state, handPos); + return 0; + + case cutpurse: + + updateCoins(currentPlayer, state, 2); + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + for (j = 0; j < state->handCount[i]; j++) + { + if (state->hand[i][j] == copper) + { + discardCard(j, i, state, 0); + break; + } + if (j == state->handCount[i]) + { + for (k = 0; k < state->handCount[i]; k++) + { + if (DEBUG) + printf("Player %d reveals card number %d\n", i, state->hand[i][k]); + } + break; + } + } + + } + + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + return 0; + + + case embargo: + //+2 Coins + state->coins = state->coins + 2; + + //see if selected pile is in play + if ( state->supplyCount[choice1] == -1 ) + { + return -1; + } + + //add embargo token to selected supply pile + state->embargoTokens[choice1]++; + + //trash card + discardCard(handPos, currentPlayer, state, 1); + return 0; + + case outpost: + //set outpost flag + state->outpostPlayed++; + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case salvager: + //+1 buy + state->numBuys++; + + if (choice1) + { + //gain coins equal to trashed card + state->coins = state->coins + getCost( handCard(choice1, state) ); + //trash card + discardCard(choice1, currentPlayer, state, 1); + } + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case sea_hag: + for (i = 0; i < state->numPlayers; i++) { + if (i != currentPlayer) { + state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; + state->deckCount[i]--; + state->discardCount[i]++; + state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse + } + } + return 0; + + case treasure_map: + //search hand for another treasure_map + index = -1; + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == treasure_map && i != handPos) + { + index = i; + break; + } + } + if (index > -1) + { + //trash both treasure cards + discardCard(handPos, currentPlayer, state, 1); + discardCard(index, currentPlayer, state, 1); + + //gain 4 Gold cards + for (i = 0; i < 4; i++) + { + gainCard(gold, state, 1, currentPlayer); + } + + //return success + return 1; + } + + //no second treasure_map found in hand + return -1; + } + + return -1; +} + +int baronCard(int choice1, struct gameState *state) +{ + int currentPlayer = whoseTurn(state); + + 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 + if (state->hand[currentPlayer][p] != estate) { //Found an estate card! + state->coins += 2;//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++) { @@ -940,19 +1114,13 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState 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: +int minionCard(int choice1, int choice2, int handPos, struct gameState, *state) +{ + int i; + int j; + int currentPlayer = whoseTurn(state); //+1 action state->numActions++; @@ -961,7 +1129,7 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState if (choice1) { - state->coins = state->coins + 2; + state->coins = state->coins + 4; } else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 { @@ -972,7 +1140,7 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } //draw 4 - for (i = 0; i < 4; i++) + for (i = 0; i < 2; i++) { drawCard(currentPlayer, state); } @@ -1001,32 +1169,78 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } return 0; +} - case steward: - if (choice1 == 1) +int ambassadorCard(int choice1, int choice2, struct gameState *state, 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) { - //+2 cards - drawCard(currentPlayer, state); - drawCard(currentPlayer, state); + return -1; } - else if (choice1 == 2) + + if (choice1 != handPos) { - //+2 coins - state->coins = state->coins + 2; + return -1; } - else + + for (i = 0; i < state->handCount[currentPlayer]; i++) { - //trash 2 cards in hand - discardCard(choice2, currentPlayer, state, 1); - discardCard(choice3, currentPlayer, state, 1); + if (i != handPos || i == state->hand[currentPlayer][choice1] || i != choice1) + { + j++; + } + } + if (j < choice2) + { + return -1; } - //discard card from hand + 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 tribute: - if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { +int tributeCard(struct gameState *state, int nextPlayer, int tributeRevealedCards[2]) +{ + int i; + int currentPlayer = whoseTurn(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]--; @@ -1069,7 +1283,7 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } for (i = 0; i <= 2; i ++) { - if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) { //Treasure cards + if (tributeRevealedCards[i] == copper && tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) { //Treasure cards state->coins += 2; } @@ -1083,186 +1297,50 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } return 0; +} - case ambassador: - j = 0; //used to check if player has enough cards to discard +int mineCard(int choice1, int choice2, struct gameState *state, int handPos) +{ + int i; + int j; + int currentPlayer = whoseTurn(state); - if (choice2 > 2 || choice2 < 0) - { - return -1; - } + j = state->hand[currentPlayer][choice1]; //store card we will trash - if (choice1 == handPos) + if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold) { return -1; } - for (i = 0; i < state->handCount[currentPlayer]; i++) - { - if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) - { - j++; - } - } - if (j < choice2) + if (choice2 > treasure_map || choice2 < curse) { 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 ) + if ( (getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2) ) { 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); - } + gainCard(choice2, state, 2, currentPlayer); - //discard card + //discard card from hand 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; + //discard trashed card for (i = 0; i < state->handCount[currentPlayer]; i++) { - if (state->hand[currentPlayer][i] == treasure_map && i != handPos) + if (state->hand[currentPlayer][i] == j) { - index = i; + discardCard(i, currentPlayer, state, 1); 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; + return 0; } + int discardCard(int handPos, int currentPlayer, struct gameState *state, int trashFlag) { diff --git a/dominion/randomtestcard1.c b/dominion/randomtestcard1.c new file mode 100644 index 000000000..b4fd3c3a4 --- /dev/null +++ b/dominion/randomtestcard1.c @@ -0,0 +1,151 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include "interface.h" +#include +#include +#include +#include +#include +#include "rngs.h" +#include + +#define DEBUG 0 +#define NOISY_TEST 0 + +int main () { + + //random seed for gamestate + int seed = time(NULL); + srand(seed); + int failedCheckCount1 = 0; //counter to see how many checks failed + int failedCheckCount2 = 0; + int failedCheckCount3 = 0; + int failedCheckCount4 = 0; + int failedCheckCount5 = 0; + int failedCheckCount6 = 0; + int numberOfTests = 1000; //number of random tests to generate + + int n, i, j, numPlayers, choice1, estateFlag; + + int k[10] = {adventurer, council_room, feast, gardens, mine, + remodel, smithy, village, baron, great_hall}; + + struct gameState state, testState; + + printf ("Testing baronCard\n"); + + printf ("RANDOM TESTER.\n"); + + + for (n = 0; n < numberOfTests; n++) { + + choice1 = rand() % 2; //use this to randomly generate 0 or 1 for choice1 + numPlayers = (rand() % 3) + 2; //number of players between 2 and 4 + initializeGame(numPlayers, k, seed, &state); //initialize a game + //deckCount, discardCount, and handCount are set to random numbers within domain + for (i = 0; i < numPlayers; i++) { + state.deckCount[i] = rand() % MAX_DECK; + state.discardCount[i] = rand() % MAX_DECK; + state.handCount[i] = rand() % MAX_HAND; + } + //also want to randomize the supply of estates so we get full coverage + if (numPlayers == 2) { + state.supplyCount[estate] = rand() % 9; //supply count random between 0 and 8 + } else { + state.supplyCount[estate] = rand() % 13; //supply count between 0 and 12 + } + +#if (NOISY_TEST == 1) + printf("\n"); + printf("====================================================\n"); + printf("Case %d\n", n); + printf("Number of Estate Cards: %d\n", state.supplyCount[estate]); + printf("numPlayers: %d\n", state.numPlayers); + for (j = 0; j < numPlayers; j++) { + printf("Player: %d -- Deck: %d, Discard: %d, Hand: %d, Choice1: %d\n", j, state.deckCount[j], state.discardCount[j], state.handCount[j], choice1); + } + //Check to see what happens when you call baronCard +#endif + //End turn a random number of times so we aren't always testing Player 0 + for (int i = 0; i < rand() % 4; i++) { + endTurn(&state); + } + //Now figure out whose turn it is + int currentPlayer = state.whoseTurn; + //Now save the game state to test state before testing + memcpy(&testState, &state, sizeof(struct gameState)); + //In the test state, current player plays baronCard + baronCard(choice1, &testState, currentPlayer); + + //Now assert what should happen + //We always know numBuys should increase by 1 + if ((state.numBuys+1) != testState.numBuys) { +#if (NOISY_TEST == 1) + printf("numBuys - expected: %d, actual: %d\n", state.numBuys+1, testState.numBuys); +#endif + failedCheckCount1++; + } + if (choice1 > 0) { + estateFlag = 0; + for (int j = 0; j < state.handCount[currentPlayer]; j++) { + if (state.hand[currentPlayer][j] == estate) { + estateFlag = 1; //if an estate card is found in p's hand, set flag to 1 + } + } + if (estateFlag == 1) { //if estate card was found + //coins increase by 4 + if (state.coins + 4 != testState.coins){ +#if (NOISY_TEST == 1) + printf("Coins - expected: %d, actual: %d\n", state.coins+4, testState.coins); +#endif + failedCheckCount2++; + } + //discardCount[p]++ + if (testState.discardCount[currentPlayer] != state.discardCount[currentPlayer] + 1) { +#if (NOISY_TEST == 1) + printf("discardCount - expected: %d, actual: %d\n", state.discardCount[currentPlayer] + 1, testState.discardCount[currentPlayer]); +#endif + failedCheckCount3++; + } + //handCount[p]-- + if (state.handCount[currentPlayer] - 1 != testState.handCount[currentPlayer]) { +#if (NOISY_TEST == 1) + printf("handCount - expected: %d, actual: %d\n", state.handCount[currentPlayer]-1, testState.handCount[currentPlayer]); +#endif + failedCheckCount4++; + } + } + else { + //if estate card wasn't found + //check if supplyCount[estate,state] > 0 + if (state.supplyCount[estate] > 0){ + //if yes, then supplyCount of estate--, discardCount[p]++, last discard should be an estate, and then check if supplycount is 0 + if((state.supplyCount[estate] -1) != testState.supplyCount[estate]){ +#if (NOISY_TEST == 1) + printf("supplyCount - expected: %d, actual: %d\n", state.supplyCount[estate] - 1, testState.supplyCount[estate]); +#endif + failedCheckCount5++; + } + if((state.discardCount[currentPlayer] + 1) != testState.discardCount[currentPlayer]){ +#if (NOISY_TEST == 1) + printf("discardCount - expected: %d, actual: %d\n", state.discardCount[currentPlayer] + 1, testState.discardCount[currentPlayer]); +#endif + failedCheckCount6++; + } + } + } + } + + + } + + printf ("END TEST\n"); + + printf("Failed Check 1: %d times\n", failedCheckCount1); + printf("Failed Check 2: %d times\n", failedCheckCount2); + printf("Failed Check 3: %d times\n", failedCheckCount3); + printf("Failed Check 4: %d times\n", failedCheckCount4); + printf("Failed Check 5: %d times\n", failedCheckCount5); + printf("Failed Check 6: %d times\n", failedCheckCount6); + return 0; + } \ No newline at end of file diff --git a/dominion/randomtestcard2.c b/dominion/randomtestcard2.c new file mode 100644 index 000000000..3d71d7023 --- /dev/null +++ b/dominion/randomtestcard2.c @@ -0,0 +1,137 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include "interface.h" +#include +#include +#include +#include +#include +#include "rngs.h" +#include + +#define DEBUG 0 +#define NOISY_TEST 0 + +int main () { + + //random seed for gamestate + int seed = time(NULL); + srand(seed); + int failedCheckCount1 = 0; //counter to see how many checks failed + int failedCheckCount2 = 0; + int failedCheckCount3 = 0; + int failedCheckCount4 = 0; + int numberOfTests = 100; //number of random tests to generate + + int n, j, numPlayers, choice2, handPos, currentPlayer; + + int k[10] = {adventurer, council_room, feast, gardens, minion, + remodel, smithy, village, baron, great_hall}; + + struct gameState state, testState; + + printf ("Testing minionCard\n"); + + printf ("RANDOM TESTER.\n"); + + + for (n = 0; n < numberOfTests; n++) { + + int choice1 = rand() % 2; //use this to randomly generate 0 or 1 for choice1 + //set choice2 = to opposite of choice1 + if (choice1 == 0) { + choice2 = 1; + } else if (choice1 == 1) { + choice2 = 0; + } + + numPlayers = (rand() % 3) + 2; //number of players between 2 and 4 + initializeGame(numPlayers, k, seed, &state); //initialize a game + //deckCount, discardCount, and handCount are set to random numbers within domain + for (int i = 0; i < numPlayers; i++) { + state.deckCount[i] = rand() % MAX_DECK; + state.discardCount[i] = rand() % MAX_DECK; + state.handCount[i] = rand() % MAX_HAND; + } + +#if (NOISY_TEST == 1) + printf("\n"); + printf("====================================================\n"); + printf("Case %d\n", n); + printf("numPlayers: %d\n", state.numPlayers); + for (j = 0; j < numPlayers; j++) { + printf("Player: %d -- Deck: %d, Discard: %d, Hand: %d, Choice1: %d, Choice2: %d\n", j, state.deckCount[j], state.discardCount[j], state.handCount[j], choice1, choice2); + } + //Check to see what happens when you call minionCard +#endif + //End turn a random number of times so we aren't always testing Player 0 + int turns = rand() % 4; + + for (int m = 0; m < turns; m++) { + endTurn(&state); + } + //Now figure out whose turn it is + currentPlayer = state.whoseTurn; + + //Now pick a random card in the currentPlayer's hand (from 0 to handCount[current] - 1) + int count = state.handCount[currentPlayer]; + handPos = rand() % count; + + //Now save the game state to test state before testing + memcpy(&testState, &state, sizeof(struct gameState)); + //In the test state, current player plays cardBaron + minionCard(choice1, choice2, &testState, handPos, currentPlayer); + + //Now assert what should happen + //We always know numActions should increase by 1 + if ((state.numActions+1) != testState.numActions) { +#if (NOISY_TEST == 1) + printf("numActions - expected: %d, actual: %d\n", state.numActions+1, testState.numActions); + #endif + failedCheckCount1++; + } + + //Checking choice1 + if (choice1 == 1) { + if (testState.coins != state.coins+2) { +#if (NOISY_TEST == 1) + printf("Number of coins - expected: %d, actual: %d\n", state.coins + 2, testState.coins); +#endif + failedCheckCount2++; + } + } + + if (choice2 == 1) { + if (testState.handCount[currentPlayer] != 4) { +#if (NOISY_TEST == 1) + printf("Hand Count - expected: 4, actual: %d\n", testState.handCount[currentPlayer]); +#endif + failedCheckCount3++; + } + } + + if (choice2 == 1) { + //loop over the number of players + for (int p = 0; p < testState.numPlayers; p++) { + //verify that if the player originally had 5 or more cards, they now have 4 cards + if (state.handCount[p] > 4) { + if (testState.handCount[p] != 4) { +#if (NOISY_TEST == 1) + printf("Hand Count of player %d - expected: 4, actual: %d\n", p, testState.handCount[p]); +#endif + failedCheckCount4++; + } + } + } + } + } + + printf ("END TEST\n"); + + printf("Failed Check 1: %d times\n", failedCheckCount1); + printf("Failed Check 2: %d times\n", failedCheckCount2); + printf("Failed Check 3: %d times\n", failedCheckCount3); + printf("Failed Check 4: %d times\n", failedCheckCount4); + + return 0; + } \ No newline at end of file diff --git a/dominion/randomtestcard3.c b/dominion/randomtestcard3.c new file mode 100644 index 000000000..6cff77b13 --- /dev/null +++ b/dominion/randomtestcard3.c @@ -0,0 +1,228 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include "interface.h" +#include +#include +#include +#include +#include +#include "rngs.h" +#include + +#define DEBUG 0 +#define NOISY_TEST 0 + +int main () { + + //random seed for gamestate + int seed = time(NULL); + srand(seed); + int failedCheckCount1 = 0; //counter to see how many checks failed + int failedCheckCount2 = 0; + int failedCheckCount3 = 0; + int failedCheckCount4 = 0; + int failedCheckCount5 = 0; + int failedCheckCount6 = 0; + int failedCheckCount7 = 0; + int failedCheckCount8 = 0; + int failedCheckCount9 = 0; + int failedCheckCount10 = 0; + + + int numberOfTests = 1000; //number of random tests to generate + + int n, j, numPlayers, currentPlayer, nextPlayer; + int tributeRevealedCards[2] = {-1,-1}; + + int addCoins = 0; //tracks number of coins to add + int addCards = 0; //tracks number of cards to add + int addActions = 0; //tracks number of actions to add + + int k[10] = {adventurer, council_room, feast, gardens, tribute, + remodel, smithy, village, baron, great_hall}; + + struct gameState state, testState; + + printf ("Testing tributeCard\n"); + printf ("RANDOM TESTER.\n"); + + for (n = 0; n < numberOfTests; n++) { + + numPlayers = (rand() % 3) + 2; //number of players between 2 and 4 + addCoins = 0; //reset the counters for coins + addActions = 0; //actions + addCards = 0; //and cards + tributeRevealedCards[0] = -1; + tributeRevealedCards[1] = -1; + initializeGame(numPlayers, k, seed, &state); //initialize a game + + //deckCount, discardCount are set to random numbers within domain + //for this test, we want some instances where there might be 0 cards in the + //discard or deck, so we are going to limit the range for the deckCount + //and the discardCounts so there's a better probability of getting a 0 + for (int i = 0; i < numPlayers; i++) { + state.deckCount[i] = rand() % 11; + for (int j = 0; j < state.deckCount[i]; j++) { + state.deck[i][j] = rand() % 27; //set to random value between 0 and 26 + } + state.discardCount[i] = rand() % 6; + for (int k = 0; k < state.discardCount[i]; k++) { + state.discard[i][k] = rand() % 27; //set to random value between 0 and 26 + } + } + + //we want the cards in the decks and discards to be set to a random mix of cards + + +#if (NOISY_TEST == 1) + printf("\n"); + printf("====================================================\n"); + printf("Case %d\n", n); + printf("numPlayers: %d\n", state.numPlayers); + for (j = 0; j < numPlayers; j++) { + printf("Player: %d -- Deck: %d, Discard: %d, Hand: %d\n", j, state.deckCount[j], state.discardCount[j], state.handCount[j]); + printDeck(j, &state); + printDiscard(j, &state); + } + //Check to see what happens when you call tributeCard +#endif + //End turn a random number of times so we aren't always testing Player 0 + int turns = rand() % 4; + + for (int m = 0; m < turns; m++) { + endTurn(&state); + } + + //Now figure out whose turn it is + currentPlayer = state.whoseTurn; + //if the current player is the last player, nextPlayer is 0 + if (currentPlayer == numPlayers - 1) { + nextPlayer = 0; + } else { //otherwise nextPlayer is currentPlayer index + 1 + nextPlayer = currentPlayer + 1; + } + + //Now save the game state to test state before testing + memcpy(&testState, &state, sizeof(struct gameState)); + //In the test state, current player plays tributeCard + tributeCard(&testState, nextPlayer, currentPlayer, tributeRevealedCards); + + //Now assert what should happen + // if the discard count plus deck count of the next player contain 1 or less cards + if ((testState.discardCount[nextPlayer] + testState.deckCount[nextPlayer]) <= 1) { + //if the deck has the only card, its the first revealed card and deck is decremented + if (testState.deckCount[nextPlayer] > 0) { + if (tributeRevealedCards[0] != state.deck[nextPlayer][state.deckCount[nextPlayer]-1]) { +#if (NOISY_TEST == 1) + printf("tributeRevealedCards[0] - expected: %d, actual: %d\n", state.deck[nextPlayer][state.deckCount[nextPlayer]-1], tributeRevealedCards[0]); +#endif + failedCheckCount1++; + } + if (testState.deckCount[nextPlayer] != state.deckCount[nextPlayer] - 1){ +#if (NOISY_TEST == 1) + printf("deckCount of nextPlayer - expected: %d, actual: %d\n", state.deckCount[nextPlayer] - 1, testState.deckCount[nextPlayer]); +#endif + failedCheckCount2++; + } + } + //if the discard has the only card, its the first revealed card and discard is decremented + else if (testState.discardCount[nextPlayer] > 0) { + if (tributeRevealedCards[0] != state.discard[nextPlayer][state.discardCount[nextPlayer]-1]){ +#if (NOISY_TEST == 1) + printf("tributeRevealedCards[0] - expected: %d, actual: %d\n", state.discard[nextPlayer][state.discardCount[nextPlayer]-1], tributeRevealedCards[0]); +#endif + failedCheckCount3++; + } + if (testState.discardCount[nextPlayer] != state.discardCount[nextPlayer] - 1){ +#if (NOISY_TEST == 1) + printf("discardCount of nextPlayer - expected: %d, actual: %d\n", state.discardCount[nextPlayer] - 1, testState.discardCount[nextPlayer]); +#endif + failedCheckCount4++; + } + } + else { +#if (NOISY_TEST == 1) + printf("No cards revealed."); +#endif + } + } else { + if (state.deckCount[nextPlayer] == 0) { + //this means deck is empty but there are at least 2 cards in discard + //then we expect discard was shuffled and moved to deck + //in the test state, the discard should be empty and + // the deck count should be state's discard - 2 + if (testState.discardCount[nextPlayer] != 0) { +#if (NOISY_TEST == 1) + printf("discardCount of nextPlayer - expected: %d, actual %d\n", 0, testState.discardCount[nextPlayer]); +#endif + failedCheckCount5++; + } + if (testState.deckCount[nextPlayer] != state.discardCount[nextPlayer] - 2) { +#if (NOISY_TEST == 1) + printf("deckCount of nextPlayer - expected:%d, actual %d\n", state.discardCount[nextPlayer]-2, testState.deckCount[nextPlayer]); +#endif + failedCheckCount6++; + } + } + } + + if (tributeRevealedCards[1] == -1) { + //we had a duplicate card + //we expect the playedCardCount to be incremented + if (testState.playedCardCount != state.playedCardCount + 1) { +#if (NOISY_TEST == 1) + printf("testState playedCardCount - expected: %d, actual: %d\n", state.playedCardCount + 1, testState.playedCardCount); +#endif + failedCheckCount7++; + } + } + + for (int i = 0; i < 2; i++) { + if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){ + addCoins += 2; + } + else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){ + addCards += 2; + } + else if (tributeRevealedCards[i] != -1) { + addActions += 2; + } + } + + if (testState.coins != state.coins + addCoins) { +#if (NOISY_TEST == 1) + printf("testState coins - expected: %d, actual: %d\n", state.coins + addCoins, testState.coins); +#endif + failedCheckCount8++; + } + if (testState.deckCount[currentPlayer] != state.deckCount[currentPlayer] + addCards) { +#if (NOISY_TEST == 1) + printf("testState deckCount[currentPlayer] - expected: %d, actual: %d\n", state.deckCount[currentPlayer] + addCards, testState.deckCount[currentPlayer]); +#endif + failedCheckCount9++; + } + if (testState.numActions != state.numActions + addActions) { +#if (NOISY_TEST == 1) + printf("testState numActions - expected: %d, actual: %d\n", state.numActions + addActions, testState.numActions); +#endif + failedCheckCount10++; + } + + // + } + + printf ("END TEST\n"); + + printf("Failed Check 1: %d times\n", failedCheckCount1); + printf("Failed Check 2: %d times\n", failedCheckCount2); + printf("Failed Check 3: %d times\n", failedCheckCount3); + printf("Failed Check 4: %d times\n", failedCheckCount4); + printf("Failed Check 5: %d times\n", failedCheckCount5); + printf("Failed Check 6: %d times\n", failedCheckCount6); + printf("Failed Check 7: %d times\n", failedCheckCount7); + printf("Failed Check 8: %d times\n", failedCheckCount8); + printf("Failed Check 9: %d times\n", failedCheckCount9); + printf("Failed Check 10: %d times\n", failedCheckCount10); + + return 0; + } \ No newline at end of file