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 cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus) { int i; int j; int index; int currentPlayer = whoseTurn(state); int nextPlayer = currentPlayer + 1; int tributeRevealedCards[2] = { -1, -1 }; int temphand[MAX_HAND];// moved above the if statement int drawntreasure = 0; int cardDrawn; int z = 0;// this is the counter for the temp hand if (nextPlayer > (state->numPlayers - 1)) { nextPlayer = 0; } //uses switch to select card and perform actions switch (card) { case adventurer: playedCard(handPos, NULL, NULL, state); while (drawntreasure < 2) { if (drawCard(currentPlayer, state) == -1) break; cardDrawn = state->hand[currentPlayer][state->handCount[currentPlayer] - 1];//top card of hand is most recently drawn card. if (cardDrawn == copper || cardDrawn == silver || cardDrawn == gold) drawntreasure++; else { temphand[z] = cardDrawn; state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1; state->handCount[currentPlayer]--; //this should just remove the top card (the most recently drawn one). z++; } } /* MUTANT (rep_const) */ while (z > -1) { state->discard[currentPlayer][state->discardCount[currentPlayer]++] = temphand[z - 1]; // discard all cards in play that have been drawn z--; } endPlayed(state, 0); return 0; case council_room: return councilRoomEffect(currentPlayer, handPos, state); case feast: if (choice1 < curse || choice1 > treasure_map) return -1; if (supplyCount(choice1, state) <= 0) { if (DEBUG) printf("None of that card left, sorry!\n"); if (DEBUG) { printf("Cards Left: %d\n", supplyCount(choice1, state)); } return -1; } else if (5 < getCost(choice1)) { if (DEBUG) { printf("That card is too expensive!\n"); printf("Coins: %d < %d\n", state->coins, getCost(choice1)); } return -1; } playedCard(handPos, NULL, NULL, state); if (DEBUG) { printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]); } gainCard(choice1, state, 0, currentPlayer);//Gain the card if (DEBUG) { printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]); } //trash feast endPlayed(state, 1); return 0; case gardens: return -1; case mine: if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos) return -1; j = state->hand[currentPlayer][choice1]; //store card we will trash if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold) { return -1; } if (choice2 > gold || choice2 < copper) { return -1; } if ((getCost(state->hand[currentPlayer][choice1]) + 3) > getCost(choice2)) { return -1; } playedCard(handPos, &choice1, NULL, state); //trash old treasure discardCard(choice1, currentPlayer, state, 1); //gain new treasure gainCard(choice2, state, 2, currentPlayer); endPlayed(state, 0); return 0; case remodel: if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos) return -1; if (choice2 < curse || choice2 > treasure_map) return -1; if ((getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2)) { return -1; } playedCard(handPos, &choice1, NULL, state); //trash choice discardCard(choice1, currentPlayer, state, 1); //gain new card gainCard(choice2, state, 0, currentPlayer); endPlayed(state, 0); return 0; case smithy: return smithyEffect(currentPlayer, handPos, state); case village: return villageEffect(currentPlayer, handPos, state); case baron: if (!(choice1 == 1 || choice1 == 2)) return -1; if (choice1 == 1) {//Boolean true or going to discard an estate int p = 0;//Iterator for hand! int card_not_discarded = 1;//Flag for discard set! while (card_not_discarded) { if (p >= state->handCount[currentPlayer]) { if (DEBUG) { printf("No estate cards in your hand, invalid choice\n"); } return -1; } else if (state->hand[currentPlayer][p] == estate) {//Found an estate card! playedCard(handPos, &p, NULL, state); *bonus += 4;//Add 4 coins to the amount of coins discardCard(p, currentPlayer, state, 0); card_not_discarded = 0;//Exit the loop } else { p++;//Next card } } } else { playedCard(handPos, NULL, NULL, state); gainCard(estate, state, 0, currentPlayer);//Gain an estate } state->numBuys++;//Increase buys by 1! endPlayed(state, 0); return 0; case great_hall: return greatHallEffect(currentPlayer, handPos, state); case minion: if (!(choice1 == 1 || choice1 == 2)) return -1; playedCard(handPos, NULL, NULL, state); //+1 action state->numActions++; if (choice1 == 1) //+2 coins { *bonus += 2; } else if (choice1 == 2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 { //discard hand while (numHandCards(state) > 0) { discardCard(0, currentPlayer, state, 0); } //draw 4 for (i = 0; i < 4; i++) { drawCard(currentPlayer, state); } //other players discard hand and redraw if hand size > 4 for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { if (state->handCount[i] > 4) { //discard hand while (state->handCount[i] > 0) { discardCard(0, i, state, 0); } //draw 4 for (j = 0; j < 4; j++) { drawCard(i, state); } } } } } endPlayed(state, 0); return 0; case steward: if (!(choice1 == 1 || choice1 == 2 || choice1 == 3)) return -1; if (choice1 == 3 && ((choice2 >= state->handCount[currentPlayer] || choice2 < 0) || (choice3 >= state->handCount[currentPlayer] || choice3 < 0) || choice2 == choice3 || (choice2 == handPos || choice3 == handPos))) return -1; if (choice1 == 1) { playedCard(handPos, NULL, NULL, state); //+2 cards drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else if (choice1 == 2) { //+2 coins playedCard(handPos, NULL, NULL, state); *bonus += 2; } else { playedCard(handPos, &choice2, &choice3, state); //trash 2 cards in hand if (choice2 < choice3) { int tmp = choice2; choice2 = choice3; choice3 = tmp; } //discard order matters, must discard max to min for correct effect discardCard(choice2, currentPlayer, state, 1); discardCard(choice3, currentPlayer, state, 1); } endPlayed(state, 0); return 0; case tribute: playedCard(handPos, NULL, NULL, state); if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { if (state->deckCount[nextPlayer] > 0) { tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer] - 1]; state->deckCount[nextPlayer]--; state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[0]; state->discardCount[nextPlayer]++; } else if (state->discardCount[nextPlayer] > 0) { tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer] - 1]; } else { //No Card to Reveal if (DEBUG) { printf("No cards to reveal\n"); } endPlayed(state, 0); return 0; } } else { if (state->deckCount[nextPlayer] == 0) { j = state->discardCount[nextPlayer]; for (i = 0; i < j; i++) { state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck state->deckCount[nextPlayer]++; state->discard[nextPlayer][i] = -1; state->discardCount[nextPlayer]--; } shuffle(nextPlayer, state);//Shuffle the deck } tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer] - 1]; state->deck[nextPlayer][state->deckCount[nextPlayer] - 1] = -1; state->deckCount[nextPlayer]--; if (state->deckCount[nextPlayer] == 0) { j = state->discardCount[nextPlayer]; for (i = 0; i < j; i++) { state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck state->deckCount[nextPlayer]++; state->discard[nextPlayer][i] = -1; state->discardCount[nextPlayer]--; } shuffle(nextPlayer, state);//Shuffle the deck } state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[0]; state->discardCount[nextPlayer]++; tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer] - 1]; state->deck[nextPlayer][state->deckCount[nextPlayer] - 1] = -1; state->deckCount[nextPlayer]--; state->discard[nextPlayer][state->discardCount[nextPlayer]] = tributeRevealedCards[1]; state->discardCount[nextPlayer]++; } if (tributeRevealedCards[0] == tributeRevealedCards[1]) {//If we have a duplicate card, just drop one tributeRevealedCards[1] = -1; } for (i = 0; i < 2; i++) { if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) {//Treasure cards *bonus += 2; } if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall) {//Victory Card Found drawCard(currentPlayer, state); drawCard(currentPlayer, state); } if (tributeRevealedCards[i] >= adventurer && tributeRevealedCards[i] <= treasure_map){//Action Card state->numActions = state->numActions + 2; } } endPlayed(state, 0); return 0; case ambassador: j = 0; //used to check if player has enough cards to discard if (choice2 > 2 || choice2 < 0) { return -1; } if (choice1 == handPos || choice1 >= numHandCards(state) || choice1 < 0) { return -1; } for (i = 0; i < state->handCount[currentPlayer]; i++) { if (i != handPos && i == state->hand[currentPlayer][choice1]) { j++; } } if (j < choice2) { return -1; } playedCard(handPos, &choice1, NULL, state); if (DEBUG) printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); //increase supply count for choosen card by amount being discarded state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; //each other player gains a copy of revealed card for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { gainCard(state->hand[currentPlayer][choice1], state, 0, i); } } //trash copies of cards returned to supply for (j = 0; j < choice2; j++) { for (i = state->handCount[currentPlayer] - 1; i >= 0; i--) { if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) { discardCard(i, currentPlayer, state, 1); break; } } } endPlayed(state, 0); return 0; case cutpurse: return cutpurseEffect(currentPlayer, handPos, state, bonus); case embargo: if (choice1 < curse || choice1 > treasure_map) return -1; //see if selected pile is in play if (state->supplyCount[choice1] == -1) { return -1; } playedCard(handPos, NULL, NULL, state); //+2 Coins *bonus += 2; //add embargo token to selected supply pile state->embargoTokens[choice1]++; //trash card endPlayed(state, 1); return 0; case outpost: if (state->outpostTurn == 1) return -1; playedCard(handPos, NULL, NULL, state); //set outpost flag state->outpostPlayed = 1; //we actually don't call endPlayed() here on purpose return 0; case salvager: if (choice1 >= state->handCount[currentPlayer] || choice1 < 0 || choice1 == handPos) return -1; playedCard(handPos, &choice1, NULL, state); //+1 buy state->numBuys++; //gain coins equal to trashed card *bonus += getCost(handCard(choice1, state)); //trash card discardCard(choice1, currentPlayer, state, 1); endPlayed(state, 0); return 0; case sea_hag: playedCard(handPos, NULL, NULL, state); for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { if (state->deckCount[i] + state->discardCount[i] > 0) { if (state->deckCount[i] == 0) { j = state->discardCount[i]; for (index = 0; index < j; index++) { state->deck[i][index] = state->discard[i][index];//Move to deck state->deckCount[i]++; state->discard[i][index] = -1; state->discardCount[i]--; } shuffle(i, state);//Shuffle the deck } state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i] - 1]; state->discardCount[i]++; //conveniently, this happens to add it to the top of the deck gainCard(curse, state, 1, i); } else { //literally no cards in their deck or discard, so they just get a curse in their deck gainCard(curse, state, 1, i); } } } endPlayed(state, 0); return 0; case treasure_map: //search hand for another treasure_map index = -1; for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == treasure_map && i != handPos) { index = i; break; } } if (index > -1){ playedCard(handPos, &index, NULL, state); //trash other treasure_map discardCard(index, currentPlayer, state, 1); //gain 4 Gold cards for (i = 0; i < 4; i++) { gainCard(gold, state, 1, currentPlayer); } } else { return -1; } endPlayed(state, 1); return 0; } return -1; }
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus) { int i; int j; int k; int index; int currentPlayer = whoseTurn(state); int nextPlayer = currentPlayer + 1; int tributeRevealedCards[2] = {-1, -1}; int drawntreasure=0; if (nextPlayer > (state->numPlayers - 1)){ nextPlayer = 0; } //uses switch to select card and perform actions switch( card ) { case adventurer: return adventurerCard (drawntreasure, state, currentPlayer); case council_room: return councilRoomCard (currentPlayer, state, handPos); case feast: return feastCard (currentPlayer, state, choice1); case gardens: return -1; case mine: return mineCard (currentPlayer, state, choice1, choice2, handPos); case remodel: return remodelCard (currentPlayer, state, choice1, choice2, handPos); case smithy: //+3 Cards for (i = 0; i < 3; i++) { drawCard(currentPlayer, state); } //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case village: //+1 Card drawCard(currentPlayer, state); //+2 Actions state->numActions = state->numActions + 2; //discard played card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case baron: state->numBuys++;//Increase buys by 1! if (choice1 > 0){//Boolean true or going to discard an estate int p = 0;//Iterator for hand! int card_not_discarded = 1;//Flag for discard set! while(card_not_discarded){ if (state->hand[currentPlayer][p] == estate){//Found an estate card! state->coins += 4;//Add 4 coins to the amount of coins state->discard[currentPlayer][state->discardCount[currentPlayer]] = state->hand[currentPlayer][p]; state->discardCount[currentPlayer]++; for (;p < state->handCount[currentPlayer]; p++){ state->hand[currentPlayer][p] = state->hand[currentPlayer][p+1]; } state->hand[currentPlayer][state->handCount[currentPlayer]] = -1; state->handCount[currentPlayer]--; card_not_discarded = 0;//Exit the loop } else if (p > state->handCount[currentPlayer]){ if(DEBUG) { printf("No estate cards in your hand, invalid choice\n"); printf("Must gain an estate if there are any\n"); } if (supplyCount(estate, state) > 0){ gainCard(estate, state, 0, currentPlayer); state->supplyCount[estate]--;//Decrement estates if (supplyCount(estate, state) == 0){ isGameOver(state); } } card_not_discarded = 0;//Exit the loop } else{ p++;//Next card } } } else{ if (supplyCount(estate, state) > 0){ gainCard(estate, state, 0, currentPlayer);//Gain an estate state->supplyCount[estate]--;//Decrement Estates if (supplyCount(estate, state) == 0){ isGameOver(state); } } } return 0; case great_hall: //+1 Card drawCard(currentPlayer, state); //+1 Actions state->numActions++; //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case minion: //+1 action state->numActions++; //discard card from hand discardCard(handPos, currentPlayer, state, 0); if (choice1) //+2 coins { state->coins = state->coins + 2; } else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4 { //discard hand while(numHandCards(state) > 0) { discardCard(handPos, currentPlayer, state, 0); } //draw 4 for (i = 0; i < 4; i++) { drawCard(currentPlayer, state); } //other players discard hand and redraw if hand size > 4 for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { if ( state->handCount[i] > 4 ) { //discard hand while( state->handCount[i] > 0 ) { discardCard(handPos, i, state, 0); } //draw 4 for (j = 0; j < 4; j++) { drawCard(i, state); } } } } } return 0; case steward: if (choice1 == 1) { //+2 cards drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else if (choice1 == 2) { //+2 coins state->coins = state->coins + 2; } else { //trash 2 cards in hand discardCard(choice2, currentPlayer, state, 1); discardCard(choice3, currentPlayer, state, 1); } //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case tribute: if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){ if (state->deckCount[nextPlayer] > 0){ tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deckCount[nextPlayer]--; } else if (state->discardCount[nextPlayer] > 0){ tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; state->discardCount[nextPlayer]--; } else{ //No Card to Reveal if (DEBUG){ printf("No cards to reveal\n"); } } } else{ if (state->deckCount[nextPlayer] == 0){ for (i = 0; i < state->discardCount[nextPlayer]; i++){ state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck state->deckCount[nextPlayer]++; state->discard[nextPlayer][i] = -1; state->discardCount[nextPlayer]--; } shuffle(nextPlayer,state);//Shuffle the deck } tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; } if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; state->playedCardCount++; tributeRevealedCards[1] = -1; } for (i = 0; i <= 2; i ++){ if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards state->coins += 2; } else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else{//Action Card state->numActions = state->numActions + 2; } } return 0; case ambassador: j = 0; //used to check if player has enough cards to discard if (choice2 > 2 || choice2 < 0) { return -1; } if (choice1 == handPos) { return -1; } for (i = 0; i < state->handCount[currentPlayer]; i++) { if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) { j++; } } if (j < choice2) { return -1; } if (DEBUG) printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); //increase supply count for choosen card by amount being discarded state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; //each other player gains a copy of revealed card for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { gainCard(state->hand[currentPlayer][choice1], state, 0, i); } } //discard played card from hand discardCard(handPos, currentPlayer, state, 0); //trash copies of cards returned to supply for (j = 0; j < choice2; j++) { for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) { discardCard(i, currentPlayer, state, 1); break; } } } return 0; case cutpurse: updateCoins(currentPlayer, state, 2); for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { for (j = 0; j < state->handCount[i]; j++) { if (state->hand[i][j] == copper) { discardCard(j, i, state, 0); break; } if (j == state->handCount[i]) { for (k = 0; k < state->handCount[i]; k++) { if (DEBUG) printf("Player %d reveals card number %d\n", i, state->hand[i][k]); } break; } } } } //discard played card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case embargo: //+2 Coins state->coins = state->coins + 2; //see if selected pile is in play if ( state->supplyCount[choice1] == -1 ) { return -1; } //add embargo token to selected supply pile state->embargoTokens[choice1]++; //trash card discardCard(handPos, currentPlayer, state, 1); return 0; case outpost: //set outpost flag state->outpostPlayed++; //discard card discardCard(handPos, currentPlayer, state, 0); return 0; case salvager: //+1 buy state->numBuys++; if (choice1) { //gain coins equal to trashed card state->coins = state->coins + getCost( handCard(choice1, state) ); //trash card discardCard(choice1, currentPlayer, state, 1); } //discard card discardCard(handPos, currentPlayer, state, 0); return 0; case sea_hag: for (i = 0; i < state->numPlayers; i++){ if (i != currentPlayer){ state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]-1]; state->discardCount[i]++; state->deck[i][state->deckCount[i]-1] = curse;//Top card now a curse } } return 0; case treasure_map: //search hand for another treasure_map index = -1; for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == treasure_map && i != handPos) { index = i; break; } } if (index > -1) { //trash both treasure cards discardCard(handPos, currentPlayer, state, 1); discardCard(index, currentPlayer, state, 1); //gain 4 Gold cards for (i = 0; i < 4; i++) { gainCard(gold, state, 1, currentPlayer); } //return success return 1; } //no second treasure_map found in hand return -1; } return -1; }
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus) { int i; int j; int k; int x; int index; int currentPlayer = whoseTurn(state); int nextPlayer = currentPlayer + 1; int tributeRevealedCards[2] = {-1, -1}; int temphand[MAX_HAND];// moved above the if statement int drawntreasure=0; // int cardDrawn; int z = 0;// this is the counter for the temp hand if (nextPlayer > (state->numPlayers - 1)) { nextPlayer = 0; } //uses switch to select card and perform actions switch( card ) { case adventurer: return adventurerEffect(state, drawntreasure, z, temphand); case council_room: //+4 Cards for (i = 0; i < 4; i++) { drawCard(currentPlayer, state); } //+1 Buy state->numBuys++; //Each other player draws a card for (i = 0; i < state->numPlayers; i++) { if ( i != currentPlayer ) { drawCard(i, state); } } //put played card in played card pile discardCard(handPos, currentPlayer, state, 0); return 0; case feast: //gain card with cost up to 5 //Backup hand for (i = 0; i <= state->handCount[currentPlayer]; i++) { temphand[i] = state->hand[currentPlayer][i];//Backup card state->hand[currentPlayer][i] = -1;//Set to nothing } //Backup hand //Update Coins for Buy updateCoins(currentPlayer, state, 5); x = 1;//Condition to loop on while( x == 1) {//Buy one card if (supplyCount(choice1, state) <= 0) { if (DEBUG) printf("None of that card left, sorry!\n"); if (DEBUG) { printf("Cards Left: %d\n", supplyCount(choice1, state)); } } else if (state->coins < getCost(choice1)) { printf("That card is too expensive!\n"); if (DEBUG) { printf("Coins: %d < %d\n", state->coins, getCost(choice1)); } } else{ if (DEBUG) { printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]); } gainCard(choice1, state, 0, currentPlayer);//Gain the card x = 0;//No more buying cards if (DEBUG) { printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]); } } } //Reset Hand for (i = 0; i <= state->handCount[currentPlayer]; i++) { state->hand[currentPlayer][i] = temphand[i]; temphand[i] = -1; } //Reset Hand return 0; case gardens: return -1; case mine: j = state->hand[currentPlayer][choice1]; //store card we will trash if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold) { return -1; } if (choice2 > treasure_map || choice2 < curse) { return -1; } if ( (getCost(state->hand[currentPlayer][choice1]) + 3) > getCost(choice2) ) { return -1; } gainCard(choice2, state, 2, currentPlayer); //discard card from hand discardCard(handPos, currentPlayer, state, 0); //discard trashed card for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == j) { discardCard(i, currentPlayer, state, 0); break; } } return 0; case remodel: j = state->hand[currentPlayer][choice1]; //store card we will trash if ( (getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2) ) { return -1; } gainCard(choice2, state, 0, currentPlayer); //discard card from hand discardCard(handPos, currentPlayer, state, 0); //discard trashed card for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == j) { discardCard(i, currentPlayer, state, 0); break; } } return 0; case smithy: return smithyEffect(state, handPos); case village: //+1 Card drawCard(currentPlayer, state); //+2 Actions state->numActions = state->numActions + 2; //discard played card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case baron: return baronEffect(state, choice1); case great_hall: //+1 Card drawCard(currentPlayer, state); //+1 Actions state->numActions++; //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case minion: return minionEffect(state, handPos, choice1, choice2); case steward: return stewardEffect(state, handPos, choice1, choice2, choice3); case tribute: if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1) { if (state->deckCount[nextPlayer] > 0) { tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deckCount[nextPlayer]--; } else if (state->discardCount[nextPlayer] > 0) { tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; state->discardCount[nextPlayer]--; } else{ //No Card to Reveal if (DEBUG) { printf("No cards to reveal\n"); } } } else{ if (state->deckCount[nextPlayer] == 0) { for (i = 0; i < state->discardCount[nextPlayer]; i++) { state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck state->deckCount[nextPlayer]++; state->discard[nextPlayer][i] = -1; state->discardCount[nextPlayer]--; } shuffle(nextPlayer,state);//Shuffle the deck } tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; } if (tributeRevealedCards[0] == tributeRevealedCards[1]) {//If we have a duplicate card, just drop one state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; state->playedCardCount++; tributeRevealedCards[1] = -1; } for (i = 0; i <= 2; i++) { if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold) {//Treasure cards state->coins += 2; } else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall) {//Victory Card Found drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else{//Action Card state->numActions = state->numActions + 2; } } return 0; case ambassador: return ambassadorEffect(state, handPos, choice1, choice2); case cutpurse: updateCoins(currentPlayer, state, 2); for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { for (j = 0; j < state->handCount[i]; j++) { if (state->hand[i][j] == copper) { discardCard(j, i, state, 0); break; } if (j == state->handCount[i]) { for (k = 0; k < state->handCount[i]; k++) { if (DEBUG) printf("Player %d reveals card number %d\n", i, state->hand[i][k]); } break; } } } } //discard played card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case embargo: return embargoEffect(state, handPos, choice1); case outpost: //set outpost flag state->outpostPlayed++; //discard card discardCard(handPos, state->whoseTurn, state, 0); return 0; case salvager: //+1 buy state->numBuys++; if (choice1) { //gain coins equal to trashed card state->coins = state->coins + getCost( handCard(choice1, state) ); //trash card discardCard(choice1, currentPlayer, state, 1); } //discard card discardCard(handPos, currentPlayer, state, 0); return 0; case sea_hag: for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; state->deckCount[i]--; state->discardCount[i]++; state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse } } return 0; case treasure_map: //search hand for another treasure_map index = -1; for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == treasure_map && i != handPos) { index = i; break; } } if (index > -1) { //trash both treasure cards discardCard(handPos, currentPlayer, state, 1); discardCard(index, currentPlayer, state, 1); //gain 4 Gold cards for (i = 0; i < 4; i++) { gainCard(gold, state, 1, currentPlayer); } //return success return 1; } //no second treasure_map found in hand return -1; } return -1; }
int main(int argc, char**argv){ struct gameState Game; struct gameState *Ga = &Game; int players, ranCard, i; int money, cardPos, curPlayer, useCard, returnCard, buyCa; int k[10]; int pool[20] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall, minion, steward, tribute, ambassador, cutpurse, embargo, outpost, salvager, sea_hag, treasure_map}; srand(atoi(argv[1])); players = rand()% 3 + 2; ranCard = rand() % 20; for(i=0;i<10;i++){ k[i] = pool[(ranCard+i)%20]; } printf("Starting Game\n"); initializeGame(players,k,atoi(argv[1]),Ga); printf("Number of player %d\n",players); while(!isGameOver(Ga)){ money = 0; cardPos = -1; curPlayer = whoseTurn(Ga); for(i=0;i<numHandCards(Ga);i++){ if (handCard(i,Ga) == copper) money++; else if(handCard(i,Ga) == silver) money += 2; else if(handCard(i,Ga) == gold) money += 3; else if(handCard(i,Ga) > 6) cardPos = i; } if(cardPos != -1){ useCard = handCard(cardPos,Ga); printf("Player %d: is playing card %d\n",curPlayer,useCard); returnCard = playCard(cardPos,1,1,1,Ga); if(returnCard== -1) printf("Playing card Failed\n",useCard); else printf("Playing card %d Succeded\n",useCard); } buyCa = k[rand()%10]; printf("Player %d has %d coins\n",curPlayer,money); if (money >= 8){ printf("Player %d is trying to buy province\n",curPlayer); if(buyCard(province,Ga)==-1){ printf("Buying Province Failed\n");} } else if (money >= getCost(buyCa)){ printf("Player %d is trying to by card %d \n"layer,buyCa); if(buyCard(buyCa,Ga)==-1){ printf("Buying %d Failed\n", buyCa);} } else if (money >= 6){ printf("Player %d is trying to buy gold\n",curPlayer); if(buyCard(gold,Ga)==-1){ printf("Buying Gold Faile\n");} } else if (money >= 3){ printf("Player %d is trying to buy silver\n",curPlayer); if (buyCard(silver,Ga)==-1){ printf("Buying Silver Failed\n");} } printf("Player %d has %d Cards in hand\n",curPlayer,numHandCards(Ga)); printf("Player %d ends turn\n",curPlayer); endTurn(Ga); }; for(i=0;i<players;i++){ printf("Player %d Score: %d\n",i,scoreFor(i,Ga)); } return 0; }
void FixEdgeInserterCore::findWeightedShortestPath(const CombinatorialEmbedding &E, edge eOrig, SList<adjEntry> &crossed) { node s = m_pr.copy(eOrig->source()); node t = m_pr.copy(eOrig->target()); OGDF_ASSERT(s != t); int eSubgraph = (m_pSubgraph != nullptr) ? (*m_pSubgraph)[eOrig] : 0; EdgeArray<int> costDual(m_dual, 0); int maxCost = 0; for(edge eDual : m_dual.edges) { int c = getCost(m_primalAdj[eDual]->theEdge(), eSubgraph); costDual[eDual] = c; if (c > maxCost) maxCost = c; } ++maxCost; Array<SListPure<edge> > nodesAtDist(maxCost); NodeArray<edge> spPred(m_dual,nullptr); int oldIdCount = m_dual.maxEdgeIndex(); // augment dual by edges from s to all adjacent faces of s ... for(adjEntry adj : s->adjEdges) { // starting edges of bfs-search are all edges leaving s edge eDual = m_dual.newEdge(m_vS, m_nodeOf[E.rightFace(adj)]); m_primalAdj[eDual] = adj; nodesAtDist[0].pushBack(eDual); } // ... and from all adjacent faces of t to t for(adjEntry adj : t->adjEdges) { edge eDual = m_dual.newEdge(m_nodeOf[E.rightFace(adj)], m_vT); m_primalAdj[eDual] = adj; } // actual search (using extended bfs on directed dual) int currentDist = 0; for( ; ; ) { // next candidate edge while(nodesAtDist[currentDist % maxCost].empty()) ++currentDist; edge eCand = nodesAtDist[currentDist % maxCost].popFrontRet(); node v = eCand->target(); // leads to an unvisited node? if (spPred[v] == nullptr) { // yes, then we set v's predecessor in search tree spPred[v] = eCand; // have we reached t ... if (v == m_vT) { // ... then search is done. // constructed list of used edges (translated to crossed // adjacency entries in PG) from t back to s (including first // and last!) do { edge eDual = spPred[v]; crossed.pushFront(m_primalAdj[eDual]); v = eDual->source(); } while(v != m_vS); break; } // append next candidate edges to queue (all edges leaving v) appendCandidates(nodesAtDist, costDual, maxCost, v, currentDist); } } // remove augmented edges again adjEntry adj; while ((adj = m_vS->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); while ((adj = m_vT->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); m_dual.resetEdgeIdCount(oldIdCount); }
int playDominion(struct gameState *state, int k[10]) { int i; int cardPos, curCard, returnCard, toBuyCard, curPlayer, money; int numPlayers = state->numPlayers; while (!isGameOver(state)) { money = 0; curPlayer = whoseTurn(state); cardPos = -1; printf("\nPlayer %d's turn.\n", curPlayer); //Check money for (i = 0; i < numHandCards(state); i++) { if (handCard(i, state) == copper) { money++; } else if (handCard(i, state) == silver) { money += 2; } else if (handCard(i, state) == gold) { money += 3; } else if (handCard(i, state) > 6) { cardPos = i; } } if (cardPos != -1) { curCard = handCard(cardPos, state); printf("Player %d plays %d\n", curPlayer, curCard); returnCard = playCard(cardPos, 1, 1, 1, state); if (returnCard == -1) { printf("Playing card %d failed\n", curCard); } else { printf ("Playing card %d succeded\n", curCard); } } toBuyCard = k[rand() % 10]; printf("Player %d has %d coins\n", curPlayer, money); if (money >= 8) { printf("Player %d is trying to buy a province\n", curPlayer); if(buyCard(province, state) == -1) { printf("Failed to buy a province"); } } else if (money >= getCost(toBuyCard)) { printf("Player %d is trying to buy card %s\n", curPlayer, getName(toBuyCard)); if (buyCard(toBuyCard, state) == -1) { printf("Buying %s failed\n", getName(toBuyCard)); } } else if (money >= 6) { printf("Player %d is trying to buy gold\n", curPlayer); if (buyCard(gold, state) == -1) { printf("Failed to buy gold\n"); } } else if (money >= 3) { printf("Player %d is trying to buy silver\n", curPlayer); if (buyCard(silver, state) == -1) { printf("Failed to buy silver\n"); } } printf("Player %d has %d cards in hand\n", curPlayer, numHandCards(state)); printf("Player %d ends turn\n", curPlayer); endTurn(state); } for (i = 0; i < numPlayers; i++) { printf("Player %d's score: %d\n", i, scoreFor(i, state)); } return 0; }
int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus) { int i; int j; int k; int x; int index; int currentPlayer = whoseTurn(state); int nextPlayer = currentPlayer + 1; int tributeRevealedCards[2] = {-1, -1}; int temphand[MAX_HAND];// moved above the if statement int drawntreasure=0; int cardDrawn; int z = 0;// this is the counter for the temp hand if (nextPlayer > (state->numPlayers - 1)){ nextPlayer = 0; } //uses switch to select card and perform actions switch( card ) { case adventurer: zzzadventurercardplay(drawntreasure, currentPlayer, cardDrawn, temphand, z, state); return 0; case council_room: //+4 Cards zzzconsoleroomcardplay(i, currentPlayer, handPos, state); return 0; case feast: //gain card with cost up to 5 //Backup hand zzzfeastcardplay(i, currentPlayer, temphand, x, choice1, state); //Reset Hand return 0; case gardens: return -1; case mine: j = state->hand[currentPlayer][choice1]; //store card we will trash if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold) { return -1; } if (choice2 > treasure_map || choice2 < curse) { return -1; } if ( (getCost(state->hand[currentPlayer][choice1]) + 3) > getCost(choice2) ) { return -1; } gainCard(choice2, state, 2, currentPlayer); //discard card from hand discardCard(handPos, currentPlayer, state, 0); //discard trashed card for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == j) { discardCard(i, currentPlayer, state, 0); break; } } return 0; case remodel: j = state->hand[currentPlayer][choice1]; //store card we will trash if ( (getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2) ) { return -1; } gainCard(choice2, state, 0, currentPlayer); //discard card from hand discardCard(handPos, currentPlayer, state, 0); //discard trashed card for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == j) { discardCard(i, currentPlayer, state, 0); break; } } return 0; case smithy: //+3 Cards zzzsmithycardplay(i, currentPlayer, handPos, state); return 0; case village: //+1 Card zzzvilliagecardplay(currentPlayer, handPos, state); return 0; case baron: //+1 buy, may discard estate card and get +4coins otherwise gain an estate card zzzbaroncardplay(currentPlayer, choice1, state); return 0; case great_hall: zzzgreat_hallcardplay(currentPlayer, handPos, state); return 0; case minion: //+1 action zzzminioncardplay(handPos, choice1, choice2, i, j, currentPlayer, state); return 0; case steward: if (choice1 == 1) { //+2 cards drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else if (choice1 == 2) { //+2 coins state->coins = state->coins + 2; } else { //trash 2 cards in hand discardCard(choice2, currentPlayer, state, 1); discardCard(choice3, currentPlayer, state, 1); } //discard card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case tribute: if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){ if (state->deckCount[nextPlayer] > 0){ tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deckCount[nextPlayer]--; } else if (state->discardCount[nextPlayer] > 0){ tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1]; state->discardCount[nextPlayer]--; } else{ //No Card to Reveal if (DEBUG){ printf("No cards to reveal\n"); } } } else{ if (state->deckCount[nextPlayer] == 0){ for (i = 0; i < state->discardCount[nextPlayer]; i++){ state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck state->deckCount[nextPlayer]++; state->discard[nextPlayer][i] = -1; state->discardCount[nextPlayer]--; } shuffle(nextPlayer,state);//Shuffle the deck } tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1]; state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1; state->deckCount[nextPlayer]--; } if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one state->playedCards[state->playedCardCount] = tributeRevealedCards[1]; state->playedCardCount++; tributeRevealedCards[1] = -1; } for (i = 0; i <= 2; i ++){ if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards state->coins += 2; } else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found drawCard(currentPlayer, state); drawCard(currentPlayer, state); } else{//Action Card state->numActions = state->numActions + 2; } } return 0; case ambassador: j = 0; //used to check if player has enough cards to discard if (choice2 > 2 || choice2 < 0) { return -1; } if (choice1 == handPos) { return -1; } for (i = 0; i < state->handCount[currentPlayer]; i++) { if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1) { j++; } } if (j < choice2) { return -1; } if (DEBUG) printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]); //increase supply count for choosen card by amount being discarded state->supplyCount[state->hand[currentPlayer][choice1]] += choice2; //each other player gains a copy of revealed card for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { gainCard(state->hand[currentPlayer][choice1], state, 0, i); } } //discard played card from hand discardCard(handPos, currentPlayer, state, 0); //trash copies of cards returned to supply for (j = 0; j < choice2; j++) { for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1]) { discardCard(i, currentPlayer, state, 1); break; } } } return 0; case cutpurse: updateCoins(currentPlayer, state, 2); for (i = 0; i < state->numPlayers; i++) { if (i != currentPlayer) { for (j = 0; j < state->handCount[i]; j++) { if (state->hand[i][j] == copper) { discardCard(j, i, state, 0); break; } if (j == state->handCount[i]) { for (k = 0; k < state->handCount[i]; k++) { if (DEBUG) printf("Player %d reveals card number %d\n", i, state->hand[i][k]); } break; } } } } //discard played card from hand discardCard(handPos, currentPlayer, state, 0); return 0; case embargo: //+2 Coins state->coins = state->coins + 2; //see if selected pile is in play if ( state->supplyCount[choice1] == -1 ) { return -1; } //add embargo token to selected supply pile state->embargoTokens[choice1]++; //trash card discardCard(handPos, currentPlayer, state, 1); return 0; case outpost: zzzoutpostcardplay(currentPlayer, handPos, state); return 0; case salvager: zzzsalvagercardplay(currentPlayer, handPos, choice1, state); return 0; case sea_hag: for (i = 0; i < state->numPlayers; i++){ if (i != currentPlayer){ state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--]; state->deckCount[i]--; state->discardCount[i]++; state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse } } return 0; case treasure_map: //search hand for another treasure_map index = -1; for (i = 0; i < state->handCount[currentPlayer]; i++) { if (state->hand[currentPlayer][i] == treasure_map && i != handPos) { index = i; break; } } if (index > -1) { //trash both treasure cards discardCard(handPos, currentPlayer, state, 1); discardCard(index, currentPlayer, state, 1); //gain 4 Gold cards for (i = 0; i < 4; i++) { gainCard(gold, state, 1, currentPlayer); } //return success return 1; } //no second treasure_map found in hand return -1; } return -1; }
void vpTemplateTrackerMIForwardAdditional::trackNoPyr(const vpImage<unsigned char> &I) { dW=0; double erreur=0; int Nbpoint=0; if(blur) vpImageFilter::filter(I, BI,fgG,taillef); vpImageFilter::getGradXGauss2D(I, dIx, fgG,fgdG,taillef); vpImageFilter::getGradYGauss2D(I, dIy, fgG,fgdG,taillef); double MI=0,MIprec=-1000; MI_preEstimation=-getCost(I,p); double i2,j2; double Tij; double IW,dx,dy; //unsigned int cr,ct; double er,et; double alpha=2.; int i,j; unsigned int iteration=0; initPosEvalRMS(p); do { if(iteration%5==0) initHessienDesired(I); Nbpoint=0; MIprec=MI; MI=0; erreur=0; zeroProbabilities(); Warp->computeCoeff(p); #ifdef VISP_HAVE_OPENMP int nthreads = omp_get_num_procs() ; //std::cout << "file: " __FILE__ << " line: " << __LINE__ << " function: " << __FUNCTION__ << " nthread: " << nthreads << std::endl; omp_set_num_threads(nthreads); #pragma omp parallel for private(Tij,IW,i,j,i2,j2,cr,ct,er,et,dx,dy) default(shared) #endif for(int point=0;point<(int)templateSize;point++) { i=ptTemplate[point].y; j=ptTemplate[point].x; X1[0]=j;X1[1]=i; Warp->computeDenom(X1,p); Warp->warpX(X1,X2,p); j2=X2[0];i2=X2[1]; if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1)) { Nbpoint++; Tij=ptTemplate[point].val; //Tij=Iterateurvecteur->val; if(!blur) IW=I.getValue(i2,j2); else IW=BI.getValue(i2,j2); dx=1.*dIx.getValue(i2,j2)*(Nc-1)/255.; dy=1.*dIy.getValue(i2,j2)*(Nc-1)/255.; ct=(int)((IW*(Nc-1))/255.); cr=(int)((Tij*(Nc-1))/255.); et=(IW*(Nc-1))/255.-ct; er=((double)Tij*(Nc-1))/255.-cr; //calcul de l'erreur erreur+=(Tij-IW)*(Tij-IW); //Calcul de l'histogramme joint par interpolation bilinÃaire (Bspline ordre 1) Warp->dWarp(X1,X2,p,dW); //double *tptemp=temp; double *tptemp=new double[nbParam];; for(unsigned int it=0;it<nbParam;it++) tptemp[it] =(dW[0][it]*dx+dW[1][it]*dy); //*tptemp++ =dW[0][it]*dIWx+dW[1][it]*dIWy; //std::cout<<cr<<" "<<ct<<" ; "; if(ApproxHessian==HESSIAN_NONSECOND||hessianComputation==vpTemplateTrackerMI::USE_HESSIEN_DESIRE) vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline); else if(ApproxHessian==HESSIAN_0 || ApproxHessian==HESSIAN_NEW) vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline); delete[] tptemp; } } if(Nbpoint==0) { //std::cout<<"plus de point dans template suivi"<<std::endl; diverge=true; MI=0; deletePosEvalRMS(); throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template")); } else { computeProba(Nbpoint); computeMI(MI); //std::cout<<iteration<<"\tMI= "<<MI<<std::endl; computeHessien(H); computeGradient(); vpMatrix::computeHLM(H,lambda,HLM); try { switch(hessianComputation) { case vpTemplateTrackerMI::USE_HESSIEN_DESIRE: dp=gain*HLMdesireInverse*G; break; case vpTemplateTrackerMI::USE_HESSIEN_BEST_COND: if(HLM.cond()>HLMdesire.cond()) dp=gain*HLMdesireInverse*G; else dp=gain*0.2*HLM.inverseByLU()*G; break; default: dp=gain*0.2*HLM.inverseByLU()*G; break; } } catch(vpException &e) { //std::cerr<<"probleme inversion"<<std::endl; deletePosEvalRMS(); throw(e); } } switch(minimizationMethod) { case vpTemplateTrackerMIForwardAdditional::USE_LMA: { vpColVector p_test_LMA(nbParam); if(ApproxHessian==HESSIAN_NONSECOND) p_test_LMA=p-100000.1*dp; else p_test_LMA=p+1.*dp; MI=-getCost(I,p); double MI_LMA=-getCost(I,p_test_LMA); if(MI_LMA>MI) { p=p_test_LMA; lambda=(lambda/10.<1e-6)?lambda/10.:1e-6; } else { lambda=(lambda*10.<1e6)?1e6:lambda*10.; } } break; case vpTemplateTrackerMIForwardAdditional::USE_GRADIENT: { dp=-gain*6.0*G; if(useBrent) { alpha=2.; computeOptimalBrentGain(I,p,-MI,dp,alpha); dp=alpha*dp; } p+=1.*dp; break; } case vpTemplateTrackerMIForwardAdditional::USE_QUASINEWTON: { double s_scal_y; if(iterationGlobale!=0) { vpColVector s_quasi=p-p_prec; vpColVector y_quasi=G-G_prec; s_scal_y=s_quasi.t()*y_quasi; //if(s_scal_y!=0)//BFGS // KQuasiNewton=KQuasiNewton-(s_quasi*y_quasi.t()*KQuasiNewton+KQuasiNewton*y_quasi*s_quasi.t())/s_scal_y+(1.+y_quasi.t()*(KQuasiNewton*y_quasi)/s_scal_y)*s_quasi*s_quasi.t()/s_scal_y; //if(s_scal_y!=0)//DFP if(std::fabs(s_scal_y) > std::numeric_limits<double>::epsilon()) KQuasiNewton=KQuasiNewton+0.001*(s_quasi*s_quasi.t()/s_scal_y-KQuasiNewton*y_quasi*y_quasi.t()*KQuasiNewton/(y_quasi.t()*KQuasiNewton*y_quasi)); } dp=-KQuasiNewton*G; p_prec=p; G_prec=G; p-=1.01*dp; } break; default: { if(ApproxHessian==HESSIAN_NONSECOND) dp=-0.1*dp; if(useBrent) { alpha=2.; computeOptimalBrentGain(I,p,-MI,dp,alpha); //std::cout<<alpha<<std::endl; dp=alpha*dp; } p+=1.*dp; break; } } computeEvalRMS(p); iteration++; iterationGlobale++; } while( (std::fabs(MI-MIprec) > std::fabs(MI)*std::numeric_limits<double>::epsilon()) &&(iteration< iterationMax)&&(evolRMS>threshold_RMS) ); //while( (MI!=MIprec) &&(iteration< iterationMax)&&(evolRMS>threshold_RMS) ); if(Nbpoint==0) { //std::cout<<"plus de point dans template suivi"<<std::endl; deletePosEvalRMS(); throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template")); } nbIteration=iteration; MI_postEstimation=-getCost(I,p); if(MI_preEstimation>MI_postEstimation) { MI_postEstimation = -1; } deletePosEvalRMS(); }
int main() { printf("This is testing the get cost function\n"); int seed = 1000; int numPlayer = 2; int p, r, handCount; int k[10] = {adventurer, council_room, feast, gardens, mine , remodel, smithy, village, baron, great_hall}; struct gameState G; p =0; handCount=1; memset(&G, 23, sizeof(struct gameState)); r = initializeGame(numPlayer, k, seed, &G); //initializing a new game G.handCount[p] = handCount; if(r==-1) { exit(0); } //testing for a normal value int i; i = getCost(2); if (i==5) { printf("This test passed.\n"); } else printf("This test failed.\n"); //testing if value is above any card level value int v; v = getCost(30); if (v==-1) { printf("This test passed.\n"); } else printf("This test failed.\n"); //testing another value v = getCost(10); if (v==4) { printf("This test passed.\n"); } else printf("This test failed.\n"); //one more test to make sure the correct //value is returned v = getCost(25); if (v!=6) { printf("This test passed.\n"); } else printf("This test failed.\n"); return 0; }
bool VACVariable::averaging() { Cost Top = wcsp->getUb(); bool change = false; EnumeratedVariable* x; EnumeratedVariable* y; Constraint* ctr = NULL; ConstraintList::iterator itc = getConstrs()->begin(); if (itc != getConstrs()->end()) ctr = (*itc).constr; while (ctr) { if (ctr->isBinary() && !ctr->isSep()) { BinaryConstraint* bctr = (BinaryConstraint*)ctr; x = (EnumeratedVariable*)bctr->getVarDiffFrom((Variable*)this); for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; for (iterator itx = x->begin(); itx != x->end(); ++itx) { Cost cbin = bctr->getCost(this, x, *it, *itx); if (cbin < cmin) cmin = cbin; } assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Long)extc; for (iterator itx = x->begin(); itx != x->end(); ++itx) { bctr->addcost(this, x, *it, *itx, costi); } if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } else if (ctr->isTernary() && !ctr->isSep()) { TernaryConstraint* tctr = (TernaryConstraint*)ctr; x = (EnumeratedVariable*)tctr->getVar(0); if (x == this) x = (EnumeratedVariable*)tctr->getVar(1); y = (EnumeratedVariable*)tctr->getVarDiffFrom((Variable*)this, (Variable*)x); for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; for (iterator itx = x->begin(); itx != x->end(); ++itx) { for (iterator ity = y->begin(); ity != y->end(); ++ity) { Cost ctern = tctr->getCost(this, x, y, *it, *itx, *ity); if (ctern < cmin) cmin = ctern; } } assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Long)extc; for (iterator itx = x->begin(); itx != x->end(); ++itx) { for (iterator ity = y->begin(); ity != y->end(); ++ity) { tctr->addCost(this, x, y, *it, *itx, *ity, costi); } } if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } else if (ctr->isNary() && !ctr->isSep()) { NaryConstraint* nctr = (NaryConstraint*)ctr; for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; int tindex = nctr->getIndex(this); String tuple; Cost cost; Long nbtuples = 0; nctr->first(); while (nctr->next(tuple, cost)) { nbtuples++; if (toValue(tuple[tindex] - CHAR_FIRST) == (*it) && cost < cmin) cmin = cost; } if (nctr->getDefCost() < cmin && nbtuples < nctr->getDomainSizeProduct() / getDomainSize()) cmin = nctr->getDefCost(); // assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Cost)extc; nctr->addtoTuples(this, *it, costi); if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } ++itc; if (itc != getConstrs()->end()) ctr = (*itc).constr; else ctr = NULL; } return change; }
//Testing mine int main() { int i, j, r, passes, choice1, choice2; int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy}; int supply[16] = {0,1,2,3,4,5,6,7,10,11,13,14,17,19,21,22}; struct gameState G; r = initializeGame(2, k, 2, &G); assert(r == 0); //Try upgrading to every card for (i = 1; i < 4; i++) { for (j = 0; j < 16; j++) { r = initializeGame(2, k, 2, &G); assert(r == 0); G.hand[0][0] = mine; G.hand[0][1] = copper; G.hand[0][2] = silver; G.hand[0][3] = gold; G.hand[0][4] = smithy; G.handCount[0] = 5; G.numActions = 1; choice1 = i; choice2 = supply[j]; //Only allow to upgrade the treasure card r = playCard(0, choice1, choice2, 0, &G); passes = 1; if (choice1 == copper && (choice2 != copper || choice2 != silver) && r == 0) { printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]); printf("Cost of copper is %d, and cost of %d is %d\n", getCost(copper), i, getCost(i)); passes = 0; } if (choice1 == silver && (choice2 != silver || choice2 != gold) && r == 0) { printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]); printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i])); passes = 0; } if (choice1 == silver && (choice2 != silver || choice2 != gold) && r == 0) { printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]); printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i])); passes = 0; } if (choice1 == gold && choice2 != gold && r == 0) { printf("Illegal move %d: traded in %d for %d. -- ", r, choice1, supply[j]); printf("Cost of copper is %d, and cost of %d is %d\n", getCost(silver), i, getCost(G.hand[0][i])); passes = 0; } } } myAssert(passes); return 0; }
/* Feast: Trash this card. Gain a card costing up to 5 Coins. Additional Rules: The gained card goes into your Discard pile. It has to be a card from the Supply. You cannot use coins from Treasures or previous Actions (like the Market) to increase the cost of the card that you gain. If you use Throne Room on Feast, you will gain two cards, even though you can only trash Feast once. Gaining the card isn't contingent on trashing Feast; they're just two things that the card tries to make you do. This adds 5 coins to the player, but does not subtract them should the chosen card be too expensive. Also the code checks that the player has the coins needed but the rules do not alow using additional coins to increase the value of the gained card. */ int playFeast(int currentPlayer, struct gameState *state, int choice1) { int temphand[MAX_HAND]; int cardNotBought; int i; //Backup hand for (i = 0; i <= state->handCount[currentPlayer]; i++) { temphand[i] = state->hand[currentPlayer][i];//Backup card state->hand[currentPlayer][i] = EMPTY_CARD;//Set to nothing } //Update Coins for Buy (adds 5 which is the incorect behavor) updateCoins(currentPlayer, state, FEAST_MAX_COST); cardNotBought = NOT_BOUGHT;//Condition to loop on while( cardNotBought == NOT_BOUGHT) {//Buy one card if (supplyCount(choice1, state) <= EMPTY_SUPPLY) { if (DEBUG) { printf("None of that card left, sorry!\n"); printf("Cards Left: %d\n", supplyCount(choice1, state)); } } else if (state->coins < getCost(choice1)) { printf("That card is too expensive!\n"); if (DEBUG) printf("Coins: %d < %d\n", state->coins, getCost(choice1)); } else { if (DEBUG) { printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer] ); } gainCard(choice1, state, TO_DISCARD, currentPlayer);//Gain the card cardNotBought = BOUGHT;//No more buying cards if (DEBUG){ printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer] ); } } //printf("Card not bought feast choice 1: %d\n", choice1); } //Reset Hand for (i = 0; i <= state->handCount[currentPlayer]; i++) { state->hand[currentPlayer][i] = temphand[i]; temphand[i] = EMPTY_CARD; } return EFFECT_SUCCESS; }
int TakeTurn(FILE* fp, int currPlayer, struct gameState* pre, struct gameState* post, int* pass, int* fail){ int errCount = 0; fprintf(fp,"Starting turn for player %d\n", currPlayer); fprintf(fp,"Printing GameState Below\n"); dumpState(fp,pre); while(numActionCard(currPlayer,pre)) { if(pre->numActions <= 0){break;} int NthActCard = (rand() % numActionCard(currPlayer,pre)) + 1; int cardPosToPlay = idxNthActCard(currPlayer,pre,NthActCard); int cardToPlay = pre->hand[currPlayer][cardPosToPlay]; //make SURE we did this right--Remove this later if it all works if(cardToPlay>=adventurer && cardToPlay <= treasure_map) { //REALLY didn't want to do this, but seems to be the only reasonable way to deal with the choice-based cards. switch(cardToPlay) { case feast: ; int cardToBuy; cardToBuy = randAffordableCard(5,pre); if(cardToBuy == -1) { if(numActionCard(currPlayer,pre) < 2) { pre->numActions = 0; break; } break; } fprintf(fp, "Player %d is playing a feast, to buy a %s\n",currPlayer, cardnames[cardToBuy]); errCount += fassert(playCard(cardPosToPlay,cardToBuy,0,0,post) == 0, pass, fail, "PlayCard returned 0"); break; case mine: if(hasHandCard(currPlayer,silver,pre)) { fprintf(fp, "Player %d is using mine to trash a silver for a gold\n",currPlayer); errCount+= fassert(playCard(cardPosToPlay,hasHandCard(currPlayer,silver,pre),gold,0,post) == 0, pass, fail, "PlayCard returned 0"); break; } else if(hasHandCard(currPlayer,copper,pre)) { fprintf(fp, "Player %d is using mine to trash a copper for a silver\n",currPlayer); errCount+= fassert(playCard(cardPosToPlay,hasHandCard(currPlayer,copper,pre),silver,0,post) == 0,pass,fail,"PlayCard returned 0"); break; } else { //hrmm, if we aren't holding a treasure card, we can't play--dont want to stick us in an infinite loop, //so going to cheat a bit here, THIS IS ONLY TO PREVENT INFINITE LOOPS IF MINE IS THE ONLY ACTION CARD IN HAND //Also, there is no point in checking to trash a gold for another gold. Totally redundant. This covers both cases if(numActionCard(currPlayer,pre) <= 1){pre->numActions = 0;} break; } case remodel: if(pre->handCount[currPlayer] > 1) { int cardToTrash; while(1) { cardToTrash = rand() % pre->handCount[currPlayer]; if(cardToTrash!=cardPosToPlay){break;} } int trashValue = getCost(cardToTrash); int cardToBuy = randAffordableCard(trashValue+2,pre); if(cardToBuy == -1) { if(numActionCard(currPlayer,pre) < 2) { pre->numActions = 0; break; } break; } fprintf(fp, "Player %d is using remodel to trash a %s and gain a %s\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]],cardnames[cardToBuy]); errCount += fassert(playCard(cardPosToPlay,cardToTrash,cardToBuy,0,post) == 0,pass,fail,"PlayCard Returned 0"); break; } else { //only card is remodel, so we can't play--set actions to 0 pre->numActions = 0; break; } case baron: if(hasHandCard(currPlayer, estate, pre)) { if(rand()%2) { fprintf(fp,"Player %d is playing baron, discarding an estate\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,1,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } } else { fprintf(fp,"Player %d is playing baron, not discarding estate\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,0,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } case minion: ; int rChoice; rChoice = (rand() % 2)+1; if(rChoice == 1) { fprintf(fp, "Player %d is playing minion, chose +2 coin\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,1,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } else { fprintf(fp, "Player %d is playing minion, chose redraw\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,0,1,0,post)==0,pass,fail,"PlayCard returned 0"); break; } case steward: rChoice = (rand()%3)+1; if(rChoice == 1) { fprintf(fp, "Player %d is playing steward, chose +2 card\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } else if(rChoice == 2) { fprintf(fp, "Player %d is playing steward, chose +2 coin\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } else { fprintf(fp, "Player %d is playing steward, chose trash 2\n",currPlayer); errCount+=fassert(playCard(cardPosToPlay,rChoice,0,0,post)==0,pass,fail,"PlayCard returned 0"); break; } case ambassador: if(pre->handCount[currPlayer]>1) { int cardToTrash; while(1) { cardToTrash = rand() % pre->handCount[currPlayer]; if(cardToTrash!=cardPosToPlay){break;} } int numToReturn = (rand() % numCardX(currPlayer,pre->hand[currPlayer][cardToTrash],pre))+1; fprintf(fp,"Player %d is playing ambassador, trashing a %s, hoping to return %d\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]],numToReturn); errCount+=fassert(playCard(cardPosToPlay,cardToTrash,numToReturn,0,post)==0,pass,fail,"PlayCard returned 0"); break; } else { if(numActionCard(currPlayer,pre) < 2) { pre->numActions = 0; } break; } case embargo: ; int cardToEmbargo; cardToEmbargo = randAffordableCard(999,pre); if(cardToBuy == -1) { if(numActionCard(currPlayer,pre) < 2) { pre->numActions = 0; } break; } fprintf(fp,"Player %d is playing embargo on %s\n",currPlayer,cardnames[cardToEmbargo]); errCount+=fassert(playCard(cardPosToPlay,cardToEmbargo,0,0,post)==0,pass,fail,"PlayCard Returned 0"); break; case salvager: if(pre->handCount[currPlayer]>1) { int cardToTrash; while(1) { cardToTrash = rand() % pre->handCount[currPlayer]; if(cardToTrash!=cardPosToPlay){break;} } fprintf(fp,"Player %d is playing salvager, trashing %s\n",currPlayer,cardnames[pre->hand[currPlayer][cardToTrash]]); errCount+=fassert(playCard(cardPosToPlay,cardToTrash,0,0,post)==0,pass,fail,"PlayCard Returned 0"); break; } else { pre->numActions = 0; break; } default: //all other cards don't need choices fprintf(fp,"Player %d is playing his %s\n",currPlayer,cardnames[cardToPlay]); errCount += fassert(playCard(cardPosToPlay,0,0,0, post) == 0, pass, fail, "PlayCard Returned 0"); break; } errCount += SanityCheck(post,pass,fail,fp); if(!errCount) { fprintf(fp,"Player %d tried to play a card, gamestate is now\n",currPlayer); dumpState(fp,post); memcpy(pre,post,sizeof(struct gameState)); } else{break;} } } //OK, now that we played all possible actions, we can try out buying stuff while(pre->numBuys > 0 && !errCount) //doesn't matter how many coins we have, can still buy for ex: copper for 0c { if(pre->coins < 2) { int doibuy = rand() % 2; if(doibuy){break;} } int cardToBuy = randAffordableCard(pre->coins,pre); if(cardToBuy == -1) { pre->numBuys = 0; break; } buyCard(cardToBuy,post); fprintf(fp,"Player %d tried to buy a %s\n",currPlayer,cardnames[cardToBuy]); errCount+=SanityCheck(post,pass,fail,fp); if(!errCount) { //fprintf(fp,"gamestate is now\n"); //dumpState(fp,post); memcpy(pre,post,sizeof(struct gameState)); } else{break;} } if(!errCount) { fprintf(fp,"Ending turn for player %d\n", currPlayer); errCount += fassert(endTurn(post) == 0, pass, fail, "endTurn Returned 0"); errCount += SanityCheck(post,pass, fail,fp); if(!errCount) { memcpy(pre,post,sizeof(struct gameState)); } } fprintf(fp,"Gamestate at end of turn\n"); dumpState(fp, post); return errCount; }
int main(int argc, char* argv[]){ int i; int ret; fprintf(stdout, "Testing getCost\n"); for(i = 0; i < 27; i++){ ret = getCost(i); switch(i){ case curse: assert(ret == 0); break; case estate: assert(ret == 2); break; case duchy: assert(ret == 5); break; case province: assert(ret == 8); break; case copper: assert(ret == 0); break; case silver: assert(ret == 3); break; case gold: assert(ret == 6); break; case adventurer: assert(ret == 6); break; case council_room: assert(ret == 5); break; case feast: assert(ret == 4); break; case gardens: assert(ret == 4); break; case mine: assert(ret == 5); break; case remodel: assert(ret == 4); break; case smithy: assert(ret == 4); break; case village: assert(ret == 3); break; case baron: assert(ret == 4); break; case great_hall: assert(ret == 3); break; case minion: assert(ret == 5); break; case steward: assert(ret == 3); break; case tribute: assert(ret == 5); break; case ambassador: assert(ret == 3); break; case cutpurse: assert(ret == 4); break; case embargo: assert(ret == 2); break; case outpost: assert(ret == 5); break; case salvager: assert(ret == 4); break; case sea_hag: assert(ret == 4); break; case treasure_map: assert(ret == 4); break; } } fprintf(stdout, "Test passed\n"); return 0; }