From 0a8842c66926a1531005b53704594dea7533ad9f Mon Sep 17 00:00:00 2001 From: Elliott Lapinel Date: Wed, 25 Sep 2019 14:57:33 -0700 Subject: [PATCH 1/5] Changed the parameters in UnitTest2 --- projects/lapinele/dominion/Makefile | 31 + projects/lapinele/dominion/READM.md | 2 + projects/lapinele/dominion/dominion.c | 1373 +++++++++++++++++ projects/lapinele/dominion/dominion.h | 131 ++ projects/lapinele/dominion/dominion_helpers.h | 15 + projects/lapinele/dominion/interface.c | 425 +++++ projects/lapinele/dominion/interface.h | 128 ++ projects/lapinele/dominion/playdom.c | 135 ++ projects/lapinele/dominion/player.c | 205 +++ projects/lapinele/dominion/rngs.c | 183 +++ projects/lapinele/dominion/rngs.h | 19 + projects/lapinele/dominion/rt.c | 27 + projects/lapinele/dominion/testdrawcard.c | 74 + 13 files changed, 2748 insertions(+) create mode 100644 projects/lapinele/dominion/Makefile create mode 100644 projects/lapinele/dominion/READM.md create mode 100644 projects/lapinele/dominion/dominion.c create mode 100644 projects/lapinele/dominion/dominion.h create mode 100644 projects/lapinele/dominion/dominion_helpers.h create mode 100644 projects/lapinele/dominion/interface.c create mode 100644 projects/lapinele/dominion/interface.h create mode 100644 projects/lapinele/dominion/playdom.c create mode 100644 projects/lapinele/dominion/player.c create mode 100644 projects/lapinele/dominion/rngs.c create mode 100644 projects/lapinele/dominion/rngs.h create mode 100644 projects/lapinele/dominion/rt.c create mode 100644 projects/lapinele/dominion/testdrawcard.c diff --git a/projects/lapinele/dominion/Makefile b/projects/lapinele/dominion/Makefile new file mode 100644 index 000000000..5541801f3 --- /dev/null +++ b/projects/lapinele/dominion/Makefile @@ -0,0 +1,31 @@ +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*/ + +testDrawCard: testDrawCard.c dominion.o rngs.o + gcc -o testDrawCard -g testDrawCard.c dominion.o rngs.o $(CFLAGS) + +interface.o: interface.h interface.c + gcc -c interface.c -g $(CFLAGS) + +runtests: testDrawCard + ./testDrawCard &> unittestresult.out + gcov dominion.c >> unittestresult.out + cat dominion.c.gcov >> unittestresult.out + + +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 *.gcov *.gcda *.gcno *.so *.out testDrawCard testDrawCard.exe diff --git a/projects/lapinele/dominion/READM.md b/projects/lapinele/dominion/READM.md new file mode 100644 index 000000000..c3599f6ad --- /dev/null +++ b/projects/lapinele/dominion/READM.md @@ -0,0 +1,2 @@ +run make all #To compile the dominion code +run ./playdom 30 # to run playdom code diff --git a/projects/lapinele/dominion/dominion.c b/projects/lapinele/dominion/dominion.c new file mode 100644 index 000000000..c94e2edb9 --- /dev/null +++ b/projects/lapinele/dominion/dominion.c @@ -0,0 +1,1373 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include "rngs.h" +#include +#include +#include + +int compare(const void* a, const void* b) { + if (*(int*)a > *(int*)b) + return 1; + if (*(int*)a < *(int*)b) + return -1; + return 0; +} + +struct gameState* newGame() { + struct gameState* g = malloc(sizeof(struct gameState)); + return g; +} + +int* kingdomCards(int k1, int k2, int k3, int k4, int k5, int k6, int k7, + int k8, int k9, int k10) { + int* k = malloc(10 * sizeof(int)); + k[0] = k1; + k[1] = k2; + k[2] = k3; + k[3] = k4; + k[4] = k5; + k[5] = k6; + k[6] = k7; + k[7] = k8; + k[8] = k9; + k[9] = k10; + return k; +} + +int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, + struct gameState *state) { + int i; + int j; + int it; + + //set up random number generator + SelectStream(1); + PutSeed((long)randomSeed); + + //check number of players + if (numPlayers > MAX_PLAYERS || numPlayers < 2) + { + return -1; + } + + //set number of players + state->numPlayers = numPlayers; + + //check selected kingdom cards are different + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + if (j != i && kingdomCards[j] == kingdomCards[i]) + { + return -1; + } + } + } + + + //initialize supply + /////////////////////////////// + + //set number of Curse cards + if (numPlayers == 2) + { + state->supplyCount[curse] = 10; + } + else if (numPlayers == 3) + { + state->supplyCount[curse] = 20; + } + else + { + state->supplyCount[curse] = 30; + } + + //set number of Victory cards + if (numPlayers == 2) + { + state->supplyCount[estate] = 8; + state->supplyCount[duchy] = 8; + state->supplyCount[province] = 8; + } + else + { + state->supplyCount[estate] = 12; + state->supplyCount[duchy] = 12; + state->supplyCount[province] = 12; + } + + //set number of Treasure cards + state->supplyCount[copper] = 60 - (7 * numPlayers); + state->supplyCount[silver] = 40; + state->supplyCount[gold] = 30; + + //set number of Kingdom cards + for (i = adventurer; i <= treasure_map; i++) //loop all cards + { + for (j = 0; j < 10; j++) //loop chosen cards + { + if (kingdomCards[j] == i) + { + //check if card is a 'Victory' Kingdom card + if (kingdomCards[j] == great_hall || kingdomCards[j] == gardens) + { + if (numPlayers == 2) { + state->supplyCount[i] = 8; + } + else { + state->supplyCount[i] = 12; + } + } + else + { + state->supplyCount[i] = 10; + } + break; + } + else //card is not in the set choosen for the game + { + state->supplyCount[i] = -1; + } + } + + } + + //////////////////////// + //supply intilization complete + + //set player decks + for (i = 0; i < numPlayers; i++) + { + state->deckCount[i] = 0; + for (j = 0; j < 3; j++) + { + state->deck[i][j] = estate; + state->deckCount[i]++; + } + for (j = 3; j < 10; j++) + { + state->deck[i][j] = copper; + state->deckCount[i]++; + } + } + + //shuffle player decks + for (i = 0; i < numPlayers; i++) + { + if ( shuffle(i, state) < 0 ) + { + return -1; + } + } + + //draw player hands + for (i = 0; i < numPlayers; i++) + { + //initialize hand size to zero + state->handCount[i] = 0; + state->discardCount[i] = 0; + //draw 5 cards + // for (j = 0; j < 5; j++) + // { + // drawCard(i, state); + // } + } + + //set embargo tokens to 0 for all supply piles + for (i = 0; i <= treasure_map; i++) + { + state->embargoTokens[i] = 0; + } + + //initialize first player's turn + state->outpostPlayed = 0; + state->phase = 0; + state->numActions = 1; + state->numBuys = 1; + state->playedCardCount = 0; + state->whoseTurn = 0; + state->handCount[state->whoseTurn] = 0; + //int it; move to top + + //Moved draw cards to here, only drawing at the start of a turn + for (it = 0; it < 5; it++) { + drawCard(state->whoseTurn, state); + } + + updateCoins(state->whoseTurn, state, 0); + + return 0; +} + +int shuffle(int player, struct gameState *state) { + + + int newDeck[MAX_DECK]; + int newDeckPos = 0; + int card; + int i; + + if (state->deckCount[player] < 1) + return -1; + qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); + /* SORT CARDS IN DECK TO ENSURE DETERMINISM! */ + + while (state->deckCount[player] > 0) { + card = floor(Random() * state->deckCount[player]); + newDeck[newDeckPos] = state->deck[player][card]; + newDeckPos++; + for (i = card; i < state->deckCount[player]-1; i++) { + state->deck[player][i] = state->deck[player][i+1]; + } + state->deckCount[player]--; + } + for (i = 0; i < newDeckPos; i++) { + state->deck[player][i] = newDeck[i]; + state->deckCount[player]++; + } + + return 0; +} + +int playCard(int handPos, int choice1, int choice2, int choice3, struct gameState *state) +{ + int card; + int coin_bonus = 0; //tracks coins gain from actions + + //check if it is the right phase + if (state->phase != 0) + { + return -1; + } + + //check if player has enough actions + if ( state->numActions < 1 ) + { + return -1; + } + + //get card played + card = handCard(handPos, state); + + //check if selected card is an action + if ( card < adventurer || card > treasure_map ) + { + return -1; + } + + //play card + if ( cardEffect(card, choice1, choice2, choice3, state, handPos, &coin_bonus) < 0 ) + { + return -1; + } + + //reduce number of actions + state->numActions--; + + //update coins (Treasure cards may be added with card draws) + updateCoins(state->whoseTurn, state, coin_bonus); + + return 0; +} + +int buyCard(int supplyPos, struct gameState *state) { + int who; + if (DEBUG) { + printf("Entering buyCard...\n"); + } + + // I don't know what to do about the phase thing. + + who = state->whoseTurn; + + if (state->numBuys < 1) { + if (DEBUG) + printf("You do not have any buys left\n"); + return -1; + } else if (supplyCount(supplyPos, state) <1) { + if (DEBUG) + printf("There are not any of that type of card left\n"); + return -1; + } else if (state->coins < getCost(supplyPos)) { + if (DEBUG) + printf("You do not have enough money to buy that. You have %d coins.\n", state->coins); + return -1; + } else { + state->phase=1; + //state->supplyCount[supplyPos]--; + gainCard(supplyPos, state, 0, who); //card goes in discard, this might be wrong.. (2 means goes into hand, 0 goes into discard) + + state->coins = (state->coins) - (getCost(supplyPos)); + state->numBuys--; + if (DEBUG) + printf("You bought card number %d for %d coins. You now have %d buys and %d coins.\n", supplyPos, getCost(supplyPos), state->numBuys, state->coins); + } + + //state->discard[who][state->discardCount[who]] = supplyPos; + //state->discardCount[who]++; + + return 0; +} + +int numHandCards(struct gameState *state) { + return state->handCount[ whoseTurn(state) ]; +} + +int handCard(int handPos, struct gameState *state) { + int currentPlayer = whoseTurn(state); + return state->hand[currentPlayer][handPos]; +} + +int supplyCount(int card, struct gameState *state) { + return state->supplyCount[card]; +} + +int fullDeckCount(int player, int card, struct gameState *state) { + int i; + int count = 0; + + for (i = 0; i < state->deckCount[player]; i++) + { + if (state->deck[player][i] == card) count++; + } + + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == card) count++; + } + + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->discard[player][i] == card) count++; + } + + return count; +} + +int whoseTurn(struct gameState *state) { + return state->whoseTurn; +} + +int endTurn(struct gameState *state) { + int k; + int i; + int currentPlayer = whoseTurn(state); + + //Discard hand + for (i = 0; i < state->handCount[currentPlayer]; i++) { + state->discard[currentPlayer][state->discardCount[currentPlayer]++] = state->hand[currentPlayer][i];//Discard + state->hand[currentPlayer][i] = -1;//Set card to -1 + } + state->handCount[currentPlayer] = 0;//Reset hand count + + //Code for determining the player + if (currentPlayer < (state->numPlayers - 1)) { + state->whoseTurn = currentPlayer + 1;//Still safe to increment + } + else { + state->whoseTurn = 0;//Max player has been reached, loop back around to player 1 + } + + state->outpostPlayed = 0; + state->phase = 0; + state->numActions = 1; + state->coins = 0; + state->numBuys = 1; + state->playedCardCount = 0; + state->handCount[state->whoseTurn] = 0; + + //int k; move to top + //Next player draws hand + for (k = 0; k < 5; k++) { + drawCard(state->whoseTurn, state);//Draw a card + } + + //Update money + updateCoins(state->whoseTurn, state, 0); + + return 0; +} + +int isGameOver(struct gameState *state) { + int i; + int j; + + //if stack of Province cards is empty, the game ends + if (state->supplyCount[province] == 0) + { + return 1; + } + + //if three supply pile are at 0, the game ends + j = 0; + for (i = 0; i < 25; i++) + { + if (state->supplyCount[i] == 0) + { + j++; + } + } + if ( j >= 3) + { + return 1; + } + + return 0; +} + +int scoreFor (int player, struct gameState *state) { + + int i; + int score = 0; + //score from hand + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == curse) { + score = score - 1; + }; + if (state->hand[player][i] == estate) { + score = score + 1; + }; + if (state->hand[player][i] == duchy) { + score = score + 3; + }; + if (state->hand[player][i] == province) { + score = score + 6; + }; + if (state->hand[player][i] == great_hall) { + score = score + 1; + }; + if (state->hand[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + //score from discard + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->discard[player][i] == curse) { + score = score - 1; + }; + if (state->discard[player][i] == estate) { + score = score + 1; + }; + if (state->discard[player][i] == duchy) { + score = score + 3; + }; + if (state->discard[player][i] == province) { + score = score + 6; + }; + if (state->discard[player][i] == great_hall) { + score = score + 1; + }; + if (state->discard[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + //score from deck + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->deck[player][i] == curse) { + score = score - 1; + }; + if (state->deck[player][i] == estate) { + score = score + 1; + }; + if (state->deck[player][i] == duchy) { + score = score + 3; + }; + if (state->deck[player][i] == province) { + score = score + 6; + }; + if (state->deck[player][i] == great_hall) { + score = score + 1; + }; + if (state->deck[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + return score; +} + +int getWinners(int players[MAX_PLAYERS], struct gameState *state) { + int i; + int j; + int highScore; + int currentPlayer; + + //get score for each player + for (i = 0; i < MAX_PLAYERS; i++) + { + //set unused player scores to -9999 + if (i >= state->numPlayers) + { + players[i] = -9999; + } + else + { + players[i] = scoreFor (i, state); + } + } + + //find highest score + j = 0; + for (i = 0; i < MAX_PLAYERS; i++) + { + if (players[i] > players[j]) + { + j = i; + } + } + highScore = players[j]; + + //add 1 to players who had less turns + currentPlayer = whoseTurn(state); + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] == highScore && i > currentPlayer ) + { + players[i]++; + } + } + + //find new highest score + j = 0; + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] > players[j] ) + { + j = i; + } + } + highScore = players[j]; + + //set winners in array to 1 and rest to 0 + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] == highScore ) + { + players[i] = 1; + } + else + { + players[i] = 0; + } + } + + return 0; +} + +int drawCard(int player, struct gameState *state) +{ int count; + int deckCounter; + if (state->deckCount[player] <= 0) { //Deck is empty + + //Step 1 Shuffle the discard pile back into a deck + int i; + //Move discard to deck + for (i = 0; i < state->discardCount[player]; i++) { + state->deck[player][i] = state->discard[player][i]; + state->discard[player][i] = -1; + } + + state->deckCount[player] = state->discardCount[player]; + state->discardCount[player] = 0;//Reset discard + + //Shufffle the deck + shuffle(player, state);//Shuffle the deck up and make it so that we can draw + + if (DEBUG) { //Debug statements + printf("Deck count now: %d\n", state->deckCount[player]); + } + + state->discardCount[player] = 0; + + //Step 2 Draw Card + count = state->handCount[player];//Get current player's hand count + + if (DEBUG) { //Debug statements + printf("Current hand count: %d\n", count); + } + + deckCounter = state->deckCount[player];//Create a holder for the deck count + + if (deckCounter == 0) + return -1; + + state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to hand + state->deckCount[player]--; + state->handCount[player]++;//Increment hand count + } + + else { + int count = state->handCount[player];//Get current hand count for player + int deckCounter; + if (DEBUG) { //Debug statements + printf("Current hand count: %d\n", count); + } + + deckCounter = state->deckCount[player];//Create holder for the deck count + state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to the hand + state->deckCount[player]--; + state->handCount[player]++;//Increment hand count + } + + return 0; +} + +int getCost(int cardNumber) +{ + switch( cardNumber ) + { + case curse: + return 0; + case estate: + return 2; + case duchy: + return 5; + case province: + return 8; + case copper: + return 0; + case silver: + return 3; + case gold: + return 6; + case adventurer: + return 6; + case council_room: + return 5; + case feast: + return 4; + case gardens: + return 4; + case mine: + return 5; + case remodel: + return 4; + case smithy: + return 4; + case village: + return 3; + case baron: + return 4; + case great_hall: + return 3; + case minion: + return 5; + case steward: + return 3; + case tribute: + return 5; + case ambassador: + return 3; + case cutpurse: + return 4; + case embargo: + return 2; + case outpost: + return 5; + case salvager: + return 4; + case sea_hag: + return 4; + case treasure_map: + return 4; + } + + 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: + 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) + { + state->coins = state->coins + 2; + } + else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 + { + //discard hand + while(numHandCards(state) > 0) + { + discardCard(handPos, currentPlayer, state, 0); + } + + //draw 4 + for (i = 0; i < 4; i++) + { + drawCard(currentPlayer, state); + } + + //other players discard hand and redraw if hand size > 4 + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + if ( state->handCount[i] > 4 ) + { + //discard hand + while( state->handCount[i] > 0 ) + { + discardCard(handPos, i, state, 0); + } + + //draw 4 + for (j = 0; j < 4; j++) + { + drawCard(i, state); + } + } + } + } + + } + return 0; + + case steward: + if (choice1 == 1) + { + //+2 cards + drawCard(currentPlayer, state); + drawCard(currentPlayer, state); + } + else if (choice1 == 2) + { + //+2 coins + state->coins = state->coins + 2; + } + else + { + //trash 2 cards in hand + discardCard(choice2, currentPlayer, state, 1); + discardCard(choice3, currentPlayer, state, 1); + } + + //discard card from hand + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case tribute: + if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { + if (state->deckCount[nextPlayer] > 0) { + tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deckCount[nextPlayer]--; + } + else if (state->discardCount[nextPlayer] > 0) { + tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; + state->discardCount[nextPlayer]--; + } + else { + //No Card to Reveal + if (DEBUG) { + printf("No cards to reveal\n"); + } + } + } + + else { + if (state->deckCount[nextPlayer] == 0) { + for (i = 0; i < state->discardCount[nextPlayer]; i++) { + state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck + state->deckCount[nextPlayer]++; + state->discard[nextPlayer][i] = -1; + state->discardCount[nextPlayer]--; + } + + shuffle(nextPlayer,state);//Shuffle the deck + } + tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; + state->deckCount[nextPlayer]--; + tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; + state->deckCount[nextPlayer]--; + } + + if (tributeRevealedCards[0] == tributeRevealedCards[1]) { //If we have a duplicate card, just drop one + state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; + state->playedCardCount++; + tributeRevealedCards[1] = -1; + } + + for (i = 0; i <= 2; i ++) { + if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) { //Treasure cards + state->coins += 2; + } + + else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall) { //Victory Card Found + drawCard(currentPlayer, state); + drawCard(currentPlayer, state); + } + else { //Action Card + state->numActions = state->numActions + 2; + } + } + + return 0; + + case ambassador: + j = 0; //used to check if player has enough cards to discard + + if (choice2 > 2 || choice2 < 0) + { + return -1; + } + + if (choice1 == handPos) + { + return -1; + } + + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) + { + j++; + } + } + if (j < choice2) + { + return -1; + } + + if (DEBUG) + printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); + + //increase supply count for choosen card by amount being discarded + state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; + + //each other player gains a copy of revealed card + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + gainCard(state->hand[currentPlayer][choice1], state, 0, i); + } + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + //trash copies of cards returned to supply + for (j = 0; j < choice2; j++) + { + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) + { + discardCard(i, currentPlayer, state, 1); + break; + } + } + } + + return 0; + + case cutpurse: + + updateCoins(currentPlayer, state, 2); + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + for (j = 0; j < state->handCount[i]; j++) + { + if (state->hand[i][j] == copper) + { + discardCard(j, i, state, 0); + break; + } + if (j == state->handCount[i]) + { + for (k = 0; k < state->handCount[i]; k++) + { + if (DEBUG) + printf("Player %d reveals card number %d\n", i, state->hand[i][k]); + } + break; + } + } + + } + + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + return 0; + + + case embargo: + //+2 Coins + state->coins = state->coins + 2; + + //see if selected pile is in play + if ( state->supplyCount[choice1] == -1 ) + { + return -1; + } + + //add embargo token to selected supply pile + state->embargoTokens[choice1]++; + + //trash card + discardCard(handPos, currentPlayer, state, 1); + return 0; + + case outpost: + //set outpost flag + state->outpostPlayed++; + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case salvager: + //+1 buy + state->numBuys++; + + if (choice1) + { + //gain coins equal to trashed card + state->coins = state->coins + getCost( handCard(choice1, state) ); + //trash card + discardCard(choice1, currentPlayer, state, 1); + } + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case sea_hag: + for (i = 0; i < state->numPlayers; i++) { + if (i != currentPlayer) { + state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; + state->deckCount[i]--; + state->discardCount[i]++; + state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse + } + } + return 0; + + case treasure_map: + //search hand for another treasure_map + index = -1; + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == treasure_map && i != handPos) + { + index = i; + break; + } + } + if (index > -1) + { + //trash both treasure cards + discardCard(handPos, currentPlayer, state, 1); + discardCard(index, currentPlayer, state, 1); + + //gain 4 Gold cards + for (i = 0; i < 4; i++) + { + gainCard(gold, state, 1, currentPlayer); + } + + //return success + return 1; + } + + //no second treasure_map found in hand + return -1; + } + + return -1; +} + +int discardCard(int handPos, int currentPlayer, struct gameState *state, int trashFlag) +{ + + //if card is not trashed, added to Played pile + if (trashFlag < 1) + { + //add card to played pile + state->playedCards[state->playedCardCount] = state->hand[currentPlayer][handPos]; + state->playedCardCount++; + } + + //set played card to -1 + state->hand[currentPlayer][handPos] = -1; + + //remove card from player's hand + if ( handPos == (state->handCount[currentPlayer] - 1) ) //last card in hand array is played + { + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + else if ( state->handCount[currentPlayer] == 1 ) //only one card in hand + { + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + else + { + //replace discarded card with last card in hand + state->hand[currentPlayer][handPos] = state->hand[currentPlayer][ (state->handCount[currentPlayer] - 1)]; + //set last card to -1 + state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1; + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + + return 0; +} + +int gainCard(int supplyPos, struct gameState *state, int toFlag, int player) +{ + //Note: supplyPos is enum of choosen card + + //check if supply pile is empty (0) or card is not used in game (-1) + if ( supplyCount(supplyPos, state) < 1 ) + { + return -1; + } + + //added card for [whoseTurn] current player: + // toFlag = 0 : add to discard + // toFlag = 1 : add to deck + // toFlag = 2 : add to hand + + if (toFlag == 1) + { + state->deck[ player ][ state->deckCount[player] ] = supplyPos; + state->deckCount[player]++; + } + else if (toFlag == 2) + { + state->hand[ player ][ state->handCount[player] ] = supplyPos; + state->handCount[player]++; + } + else + { + state->discard[player][ state->discardCount[player] ] = supplyPos; + state->discardCount[player]++; + } + + //decrease number in supply pile + state->supplyCount[supplyPos]--; + + return 0; +} + +int updateCoins(int player, struct gameState *state, int bonus) +{ + int i; + + //reset coin count + state->coins = 0; + + //add coins for each Treasure card in player's hand + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == copper) + { + state->coins += 1; + } + else if (state->hand[player][i] == silver) + { + state->coins += 2; + } + else if (state->hand[player][i] == gold) + { + state->coins += 3; + } + } + + //add bonus + state->coins += bonus; + + return 0; +} + + +//end of dominion.c + diff --git a/projects/lapinele/dominion/dominion.h b/projects/lapinele/dominion/dominion.h new file mode 100644 index 000000000..f9d9039b8 --- /dev/null +++ b/projects/lapinele/dominion/dominion.h @@ -0,0 +1,131 @@ +#ifndef _DOMINION_H +#define _DOMINION_H + +// Code from various sources, baseline from Kristen Bartosz + +#define MAX_HAND 500 +#define MAX_DECK 500 + +#define MAX_PLAYERS 4 + +#define DEBUG 0 + +/* http://dominion.diehrstraits.com has card texts */ +/* http://dominion.isotropic.org has other stuff */ + +/* hand# means index of a card in current active player's hand */ + +enum CARD +{ curse = 0, + estate, + duchy, + province, + + copper, + silver, + gold, + + adventurer, + /* If no/only 1 treasure found, stop when full deck seen */ + council_room, + feast, /* choice1 is supply # of card gained) */ + gardens, + mine, /* choice1 is hand# of money to trash, choice2 is supply# of + money to put in hand */ + remodel, /* choice1 is hand# of card to remodel, choice2 is supply# */ + smithy, + village, + + baron, /* choice1: boolean for discard of estate */ + /* Discard is always of first (lowest index) estate */ + great_hall, + minion, /* choice1: 1 = +2 coin, 2 = redraw */ + steward, /* choice1: 1 = +2 card, 2 = +2 coin, 3 = trash 2 (choice2,3) */ + tribute, + + ambassador, /* choice1 = hand#, choice2 = number to return to supply */ + cutpurse, + embargo, /* choice1 = supply# */ + outpost, + salvager, /* choice1 = hand# to trash */ + sea_hag, + treasure_map +}; + +struct gameState { + int numPlayers; //number of players + int supplyCount[treasure_map+1]; //this is the amount of a specific type of card given a specific number. + int embargoTokens[treasure_map+1]; + int outpostPlayed; + int outpostTurn; + int whoseTurn; + int phase; + int numActions; /* Starts at 1 each turn */ + int coins; /* Use as you see fit! */ + int numBuys; /* Starts at 1 each turn */ + int hand[MAX_PLAYERS][MAX_HAND]; + int handCount[MAX_PLAYERS]; + int deck[MAX_PLAYERS][MAX_DECK]; + int deckCount[MAX_PLAYERS]; + int discard[MAX_PLAYERS][MAX_DECK]; + int discardCount[MAX_PLAYERS]; + int playedCards[MAX_DECK]; + int playedCardCount; +}; + +/* All functions return -1 on failure, and DO NOT CHANGE GAME STATE; + unless specified for other return, return 0 on success */ + +struct gameState* newGame(); + +int* kingdomCards(int k1, int k2, int k3, int k4, int k5, int k6, int k7, + int k8, int k9, int k10); + +int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, + struct gameState *state); +/* Responsible for initializing all supplies, and shuffling deck and + drawing starting hands for all players. Check that 10 cards selected + are in fact (different) kingdom cards, and that numPlayers is valid. + +Cards not in game should initialize supply position to -1 */ + +int shuffle(int player, struct gameState *state); +/* Assumes all cards are now in deck array (or hand/played): discard is + empty */ + +int playCard(int handPos, int choice1, int choice2, int choice3, + struct gameState *state); +/* Play card with index handPos from current player's hand */ + +int buyCard(int supplyPos, struct gameState *state); +/* Buy card with supply index supplyPos */ + +int numHandCards(struct gameState *state); +/* How many cards current player has in hand */ + +int handCard(int handNum, struct gameState *state); +/* enum value of indexed card in player's hand */ + +int supplyCount(int card, struct gameState *state); +/* How many of given card are left in supply */ + +int fullDeckCount(int player, int card, struct gameState *state); +/* Here deck = hand + discard + deck */ + +int whoseTurn(struct gameState *state); + +int endTurn(struct gameState *state); +/* Must do phase C and advance to next player; do not advance whose turn + if game is over */ + +int isGameOver(struct gameState *state); + +int scoreFor(int player, struct gameState *state); +/* Negative here does not mean invalid; scores may be negative, + -9999 means invalid input */ + +int getWinners(int players[MAX_PLAYERS], struct gameState *state); +/* Set array position of each player who won (remember ties!) to + 1, others to 0 */ + +#endif diff --git a/projects/lapinele/dominion/dominion_helpers.h b/projects/lapinele/dominion/dominion_helpers.h new file mode 100644 index 000000000..0887fda15 --- /dev/null +++ b/projects/lapinele/dominion/dominion_helpers.h @@ -0,0 +1,15 @@ +#ifndef _DOMINION_HELPERS_H +#define _DOMINION_HELPERS_H + +#include "dominion.h" + +int drawCard(int player, struct gameState *state); +int updateCoins(int player, struct gameState *state, int bonus); +int discardCard(int handPos, int currentPlayer, struct gameState *state, + int trashFlag); +int gainCard(int supplyPos, struct gameState *state, int toFlag, int player); +int getCost(int cardNumber); +int cardEffect(int card, int choice1, int choice2, int choice3, + struct gameState *state, int handPos, int *bonus); + +#endif diff --git a/projects/lapinele/dominion/interface.c b/projects/lapinele/dominion/interface.c new file mode 100644 index 000000000..58cc5ba58 --- /dev/null +++ b/projects/lapinele/dominion/interface.c @@ -0,0 +1,425 @@ +/* Interactive Dominion Interface + +Sam Heinith CS362 +1/26/2010 +*/ + +#include +#include +#include +#include +#include "rngs.h" +#include "interface.h" +#include "dominion.h" + + +void cardNumToName(int card, char *name) { + switch(card) { + case curse: + strcpy(name,"Curse"); + break; + case estate: + strcpy(name,"Estate"); + break; + case duchy: + strcpy(name,"Duchy"); + break; + case province: + strcpy(name,"Province"); + break; + case copper: + strcpy(name,"Copper"); + break; + case silver: + strcpy(name,"Silver"); + break; + case gold: + strcpy(name,"Gold"); + break; + case adventurer: + strcpy(name,"Adventurer"); + break; + case council_room: + strcpy(name,"Council Room"); + break; + case feast: + strcpy(name,"Feast"); + break; + case gardens: + strcpy(name,"Gardens"); + break; + case mine: + strcpy(name,"Mine"); + break; + case remodel: + strcpy(name,"Remodel"); + break; + case smithy: + strcpy(name,"Smithy"); + break; + case village: + strcpy(name,"Village"); + break; + case baron: + strcpy(name,"Baron"); + break; + case great_hall: + strcpy(name,"Great Hall"); + break; + case minion: + strcpy(name,"Minion"); + break; + case steward: + strcpy(name,"Steward"); + break; + case tribute: + strcpy(name,"Tribute"); + break; + case ambassador: + strcpy(name,"Ambassador"); + break; + case cutpurse: + strcpy(name,"Cutpurse"); + break; + case embargo: + strcpy(name,"Embargo"); + break; + case outpost: + strcpy(name,"Outpost"); + break; + case salvager: + strcpy(name,"Salvager"); + break; + case sea_hag: + strcpy(name,"Sea Hag"); + break; + case treasure_map: + strcpy(name,"Treasure Map"); + break; + + default: + strcpy(name,"?"); + } + +} + + + +int getCardCost(int card) { + int cost; + switch(card) { + case curse: + cost = CURSE_COST; + break; + case estate: + cost = ESTATE_COST; + break; + case duchy: + cost = DUCHY_COST; + break; + case province: + cost = PROVINCE_COST; + break; + case copper: + cost = COPPER_COST; + break; + case silver: + cost = SILVER_COST; + break; + case gold: + cost = GOLD_COST; + break; + case adventurer: + cost = ADVENTURER_COST; + break; + case council_room: + cost = COUNCIL_ROOM_COST; + break; + case feast: + cost = FEAST_COST; + break; + case gardens: + cost = GARDEN_COST; + break; + case mine: + cost = MINE_COST; + break; + case remodel: + cost = REMODEL_COST; + break; + case smithy: + cost = SMITHY_COST; + break; + case village: + cost = VILLAGE_COST; + break; + case baron: + cost = BARON_COST; + break; + case great_hall: + cost = GREAT_HALL_COST; + break; + case minion: + cost = MINION_COST; + break; + case steward: + cost = STEWARD_COST; + break; + case tribute: + cost = TRIBUTE_COST; + break; + case ambassador: + cost = AMBASSADOR_COST; + break; + case cutpurse: + cost = CUTPURSE_COST; + break; + case embargo: + cost = EMBARGO_COST; + break; + case outpost: + cost = OUTPOST_COST; + break; + case salvager: + cost = SALVAGER_COST; + break; + case sea_hag: + cost = SEA_HAG_COST; + break; + case treasure_map: + cost = TREASURE_MAP_COST; + break; + default: + cost = ONETHOUSAND; + } + return cost; +} + + + + + + +void printHand(int player, struct gameState *game) { + int handCount = game->handCount[player]; + int handIndex; + printf("Player %d's hand:\n", player); + if(handCount > 0) printf("# Card\n"); + for(handIndex = 0; handIndex < handCount; handIndex++) { + int card = game->hand[player][handIndex]; + char name[MAX_STRING_LENGTH]; + cardNumToName(card, name); + printf("%-2d %-13s\n", handIndex, name); + } + printf("\n"); +} + + + +void printDeck(int player, struct gameState *game) { + int deckCount = game->deckCount[player]; + int deckIndex; + printf("Player %d's deck: \n", player); + if(deckCount > 0) printf("# Card\n"); + for(deckIndex = 0; deckIndex < deckCount; deckIndex++) { + int card = game->deck[player][deckIndex]; + char name[MAX_STRING_LENGTH]; + cardNumToName(card, name); + printf("%-2d %-13s\n", deckIndex, name); + } + printf("\n"); +} + +void printPlayed(int player, struct gameState *game) { + int playedCount = game->playedCardCount; + int playedIndex; + printf("Player %d's played cards: \n", player); + if(playedCount > 0) printf("# Card\n"); + for(playedIndex = 0; playedIndex < playedCount; playedIndex++) { + int card = game->playedCards[playedIndex]; + char name[MAX_STRING_LENGTH]; + cardNumToName(card, name); + printf("%-2d %-13s \n", playedIndex, name); + } + printf("\n"); +} + + + +void printDiscard(int player, struct gameState *game) { + int discardCount = game->discardCount[player]; + int discardIndex; + printf("Player %d's discard: \n", player); + if(discardCount > 0) printf("# Card\n"); + for(discardIndex = 0; discardIndex < discardCount; discardIndex++) { + int card = game->discard[player][discardIndex]; + char name[MAX_STRING_LENGTH]; + cardNumToName(card, name); + printf("%-2d %-13s \n", discardIndex, name); + } + printf("\n"); +} + + + + +void printSupply(struct gameState *game) { + int cardNum, cardCost, cardCount; + char name[MAX_STRING_LENGTH]; + printf("# Card Cost Copies\n"); + for(cardNum = 0; cardNum < NUM_TOTAL_K_CARDS; cardNum++) { + cardCount = game->supplyCount[cardNum]; + if(cardCount == -1) continue; + cardNumToName(cardNum, name); + cardCost = getCardCost(cardNum); + printf("%-2d %-13s %-5d %-5d", cardNum, name, cardCost, cardCount); + printf("\n"); + } + printf("\n"); +} + + +void printState(struct gameState *game) { + int numActions = game->numActions; + int numCoins = game->coins; + int numBuys = game->numBuys; + int currentPlayer = game->whoseTurn; + int phase = game->phase; + char phaseName[MAX_STRING_LENGTH]; + phaseNumToName(phase,phaseName); + printf("Player %d:\n%s phase\n%d actions\n%d coins\n%d buys\n\n", currentPlayer, phaseName, numActions, numCoins, numBuys); +} + +void printScores(struct gameState *game) { + int playerNum, score[MAX_PLAYERS]; + int numPlayers = game->numPlayers; + for(playerNum = 0; playerNum < numPlayers; playerNum++) { + score[playerNum] = scoreFor(playerNum,game); + printf("Player %d has a score of %d\n", playerNum, score[playerNum]); + } +} + + +void printHelp(void) { + printf("Commands are: \n\ + add [Supply Card Number] - add any card to your hand (teh hacks)\n\ + buy [Supply Card Number] - buy a card at supply position\n\ + end - end your turn\n\ + init [Number of Players] [Number of Bots] - initialize the game\n\ + num - print number of cards in your hand\n\ + play [Hand Index] [Choice] [Choice] [Choice] - play a card from your hand\n\ + resign - end the game showing the current scores\n\ + show - show your current hand\n\ + stat - show your turn's status\n\ + supp - show the supply\n\ + whos - whos turn\n\ + exit - exit the interface"); + printf("\n\n"); + +} + + +void phaseNumToName(int phase, char *name) { + switch(phase) { + case ACTION_PHASE: + strcpy(name,"Action"); + break; + case BUY_PHASE: + strcpy(name,"Buy"); + break; + case CLEANUP_PHASE: + strcpy(name,"Cleanup"); + break; + } +} + + +int addCardToHand(int player, int card, struct gameState *game) { + if(card >= adventurer && card < NUM_TOTAL_K_CARDS) { + int handTop = game->handCount[player]; + game->hand[player][handTop] = card; + game->handCount[player]++; + return SUCCESS; + } else { + return FAILURE; + } + +} + +void selectKingdomCards(int randomSeed, int kingCards[NUM_K_CARDS]) { + int i, used, card, numSelected = 0; + SelectStream(1); + PutSeed((long)randomSeed); + + + while(numSelected < NUM_K_CARDS) { + used = FALSE; + card = floor(Random() * NUM_TOTAL_K_CARDS); + if(card < adventurer) continue; + for(i = 0; i < numSelected; i++) { + if(kingCards[i] == card) { + used = TRUE; + break; + } + } + if(used == TRUE) continue; + kingCards[numSelected] = card; + numSelected++; + } +} + + +int countHandCoins(int player, struct gameState *game) { + int card, index, coinage = 0; + + for(index = 0; index < game->handCount[player]; index++) { + card = game->hand[player][index]; + switch(card) { + case copper: + coinage += COPPER_VALUE; + break; + case silver: + coinage += SILVER_VALUE; + break; + case gold: + coinage += GOLD_VALUE; + break; + } + } + return coinage; +} + + +void executeBotTurn(int player, int *turnNum, struct gameState *game) { + int coins = countHandCoins(player, game); + + printf("*****************Executing Bot Player %d Turn Number %d*****************\n", player, *turnNum); + printSupply(game); + //sleep(1); //Thinking... + + if(coins >= PROVINCE_COST && supplyCount(province,game) > 0) { + buyCard(province,game); + printf("Player %d buys card Province\n\n", player); + } + else if(supplyCount(province,game) == 0 && coins >= DUCHY_COST ) { + buyCard(duchy,game); + printf("Player %d buys card Duchy\n\n", player); + } + else if(coins >= GOLD_COST && supplyCount(gold,game) > 0) { + buyCard(gold,game); + printf("Player %d buys card Gold\n\n", player); + } + else if(coins >= SILVER_COST && supplyCount(silver,game) > 0) { + buyCard(silver,game); + printf("Player %d buys card Silver\n\n", player); + + } + + + if(player == (game->numPlayers -1)) (*turnNum)++; + endTurn(game); + if(! isGameOver(game)) { + int currentPlayer = whoseTurn(game); + printf("Player %d's turn number %d\n\n", currentPlayer, (*turnNum)); + } +} diff --git a/projects/lapinele/dominion/interface.h b/projects/lapinele/dominion/interface.h new file mode 100644 index 000000000..6f7bacac2 --- /dev/null +++ b/projects/lapinele/dominion/interface.h @@ -0,0 +1,128 @@ +/* Interactive Dominion Interface + + Sam Heinith CS362 + 1/26/2010 +*/ + + + +#ifndef _INTERFACE_H +#define _INTERFACE_H + + + +#include "dominion.h" + +//Last card enum (Treasure map) card number plus one for the 0th card. +#define NUM_TOTAL_K_CARDS (treasure_map + 1) +#define NUM_K_CARDS 10 +#define NUM_V_CARDS_2 8 +#define NUM_V_CARDS_3or4 12 +#define NUM_C_CARDS_2 10 +#define NUM_C_CARDS_3 20 +#define NUM_C_CARDS_4 30 +#define NUM_COPPER 60 +#define NUM_SILVER 40 +#define NUM_GOLD 30 +#define UNUSED -1 +#define START_COPPER 7 +#define START_ESTATE 3 +#define HANDSIZE 5 + +#define COMPARE(string1, string2) strncmp(string1, string2, 4) +#define MAX_STRING_LENGTH 32 +#define TRUE 1 +#define FALSE 0 + +#define SUCCESS 0 +#define FAILURE -1 + +#define MATCH 0 +#define WINNER 1 +#define NOT_WINNER 0 + +//The Game Phases +#define ACTION_PHASE 0 +#define BUY_PHASE 1 +#define CLEANUP_PHASE 2 + +#define COPPER_VALUE 1 +#define SILVER_VALUE 2 +#define GOLD_VALUE 3 + +//From Dominion List Spoiler +#define COPPER_COST 0 +#define SILVER_COST 3 +#define GOLD_COST 6 +#define ESTATE_COST 2 +#define DUCHY_COST 5 +#define PROVINCE_COST 8 +#define CURSE_COST 0 +#define ADVENTURER_COST 6 +#define COUNCIL_ROOM_COST 5 +#define FEAST_COST 4 +#define GARDEN_COST 4 +#define MINE_COST 5 +#define MONEYLENDER_COST 4 +#define REMODEL_COST 4 +#define SMITHY_COST 4 +#define VILLAGE_COST 3 +#define WOODCUTTER_COST 3 +#define BARON_COST 4 +#define GREAT_HALL_COST 3 +#define MINION_COST 5 +#define SHANTY_TOWN_COST 3 +#define STEWARD_COST 3 +#define TRIBUTE_COST 5 +#define WISHING_WELL_COST 3 +#define AMBASSADOR_COST 3 +#define CUTPURSE_COST 4 +#define EMBARGO_COST 2 +#define OUTPOST_COST 5 +#define SALVAGER_COST 4 +#define SEA_HAG_COST 4 +#define TREASURE_MAP_COST 4 +#define ONETHOUSAND 1000 + + +int addCardToHand(int player, int card, struct gameState *game); + +int countHandCoins(int player, struct gameState *game); + + +void executeBotTurn(int player, int *turnNum, struct gameState *game); + +void phaseNumToName(int phase, char *name); +void cardNumToName(int card, char *name); + +int getCardCost(int card); + +void printHelp(void); + +void printHand(int player, struct gameState *game); + +void printDeck(int player, struct gameState *game); + +void printDiscard(int player, struct gameState *game); + +void printPlayed(int player, struct gameState *game); + +void printState(struct gameState *game); + +void printSupply(struct gameState *game); + +void printGameState(struct gameState *game); + +void printScores(struct gameState *game); + +void selectKingdomCards(int randomSeed, int kingdomCards[NUM_K_CARDS]); + + + +#endif + + + + + + diff --git a/projects/lapinele/dominion/playdom.c b/projects/lapinele/dominion/playdom.c new file mode 100644 index 000000000..336d9a661 --- /dev/null +++ b/projects/lapinele/dominion/playdom.c @@ -0,0 +1,135 @@ +#include "dominion.h" +#include +#include "rngs.h" +#include + +int main (int argc, char** argv) { + struct gameState G; + int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, + sea_hag, tribute, smithy + }; + + printf ("Starting game.\n"); + + initializeGame(2, k, atoi(argv[1]), &G); + + int money = 0; + int smithyPos = -1; + int adventurerPos = -1; + int i=0; + + int numSmithies = 0; + int numAdventurers = 0; + + while (!isGameOver(&G)) { + money = 0; + smithyPos = -1; + adventurerPos = -1; + for (i = 0; i < numHandCards(&G); i++) { + if (handCard(i, &G) == copper) + money++; + else if (handCard(i, &G) == silver) + money += 2; + else if (handCard(i, &G) == gold) + money += 3; + else if (handCard(i, &G) == smithy) + smithyPos = i; + else if (handCard(i, &G) == adventurer) + adventurerPos = i; + } + + if (whoseTurn(&G) == 0) { + if (smithyPos != -1) { + printf("0: smithy played from position %d\n", smithyPos); + playCard(smithyPos, -1, -1, -1, &G); + printf("smithy played.\n"); + money = 0; + i=0; + while(i= 8) { + printf("0: bought province\n"); + buyCard(province, &G); + } + else if (money >= 6) { + printf("0: bought gold\n"); + buyCard(gold, &G); + } + else if ((money >= 4) && (numSmithies < 2)) { + printf("0: bought smithy\n"); + buyCard(smithy, &G); + numSmithies++; + } + else if (money >= 3) { + printf("0: bought silver\n"); + buyCard(silver, &G); + } + + printf("0: end turn\n"); + endTurn(&G); + } + else { + if (adventurerPos != -1) { + printf("1: adventurer played from position %d\n", adventurerPos); + playCard(adventurerPos, -1, -1, -1, &G); + money = 0; + i=0; + while(i= 8) { + printf("1: bought province\n"); + buyCard(province, &G); + } + else if ((money >= 6) && (numAdventurers < 2)) { + printf("1: bought adventurer\n"); + buyCard(adventurer, &G); + numAdventurers++; + } else if (money >= 6) { + printf("1: bought gold\n"); + buyCard(gold, &G); + } + else if (money >= 3) { + printf("1: bought silver\n"); + buyCard(silver, &G); + } + printf("1: endTurn\n"); + + endTurn(&G); + } + } // end of While + + printf ("Finished game.\n"); + printf ("Player 0: %d\nPlayer 1: %d\n", scoreFor(0, &G), scoreFor(1, &G)); + + return 0; +} diff --git a/projects/lapinele/dominion/player.c b/projects/lapinele/dominion/player.c new file mode 100644 index 000000000..0a169d126 --- /dev/null +++ b/projects/lapinele/dominion/player.c @@ -0,0 +1,205 @@ +/* Interactive Dominion Interface + Version 7 + + Sam Heinith CS362 + Questions/Comments: + heiniths@onid.orst.edu + 1/26/2010 +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include "dominion.h" +#include "interface.h" +#include "rngs.h" + + +int main2(int argc, char *argv[]) { + //Default cards, as defined in playDom + int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy}; + struct gameState g; + initializeGame(2,k,1,&g); + printf ("SUCCESSFUL INIT\n"); + getchar(); + return 0; +} + +int main(int argc, char* argv[]) { + char *add = "add"; + char *buyC = "buy"; + char *endT = "end"; + char *exit = "exit"; + char *help = "help"; + char *init = "init"; + char *numH = "num"; + char *play = "play"; + char *resign = "resi"; + char *show = "show"; + char *stat = "stat"; + char *supply = "supp"; + char *whos = "whos"; + + char command[MAX_STRING_LENGTH]; + char line[MAX_STRING_LENGTH]; + char cardName[MAX_STRING_LENGTH]; + + //Array to hold bot presence + int isBot[MAX_PLAYERS] = { 0, 0, 0, 0}; + + int players[MAX_PLAYERS]; + int playerNum; + int outcome; + int currentPlayer; + int gameOver = FALSE; + int gameStarted = FALSE; + int turnNum = 0; + + int randomSeed = atoi(argv[1]); + + //Default cards, as defined in playDom + int kCards[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy}; + + struct gameState g; + struct gameState * game = &g; + + memset(game,0,sizeof(struct gameState)); + + if(argc != 2) { + printf("Usage: player [integer random number seed]\n"); + return EXIT_SUCCESS; + } + + if(randomSeed <= 0) { + printf("Usage: player [integer random number seed]\n"); + return EXIT_SUCCESS; + } + + initializeGame(2,kCards,randomSeed,game); + + printf("Please enter a command or \"help\" for commands\n"); + + + while(TRUE) { + int arg0 = UNUSED; + int arg1 = UNUSED; + int arg2 = UNUSED; + int arg3 = UNUSED; + + outcome = FAILURE; + strcpy(line,""); + strcpy(command,""); + strcpy(cardName,""); + + currentPlayer = whoseTurn(game); + + //If you are getting a seg fault comment this if block out + gameOver = isGameOver(game); + if(gameStarted == TRUE && gameOver == TRUE) { + printScores(game); + getWinners(players, game); + printf("After %d turns, the winner(s) are:\n", turnNum); + for(playerNum = 0; playerNum < game->numPlayers; playerNum++) { + if(players[playerNum] == WINNER) printf("Player %d\n", playerNum); + } + for(playerNum = 0; playerNum < game->numPlayers; playerNum++) { + printHand(playerNum, game); + printPlayed(playerNum, game); + printDiscard(playerNum, game); + printDeck(playerNum, game); + } + + break; //Exit out of the game/while loop + } + + + if(isBot[currentPlayer] == TRUE) { + executeBotTurn(currentPlayer, &turnNum, game); + continue; + } + + printf("$ "); + fgets(line, MAX_STRING_LENGTH, stdin); + sscanf(line, "%s %d %d %d %d", command, &arg0, &arg1, &arg2, &arg3); + + + if(COMPARE(command, add) == 0) { + outcome = addCardToHand(currentPlayer, arg0, game); + cardNumToName(arg0, cardName); + printf("Player %d adds %s to their hand\n\n", currentPlayer, cardName); + } else if(COMPARE(command, buyC) == 0) { + outcome = buyCard(arg0, game); + cardNumToName(arg0, cardName); + if(outcome == SUCCESS) { + printf("Player %d buys card %d, %s\n\n", currentPlayer, arg0, cardName); + } else { + printf("Player %d cannot buy card %d, %s\n\n", currentPlayer, arg0, cardName); + } + } else if(COMPARE(command, endT) == 0) { + if(gameStarted == TRUE) { + if(currentPlayer == (game->numPlayers -1)) turnNum++; + endTurn(game); + currentPlayer = whoseTurn(game); + printf("Player %d's turn number %d\n\n", currentPlayer, turnNum); + } + + } else if(COMPARE(command, exit) == 0) { + break; + } else if(COMPARE(command, help) == 0) { + printHelp(); + } else if(COMPARE(command, init) == 0) { + int numHuman = arg0 - arg1; + for(playerNum = numHuman; playerNum < arg0; playerNum++) { + isBot[playerNum] = TRUE; + } + // selectKingdomCards(randomSeed, kCards); //Comment this out to use the default card set defined in playDom. + outcome = initializeGame(arg0, kCards, randomSeed, game); + printf("\n"); + if(outcome == SUCCESS) { + gameStarted = TRUE; + currentPlayer = whoseTurn(game); + printf("Player %d's turn number %d\n\n", currentPlayer, turnNum); + } + + } else if(COMPARE(command, numH) == 0) { + int numCards = numHandCards(game); + printf("There are %d cards in your hand.\n", numCards); + } else if(COMPARE(command, play) == 0) { + int card = handCard(arg0,game); + outcome = playCard(arg0, arg1, arg2, arg3, game); + cardNumToName(card, cardName); + if(outcome == SUCCESS) { + printf("Player %d plays %s\n\n", currentPlayer, cardName); + } else { + printf("Player %d cannot play card %d\n\n", currentPlayer, arg0); + } + + } else if(COMPARE(command, resign) == 0) { + endTurn(game); + printScores(game); + break; + } else if(COMPARE(command, show) == 0) { + if(gameStarted == FALSE) continue; + printHand(currentPlayer, game); + printPlayed(currentPlayer, game); + //printDiscard(currentPlayer, game); + //printDeck(currentPlayer, game); + } else if(COMPARE(command, stat) == 0) { + if(gameStarted == FALSE) continue; + printState(game); + } else if(COMPARE(command, supply) == 0) { + printSupply(game); + } else if(COMPARE(command, whos) == 0) { + int playerNum = whoseTurn(game); + printf("Player %d's turn\n", playerNum); + } + } + + return EXIT_SUCCESS; + +} diff --git a/projects/lapinele/dominion/rngs.c b/projects/lapinele/dominion/rngs.c new file mode 100644 index 000000000..a85bbc961 --- /dev/null +++ b/projects/lapinele/dominion/rngs.c @@ -0,0 +1,183 @@ +/* ------------------------------------------------------------------------- + * This is an ANSI C library for multi-stream random number generation. + * The use of this library is recommended as a replacement for the ANSI C + * rand() and srand() functions, particularly in simulation applications + * where the statistical 'goodness' of the random number generator is + * important. The library supplies 256 streams of random numbers; use + * SelectStream(s) to switch between streams indexed s = 0,1,...,255. + * + * The streams must be initialized. The recommended way to do this is by + * using the function PlantSeeds(x) with the value of x used to initialize + * the default stream and all other streams initialized automatically with + * values dependent on the value of x. The following convention is used + * to initialize the default stream: + * if x > 0 then x is the state + * if x < 0 then the state is obtained from the system clock + * if x = 0 then the state is to be supplied interactively. + * + * The generator used in this library is a so-called 'Lehmer random number + * generator' which returns a pseudo-random number uniformly distributed + * 0.0 and 1.0. The period is (m - 1) where m = 2,147,483,647 and the + * smallest and largest possible values are (1 / m) and 1 - (1 / m) + * respectively. For more details see: + * + * "Random Number Generators: Good Ones Are Hard To Find" + * Steve Park and Keith Miller + * Communications of the ACM, October 1988 + * + * Name : rngs.c (Random Number Generation - Multiple Streams) + * Authors : Steve Park & Dave Geyer + * Language : ANSI C + * Latest Revision : 09-22-98 + * ------------------------------------------------------------------------- + */ + +#include +#include +#include "rngs.h" + +#define MODULUS 2147483647 /* DON'T CHANGE THIS VALUE */ +#define MULTIPLIER 48271 /* DON'T CHANGE THIS VALUE */ +#define CHECK 399268537 /* DON'T CHANGE THIS VALUE */ +#define STREAMS 256 /* # of streams, DON'T CHANGE THIS VALUE */ +#define A256 22925 /* jump multiplier, DON'T CHANGE THIS VALUE */ +#define DEFAULT 123456789 /* initial seed, use 0 < DEFAULT < MODULUS */ + +static long seed[STREAMS] = {DEFAULT}; /* current state of each stream */ +static int stream = 0; /* stream index, 0 is the default */ +static int initialized = 0; /* test for stream initialization */ + + +double Random(void) +/* ---------------------------------------------------------------- + * Random returns a pseudo-random real number uniformly distributed + * between 0.0 and 1.0. + * ---------------------------------------------------------------- + */ +{ + const long Q = MODULUS / MULTIPLIER; + const long R = MODULUS % MULTIPLIER; + long t; + + t = MULTIPLIER * (seed[stream] % Q) - R * (seed[stream] / Q); + if (t > 0) + seed[stream] = t; + else + seed[stream] = t + MODULUS; + return ((double) seed[stream] / MODULUS); +} + + +void PlantSeeds(long x) +/* --------------------------------------------------------------------- + * Use this function to set the state of all the random number generator + * streams by "planting" a sequence of states (seeds), one per stream, + * with all states dictated by the state of the default stream. + * The sequence of planted states is separated one from the next by + * 8,367,782 calls to Random(). + * --------------------------------------------------------------------- + */ +{ + const long Q = MODULUS / A256; + const long R = MODULUS % A256; + int j; + int s; + + initialized = 1; + s = stream; /* remember the current stream */ + SelectStream(0); /* change to stream 0 */ + PutSeed(x); /* set seed[0] */ + stream = s; /* reset the current stream */ + for (j = 1; j < STREAMS; j++) { + x = A256 * (seed[j - 1] % Q) - R * (seed[j - 1] / Q); + if (x > 0) + seed[j] = x; + else + seed[j] = x + MODULUS; + } +} + + +void PutSeed(long x) +/* --------------------------------------------------------------- + * Use this function to set the state of the current random number + * generator stream according to the following conventions: + * if x > 0 then x is the state (unless too large) + * if x < 0 then the state is obtained from the system clock + * if x = 0 then the state is to be supplied interactively + * --------------------------------------------------------------- + */ +{ + char ok = 0; + + if (x > 0) + x = x % MODULUS; /* correct if x is too large */ + if (x < 0) + x = ((unsigned long) time((time_t *) NULL)) % MODULUS; + if (x == 0) + while (!ok) { + printf("\nEnter a positive integer seed (9 digits or less) >> "); + scanf("%ld", &x); + ok = (0 < x) && (x < MODULUS); + if (!ok) + printf("\nInput out of range ... try again\n"); + } + seed[stream] = x; +} + + +void GetSeed(long *x) +/* --------------------------------------------------------------- + * Use this function to get the state of the current random number + * generator stream. + * --------------------------------------------------------------- + */ +{ + *x = seed[stream]; +} + + +void SelectStream(int index) +/* ------------------------------------------------------------------ + * Use this function to set the current random number generator + * stream -- that stream from which the next random number will come. + * ------------------------------------------------------------------ + */ +{ + stream = ((unsigned int) index) % STREAMS; + if ((initialized == 0) && (stream != 0)) /* protect against */ + PlantSeeds(DEFAULT); /* un-initialized streams */ +} + + +void TestRandom(void) +/* ------------------------------------------------------------------ + * Use this (optional) function to test for a correct implementation. + * ------------------------------------------------------------------ + */ +{ + long i; + long x; + double u; + char ok = 0; + + SelectStream(0); /* select the default stream */ + PutSeed(1); /* and set the state to 1 */ + for(i = 0; i < 10000; i++) { + u = Random(); + if (ok) + printf(" %f \n\n", u); + + } + GetSeed(&x); /* get the new state value */ + ok = (x == CHECK); /* and check for correctness */ + + SelectStream(1); /* select stream 1 */ + PlantSeeds(1); /* set the state of all streams */ + GetSeed(&x); /* get the state of stream 1 */ + ok = ok && (x == A256); /* x should be the jump multiplier */ + if (ok) + printf("\n The implementation of rngs.c is correct.\n\n"); + else + printf("\n\a ERROR -- the implementation of rngs.c is not correct.\n\n"); +} diff --git a/projects/lapinele/dominion/rngs.h b/projects/lapinele/dominion/rngs.h new file mode 100644 index 000000000..c9f3f451a --- /dev/null +++ b/projects/lapinele/dominion/rngs.h @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------- + * Name : rngs.h (header file for the library file rngs.c) + * Author : Steve Park & Dave Geyer + * Language : ANSI C + * Latest Revision : 09-22-98 + * ----------------------------------------------------------------------- + */ + +#if !defined( _RNGS_ ) +#define _RNGS_ + +double Random(void); +void PlantSeeds(long x); +void GetSeed(long *x); +void PutSeed(long x); +void SelectStream(int index); +void TestRandom(void); + +#endif diff --git a/projects/lapinele/dominion/rt.c b/projects/lapinele/dominion/rt.c new file mode 100644 index 000000000..5805bb9b4 --- /dev/null +++ b/projects/lapinele/dominion/rt.c @@ -0,0 +1,27 @@ +#include "rngs.h" +#include +#include + +int main(int argc, char** argv) { + if (argc < 3) { + printf ("Not enough inputs: seed target\n"); + } + + SelectStream(1); + PutSeed((long)atoi(argv[1])); + + int done = 0; + int c = 1000000000; + + while (!done) { + c = floor(Random() * 1000000000); + // if (c % 100000 == 0) { + // printf ("c = %d\n", c); + // } + if (c == atoi(argv[2])) { + printf ("Found the bug!\n"); + done = 1; + } + } +} + diff --git a/projects/lapinele/dominion/testdrawcard.c b/projects/lapinele/dominion/testdrawcard.c new file mode 100644 index 000000000..da5379646 --- /dev/null +++ b/projects/lapinele/dominion/testdrawcard.c @@ -0,0 +1,74 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include +#include +#include +#include "rngs.h" + +#define DEBUG 0 +#define NOISY_TEST 1 + +int checkDrawCard(int p, struct gameState *post) { + struct gameState pre; + memcpy (&pre, post, sizeof(struct gameState)); + + int r; + // printf ("drawCard PRE: p %d HC %d DeC %d DiC %d\n", + // p, pre.handCount[p], pre.deckCount[p], pre.discardCount[p]); + + r = drawCard (p, post); + + //printf ("drawCard POST: p %d HC %d DeC %d DiC %d\n", + // p, post->handCount[p], post->deckCount[p], post->discardCount[p]); + + if (pre.deckCount[p] > 0) { + pre.handCount[p]++; + pre.hand[p][pre.handCount[p]-1] = pre.deck[p][pre.deckCount[p]-1]; + pre.deckCount[p]--; + } else if (pre.discardCount[p] > 0) { + memcpy(pre.deck[p], post->deck[p], sizeof(int) * pre.discardCount[p]); + memcpy(pre.discard[p], post->discard[p], sizeof(int)*pre.discardCount[p]); + pre.hand[p][post->handCount[p]-1] = post->hand[p][post->handCount[p]-1]; + pre.handCount[p]++; + pre.deckCount[p] = pre.discardCount[p]-1; + pre.discardCount[p] = 0; + } + + assert (r == 0); + + assert(memcmp(&pre, post, sizeof(struct gameState)) == 0); +} + +int main () { + + int i, n, r, p, deckCount, discardCount, handCount; + + int k[10] = {adventurer, council_room, feast, gardens, mine, + remodel, smithy, village, baron, great_hall + }; + + struct gameState G; + + printf ("Testing drawCard.\n"); + + printf ("RANDOM TESTS.\n"); + + SelectStream(2); + PutSeed(3); + + for (n = 0; n < 2000; n++) { + for (i = 0; i < sizeof(struct gameState); i++) { + ((char*)&G)[i] = floor(Random() * 256); + } + p = floor(Random() * 2); + G.deckCount[p] = floor(Random() * MAX_DECK); + G.discardCount[p] = floor(Random() * MAX_DECK); + G.handCount[p] = floor(Random() * MAX_HAND); + checkDrawCard(p, &G); + } + + printf ("ALL TESTS OK\n"); + + exit(0); + +} From 1dfe1584686629ac807dcf64a6d5e2cabe1cfd3b Mon Sep 17 00:00:00 2001 From: Elliott Lapinel Date: Sat, 5 Oct 2019 12:13:17 -0700 Subject: [PATCH 2/5] To Complete Assignment --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ac30f558e..367cd7f68 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# CS362-F2019 -OSU CS362 Software Engineering II Fall 2019 +# Elliott Lapinel, lapinele From b0e39c92eb90bb0dd902c346c3e81df46fce6d87 Mon Sep 17 00:00:00 2001 From: Elliott Lapinel Date: Sat, 12 Oct 2019 15:04:40 -0700 Subject: [PATCH 3/5] Adding Bugs --- dominion/dominion.c | 2567 ++++++++++++++++++++++--------------------- 1 file changed, 1298 insertions(+), 1269 deletions(-) diff --git a/dominion/dominion.c b/dominion/dominion.c index c94e2edb9..201b7361b 100644 --- a/dominion/dominion.c +++ b/dominion/dominion.c @@ -6,1366 +6,1395 @@ #include int compare(const void* a, const void* b) { - if (*(int*)a > *(int*)b) - return 1; - if (*(int*)a < *(int*)b) - return -1; - return 0; + if (*(int*)a > *(int*)b) + return 1; + if (*(int*)a < *(int*)b) + return -1; + return 0; } struct gameState* newGame() { - struct gameState* g = malloc(sizeof(struct gameState)); - return g; + struct gameState* g = malloc(sizeof(struct gameState)); + return g; } int* kingdomCards(int k1, int k2, int k3, int k4, int k5, int k6, int k7, - int k8, int k9, int k10) { - int* k = malloc(10 * sizeof(int)); - k[0] = k1; - k[1] = k2; - k[2] = k3; - k[3] = k4; - k[4] = k5; - k[5] = k6; - k[6] = k7; - k[7] = k8; - k[8] = k9; - k[9] = k10; - return k; + int k8, int k9, int k10) { + int* k = malloc(10 * sizeof(int)); + k[0] = k1; + k[1] = k2; + k[2] = k3; + k[3] = k4; + k[4] = k5; + k[5] = k6; + k[6] = k7; + k[7] = k8; + k[8] = k9; + k[9] = k10; + return k; } int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, - struct gameState *state) { - int i; - int j; - int it; - - //set up random number generator - SelectStream(1); - PutSeed((long)randomSeed); - - //check number of players - if (numPlayers > MAX_PLAYERS || numPlayers < 2) - { - return -1; - } - - //set number of players - state->numPlayers = numPlayers; - - //check selected kingdom cards are different - for (i = 0; i < 10; i++) - { - for (j = 0; j < 10; j++) - { - if (j != i && kingdomCards[j] == kingdomCards[i]) - { - return -1; - } - } - } - - - //initialize supply - /////////////////////////////// - - //set number of Curse cards - if (numPlayers == 2) - { - state->supplyCount[curse] = 10; - } - else if (numPlayers == 3) - { - state->supplyCount[curse] = 20; - } - else - { - state->supplyCount[curse] = 30; - } - - //set number of Victory cards - if (numPlayers == 2) - { - state->supplyCount[estate] = 8; - state->supplyCount[duchy] = 8; - state->supplyCount[province] = 8; - } - else - { - state->supplyCount[estate] = 12; - state->supplyCount[duchy] = 12; - state->supplyCount[province] = 12; - } - - //set number of Treasure cards - state->supplyCount[copper] = 60 - (7 * numPlayers); - state->supplyCount[silver] = 40; - state->supplyCount[gold] = 30; - - //set number of Kingdom cards - for (i = adventurer; i <= treasure_map; i++) //loop all cards - { - for (j = 0; j < 10; j++) //loop chosen cards - { - if (kingdomCards[j] == i) - { - //check if card is a 'Victory' Kingdom card - if (kingdomCards[j] == great_hall || kingdomCards[j] == gardens) - { - if (numPlayers == 2) { - state->supplyCount[i] = 8; - } - else { - state->supplyCount[i] = 12; - } - } - else - { - state->supplyCount[i] = 10; - } - break; - } - else //card is not in the set choosen for the game - { - state->supplyCount[i] = -1; - } - } - - } - - //////////////////////// - //supply intilization complete - - //set player decks - for (i = 0; i < numPlayers; i++) - { - state->deckCount[i] = 0; - for (j = 0; j < 3; j++) - { - state->deck[i][j] = estate; - state->deckCount[i]++; - } - for (j = 3; j < 10; j++) - { - state->deck[i][j] = copper; - state->deckCount[i]++; - } - } - - //shuffle player decks - for (i = 0; i < numPlayers; i++) - { - if ( shuffle(i, state) < 0 ) - { - return -1; - } - } - - //draw player hands - for (i = 0; i < numPlayers; i++) - { - //initialize hand size to zero - state->handCount[i] = 0; - state->discardCount[i] = 0; - //draw 5 cards - // for (j = 0; j < 5; j++) - // { - // drawCard(i, state); - // } - } - - //set embargo tokens to 0 for all supply piles - for (i = 0; i <= treasure_map; i++) - { - state->embargoTokens[i] = 0; - } - - //initialize first player's turn - state->outpostPlayed = 0; - state->phase = 0; - state->numActions = 1; - state->numBuys = 1; - state->playedCardCount = 0; - state->whoseTurn = 0; - state->handCount[state->whoseTurn] = 0; - //int it; move to top - - //Moved draw cards to here, only drawing at the start of a turn - for (it = 0; it < 5; it++) { - drawCard(state->whoseTurn, state); - } - - updateCoins(state->whoseTurn, state, 0); - - return 0; + struct gameState *state) { + int i; + int j; + int it; + + //set up random number generator + SelectStream(1); + PutSeed((long)randomSeed); + + //check number of players + if (numPlayers > MAX_PLAYERS || numPlayers < 2) + { + return -1; + } + + //set number of players + state->numPlayers = numPlayers; + + //check selected kingdom cards are different + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + if (j != i && kingdomCards[j] == kingdomCards[i]) + { + return -1; + } + } + } + + + //initialize supply + /////////////////////////////// + + //set number of Curse cards + if (numPlayers == 2) + { + state->supplyCount[curse] = 10; + } + else if (numPlayers == 3) + { + state->supplyCount[curse] = 20; + } + else + { + state->supplyCount[curse] = 30; + } + + //set number of Victory cards + if (numPlayers == 2) + { + state->supplyCount[estate] = 8; + state->supplyCount[duchy] = 8; + state->supplyCount[province] = 8; + } + else + { + state->supplyCount[estate] = 12; + state->supplyCount[duchy] = 12; + state->supplyCount[province] = 12; + } + + //set number of Treasure cards + state->supplyCount[copper] = 60 - (7 * numPlayers); + state->supplyCount[silver] = 40; + state->supplyCount[gold] = 30; + + //set number of Kingdom cards + for (i = adventurer; i <= treasure_map; i++) //loop all cards + { + for (j = 0; j < 10; j++) //loop chosen cards + { + if (kingdomCards[j] == i) + { + //check if card is a 'Victory' Kingdom card + if (kingdomCards[j] == great_hall || kingdomCards[j] == gardens) + { + if (numPlayers == 2) { + state->supplyCount[i] = 8; + } + else { + state->supplyCount[i] = 12; + } + } + else + { + state->supplyCount[i] = 10; + } + break; + } + else //card is not in the set choosen for the game + { + state->supplyCount[i] = -1; + } + } + + } + + //////////////////////// + //supply intilization complete + + //set player decks + for (i = 0; i < numPlayers; i++) + { + state->deckCount[i] = 0; + for (j = 0; j < 3; j++) + { + state->deck[i][j] = estate; + state->deckCount[i]++; + } + for (j = 3; j < 10; j++) + { + state->deck[i][j] = copper; + state->deckCount[i]++; + } + } + + //shuffle player decks + for (i = 0; i < numPlayers; i++) + { + if ( shuffle(i, state) < 0 ) + { + return -1; + } + } + + //draw player hands + for (i = 0; i < numPlayers; i++) + { + //initialize hand size to zero + state->handCount[i] = 0; + state->discardCount[i] = 0; + //draw 5 cards + // for (j = 0; j < 5; j++) + // { + // drawCard(i, state); + // } + } + + //set embargo tokens to 0 for all supply piles + for (i = 0; i <= treasure_map; i++) + { + state->embargoTokens[i] = 0; + } + + //initialize first player's turn + state->outpostPlayed = 0; + state->phase = 0; + state->numActions = 1; + state->numBuys = 1; + state->playedCardCount = 0; + state->whoseTurn = 0; + state->handCount[state->whoseTurn] = 0; + //int it; move to top + + //Moved draw cards to here, only drawing at the start of a turn + for (it = 0; it < 5; it++) { + drawCard(state->whoseTurn, state); + } + + updateCoins(state->whoseTurn, state, 0); + + return 0; } int shuffle(int player, struct gameState *state) { - int newDeck[MAX_DECK]; - int newDeckPos = 0; - int card; - int i; - - if (state->deckCount[player] < 1) - return -1; - qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); - /* SORT CARDS IN DECK TO ENSURE DETERMINISM! */ - - while (state->deckCount[player] > 0) { - card = floor(Random() * state->deckCount[player]); - newDeck[newDeckPos] = state->deck[player][card]; - newDeckPos++; - for (i = card; i < state->deckCount[player]-1; i++) { - state->deck[player][i] = state->deck[player][i+1]; - } - state->deckCount[player]--; - } - for (i = 0; i < newDeckPos; i++) { - state->deck[player][i] = newDeck[i]; - state->deckCount[player]++; - } - - return 0; + int newDeck[MAX_DECK]; + int newDeckPos = 0; + int card; + int i; + + if (state->deckCount[player] < 1) + return -1; + qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); + /* SORT CARDS IN DECK TO ENSURE DETERMINISM! */ + + while (state->deckCount[player] > 0) { + card = floor(Random() * state->deckCount[player]); + newDeck[newDeckPos] = state->deck[player][card]; + newDeckPos++; + for (i = card; i < state->deckCount[player]-1; i++) { + state->deck[player][i] = state->deck[player][i+1]; + } + state->deckCount[player]--; + } + for (i = 0; i < newDeckPos; i++) { + state->deck[player][i] = newDeck[i]; + state->deckCount[player]++; + } + + return 0; } int playCard(int handPos, int choice1, int choice2, int choice3, struct gameState *state) { - int card; - int coin_bonus = 0; //tracks coins gain from actions - - //check if it is the right phase - if (state->phase != 0) - { - return -1; - } - - //check if player has enough actions - if ( state->numActions < 1 ) - { - return -1; - } - - //get card played - card = handCard(handPos, state); - - //check if selected card is an action - if ( card < adventurer || card > treasure_map ) - { - return -1; - } - - //play card - if ( cardEffect(card, choice1, choice2, choice3, state, handPos, &coin_bonus) < 0 ) - { - return -1; - } - - //reduce number of actions - state->numActions--; - - //update coins (Treasure cards may be added with card draws) - updateCoins(state->whoseTurn, state, coin_bonus); - - return 0; + int card; + int coin_bonus = 0; //tracks coins gain from actions + + //check if it is the right phase + if (state->phase != 0) + { + return -1; + } + + //check if player has enough actions + if ( state->numActions < 1 ) + { + return -1; + } + + //get card played + card = handCard(handPos, state); + + //check if selected card is an action + if ( card < adventurer || card > treasure_map ) + { + return -1; + } + + //play card + if ( cardEffect(card, choice1, choice2, choice3, state, handPos, &coin_bonus) < 0 ) + { + return -1; + } + + //reduce number of actions + state->numActions--; + + //update coins (Treasure cards may be added with card draws) + updateCoins(state->whoseTurn, state, coin_bonus); + + return 0; } int buyCard(int supplyPos, struct gameState *state) { - int who; - if (DEBUG) { - printf("Entering buyCard...\n"); - } - - // I don't know what to do about the phase thing. - - who = state->whoseTurn; - - if (state->numBuys < 1) { - if (DEBUG) - printf("You do not have any buys left\n"); - return -1; - } else if (supplyCount(supplyPos, state) <1) { - if (DEBUG) - printf("There are not any of that type of card left\n"); - return -1; - } else if (state->coins < getCost(supplyPos)) { - if (DEBUG) - printf("You do not have enough money to buy that. You have %d coins.\n", state->coins); - return -1; - } else { - state->phase=1; - //state->supplyCount[supplyPos]--; - gainCard(supplyPos, state, 0, who); //card goes in discard, this might be wrong.. (2 means goes into hand, 0 goes into discard) - - state->coins = (state->coins) - (getCost(supplyPos)); - state->numBuys--; - if (DEBUG) - printf("You bought card number %d for %d coins. You now have %d buys and %d coins.\n", supplyPos, getCost(supplyPos), state->numBuys, state->coins); - } - - //state->discard[who][state->discardCount[who]] = supplyPos; - //state->discardCount[who]++; - - return 0; + int who; + if (DEBUG) { + printf("Entering buyCard...\n"); + } + + // I don't know what to do about the phase thing. + + who = state->whoseTurn; + + if (state->numBuys < 1) { + if (DEBUG) + printf("You do not have any buys left\n"); + return -1; + } else if (supplyCount(supplyPos, state) <1) { + if (DEBUG) + printf("There are not any of that type of card left\n"); + return -1; + } else if (state->coins < getCost(supplyPos)) { + if (DEBUG) + printf("You do not have enough money to buy that. You have %d coins.\n", state->coins); + return -1; + } else { + state->phase=1; + //state->supplyCount[supplyPos]--; + gainCard(supplyPos, state, 0, who); //card goes in discard, this might be wrong.. (2 means goes into hand, 0 goes into discard) + + state->coins = (state->coins) - (getCost(supplyPos)); + state->numBuys--; + if (DEBUG) + printf("You bought card number %d for %d coins. You now have %d buys and %d coins.\n", supplyPos, getCost(supplyPos), state->numBuys, state->coins); + } + + //state->discard[who][state->discardCount[who]] = supplyPos; + //state->discardCount[who]++; + + return 0; } int numHandCards(struct gameState *state) { - return state->handCount[ whoseTurn(state) ]; + return state->handCount[ whoseTurn(state) ]; } int handCard(int handPos, struct gameState *state) { - int currentPlayer = whoseTurn(state); - return state->hand[currentPlayer][handPos]; + int currentPlayer = whoseTurn(state); + return state->hand[currentPlayer][handPos]; } int supplyCount(int card, struct gameState *state) { - return state->supplyCount[card]; + return state->supplyCount[card]; } int fullDeckCount(int player, int card, struct gameState *state) { - int i; - int count = 0; + int i; + int count = 0; - for (i = 0; i < state->deckCount[player]; i++) - { - if (state->deck[player][i] == card) count++; - } + for (i = 0; i < state->deckCount[player]; i++) + { + if (state->deck[player][i] == card) count++; + } - for (i = 0; i < state->handCount[player]; i++) - { - if (state->hand[player][i] == card) count++; - } + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == card) count++; + } - for (i = 0; i < state->discardCount[player]; i++) - { - if (state->discard[player][i] == card) count++; - } + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->discard[player][i] == card) count++; + } - return count; + return count; } int whoseTurn(struct gameState *state) { - return state->whoseTurn; + return state->whoseTurn; } int endTurn(struct gameState *state) { - int k; - int i; - int currentPlayer = whoseTurn(state); - - //Discard hand - for (i = 0; i < state->handCount[currentPlayer]; i++) { - state->discard[currentPlayer][state->discardCount[currentPlayer]++] = state->hand[currentPlayer][i];//Discard - state->hand[currentPlayer][i] = -1;//Set card to -1 - } - state->handCount[currentPlayer] = 0;//Reset hand count - - //Code for determining the player - if (currentPlayer < (state->numPlayers - 1)) { - state->whoseTurn = currentPlayer + 1;//Still safe to increment - } - else { - state->whoseTurn = 0;//Max player has been reached, loop back around to player 1 - } - - state->outpostPlayed = 0; - state->phase = 0; - state->numActions = 1; - state->coins = 0; - state->numBuys = 1; - state->playedCardCount = 0; - state->handCount[state->whoseTurn] = 0; - - //int k; move to top - //Next player draws hand - for (k = 0; k < 5; k++) { - drawCard(state->whoseTurn, state);//Draw a card - } - - //Update money - updateCoins(state->whoseTurn, state, 0); - - return 0; + int k; + int i; + int currentPlayer = whoseTurn(state); + + //Discard hand + for (i = 0; i < state->handCount[currentPlayer]; i++) { + state->discard[currentPlayer][state->discardCount[currentPlayer]++] = state->hand[currentPlayer][i];//Discard + state->hand[currentPlayer][i] = -1;//Set card to -1 + } + state->handCount[currentPlayer] = 0;//Reset hand count + + //Code for determining the player + if (currentPlayer < (state->numPlayers - 1)) { + state->whoseTurn = currentPlayer + 1;//Still safe to increment + } + else { + state->whoseTurn = 0;//Max player has been reached, loop back around to player 1 + } + + state->outpostPlayed = 0; + state->phase = 0; + state->numActions = 1; + state->coins = 0; + state->numBuys = 1; + state->playedCardCount = 0; + state->handCount[state->whoseTurn] = 0; + + //int k; move to top + //Next player draws hand + for (k = 0; k < 5; k++) { + drawCard(state->whoseTurn, state);//Draw a card + } + + //Update money + updateCoins(state->whoseTurn, state, 0); + + return 0; } int isGameOver(struct gameState *state) { - int i; - int j; - - //if stack of Province cards is empty, the game ends - if (state->supplyCount[province] == 0) - { - return 1; - } - - //if three supply pile are at 0, the game ends - j = 0; - for (i = 0; i < 25; i++) - { - if (state->supplyCount[i] == 0) - { - j++; - } - } - if ( j >= 3) - { - return 1; - } - - return 0; + int i; + int j; + + //if stack of Province cards is empty, the game ends + if (state->supplyCount[province] == 0) + { + return 1; + } + + //if three supply pile are at 0, the game ends + j = 0; + for (i = 0; i < 25; i++) + { + if (state->supplyCount[i] == 0) + { + j++; + } + } + if ( j >= 3) + { + return 1; + } + + return 0; } int scoreFor (int player, struct gameState *state) { - int i; - int score = 0; - //score from hand - for (i = 0; i < state->handCount[player]; i++) - { - if (state->hand[player][i] == curse) { - score = score - 1; - }; - if (state->hand[player][i] == estate) { - score = score + 1; - }; - if (state->hand[player][i] == duchy) { - score = score + 3; - }; - if (state->hand[player][i] == province) { - score = score + 6; - }; - if (state->hand[player][i] == great_hall) { - score = score + 1; - }; - if (state->hand[player][i] == gardens) { - score = score + ( fullDeckCount(player, 0, state) / 10 ); - }; - } - - //score from discard - for (i = 0; i < state->discardCount[player]; i++) - { - if (state->discard[player][i] == curse) { - score = score - 1; - }; - if (state->discard[player][i] == estate) { - score = score + 1; - }; - if (state->discard[player][i] == duchy) { - score = score + 3; - }; - if (state->discard[player][i] == province) { - score = score + 6; - }; - if (state->discard[player][i] == great_hall) { - score = score + 1; - }; - if (state->discard[player][i] == gardens) { - score = score + ( fullDeckCount(player, 0, state) / 10 ); - }; - } - - //score from deck - for (i = 0; i < state->discardCount[player]; i++) - { - if (state->deck[player][i] == curse) { - score = score - 1; - }; - if (state->deck[player][i] == estate) { - score = score + 1; - }; - if (state->deck[player][i] == duchy) { - score = score + 3; - }; - if (state->deck[player][i] == province) { - score = score + 6; - }; - if (state->deck[player][i] == great_hall) { - score = score + 1; - }; - if (state->deck[player][i] == gardens) { - score = score + ( fullDeckCount(player, 0, state) / 10 ); - }; - } - - return score; + int i; + int score = 0; + //score from hand + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == curse) { + score = score - 1; + }; + if (state->hand[player][i] == estate) { + score = score + 1; + }; + if (state->hand[player][i] == duchy) { + score = score + 3; + }; + if (state->hand[player][i] == province) { + score = score + 6; + }; + if (state->hand[player][i] == great_hall) { + score = score + 1; + }; + if (state->hand[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + //score from discard + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->discard[player][i] == curse) { + score = score - 1; + }; + if (state->discard[player][i] == estate) { + score = score + 1; + }; + if (state->discard[player][i] == duchy) { + score = score + 3; + }; + if (state->discard[player][i] == province) { + score = score + 6; + }; + if (state->discard[player][i] == great_hall) { + score = score + 1; + }; + if (state->discard[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + //score from deck + for (i = 0; i < state->discardCount[player]; i++) + { + if (state->deck[player][i] == curse) { + score = score - 1; + }; + if (state->deck[player][i] == estate) { + score = score + 1; + }; + if (state->deck[player][i] == duchy) { + score = score + 3; + }; + if (state->deck[player][i] == province) { + score = score + 6; + }; + if (state->deck[player][i] == great_hall) { + score = score + 1; + }; + if (state->deck[player][i] == gardens) { + score = score + ( fullDeckCount(player, 0, state) / 10 ); + }; + } + + return score; } int getWinners(int players[MAX_PLAYERS], struct gameState *state) { - int i; - int j; - int highScore; - int currentPlayer; - - //get score for each player - for (i = 0; i < MAX_PLAYERS; i++) - { - //set unused player scores to -9999 - if (i >= state->numPlayers) - { - players[i] = -9999; - } - else - { - players[i] = scoreFor (i, state); - } - } - - //find highest score - j = 0; - for (i = 0; i < MAX_PLAYERS; i++) - { - if (players[i] > players[j]) - { - j = i; - } - } - highScore = players[j]; - - //add 1 to players who had less turns - currentPlayer = whoseTurn(state); - for (i = 0; i < MAX_PLAYERS; i++) - { - if ( players[i] == highScore && i > currentPlayer ) - { - players[i]++; - } - } - - //find new highest score - j = 0; - for (i = 0; i < MAX_PLAYERS; i++) - { - if ( players[i] > players[j] ) - { - j = i; - } - } - highScore = players[j]; - - //set winners in array to 1 and rest to 0 - for (i = 0; i < MAX_PLAYERS; i++) - { - if ( players[i] == highScore ) - { - players[i] = 1; - } - else - { - players[i] = 0; - } - } - - return 0; + int i; + int j; + int highScore; + int currentPlayer; + + //get score for each player + for (i = 0; i < MAX_PLAYERS; i++) + { + //set unused player scores to -9999 + if (i >= state->numPlayers) + { + players[i] = -9999; + } + else + { + players[i] = scoreFor (i, state); + } + } + + //find highest score + j = 0; + for (i = 0; i < MAX_PLAYERS; i++) + { + if (players[i] > players[j]) + { + j = i; + } + } + highScore = players[j]; + + //add 1 to players who had less turns + currentPlayer = whoseTurn(state); + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] == highScore && i > currentPlayer ) + { + players[i]++; + } + } + + //find new highest score + j = 0; + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] > players[j] ) + { + j = i; + } + } + highScore = players[j]; + + //set winners in array to 1 and rest to 0 + for (i = 0; i < MAX_PLAYERS; i++) + { + if ( players[i] == highScore ) + { + players[i] = 1; + } + else + { + players[i] = 0; + } + } + + return 0; } int drawCard(int player, struct gameState *state) { int count; - int deckCounter; - if (state->deckCount[player] <= 0) { //Deck is empty + int deckCounter; + if (state->deckCount[player] <= 0) { //Deck is empty - //Step 1 Shuffle the discard pile back into a deck - int i; - //Move discard to deck - for (i = 0; i < state->discardCount[player]; i++) { - state->deck[player][i] = state->discard[player][i]; - state->discard[player][i] = -1; - } + //Step 1 Shuffle the discard pile back into a deck + int i; + //Move discard to deck + for (i = 0; i < state->discardCount[player]; i++) { + state->deck[player][i] = state->discard[player][i]; + state->discard[player][i] = -1; + } - state->deckCount[player] = state->discardCount[player]; - state->discardCount[player] = 0;//Reset discard + state->deckCount[player] = state->discardCount[player]; + state->discardCount[player] = 0;//Reset discard - //Shufffle the deck - shuffle(player, state);//Shuffle the deck up and make it so that we can draw + //Shufffle the deck + shuffle(player, state);//Shuffle the deck up and make it so that we can draw - if (DEBUG) { //Debug statements - printf("Deck count now: %d\n", state->deckCount[player]); - } + if (DEBUG) { //Debug statements + printf("Deck count now: %d\n", state->deckCount[player]); + } - state->discardCount[player] = 0; + state->discardCount[player] = 0; - //Step 2 Draw Card - count = state->handCount[player];//Get current player's hand count + //Step 2 Draw Card + count = state->handCount[player];//Get current player's hand count - if (DEBUG) { //Debug statements - printf("Current hand count: %d\n", count); - } + if (DEBUG) { //Debug statements + printf("Current hand count: %d\n", count); + } - deckCounter = state->deckCount[player];//Create a holder for the deck count + deckCounter = state->deckCount[player];//Create a holder for the deck count - if (deckCounter == 0) - return -1; + if (deckCounter == 0) + return -1; - state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to hand - state->deckCount[player]--; - state->handCount[player]++;//Increment hand count - } + state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to hand + state->deckCount[player]--; + state->handCount[player]++;//Increment hand count + } - else { - int count = state->handCount[player];//Get current hand count for player - int deckCounter; - if (DEBUG) { //Debug statements - printf("Current hand count: %d\n", count); - } + else { + int count = state->handCount[player];//Get current hand count for player + int deckCounter; + if (DEBUG) { //Debug statements + printf("Current hand count: %d\n", count); + } - deckCounter = state->deckCount[player];//Create holder for the deck count - state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to the hand - state->deckCount[player]--; - state->handCount[player]++;//Increment hand count - } + deckCounter = state->deckCount[player];//Create holder for the deck count + state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to the hand + state->deckCount[player]--; + state->handCount[player]++;//Increment hand count + } - return 0; + return 0; } int getCost(int cardNumber) { - switch( cardNumber ) - { - case curse: - return 0; - case estate: - return 2; - case duchy: - return 5; - case province: - return 8; - case copper: - return 0; - case silver: - return 3; - case gold: - return 6; - case adventurer: - return 6; - case council_room: - return 5; - case feast: - return 4; - case gardens: - return 4; - case mine: - return 5; - case remodel: - return 4; - case smithy: - return 4; - case village: - return 3; - case baron: - return 4; - case great_hall: - return 3; - case minion: - return 5; - case steward: - return 3; - case tribute: - return 5; - case ambassador: - return 3; - case cutpurse: - return 4; - case embargo: - return 2; - case outpost: - return 5; - case salvager: - return 4; - case sea_hag: - return 4; - case treasure_map: - return 4; - } - - return -1; + switch( cardNumber ) + { + case curse: + return 0; + case estate: + return 2; + case duchy: + return 5; + case province: + return 8; + case copper: + return 0; + case silver: + return 3; + case gold: + return 6; + case adventurer: + return 6; + case council_room: + return 5; + case feast: + return 4; + case gardens: + return 4; + case mine: + return 5; + case remodel: + return 4; + case smithy: + return 4; + case village: + return 3; + case baron: + return 4; + case great_hall: + return 3; + case minion: + return 5; + case steward: + return 3; + case tribute: + return 5; + case ambassador: + return 3; + case cutpurse: + return 4; + case embargo: + return 2; + case outpost: + return 5; + case salvager: + return 4; + case sea_hag: + return 4; + case treasure_map: + return 4; + } + + return -1; } +void baronEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) +{ + 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); + } + } + } + + + + + + +} +void minionEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) +{ + //+1 action + state->numActions++; + + //discard card from hand + discardCard(handPos, currentPlayer, state, 0); + + if (choice1) + { + //Bug HEre + state->coins = state->coins + 3; + } + 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); + } + } + } + } + + } + +} +void tributeEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) +{ + 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; + } + } +} +void ambassadorEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) +{ + + 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; + } + } + } + +} +void mineEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) +{ + 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; + } + } + + +} 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) - { - state->coins = state->coins + 2; - } - else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 - { - //discard hand - while(numHandCards(state) > 0) - { - discardCard(handPos, currentPlayer, state, 0); - } - - //draw 4 - for (i = 0; i < 4; i++) - { - drawCard(currentPlayer, state); - } - - //other players discard hand and redraw if hand size > 4 - for (i = 0; i < state->numPlayers; i++) - { - if (i != currentPlayer) - { - if ( state->handCount[i] > 4 ) - { - //discard hand - while( state->handCount[i] > 0 ) - { - discardCard(handPos, i, state, 0); - } - - //draw 4 - for (j = 0; j < 4; j++) - { - drawCard(i, state); - } - } - } - } - - } - return 0; - - case steward: - if (choice1 == 1) - { - //+2 cards - drawCard(currentPlayer, state); - drawCard(currentPlayer, state); - } - else if (choice1 == 2) - { - //+2 coins - state->coins = state->coins + 2; - } - else - { - //trash 2 cards in hand - discardCard(choice2, currentPlayer, state, 1); - discardCard(choice3, currentPlayer, state, 1); - } - - //discard card from hand - discardCard(handPos, currentPlayer, state, 0); - return 0; - - case tribute: - if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { - if (state->deckCount[nextPlayer] > 0) { - tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; - state->deckCount[nextPlayer]--; - } - else if (state->discardCount[nextPlayer] > 0) { - tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; - state->discardCount[nextPlayer]--; - } - else { - //No Card to Reveal - if (DEBUG) { - printf("No cards to reveal\n"); - } - } - } - - else { - if (state->deckCount[nextPlayer] == 0) { - for (i = 0; i < state->discardCount[nextPlayer]; i++) { - state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck - state->deckCount[nextPlayer]++; - state->discard[nextPlayer][i] = -1; - state->discardCount[nextPlayer]--; - } - - shuffle(nextPlayer,state);//Shuffle the deck - } - tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; - state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; - state->deckCount[nextPlayer]--; - tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; - state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; - state->deckCount[nextPlayer]--; - } - - if (tributeRevealedCards[0] == tributeRevealedCards[1]) { //If we have a duplicate card, just drop one - state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; - state->playedCardCount++; - tributeRevealedCards[1] = -1; - } - - for (i = 0; i <= 2; i ++) { - if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) { //Treasure cards - state->coins += 2; - } - - else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall) { //Victory Card Found - drawCard(currentPlayer, state); - drawCard(currentPlayer, state); - } - else { //Action Card - state->numActions = state->numActions + 2; - } - } - - return 0; - - case ambassador: - j = 0; //used to check if player has enough cards to discard - - if (choice2 > 2 || choice2 < 0) - { - return -1; - } - - if (choice1 == handPos) - { - return -1; - } - - for (i = 0; i < state->handCount[currentPlayer]; i++) - { - if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) - { - j++; - } - } - if (j < choice2) - { - return -1; - } - - if (DEBUG) - printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); - - //increase supply count for choosen card by amount being discarded - state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; - - //each other player gains a copy of revealed card - for (i = 0; i < state->numPlayers; i++) - { - if (i != currentPlayer) - { - gainCard(state->hand[currentPlayer][choice1], state, 0, i); - } - } - - //discard played card from hand - discardCard(handPos, currentPlayer, state, 0); - - //trash copies of cards returned to supply - for (j = 0; j < choice2; j++) - { - for (i = 0; i < state->handCount[currentPlayer]; i++) - { - if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) - { - discardCard(i, currentPlayer, state, 1); - break; - } - } - } - - return 0; - - case cutpurse: - - updateCoins(currentPlayer, state, 2); - for (i = 0; i < state->numPlayers; i++) - { - if (i != currentPlayer) - { - for (j = 0; j < state->handCount[i]; j++) - { - if (state->hand[i][j] == copper) - { - discardCard(j, i, state, 0); - break; - } - if (j == state->handCount[i]) - { - for (k = 0; k < state->handCount[i]; k++) - { - if (DEBUG) - printf("Player %d reveals card number %d\n", i, state->hand[i][k]); - } - break; - } - } - - } - - } - - //discard played card from hand - discardCard(handPos, currentPlayer, state, 0); - - return 0; - - - case embargo: - //+2 Coins - state->coins = state->coins + 2; - - //see if selected pile is in play - if ( state->supplyCount[choice1] == -1 ) - { - return -1; - } - - //add embargo token to selected supply pile - state->embargoTokens[choice1]++; - - //trash card - discardCard(handPos, currentPlayer, state, 1); - return 0; - - case outpost: - //set outpost flag - state->outpostPlayed++; - - //discard card - discardCard(handPos, currentPlayer, state, 0); - return 0; - - case salvager: - //+1 buy - state->numBuys++; - - if (choice1) - { - //gain coins equal to trashed card - state->coins = state->coins + getCost( handCard(choice1, state) ); - //trash card - discardCard(choice1, currentPlayer, state, 1); - } - - //discard card - discardCard(handPos, currentPlayer, state, 0); - return 0; - - case sea_hag: - for (i = 0; i < state->numPlayers; i++) { - if (i != currentPlayer) { - state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; - state->deckCount[i]--; - state->discardCount[i]++; - state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse - } - } - return 0; - - case treasure_map: - //search hand for another treasure_map - index = -1; - for (i = 0; i < state->handCount[currentPlayer]; i++) - { - if (state->hand[currentPlayer][i] == treasure_map && i != handPos) - { - index = i; - break; - } - } - if (index > -1) - { - //trash both treasure cards - discardCard(handPos, currentPlayer, state, 1); - discardCard(index, currentPlayer, state, 1); - - //gain 4 Gold cards - for (i = 0; i < 4; i++) - { - gainCard(gold, state, 1, currentPlayer); - } - - //return success - return 1; - } - - //no second treasure_map found in hand - return -1; - } - - return -1; + int 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: + mineEffect(); + + 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: + baronEffect(); + 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: + minionEffect(); + 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: + tributeEffect(); + + return 0; + + case ambassador: + ambassadorEffect(); + + 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 discardCard(int handPos, int currentPlayer, struct gameState *state, int trashFlag) { - //if card is not trashed, added to Played pile - if (trashFlag < 1) - { - //add card to played pile - state->playedCards[state->playedCardCount] = state->hand[currentPlayer][handPos]; - state->playedCardCount++; - } - - //set played card to -1 - state->hand[currentPlayer][handPos] = -1; - - //remove card from player's hand - if ( handPos == (state->handCount[currentPlayer] - 1) ) //last card in hand array is played - { - //reduce number of cards in hand - state->handCount[currentPlayer]--; - } - else if ( state->handCount[currentPlayer] == 1 ) //only one card in hand - { - //reduce number of cards in hand - state->handCount[currentPlayer]--; - } - else - { - //replace discarded card with last card in hand - state->hand[currentPlayer][handPos] = state->hand[currentPlayer][ (state->handCount[currentPlayer] - 1)]; - //set last card to -1 - state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1; - //reduce number of cards in hand - state->handCount[currentPlayer]--; - } - - return 0; + //if card is not trashed, added to Played pile + if (trashFlag < 1) + { + //add card to played pile + state->playedCards[state->playedCardCount] = state->hand[currentPlayer][handPos]; + state->playedCardCount++; + } + + //set played card to -1 + state->hand[currentPlayer][handPos] = -1; + + //remove card from player's hand + if ( handPos == (state->handCount[currentPlayer] - 1) ) //last card in hand array is played + { + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + else if ( state->handCount[currentPlayer] == 1 ) //only one card in hand + { + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + else + { + //replace discarded card with last card in hand + state->hand[currentPlayer][handPos] = state->hand[currentPlayer][ (state->handCount[currentPlayer] - 1)]; + //set last card to -1 + state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1; + //reduce number of cards in hand + state->handCount[currentPlayer]--; + } + + return 0; } int gainCard(int supplyPos, struct gameState *state, int toFlag, int player) { - //Note: supplyPos is enum of choosen card - - //check if supply pile is empty (0) or card is not used in game (-1) - if ( supplyCount(supplyPos, state) < 1 ) - { - return -1; - } - - //added card for [whoseTurn] current player: - // toFlag = 0 : add to discard - // toFlag = 1 : add to deck - // toFlag = 2 : add to hand - - if (toFlag == 1) - { - state->deck[ player ][ state->deckCount[player] ] = supplyPos; - state->deckCount[player]++; - } - else if (toFlag == 2) - { - state->hand[ player ][ state->handCount[player] ] = supplyPos; - state->handCount[player]++; - } - else - { - state->discard[player][ state->discardCount[player] ] = supplyPos; - state->discardCount[player]++; - } - - //decrease number in supply pile - state->supplyCount[supplyPos]--; - - return 0; + //Note: supplyPos is enum of choosen card + + //check if supply pile is empty (0) or card is not used in game (-1) + if ( supplyCount(supplyPos, state) < 1 ) + { + return -1; + } + + //added card for [whoseTurn] current player: + // toFlag = 0 : add to discard + // toFlag = 1 : add to deck + // toFlag = 2 : add to hand + + if (toFlag == 1) + { + state->deck[ player ][ state->deckCount[player] ] = supplyPos; + state->deckCount[player]++; + } + else if (toFlag == 2) + { + state->hand[ player ][ state->handCount[player] ] = supplyPos; + state->handCount[player]++; + } + else + { + state->discard[player][ state->discardCount[player] ] = supplyPos; + state->discardCount[player]++; + } + + //decrease number in supply pile + state->supplyCount[supplyPos]--; + + return 0; } int updateCoins(int player, struct gameState *state, int bonus) { - int i; - - //reset coin count - state->coins = 0; - - //add coins for each Treasure card in player's hand - for (i = 0; i < state->handCount[player]; i++) - { - if (state->hand[player][i] == copper) - { - state->coins += 1; - } - else if (state->hand[player][i] == silver) - { - state->coins += 2; - } - else if (state->hand[player][i] == gold) - { - state->coins += 3; - } - } - - //add bonus - state->coins += bonus; - - return 0; + int i; + + //reset coin count + state->coins = 0; + + //add coins for each Treasure card in player's hand + for (i = 0; i < state->handCount[player]; i++) + { + if (state->hand[player][i] == copper) + { + state->coins += 1; + } + else if (state->hand[player][i] == silver) + { + state->coins += 2; + } + else if (state->hand[player][i] == gold) + { + state->coins += 3; + } + } + + //add bonus + state->coins += bonus; + + return 0; } From e71fe78233e30f2663a578b67208e719857b3d24 Mon Sep 17 00:00:00 2001 From: Elliott Lapinel Date: Sun, 13 Oct 2019 16:45:38 -0700 Subject: [PATCH 4/5] Added Bugs --- dominion/dominion.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dominion/dominion.c b/dominion/dominion.c index 201b7361b..a5d9d942c 100644 --- a/dominion/dominion.c +++ b/dominion/dominion.c @@ -706,7 +706,7 @@ void baronEffect(int card, int choice1, int choice2,int choice3,struct gameState if (supplyCount(estate, state) > 0) { gainCard(estate, state, 0, currentPlayer); - state->supplyCount[estate]--;//Decrement estates + state->supplyCount[estate]++;//Decrement estates if (supplyCount(estate, state) == 0) { isGameOver(state); } @@ -724,7 +724,7 @@ void baronEffect(int card, int choice1, int choice2,int choice3,struct gameState if (supplyCount(estate, state) > 0) { gainCard(estate, state, 0, currentPlayer);//Gain an estate - state->supplyCount[estate]--;//Decrement Estates + state->supplyCount[estate]++;//Decrement Estates if (supplyCount(estate, state) == 0) { isGameOver(state); } @@ -740,7 +740,7 @@ void baronEffect(int card, int choice1, int choice2,int choice3,struct gameState void minionEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) { //+1 action - state->numActions++; + state->numActions--; //discard card from hand discardCard(handPos, currentPlayer, state, 0); @@ -792,7 +792,7 @@ void minionEffect(int card, int choice1, int choice2,int choice3,struct gameStat void tributeEffect(int card, int choice1, int choice2,int choice3,struct gameState* state, int handPos, int* bonus) { if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { - if (state->deckCount[nextPlayer] > 0) { + if (state->deckCount[nextPlayer] > 5) { tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deckCount[nextPlayer]--; } @@ -817,7 +817,7 @@ void tributeEffect(int card, int choice1, int choice2,int choice3,struct gameSta state->discardCount[nextPlayer]--; } - shuffle(nextPlayer,state);//Shuffle the deck + shuffle(currentPlayer,state);//Shuffle the deck } tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; @@ -890,7 +890,7 @@ void ambassadorEffect(int card, int choice1, int choice2,int choice3,struct game } //discard played card from hand - discardCard(handPos, currentPlayer, state, 0); + discardCard(handPos, nextPlayer, state, 0); //trash copies of cards returned to supply for (j = 0; j < choice2; j++) @@ -899,7 +899,7 @@ void ambassadorEffect(int card, int choice1, int choice2,int choice3,struct game { if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) { - discardCard(i, currentPlayer, state, 1); + discardCard(i, nextPlayer, state, 1); break; } } @@ -925,13 +925,13 @@ void mineEffect(int card, int choice1, int choice2,int choice3,struct gameState* return -1; } - gainCard(choice2, state, 2, currentPlayer); + gainCard(choice2, state, 2, nextPlayer); //discard card from hand discardCard(handPos, currentPlayer, state, 0); //discard trashed card - for (i = 0; i < state->handCount[currentPlayer]; i++) + for (i = 5; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == j) { From e976b0ca36e8ccaef10d7bf3ad64d08c0f40ccda Mon Sep 17 00:00:00 2001 From: Elliott Lapinel Date: Sun, 10 Nov 2019 15:27:47 -0800 Subject: [PATCH 5/5] For CS362 Quiz --- projects/lapinele/quiz/Makefile | 5 +++ projects/lapinele/quiz/testme.c | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 projects/lapinele/quiz/Makefile create mode 100644 projects/lapinele/quiz/testme.c diff --git a/projects/lapinele/quiz/Makefile b/projects/lapinele/quiz/Makefile new file mode 100644 index 000000000..a5510b657 --- /dev/null +++ b/projects/lapinele/quiz/Makefile @@ -0,0 +1,5 @@ +CFLAGS =-Wall -fpic -coverage -lm + +testResults: + gcc -o testMe testme.c $(CFLAGS) + testMe diff --git a/projects/lapinele/quiz/testme.c b/projects/lapinele/quiz/testme.c new file mode 100644 index 000000000..1f5c79a50 --- /dev/null +++ b/projects/lapinele/quiz/testme.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +char inputChar() +{ + char randomChar; + //gives me a bunch of different characters + randomChar=rand()%127; + return randomChar; +} + +char *inputString() +{ + char* stringPointer; + stringPointer=malloc(6*sizeof(char)); + int i; + char dumbArray[6]={'r','e','s','e','t','\0'}; + for(i=0;i<5;i++) + { + int location=rand()%6; + stringPointer[i]=dumbArray[location]; + + } + return stringPointer; +} + +void testme() +{ + int tcCount = 0; + char *s; + char c; + int state = 0; + while (1) + { + tcCount++; + c = inputChar(); + s = inputString(); + printf("Iteration %d: c = %c, s = %s, state = %d\n", tcCount, c, s, state); + + if (c == '[' && state == 0) state = 1; + if (c == '(' && state == 1) state = 2; + if (c == '{' && state == 2) state = 3; + if (c == ' '&& state == 3) state = 4; + if (c == 'a' && state == 4) state = 5; + if (c == 'x' && state == 5) state = 6; + if (c == '}' && state == 6) state = 7; + if (c == ')' && state == 7) state = 8; + if (c == ']' && state == 8) state = 9; + if (s[0] == 'r' && s[1] == 'e' + && s[2] == 's' && s[3] == 'e' + && s[4] == 't' && s[5] == '\0' + && state == 9) + { + printf("error "); + exit(200); + } + } +} + + +int main(int argc, char *argv[]) +{ + srand(time(NULL)); + testme(); + return 0; +}