From d57bf2bda431dc9a16942421e353979fbbe4e223 Mon Sep 17 00:00:00 2001 From: Tyler Date: Wed, 26 Jun 2019 17:49:37 -0700 Subject: [PATCH 1/3] assignment 1 --- projects/turnerty/README.md | 3 + projects/turnerty/dominion/Makefile | 39 + projects/turnerty/dominion/READM.md | 2 + projects/turnerty/dominion/badTestDrawCard | Bin 0 -> 29572 bytes projects/turnerty/dominion/badTestDrawCard.c | 44 + .../turnerty/dominion/betterTestDrawCard.c | 70 + projects/turnerty/dominion/dominion.c | 1333 +++++++++++++++++ projects/turnerty/dominion/dominion.h | 131 ++ projects/turnerty/dominion/dominion_helpers.h | 15 + projects/turnerty/dominion/interface.c | 363 +++++ projects/turnerty/dominion/interface.h | 128 ++ projects/turnerty/dominion/playdom | Bin 0 -> 86888 bytes projects/turnerty/dominion/playdom.c | 134 ++ projects/turnerty/dominion/player | Bin 0 -> 108236 bytes projects/turnerty/dominion/player.c | 217 +++ projects/turnerty/dominion/rngs.c | 183 +++ projects/turnerty/dominion/rngs.h | 19 + projects/turnerty/dominion/rt.c | 27 + projects/turnerty/dominion/supplyTest.c | 30 + projects/turnerty/dominion/testBuyCard.c | 94 ++ projects/turnerty/dominion/testDrawCard.c | 93 ++ projects/turnerty/dominion/testInit.c | 56 + projects/turnerty/dominion/testShuffle.c | 27 + 23 files changed, 3008 insertions(+) create mode 100644 projects/turnerty/README.md create mode 100644 projects/turnerty/dominion/Makefile create mode 100644 projects/turnerty/dominion/READM.md create mode 100644 projects/turnerty/dominion/badTestDrawCard create mode 100644 projects/turnerty/dominion/badTestDrawCard.c create mode 100644 projects/turnerty/dominion/betterTestDrawCard.c create mode 100644 projects/turnerty/dominion/dominion.c create mode 100644 projects/turnerty/dominion/dominion.h create mode 100644 projects/turnerty/dominion/dominion_helpers.h create mode 100644 projects/turnerty/dominion/interface.c create mode 100644 projects/turnerty/dominion/interface.h create mode 100644 projects/turnerty/dominion/playdom create mode 100644 projects/turnerty/dominion/playdom.c create mode 100644 projects/turnerty/dominion/player create mode 100644 projects/turnerty/dominion/player.c create mode 100644 projects/turnerty/dominion/rngs.c create mode 100644 projects/turnerty/dominion/rngs.h create mode 100644 projects/turnerty/dominion/rt.c create mode 100644 projects/turnerty/dominion/supplyTest.c create mode 100644 projects/turnerty/dominion/testBuyCard.c create mode 100644 projects/turnerty/dominion/testDrawCard.c create mode 100644 projects/turnerty/dominion/testInit.c create mode 100644 projects/turnerty/dominion/testShuffle.c diff --git a/projects/turnerty/README.md b/projects/turnerty/README.md new file mode 100644 index 00000000..06e4d218 --- /dev/null +++ b/projects/turnerty/README.md @@ -0,0 +1,3 @@ +#Tyler Turner, turnerty +Software Engineering (CS 362) class's master repository. +class-cs362-400-su19 diff --git a/projects/turnerty/dominion/Makefile b/projects/turnerty/dominion/Makefile new file mode 100644 index 00000000..25a61b69 --- /dev/null +++ b/projects/turnerty/dominion/Makefile @@ -0,0 +1,39 @@ +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) + +badTestDrawCard: badTestDrawCard.c dominion.o rngs.o + gcc -o badTestDrawCard -g badTestDrawCard.c dominion.o rngs.o $(CFLAGS) + +testBuyCard: testDrawCard.c dominion.o rngs.o + gcc -o testDrawCard -g testDrawCard.c dominion.o rngs.o $(CFLAGS) + +testAll: dominion.o testSuite.c + gcc -o testSuite testSuite.c -g 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/turnerty/dominion/READM.md b/projects/turnerty/dominion/READM.md new file mode 100644 index 00000000..c3599f6a --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/badTestDrawCard b/projects/turnerty/dominion/badTestDrawCard new file mode 100644 index 0000000000000000000000000000000000000000..362cc238c1c401460e9b674c41da7cc146018dcc GIT binary patch literal 29572 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 +#include +#include +#include "rngs.h" + +#define DEBUG 0 +#define NOISY_TEST 1 + +int checkDrawCard(int p, struct gameState *post) { + int r; + + r = drawCard (p, post); +} + +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() * 1000); + checkDrawCard(p, &G); + } + + printf ("ALL TESTS OK\n"); + + exit(0); +} diff --git a/projects/turnerty/dominion/betterTestDrawCard.c b/projects/turnerty/dominion/betterTestDrawCard.c new file mode 100644 index 00000000..befb2921 --- /dev/null +++ b/projects/turnerty/dominion/betterTestDrawCard.c @@ -0,0 +1,70 @@ +#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) { + int r; + + r = drawCard (p, post); + + assert (r == 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); + + printf ("SIMPLE FIXED TESTS.\n"); + for (p = 0; p < 2; p++) { + for (deckCount = 0; deckCount < 5; deckCount++) { + for (discardCount = 0; discardCount < 5; discardCount++) { + for (handCount = 0; handCount < 5; handCount++) { + memset(&G, 23, sizeof(struct gameState)); + r = initializeGame(2, k, 1, &G); + G.deckCount[p] = deckCount; + memset(G.deck[p], 0, sizeof(int) * deckCount); + G.discardCount[p] = discardCount; + memset(G.discard[p], 0, sizeof(int) * discardCount); + G.handCount[p] = handCount; + memset(G.hand[p], 0, sizeof(int) * handCount); + checkDrawCard(p, &G); + } + } + } + } + + return 0; +} diff --git a/projects/turnerty/dominion/dominion.c b/projects/turnerty/dominion/dominion.c new file mode 100644 index 00000000..88f32414 --- /dev/null +++ b/projects/turnerty/dominion/dominion.c @@ -0,0 +1,1333 @@ +#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) //+2 coins + { + state->coins = state->coins + 2; + } + + else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 + { + //discard hand + while(numHandCards(state) > 0) + { + discardCard(handPos, currentPlayer, state, 0); + } + + //draw 4 + for (i = 0; i < 4; i++) + { + drawCard(currentPlayer, state); + } + + //other players discard hand and redraw if hand size > 4 + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + if ( state->handCount[i] > 4 ) + { + //discard hand + while( state->handCount[i] > 0 ) + { + discardCard(handPos, i, state, 0); + } + + //draw 4 + for (j = 0; j < 4; j++) + { + drawCard(i, state); + } + } + } + } + + } + return 0; + + case steward: + if (choice1 == 1) + { + //+2 cards + drawCard(currentPlayer, state); + drawCard(currentPlayer, state); + } + else if (choice1 == 2) + { + //+2 coins + state->coins = state->coins + 2; + } + else + { + //trash 2 cards in hand + discardCard(choice2, currentPlayer, state, 1); + discardCard(choice3, currentPlayer, state, 1); + } + + //discard card from hand + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case tribute: + if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){ + if (state->deckCount[nextPlayer] > 0){ + tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deckCount[nextPlayer]--; + } + else if (state->discardCount[nextPlayer] > 0){ + tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; + state->discardCount[nextPlayer]--; + } + else{ + //No Card to Reveal + if (DEBUG){ + printf("No cards to reveal\n"); + } + } + } + + else{ + if (state->deckCount[nextPlayer] == 0){ + for (i = 0; i < state->discardCount[nextPlayer]; i++){ + state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck + state->deckCount[nextPlayer]++; + state->discard[nextPlayer][i] = -1; + state->discardCount[nextPlayer]--; + } + + shuffle(nextPlayer,state);//Shuffle the deck + } + tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; + state->deckCount[nextPlayer]--; + tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; + state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; + state->deckCount[nextPlayer]--; + } + + if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one + state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; + state->playedCardCount++; + tributeRevealedCards[1] = -1; + } + + for (i = 0; i <= 2; i ++){ + if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards + state->coins += 2; + } + + else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found + drawCard(currentPlayer, state); + drawCard(currentPlayer, state); + } + else{//Action Card + state->numActions = state->numActions + 2; + } + } + + return 0; + + case ambassador: + j = 0; //used to check if player has enough cards to discard + + if (choice2 > 2 || choice2 < 0) + { + return -1; + } + + if (choice1 == handPos) + { + return -1; + } + + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) + { + j++; + } + } + if (j < choice2) + { + return -1; + } + + if (DEBUG) + printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); + + //increase supply count for choosen card by amount being discarded + state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; + + //each other player gains a copy of revealed card + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + gainCard(state->hand[currentPlayer][choice1], state, 0, i); + } + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + //trash copies of cards returned to supply + for (j = 0; j < choice2; j++) + { + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) + { + discardCard(i, currentPlayer, state, 1); + break; + } + } + } + + return 0; + + case cutpurse: + + updateCoins(currentPlayer, state, 2); + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + for (j = 0; j < state->handCount[i]; j++) + { + if (state->hand[i][j] == copper) + { + discardCard(j, i, state, 0); + break; + } + if (j == state->handCount[i]) + { + for (k = 0; k < state->handCount[i]; k++) + { + if (DEBUG) + printf("Player %d reveals card number %d\n", i, state->hand[i][k]); + } + break; + } + } + + } + + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + return 0; + + + case embargo: + //+2 Coins + state->coins = state->coins + 2; + + //see if selected pile is in play + if ( state->supplyCount[choice1] == -1 ) + { + return -1; + } + + //add embargo token to selected supply pile + state->embargoTokens[choice1]++; + + //trash card + discardCard(handPos, currentPlayer, state, 1); + return 0; + + case outpost: + //set outpost flag + state->outpostPlayed++; + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case salvager: + //+1 buy + state->numBuys++; + + if (choice1) + { + //gain coins equal to trashed card + state->coins = state->coins + getCost( handCard(choice1, state) ); + //trash card + discardCard(choice1, currentPlayer, state, 1); + } + + //discard card + discardCard(handPos, currentPlayer, state, 0); + return 0; + + case sea_hag: + for (i = 0; i < state->numPlayers; i++){ + if (i != currentPlayer){ + state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; state->deckCount[i]--; + state->discardCount[i]++; + state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse + } + } + return 0; + + case treasure_map: + //search hand for another treasure_map + index = -1; + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == treasure_map && i != handPos) + { + index = i; + break; + } + } + if (index > -1) + { + //trash both treasure cards + discardCard(handPos, currentPlayer, state, 1); + discardCard(index, currentPlayer, state, 1); + + //gain 4 Gold cards + for (i = 0; i < 4; i++) + { + gainCard(gold, state, 1, currentPlayer); + } + + //return success + return 1; + } + + //no second treasure_map found in hand + return -1; + } + + return -1; +} + +int 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/turnerty/dominion/dominion.h b/projects/turnerty/dominion/dominion.h new file mode 100644 index 00000000..050eed97 --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/dominion_helpers.h b/projects/turnerty/dominion/dominion_helpers.h new file mode 100644 index 00000000..8bcf1a18 --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/interface.c b/projects/turnerty/dominion/interface.c new file mode 100644 index 00000000..d508824a --- /dev/null +++ b/projects/turnerty/dominion/interface.c @@ -0,0 +1,363 @@ +/* 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/turnerty/dominion/interface.h b/projects/turnerty/dominion/interface.h new file mode 100644 index 00000000..67b55dce --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/playdom b/projects/turnerty/dominion/playdom new file mode 100644 index 0000000000000000000000000000000000000000..0134b6035238caeccc30cecb7bd3742a99e35b7b GIT binary patch literal 86888 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 Q)?a+%{(rZOn&+qg4SN`GGynhq literal 0 HcmV?d00001 diff --git a/projects/turnerty/dominion/playdom.c b/projects/turnerty/dominion/playdom.c new file mode 100644 index 00000000..e79035ef --- /dev/null +++ b/projects/turnerty/dominion/playdom.c @@ -0,0 +1,134 @@ +#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/turnerty/dominion/player b/projects/turnerty/dominion/player new file mode 100644 index 0000000000000000000000000000000000000000..7ccb2f8e026c2b5401c6ec66d62e1aeb73aafde9 GIT binary patch literal 108236 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 Q^D@$%hGpdcbCbI9-|qt63jhEB literal 0 HcmV?d00001 diff --git a/projects/turnerty/dominion/player.c b/projects/turnerty/dominion/player.c new file mode 100644 index 00000000..0f3cb992 --- /dev/null +++ b/projects/turnerty/dominion/player.c @@ -0,0 +1,217 @@ +/* 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/turnerty/dominion/rngs.c b/projects/turnerty/dominion/rngs.c new file mode 100644 index 00000000..3a2510a3 --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/rngs.h b/projects/turnerty/dominion/rngs.h new file mode 100644 index 00000000..4bc7c06e --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/rt.c b/projects/turnerty/dominion/rt.c new file mode 100644 index 00000000..79da137c --- /dev/null +++ b/projects/turnerty/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/turnerty/dominion/supplyTest.c b/projects/turnerty/dominion/supplyTest.c new file mode 100644 index 00000000..c58a47ec --- /dev/null +++ b/projects/turnerty/dominion/supplyTest.c @@ -0,0 +1,30 @@ +#include "dominion.h" +#include "dominion_helpers.h" +#include +#include +#include +#include "rngs.h" + +#define DEBUG 0 +#define NOISY_TEST 1 + +int main () { + + int r; + + int k[10] = {adventurer, council_room, feast, gardens, mine, + remodel, smithy, village, baron, great_hall}; + + struct gameState G; + + r = initializeGame(4, k, 1, &G); + + printf ("initializeGame(4, k, 1, &G) = %d\n", r); + assert(r == 0); + + r = supplyCount(adventurer, &G); + printf ("supplyCount(adventurer, &G) = %d\n", r); + assert(r == 10); + + return 0; +} diff --git a/projects/turnerty/dominion/testBuyCard.c b/projects/turnerty/dominion/testBuyCard.c new file mode 100644 index 00000000..e82049ea --- /dev/null +++ b/projects/turnerty/dominion/testBuyCard.c @@ -0,0 +1,94 @@ +#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 buyCard.\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); + + printf ("SIMPLE FIXED TESTS.\n"); + for (p = 0; p < 2; p++) { + for (deckCount = 0; deckCount < 5; deckCount++) { + for (discardCount = 0; discardCount < 5; discardCount++) { + for (handCount = 0; handCount < 5; handCount++) { + memset(&G, 23, sizeof(struct gameState)); + r = initializeGame(2, k, 1, &G); + G.deckCount[p] = deckCount; + memset(G.deck[p], 0, sizeof(int) * deckCount); + G.discardCount[p] = discardCount; + memset(G.discard[p], 0, sizeof(int) * discardCount); + G.handCount[p] = handCount; + memset(G.hand[p], 0, sizeof(int) * handCount); + checkDrawCard(p, &G); + } + } + } + } + + return 0; +} diff --git a/projects/turnerty/dominion/testDrawCard.c b/projects/turnerty/dominion/testDrawCard.c new file mode 100644 index 00000000..526bd3bb --- /dev/null +++ b/projects/turnerty/dominion/testDrawCard.c @@ -0,0 +1,93 @@ +#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); + + printf ("SIMPLE FIXED TESTS.\n"); + for (p = 0; p < 2; p++) { + for (deckCount = 0; deckCount < 5; deckCount++) { + for (discardCount = 0; discardCount < 5; discardCount++) { + for (handCount = 0; handCount < 5; handCount++) { + memset(&G, 23, sizeof(struct gameState)); + r = initializeGame(2, k, 1, &G); + G.deckCount[p] = deckCount; + memset(G.deck[p], 0, sizeof(int) * deckCount); + G.discardCount[p] = discardCount; + memset(G.discard[p], 0, sizeof(int) * discardCount); + G.handCount[p] = handCount; + memset(G.hand[p], 0, sizeof(int) * handCount); + checkDrawCard(p, &G); + } + } + } + } + + return 0; +} diff --git a/projects/turnerty/dominion/testInit.c b/projects/turnerty/dominion/testInit.c new file mode 100644 index 00000000..1c48d217 --- /dev/null +++ b/projects/turnerty/dominion/testInit.c @@ -0,0 +1,56 @@ +#include "dominion.h" +#include +#include +#include "rngs.h" + +int main (int argc, char** argv) { + + struct gameState G; + + int i; + + int start = -1; + + int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, + sea_hag, tribute, smithy}; + + memset(&G, 'z', sizeof(struct gameState)); + + initializeGame(4, k, atoi(argv[1]), &G); + + printf ("Rough guide to locations in structure:\n"); + printf ("0: numPlayers\n"); + printf ("%ld: supplyCount[0]\n", ((long)&(G.supplyCount[0]))-((long)&G)); + printf ("%ld: embargoTokens[0]\n", ((long)&(G.embargoTokens[0]))-((long)&G)); + printf ("%ld: hand[0][0]\n", ((long)&(G.hand[0][0]))-(long)(&G)); + printf ("%ld: deck[0][0]\n", ((long)&(G.deck[0][0]))-(long)(&G)); + printf ("%ld: discard[0][0]\n", ((long)&(G.discard[0][0]))-(long)(&G)); + printf ("%ld: playerCards[0]\n", ((long)&(G.playedCards[0]))-(long)(&G)); + + for (i = 0; i < sizeof(struct gameState); i++) { + if (((char*)&G)[i] == 'z') { + if (start == -1) { + start = i; + } + } else{ + if (start != -1) { + if (start == (i-1)) { + printf ("Byte %d uninitialized.\n", start); + } else { + printf ("Bytes %d-%d uninitialized.\n", start, i-1); + } + start = -1; + } + } + } + + if (start != -1) { + if (start == (i-1)) { + printf ("Byte %d uninitialized.\n", start); + } else { + printf ("Bytes %d-%d uninitialized.\n", start, i-1); + } + } + + return 0; +} diff --git a/projects/turnerty/dominion/testShuffle.c b/projects/turnerty/dominion/testShuffle.c new file mode 100644 index 00000000..c1fcc7c0 --- /dev/null +++ b/projects/turnerty/dominion/testShuffle.c @@ -0,0 +1,27 @@ +#include "dominion.h" +#include +#include + +int compare(const int* a, const int* b); + +int main () { + struct gameState G; + struct gameState G2; + + // Initialize G. + + memcpy (&G2, &G, sizeof(struct gameState)); + + int ret = shuffle(0,&G); + + if (G.deckCount[0] > 0) { + assert (ret != -1); + + qsort ((void*)(G.deck[0]), G.deckCount[0], sizeof(int), compare); + qsort ((void*)(G2.deck[0]), G2.deckCount[0], sizeof(int), compare); + } else + assert (ret == -1); + + assert(memcmp(&G, &G2, sizeof(struct gameState)) == 0); + +} From dc6e2d91dac726baba9039378493788458c2ce57 Mon Sep 17 00:00:00 2001 From: Tyler Turner Date: Sun, 7 Jul 2019 19:23:16 -0700 Subject: [PATCH 2/3] refactor done --- projects/turnerty/dominion/dominion.c | 726 ++++++++++++++------------ projects/turnerty/dominion/dominion.h | 12 +- 2 files changed, 397 insertions(+), 341 deletions(-) diff --git a/projects/turnerty/dominion/dominion.c b/projects/turnerty/dominion/dominion.c index 88f32414..916a52ac 100644 --- a/projects/turnerty/dominion/dominion.c +++ b/projects/turnerty/dominion/dominion.c @@ -39,11 +39,11 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, int i; int j; - int it; + int it; //set up random number generator SelectStream(1); PutSeed((long)randomSeed); - + //check number of players if (numPlayers > MAX_PLAYERS || numPlayers < 2) { @@ -112,8 +112,8 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, //check if card is a 'Victory' Kingdom card if (kingdomCards[j] == great_hall || kingdomCards[j] == gardens) { - if (numPlayers == 2){ - state->supplyCount[i] = 8; + if (numPlayers == 2){ + state->supplyCount[i] = 8; } else{ state->supplyCount[i] = 12; } } @@ -146,7 +146,7 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, for (j = 3; j < 10; j++) { state->deck[i][j] = copper; - state->deckCount[i]++; + state->deckCount[i]++; } } @@ -161,7 +161,7 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, //draw player hands for (i = 0; i < numPlayers; i++) - { + { //initialize hand size to zero state->handCount[i] = 0; state->discardCount[i] = 0; @@ -171,7 +171,7 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, // drawCard(i, state); // } } - + //set embargo tokens to 0 for all supply piles for (i = 0; i <= treasure_map; i++) { @@ -199,7 +199,7 @@ int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed, } int shuffle(int player, struct gameState *state) { - + int newDeck[MAX_DECK]; int newDeckPos = 0; @@ -208,7 +208,7 @@ int shuffle(int player, struct gameState *state) { if (state->deckCount[player] < 1) return -1; - qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); + qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); /* SORT CARDS IN DECK TO ENSURE DETERMINISM! */ while (state->deckCount[player] > 0) { @@ -228,8 +228,8 @@ int shuffle(int player, struct gameState *state) { return 0; } -int playCard(int handPos, int choice1, int choice2, int choice3, struct gameState *state) -{ +int playCard(int handPos, int choice1, int choice2, int choice3, struct gameState *state) +{ int card; int coin_bonus = 0; //tracks coins gain from actions @@ -238,34 +238,34 @@ int playCard(int handPos, int choice1, int choice2, int choice3, struct gameStat { 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; } @@ -288,14 +288,14 @@ int buyCard(int supplyPos, struct gameState *state) { printf("There are not any of that type of card left\n"); return -1; } else if (state->coins < getCost(supplyPos)){ - if (DEBUG) + 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) @@ -304,7 +304,7 @@ int buyCard(int supplyPos, struct gameState *state) { //state->discard[who][state->discardCount[who]] = supplyPos; //state->discardCount[who]++; - + return 0; } @@ -351,16 +351,16 @@ 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)){ + if (currentPlayer < (state->numPlayers - 1)){ state->whoseTurn = currentPlayer + 1;//Still safe to increment } else{ @@ -390,7 +390,7 @@ int endTurn(struct gameState *state) { int isGameOver(struct gameState *state) { int i; int j; - + //if stack of Province cards is empty, the game ends if (state->supplyCount[province] == 0) { @@ -455,7 +455,7 @@ int scoreFor (int player, struct gameState *state) { } int getWinners(int players[MAX_PLAYERS], struct gameState *state) { - int i; + int i; int j; int highScore; int currentPlayer; @@ -526,7 +526,7 @@ 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 @@ -540,20 +540,20 @@ int drawCard(int player, struct gameState *state) //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) @@ -582,7 +582,7 @@ int drawCard(int player, struct gameState *state) int getCost(int cardNumber) { - switch( cardNumber ) + switch( cardNumber ) { case curse: return 0; @@ -628,7 +628,7 @@ int getCost(int cardNumber) return 3; case cutpurse: return 4; - case embargo: + case embargo: return 2; case outpost: return 5; @@ -639,7 +639,7 @@ int getCost(int cardNumber) case treasure_map: return 4; } - + return -1; } @@ -661,10 +661,10 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState if (nextPlayer > (state->numPlayers - 1)){ nextPlayer = 0; } - - + + //uses switch to select card and perform actions - switch( card ) + switch( card ) { case adventurer: while(drawntreasure<2){ @@ -686,17 +686,17 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState 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++) { @@ -705,12 +705,12 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState 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 @@ -753,7 +753,7 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } } - } + } //Reset Hand for (i = 0; i <= state->handCount[currentPlayer]; i++){ @@ -761,47 +761,16 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState 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; - } - } - + case mine: + mine(choice1, choice2, state); return 0; - + case remodel: j = state->hand[currentPlayer][choice1]; //store card we will trash @@ -820,149 +789,56 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState { if (state->hand[currentPlayer][i] == j) { - discardCard(i, currentPlayer, state, 0); + 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); - } - } - } - - + baron(choice1, state); return 0; - + + case great_hall: //+1 Card drawCard(currentPlayer, state); - + //+1 Actions state->numActions++; - + //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; - + case minion: - //+1 action - state->numActions++; - - //discard card from hand - discardCard(handPos, currentPlayer, state, 0); - - if (choice1) //+2 coins - { - state->coins = state->coins + 2; - } - - else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 - { - //discard hand - while(numHandCards(state) > 0) - { - discardCard(handPos, currentPlayer, state, 0); - } - - //draw 4 - for (i = 0; i < 4; i++) - { - drawCard(currentPlayer, state); - } - - //other players discard hand and redraw if hand size > 4 - for (i = 0; i < state->numPlayers; i++) - { - if (i != currentPlayer) - { - if ( state->handCount[i] > 4 ) - { - //discard hand - while( state->handCount[i] > 0 ) - { - discardCard(handPos, i, state, 0); - } - - //draw 4 - for (j = 0; j < 4; j++) - { - drawCard(i, state); - } - } - } - } - - } + minion(handPos, choice1, choice2, state); return 0; - + case steward: if (choice1 == 1) { @@ -981,128 +857,19 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState 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; - } - } - + case tribute: + tribute(state); 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; - } - } - } + case ambassador: + ambassador(handPos, choice1, choice2, state); return 0; - + case cutpurse: updateCoins(currentPlayer, state, 2); @@ -1123,62 +890,62 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState { 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); + discardCard(handPos, currentPlayer, state, 0); return 0; - - case embargo: + + 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); + 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); + 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){ @@ -1188,7 +955,7 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState } } return 0; - + case treasure_map: //search hand for another treasure_map index = -1; @@ -1211,32 +978,32 @@ int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState { 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 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->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 { @@ -1248,7 +1015,7 @@ int discardCard(int handPos, int currentPlayer, struct gameState *state, int tra //reduce number of cards in hand state->handCount[currentPlayer]--; } - else + else { //replace discarded card with last card in hand state->hand[currentPlayer][handPos] = state->hand[currentPlayer][ (state->handCount[currentPlayer] - 1)]; @@ -1257,20 +1024,20 @@ int discardCard(int handPos, int currentPlayer, struct gameState *state, int tra //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 @@ -1291,17 +1058,17 @@ int gainCard(int supplyPos, struct gameState *state, int toFlag, int player) 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; @@ -1319,8 +1086,8 @@ int updateCoins(int player, struct gameState *state, int bonus) else if (state->hand[player][i] == gold) { state->coins += 3; - } - } + } + } //add bonus state->coins += bonus; @@ -1328,6 +1095,285 @@ int updateCoins(int player, struct gameState *state, int bonus) return 0; } +int baron(int choice, struct gameSate *state) +{ + int currentPlayer = whoseTurn(state); + state->numBuys++;//Increase buys by 1! + if (choice > 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 + } -//end of dominion.c + 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; +} + +int minion(int handPos, int choice1, int choice2, struct gameState *state) +{ + int currentPlayer = whoseTurn(state); + int i; + int j; + state->numActions++; + //discard card from hand + discardCard(handPos, currentPlayer, state, 0); + + if (choice1) //+2 coins + { + state->coins = state->coins + 2; + } + + else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 + { + //discard hand + while(numHandCards(state) > 0) + { + discardCard(handPos, currentPlayer, state, 0); + } + + //draw 4 + for (i = 0; i < 4; i++) + { + drawCard(currentPlayer, state); + } + + //other players discard hand and redraw if hand size > 4 + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + if ( state->handCount[i] > 4 ) + { + //discard hand + while( state->handCount[i] > 0 ) + { + discardCard(handPos, i, state, 0); + } + + //draw 4 + for (j = 0; j < 4; j++) + { + drawCard(i, state); + } + } + } + } + } + return 0; +} + +int ambassador(int handPos, int choice1, int choice2, struct gameSate *state) +{ + int i; + int currentPlayer = whoseTurn(state); + int j = 0; //used to check if player has enough cards to discard + + if (choice2 > 2 || choice2 < 0) + { + return -1; + } + + if (choice1 == handPos) + { + return -1; + } + + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) + { + j++; + } + } + if (j < choice2) + { + return -1; + } + + if (DEBUG) + printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); + + //increase supply count for choosen card by amount being discarded + state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; + + //each other player gains a copy of revealed card + for (i = 0; i < state->numPlayers; i++) + { + if (i != currentPlayer) + { + gainCard(state->hand[currentPlayer][choice1], state, 0, i); + } + } + + //discard played card from hand + discardCard(handPos, currentPlayer, state, 0); + + //trash copies of cards returned to supply + for (j = 0; j < choice2; j++) + { + for (i = 0; i < state->handCount[currentPlayer]; i++) + { + if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) + { + discardCard(i, currentPlayer, state, 1); + break; + } + } + } + + return 0; +} + +int tribute(struct gameSate *state); +{ + int i; + int index; + int currentPlayer = whoseTurn(state); + int nextPlayer = currentPlayer + 1; + + int tributeRevealedCards[2] = {-1, -1}; + int cardDrawn; + int z = 0;// this is the counter for the temp hand + if (nextPlayer > (state->numPlayers - 1)){ + nextPlayer = 0; + } + + 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; +} + +int mine(int choice1, int choice2, struct gameState *state) +{ + int currentPlayer = whoseTurn(state); + int j; + + 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; +} +//end of dominion.c diff --git a/projects/turnerty/dominion/dominion.h b/projects/turnerty/dominion/dominion.h index 050eed97..609088a6 100644 --- a/projects/turnerty/dominion/dominion.h +++ b/projects/turnerty/dominion/dominion.h @@ -85,7 +85,7 @@ 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. + are in fact (different) kingdom cards, and that numPlayers is valid. Cards not in game should initialize supply position to -1 */ @@ -128,4 +128,14 @@ int getWinners(int players[MAX_PLAYERS], struct gameState *state); /* Set array position of each player who won (remember ties!) to 1, others to 0 */ +int baron(int choice, struct gameSate *state); + +int minion(int handPos, int choice1, int choice2, struct gameSate *state); + +int ambassador(int handPos, int choice1, int choice2, struct gameState *state); + +int tribute(struct gameState *state); + +int mine(int choice1, int choice2, struct gameSate *state); + #endif From 9a983f168aad7e7120417b122e47237f1d5e131e Mon Sep 17 00:00:00 2001 From: Tyler Turner Date: Sun, 7 Jul 2019 19:49:10 -0700 Subject: [PATCH 3/3] added bugs --- projects/turnerty/dominion/dominion.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/turnerty/dominion/dominion.c b/projects/turnerty/dominion/dominion.c index 916a52ac..03f0cd42 100644 --- a/projects/turnerty/dominion/dominion.c +++ b/projects/turnerty/dominion/dominion.c @@ -1098,16 +1098,15 @@ int updateCoins(int player, struct gameState *state, int bonus) int baron(int choice, struct gameSate *state) { int currentPlayer = whoseTurn(state); - state->numBuys++;//Increase buys by 1! if (choice > 0){//Boolean true or going to discard an estate int p = 0;//Iterator for hand! - int card_not_discarded = 1;//Flag for discard set! + int card_not_discarded = 0;//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++){ + for (p < state->handCount[currentPlayer]; p++){ state->hand[currentPlayer][p] = state->hand[currentPlayer][p+1]; } state->hand[currentPlayer][state->handCount[currentPlayer]] = -1; @@ -1123,7 +1122,7 @@ int baron(int choice, struct gameSate *state) gainCard(estate, state, 0, currentPlayer); state->supplyCount[estate]--;//Decrement estates if (supplyCount(estate, state) == 0){ - isGameOver(state); + isGameOver(state); } } card_not_discarded = 0;//Exit the loop