diff --git a/projects/alghanmz/README.md b/projects/alghanmz/README.md
new file mode 100644
index 000000000..210364047
--- /dev/null
+++ b/projects/alghanmz/README.md
@@ -0,0 +1,2 @@
+#Ziyad Alghanmi, alghanmz
+OSU CS362 Software Engineering II Fall 2019
diff --git a/projects/alghanmz/dominion/Makefile b/projects/alghanmz/dominion/Makefile
new file mode 100644
index 000000000..5541801f3
--- /dev/null
+++ b/projects/alghanmz/dominion/Makefile
@@ -0,0 +1,31 @@
+CFLAGS= -Wall -fpic -coverage -lm -std=c99
+
+rngs.o: rngs.h rngs.c
+ gcc -c rngs.c -g $(CFLAGS)
+
+dominion.o: dominion.h dominion.c rngs.o
+ gcc -c dominion.c -g $(CFLAGS)
+
+playdom: dominion.o playdom.c
+ gcc -o playdom playdom.c -g dominion.o rngs.o $(CFLAGS)
+#To run playdom you need to entere: ./playdom like ./playdom 10*/
+
+testDrawCard: testDrawCard.c dominion.o rngs.o
+ gcc -o testDrawCard -g testDrawCard.c dominion.o rngs.o $(CFLAGS)
+
+interface.o: interface.h interface.c
+ gcc -c interface.c -g $(CFLAGS)
+
+runtests: testDrawCard
+ ./testDrawCard &> unittestresult.out
+ gcov dominion.c >> unittestresult.out
+ cat dominion.c.gcov >> unittestresult.out
+
+
+player: player.c interface.o
+ gcc -o player player.c -g dominion.o rngs.o interface.o $(CFLAGS)
+
+all: playdom player
+
+clean:
+ rm -f *.o playdom.exe playdom player player.exe *.gcov *.gcda *.gcno *.so *.out testDrawCard testDrawCard.exe
diff --git a/projects/alghanmz/dominion/READM.md b/projects/alghanmz/dominion/READM.md
new file mode 100644
index 000000000..c3599f6ad
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/dominion.c b/projects/alghanmz/dominion/dominion.c
new file mode 100644
index 000000000..739e2605e
--- /dev/null
+++ b/projects/alghanmz/dominion/dominion.c
@@ -0,0 +1,1405 @@
+#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 doMine(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ 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;
+}
+
+void getEstateCard(struct gameState *state, int currentPlayer)
+{
+ if (supplyCount(estate, state) > 0) {
+ gainCard(estate, state, 0, currentPlayer);//Gain an estate
+
+ state->supplyCount[estate]--;//Decrement Estates
+ if (supplyCount(estate, state) == 0) {
+ isGameOver(state);
+ }
+ }
+}
+
+void doBaron(int choice1, struct gameState *state, int currentPlayer)
+{
+ state->numBuys++;//Increase buys by 1!
+ state->numBuys++;//Increase buys by 1!
+ if (choice1 > 0) { //Boolean true or going to discard an estate
+ int p = 1; //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");
+ }
+ getEstateCard(state, currentPlayer);
+ card_not_discarded = 0;//Exit the loop
+ }
+
+ else {
+ p++;//Next card
+ }
+ }
+ }
+
+ else {
+ getEstateCard(state, currentPlayer);
+ }
+}
+
+void doMinion(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ int j;
+
+ //+1 action
+ state->numActions++;
+
+ //discard card from hand
+ discardCard(handPos, currentPlayer, state, 0);
+
+ if (choice1)
+ {
+ state->coins = state->coins + 2;
+ }
+ else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
+ {
+ //discard hand
+ while(numHandCards(state) > 1 /*0*/)
+ {
+ discardCard(handPos, currentPlayer, state, 0);
+ }
+
+ //draw 4
+ for (i = 0; i < 4; i++)
+ {
+ drawCard(currentPlayer, state);
+ }
+
+ //other players discard hand and redraw if hand size > 4
+ for (i = 0; i < state->numPlayers; i++)
+ {
+ if (i != currentPlayer)
+ {
+ //if ( state->handCount[i] > 4 )
+ {
+ //discard hand
+ while( state->handCount[i] > 0 )
+ {
+ discardCard(handPos, i, state, 0);
+ }
+
+ //draw 4
+ for (j = 0; j < 4; j++)
+ {
+ drawCard(i, state);
+ }
+ }
+ }
+ }
+ }
+}
+
+void doTribute(struct gameState *state, int currentPlayer, int nextPlayer, int tributeRevealedCards[2])
+{
+ int i;
+
+ 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->numActions = state->numActions + 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->coins += 2;
+ }
+ }
+}
+
+int doAmbassador(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ int j;
+
+ j = 0; //used to check if player has enough cards to discard
+
+ if (choice2 > 3 || 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 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:
+ return doMine(choice1, choice2, state, handPos, currentPlayer);
+
+ 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:
+ doBaron(choice1, state, currentPlayer);
+ 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:
+ doMinion(choice1, choice2, state, handPos, currentPlayer);
+ 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:
+ doTribute(state, currentPlayer, nextPlayer, tributeRevealedCards);
+ return 0;
+
+ case ambassador:
+ return doAmbassador(choice1, choice2, state, handPos, currentPlayer);
+
+ 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/alghanmz/dominion/dominion.gcno b/projects/alghanmz/dominion/dominion.gcno
new file mode 100644
index 000000000..aca03b487
Binary files /dev/null and b/projects/alghanmz/dominion/dominion.gcno differ
diff --git a/projects/alghanmz/dominion/dominion.h b/projects/alghanmz/dominion/dominion.h
new file mode 100644
index 000000000..f9d9039b8
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/dominion.o b/projects/alghanmz/dominion/dominion.o
new file mode 100644
index 000000000..fcc04d0a0
Binary files /dev/null and b/projects/alghanmz/dominion/dominion.o differ
diff --git a/projects/alghanmz/dominion/dominion_helpers.h b/projects/alghanmz/dominion/dominion_helpers.h
new file mode 100644
index 000000000..0887fda15
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/interface.c b/projects/alghanmz/dominion/interface.c
new file mode 100644
index 000000000..58cc5ba58
--- /dev/null
+++ b/projects/alghanmz/dominion/interface.c
@@ -0,0 +1,425 @@
+/* Interactive Dominion Interface
+
+Sam Heinith CS362
+1/26/2010
+*/
+
+#include
+#include
+#include
+#include
+#include "rngs.h"
+#include "interface.h"
+#include "dominion.h"
+
+
+void cardNumToName(int card, char *name) {
+ switch(card) {
+ case curse:
+ strcpy(name,"Curse");
+ break;
+ case estate:
+ strcpy(name,"Estate");
+ break;
+ case duchy:
+ strcpy(name,"Duchy");
+ break;
+ case province:
+ strcpy(name,"Province");
+ break;
+ case copper:
+ strcpy(name,"Copper");
+ break;
+ case silver:
+ strcpy(name,"Silver");
+ break;
+ case gold:
+ strcpy(name,"Gold");
+ break;
+ case adventurer:
+ strcpy(name,"Adventurer");
+ break;
+ case council_room:
+ strcpy(name,"Council Room");
+ break;
+ case feast:
+ strcpy(name,"Feast");
+ break;
+ case gardens:
+ strcpy(name,"Gardens");
+ break;
+ case mine:
+ strcpy(name,"Mine");
+ break;
+ case remodel:
+ strcpy(name,"Remodel");
+ break;
+ case smithy:
+ strcpy(name,"Smithy");
+ break;
+ case village:
+ strcpy(name,"Village");
+ break;
+ case baron:
+ strcpy(name,"Baron");
+ break;
+ case great_hall:
+ strcpy(name,"Great Hall");
+ break;
+ case minion:
+ strcpy(name,"Minion");
+ break;
+ case steward:
+ strcpy(name,"Steward");
+ break;
+ case tribute:
+ strcpy(name,"Tribute");
+ break;
+ case ambassador:
+ strcpy(name,"Ambassador");
+ break;
+ case cutpurse:
+ strcpy(name,"Cutpurse");
+ break;
+ case embargo:
+ strcpy(name,"Embargo");
+ break;
+ case outpost:
+ strcpy(name,"Outpost");
+ break;
+ case salvager:
+ strcpy(name,"Salvager");
+ break;
+ case sea_hag:
+ strcpy(name,"Sea Hag");
+ break;
+ case treasure_map:
+ strcpy(name,"Treasure Map");
+ break;
+
+ default:
+ strcpy(name,"?");
+ }
+
+}
+
+
+
+int getCardCost(int card) {
+ int cost;
+ switch(card) {
+ case curse:
+ cost = CURSE_COST;
+ break;
+ case estate:
+ cost = ESTATE_COST;
+ break;
+ case duchy:
+ cost = DUCHY_COST;
+ break;
+ case province:
+ cost = PROVINCE_COST;
+ break;
+ case copper:
+ cost = COPPER_COST;
+ break;
+ case silver:
+ cost = SILVER_COST;
+ break;
+ case gold:
+ cost = GOLD_COST;
+ break;
+ case adventurer:
+ cost = ADVENTURER_COST;
+ break;
+ case council_room:
+ cost = COUNCIL_ROOM_COST;
+ break;
+ case feast:
+ cost = FEAST_COST;
+ break;
+ case gardens:
+ cost = GARDEN_COST;
+ break;
+ case mine:
+ cost = MINE_COST;
+ break;
+ case remodel:
+ cost = REMODEL_COST;
+ break;
+ case smithy:
+ cost = SMITHY_COST;
+ break;
+ case village:
+ cost = VILLAGE_COST;
+ break;
+ case baron:
+ cost = BARON_COST;
+ break;
+ case great_hall:
+ cost = GREAT_HALL_COST;
+ break;
+ case minion:
+ cost = MINION_COST;
+ break;
+ case steward:
+ cost = STEWARD_COST;
+ break;
+ case tribute:
+ cost = TRIBUTE_COST;
+ break;
+ case ambassador:
+ cost = AMBASSADOR_COST;
+ break;
+ case cutpurse:
+ cost = CUTPURSE_COST;
+ break;
+ case embargo:
+ cost = EMBARGO_COST;
+ break;
+ case outpost:
+ cost = OUTPOST_COST;
+ break;
+ case salvager:
+ cost = SALVAGER_COST;
+ break;
+ case sea_hag:
+ cost = SEA_HAG_COST;
+ break;
+ case treasure_map:
+ cost = TREASURE_MAP_COST;
+ break;
+ default:
+ cost = ONETHOUSAND;
+ }
+ return cost;
+}
+
+
+
+
+
+
+void printHand(int player, struct gameState *game) {
+ int handCount = game->handCount[player];
+ int handIndex;
+ printf("Player %d's hand:\n", player);
+ if(handCount > 0) printf("# Card\n");
+ for(handIndex = 0; handIndex < handCount; handIndex++) {
+ int card = game->hand[player][handIndex];
+ char name[MAX_STRING_LENGTH];
+ cardNumToName(card, name);
+ printf("%-2d %-13s\n", handIndex, name);
+ }
+ printf("\n");
+}
+
+
+
+void printDeck(int player, struct gameState *game) {
+ int deckCount = game->deckCount[player];
+ int deckIndex;
+ printf("Player %d's deck: \n", player);
+ if(deckCount > 0) printf("# Card\n");
+ for(deckIndex = 0; deckIndex < deckCount; deckIndex++) {
+ int card = game->deck[player][deckIndex];
+ char name[MAX_STRING_LENGTH];
+ cardNumToName(card, name);
+ printf("%-2d %-13s\n", deckIndex, name);
+ }
+ printf("\n");
+}
+
+void printPlayed(int player, struct gameState *game) {
+ int playedCount = game->playedCardCount;
+ int playedIndex;
+ printf("Player %d's played cards: \n", player);
+ if(playedCount > 0) printf("# Card\n");
+ for(playedIndex = 0; playedIndex < playedCount; playedIndex++) {
+ int card = game->playedCards[playedIndex];
+ char name[MAX_STRING_LENGTH];
+ cardNumToName(card, name);
+ printf("%-2d %-13s \n", playedIndex, name);
+ }
+ printf("\n");
+}
+
+
+
+void printDiscard(int player, struct gameState *game) {
+ int discardCount = game->discardCount[player];
+ int discardIndex;
+ printf("Player %d's discard: \n", player);
+ if(discardCount > 0) printf("# Card\n");
+ for(discardIndex = 0; discardIndex < discardCount; discardIndex++) {
+ int card = game->discard[player][discardIndex];
+ char name[MAX_STRING_LENGTH];
+ cardNumToName(card, name);
+ printf("%-2d %-13s \n", discardIndex, name);
+ }
+ printf("\n");
+}
+
+
+
+
+void printSupply(struct gameState *game) {
+ int cardNum, cardCost, cardCount;
+ char name[MAX_STRING_LENGTH];
+ printf("# Card Cost Copies\n");
+ for(cardNum = 0; cardNum < NUM_TOTAL_K_CARDS; cardNum++) {
+ cardCount = game->supplyCount[cardNum];
+ if(cardCount == -1) continue;
+ cardNumToName(cardNum, name);
+ cardCost = getCardCost(cardNum);
+ printf("%-2d %-13s %-5d %-5d", cardNum, name, cardCost, cardCount);
+ printf("\n");
+ }
+ printf("\n");
+}
+
+
+void printState(struct gameState *game) {
+ int numActions = game->numActions;
+ int numCoins = game->coins;
+ int numBuys = game->numBuys;
+ int currentPlayer = game->whoseTurn;
+ int phase = game->phase;
+ char phaseName[MAX_STRING_LENGTH];
+ phaseNumToName(phase,phaseName);
+ printf("Player %d:\n%s phase\n%d actions\n%d coins\n%d buys\n\n", currentPlayer, phaseName, numActions, numCoins, numBuys);
+}
+
+void printScores(struct gameState *game) {
+ int playerNum, score[MAX_PLAYERS];
+ int numPlayers = game->numPlayers;
+ for(playerNum = 0; playerNum < numPlayers; playerNum++) {
+ score[playerNum] = scoreFor(playerNum,game);
+ printf("Player %d has a score of %d\n", playerNum, score[playerNum]);
+ }
+}
+
+
+void printHelp(void) {
+ printf("Commands are: \n\
+ add [Supply Card Number] - add any card to your hand (teh hacks)\n\
+ buy [Supply Card Number] - buy a card at supply position\n\
+ end - end your turn\n\
+ init [Number of Players] [Number of Bots] - initialize the game\n\
+ num - print number of cards in your hand\n\
+ play [Hand Index] [Choice] [Choice] [Choice] - play a card from your hand\n\
+ resign - end the game showing the current scores\n\
+ show - show your current hand\n\
+ stat - show your turn's status\n\
+ supp - show the supply\n\
+ whos - whos turn\n\
+ exit - exit the interface");
+ printf("\n\n");
+
+}
+
+
+void phaseNumToName(int phase, char *name) {
+ switch(phase) {
+ case ACTION_PHASE:
+ strcpy(name,"Action");
+ break;
+ case BUY_PHASE:
+ strcpy(name,"Buy");
+ break;
+ case CLEANUP_PHASE:
+ strcpy(name,"Cleanup");
+ break;
+ }
+}
+
+
+int addCardToHand(int player, int card, struct gameState *game) {
+ if(card >= adventurer && card < NUM_TOTAL_K_CARDS) {
+ int handTop = game->handCount[player];
+ game->hand[player][handTop] = card;
+ game->handCount[player]++;
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+
+}
+
+void selectKingdomCards(int randomSeed, int kingCards[NUM_K_CARDS]) {
+ int i, used, card, numSelected = 0;
+ SelectStream(1);
+ PutSeed((long)randomSeed);
+
+
+ while(numSelected < NUM_K_CARDS) {
+ used = FALSE;
+ card = floor(Random() * NUM_TOTAL_K_CARDS);
+ if(card < adventurer) continue;
+ for(i = 0; i < numSelected; i++) {
+ if(kingCards[i] == card) {
+ used = TRUE;
+ break;
+ }
+ }
+ if(used == TRUE) continue;
+ kingCards[numSelected] = card;
+ numSelected++;
+ }
+}
+
+
+int countHandCoins(int player, struct gameState *game) {
+ int card, index, coinage = 0;
+
+ for(index = 0; index < game->handCount[player]; index++) {
+ card = game->hand[player][index];
+ switch(card) {
+ case copper:
+ coinage += COPPER_VALUE;
+ break;
+ case silver:
+ coinage += SILVER_VALUE;
+ break;
+ case gold:
+ coinage += GOLD_VALUE;
+ break;
+ }
+ }
+ return coinage;
+}
+
+
+void executeBotTurn(int player, int *turnNum, struct gameState *game) {
+ int coins = countHandCoins(player, game);
+
+ printf("*****************Executing Bot Player %d Turn Number %d*****************\n", player, *turnNum);
+ printSupply(game);
+ //sleep(1); //Thinking...
+
+ if(coins >= PROVINCE_COST && supplyCount(province,game) > 0) {
+ buyCard(province,game);
+ printf("Player %d buys card Province\n\n", player);
+ }
+ else if(supplyCount(province,game) == 0 && coins >= DUCHY_COST ) {
+ buyCard(duchy,game);
+ printf("Player %d buys card Duchy\n\n", player);
+ }
+ else if(coins >= GOLD_COST && supplyCount(gold,game) > 0) {
+ buyCard(gold,game);
+ printf("Player %d buys card Gold\n\n", player);
+ }
+ else if(coins >= SILVER_COST && supplyCount(silver,game) > 0) {
+ buyCard(silver,game);
+ printf("Player %d buys card Silver\n\n", player);
+
+ }
+
+
+ if(player == (game->numPlayers -1)) (*turnNum)++;
+ endTurn(game);
+ if(! isGameOver(game)) {
+ int currentPlayer = whoseTurn(game);
+ printf("Player %d's turn number %d\n\n", currentPlayer, (*turnNum));
+ }
+}
diff --git a/projects/alghanmz/dominion/interface.h b/projects/alghanmz/dominion/interface.h
new file mode 100644
index 000000000..6f7bacac2
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/playdom.c b/projects/alghanmz/dominion/playdom.c
new file mode 100644
index 000000000..336d9a661
--- /dev/null
+++ b/projects/alghanmz/dominion/playdom.c
@@ -0,0 +1,135 @@
+#include "dominion.h"
+#include
+#include "rngs.h"
+#include
+
+int main (int argc, char** argv) {
+ struct gameState G;
+ int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse,
+ sea_hag, tribute, smithy
+ };
+
+ printf ("Starting game.\n");
+
+ initializeGame(2, k, atoi(argv[1]), &G);
+
+ int money = 0;
+ int smithyPos = -1;
+ int adventurerPos = -1;
+ int i=0;
+
+ int numSmithies = 0;
+ int numAdventurers = 0;
+
+ while (!isGameOver(&G)) {
+ money = 0;
+ smithyPos = -1;
+ adventurerPos = -1;
+ for (i = 0; i < numHandCards(&G); i++) {
+ if (handCard(i, &G) == copper)
+ money++;
+ else if (handCard(i, &G) == silver)
+ money += 2;
+ else if (handCard(i, &G) == gold)
+ money += 3;
+ else if (handCard(i, &G) == smithy)
+ smithyPos = i;
+ else if (handCard(i, &G) == adventurer)
+ adventurerPos = i;
+ }
+
+ if (whoseTurn(&G) == 0) {
+ if (smithyPos != -1) {
+ printf("0: smithy played from position %d\n", smithyPos);
+ playCard(smithyPos, -1, -1, -1, &G);
+ printf("smithy played.\n");
+ money = 0;
+ i=0;
+ while(i= 8) {
+ printf("0: bought province\n");
+ buyCard(province, &G);
+ }
+ else if (money >= 6) {
+ printf("0: bought gold\n");
+ buyCard(gold, &G);
+ }
+ else if ((money >= 4) && (numSmithies < 2)) {
+ printf("0: bought smithy\n");
+ buyCard(smithy, &G);
+ numSmithies++;
+ }
+ else if (money >= 3) {
+ printf("0: bought silver\n");
+ buyCard(silver, &G);
+ }
+
+ printf("0: end turn\n");
+ endTurn(&G);
+ }
+ else {
+ if (adventurerPos != -1) {
+ printf("1: adventurer played from position %d\n", adventurerPos);
+ playCard(adventurerPos, -1, -1, -1, &G);
+ money = 0;
+ i=0;
+ while(i= 8) {
+ printf("1: bought province\n");
+ buyCard(province, &G);
+ }
+ else if ((money >= 6) && (numAdventurers < 2)) {
+ printf("1: bought adventurer\n");
+ buyCard(adventurer, &G);
+ numAdventurers++;
+ } else if (money >= 6) {
+ printf("1: bought gold\n");
+ buyCard(gold, &G);
+ }
+ else if (money >= 3) {
+ printf("1: bought silver\n");
+ buyCard(silver, &G);
+ }
+ printf("1: endTurn\n");
+
+ endTurn(&G);
+ }
+ } // end of While
+
+ printf ("Finished game.\n");
+ printf ("Player 0: %d\nPlayer 1: %d\n", scoreFor(0, &G), scoreFor(1, &G));
+
+ return 0;
+}
diff --git a/projects/alghanmz/dominion/player.c b/projects/alghanmz/dominion/player.c
new file mode 100644
index 000000000..0a169d126
--- /dev/null
+++ b/projects/alghanmz/dominion/player.c
@@ -0,0 +1,205 @@
+/* Interactive Dominion Interface
+ Version 7
+
+ Sam Heinith CS362
+ Questions/Comments:
+ heiniths@onid.orst.edu
+ 1/26/2010
+*/
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dominion.h"
+#include "interface.h"
+#include "rngs.h"
+
+
+int main2(int argc, char *argv[]) {
+ //Default cards, as defined in playDom
+ int k[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy};
+ struct gameState g;
+ initializeGame(2,k,1,&g);
+ printf ("SUCCESSFUL INIT\n");
+ getchar();
+ return 0;
+}
+
+int main(int argc, char* argv[]) {
+ char *add = "add";
+ char *buyC = "buy";
+ char *endT = "end";
+ char *exit = "exit";
+ char *help = "help";
+ char *init = "init";
+ char *numH = "num";
+ char *play = "play";
+ char *resign = "resi";
+ char *show = "show";
+ char *stat = "stat";
+ char *supply = "supp";
+ char *whos = "whos";
+
+ char command[MAX_STRING_LENGTH];
+ char line[MAX_STRING_LENGTH];
+ char cardName[MAX_STRING_LENGTH];
+
+ //Array to hold bot presence
+ int isBot[MAX_PLAYERS] = { 0, 0, 0, 0};
+
+ int players[MAX_PLAYERS];
+ int playerNum;
+ int outcome;
+ int currentPlayer;
+ int gameOver = FALSE;
+ int gameStarted = FALSE;
+ int turnNum = 0;
+
+ int randomSeed = atoi(argv[1]);
+
+ //Default cards, as defined in playDom
+ int kCards[10] = {adventurer, gardens, embargo, village, minion, mine, cutpurse, sea_hag, tribute, smithy};
+
+ struct gameState g;
+ struct gameState * game = &g;
+
+ memset(game,0,sizeof(struct gameState));
+
+ if(argc != 2) {
+ printf("Usage: player [integer random number seed]\n");
+ return EXIT_SUCCESS;
+ }
+
+ if(randomSeed <= 0) {
+ printf("Usage: player [integer random number seed]\n");
+ return EXIT_SUCCESS;
+ }
+
+ initializeGame(2,kCards,randomSeed,game);
+
+ printf("Please enter a command or \"help\" for commands\n");
+
+
+ while(TRUE) {
+ int arg0 = UNUSED;
+ int arg1 = UNUSED;
+ int arg2 = UNUSED;
+ int arg3 = UNUSED;
+
+ outcome = FAILURE;
+ strcpy(line,"");
+ strcpy(command,"");
+ strcpy(cardName,"");
+
+ currentPlayer = whoseTurn(game);
+
+ //If you are getting a seg fault comment this if block out
+ gameOver = isGameOver(game);
+ if(gameStarted == TRUE && gameOver == TRUE) {
+ printScores(game);
+ getWinners(players, game);
+ printf("After %d turns, the winner(s) are:\n", turnNum);
+ for(playerNum = 0; playerNum < game->numPlayers; playerNum++) {
+ if(players[playerNum] == WINNER) printf("Player %d\n", playerNum);
+ }
+ for(playerNum = 0; playerNum < game->numPlayers; playerNum++) {
+ printHand(playerNum, game);
+ printPlayed(playerNum, game);
+ printDiscard(playerNum, game);
+ printDeck(playerNum, game);
+ }
+
+ break; //Exit out of the game/while loop
+ }
+
+
+ if(isBot[currentPlayer] == TRUE) {
+ executeBotTurn(currentPlayer, &turnNum, game);
+ continue;
+ }
+
+ printf("$ ");
+ fgets(line, MAX_STRING_LENGTH, stdin);
+ sscanf(line, "%s %d %d %d %d", command, &arg0, &arg1, &arg2, &arg3);
+
+
+ if(COMPARE(command, add) == 0) {
+ outcome = addCardToHand(currentPlayer, arg0, game);
+ cardNumToName(arg0, cardName);
+ printf("Player %d adds %s to their hand\n\n", currentPlayer, cardName);
+ } else if(COMPARE(command, buyC) == 0) {
+ outcome = buyCard(arg0, game);
+ cardNumToName(arg0, cardName);
+ if(outcome == SUCCESS) {
+ printf("Player %d buys card %d, %s\n\n", currentPlayer, arg0, cardName);
+ } else {
+ printf("Player %d cannot buy card %d, %s\n\n", currentPlayer, arg0, cardName);
+ }
+ } else if(COMPARE(command, endT) == 0) {
+ if(gameStarted == TRUE) {
+ if(currentPlayer == (game->numPlayers -1)) turnNum++;
+ endTurn(game);
+ currentPlayer = whoseTurn(game);
+ printf("Player %d's turn number %d\n\n", currentPlayer, turnNum);
+ }
+
+ } else if(COMPARE(command, exit) == 0) {
+ break;
+ } else if(COMPARE(command, help) == 0) {
+ printHelp();
+ } else if(COMPARE(command, init) == 0) {
+ int numHuman = arg0 - arg1;
+ for(playerNum = numHuman; playerNum < arg0; playerNum++) {
+ isBot[playerNum] = TRUE;
+ }
+ // selectKingdomCards(randomSeed, kCards); //Comment this out to use the default card set defined in playDom.
+ outcome = initializeGame(arg0, kCards, randomSeed, game);
+ printf("\n");
+ if(outcome == SUCCESS) {
+ gameStarted = TRUE;
+ currentPlayer = whoseTurn(game);
+ printf("Player %d's turn number %d\n\n", currentPlayer, turnNum);
+ }
+
+ } else if(COMPARE(command, numH) == 0) {
+ int numCards = numHandCards(game);
+ printf("There are %d cards in your hand.\n", numCards);
+ } else if(COMPARE(command, play) == 0) {
+ int card = handCard(arg0,game);
+ outcome = playCard(arg0, arg1, arg2, arg3, game);
+ cardNumToName(card, cardName);
+ if(outcome == SUCCESS) {
+ printf("Player %d plays %s\n\n", currentPlayer, cardName);
+ } else {
+ printf("Player %d cannot play card %d\n\n", currentPlayer, arg0);
+ }
+
+ } else if(COMPARE(command, resign) == 0) {
+ endTurn(game);
+ printScores(game);
+ break;
+ } else if(COMPARE(command, show) == 0) {
+ if(gameStarted == FALSE) continue;
+ printHand(currentPlayer, game);
+ printPlayed(currentPlayer, game);
+ //printDiscard(currentPlayer, game);
+ //printDeck(currentPlayer, game);
+ } else if(COMPARE(command, stat) == 0) {
+ if(gameStarted == FALSE) continue;
+ printState(game);
+ } else if(COMPARE(command, supply) == 0) {
+ printSupply(game);
+ } else if(COMPARE(command, whos) == 0) {
+ int playerNum = whoseTurn(game);
+ printf("Player %d's turn\n", playerNum);
+ }
+ }
+
+ return EXIT_SUCCESS;
+
+}
diff --git a/projects/alghanmz/dominion/rngs.c b/projects/alghanmz/dominion/rngs.c
new file mode 100644
index 000000000..a85bbc961
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/rngs.gcno b/projects/alghanmz/dominion/rngs.gcno
new file mode 100644
index 000000000..37805923b
Binary files /dev/null and b/projects/alghanmz/dominion/rngs.gcno differ
diff --git a/projects/alghanmz/dominion/rngs.h b/projects/alghanmz/dominion/rngs.h
new file mode 100644
index 000000000..c9f3f451a
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/rngs.o b/projects/alghanmz/dominion/rngs.o
new file mode 100644
index 000000000..b67f557ce
Binary files /dev/null and b/projects/alghanmz/dominion/rngs.o differ
diff --git a/projects/alghanmz/dominion/rt.c b/projects/alghanmz/dominion/rt.c
new file mode 100644
index 000000000..5805bb9b4
--- /dev/null
+++ b/projects/alghanmz/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/alghanmz/dominion/save/refactored_dominion.c b/projects/alghanmz/dominion/save/refactored_dominion.c
new file mode 100644
index 000000000..a6af075af
--- /dev/null
+++ b/projects/alghanmz/dominion/save/refactored_dominion.c
@@ -0,0 +1,1402 @@
+#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 doMine(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ 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;
+}
+
+void getEstateCard(struct gameState *state, int currentPlayer)
+{
+ if (supplyCount(estate, state) > 0) {
+ gainCard(estate, state, 0, currentPlayer);//Gain an estate
+
+ state->supplyCount[estate]--;//Decrement Estates
+ if (supplyCount(estate, state) == 0) {
+ isGameOver(state);
+ }
+ }
+}
+
+void doBaron(int choice1, struct gameState *state, int currentPlayer)
+{
+ 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");
+ }
+ getEstateCard(state, currentPlayer);
+ card_not_discarded = 0;//Exit the loop
+ }
+
+ else {
+ p++;//Next card
+ }
+ }
+ }
+
+ else {
+ getEstateCard(state, currentPlayer);
+ }
+}
+
+void doMinion(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ int j;
+
+ //+1 action
+ state->numActions++;
+
+ //discard card from hand
+ discardCard(handPos, currentPlayer, state, 0);
+
+ if (choice1)
+ {
+ state->coins = state->coins + 2;
+ }
+ else if (choice2) //discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
+ {
+ //discard hand
+ while(numHandCards(state) > 0)
+ {
+ discardCard(handPos, currentPlayer, state, 0);
+ }
+
+ //draw 4
+ for (i = 0; i < 4; i++)
+ {
+ drawCard(currentPlayer, state);
+ }
+
+ //other players discard hand and redraw if hand size > 4
+ for (i = 0; i < state->numPlayers; i++)
+ {
+ if (i != currentPlayer)
+ {
+ if ( state->handCount[i] > 4 )
+ {
+ //discard hand
+ while( state->handCount[i] > 0 )
+ {
+ discardCard(handPos, i, state, 0);
+ }
+
+ //draw 4
+ for (j = 0; j < 4; j++)
+ {
+ drawCard(i, state);
+ }
+ }
+ }
+ }
+ }
+}
+
+void doTribute(struct gameState *state, int currentPlayer, int nextPlayer, int tributeRevealedCards[2])
+{
+ int i;
+
+ 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;
+ }
+ }
+}
+
+int doAmbassador(int choice1, int choice2, struct gameState *state, int handPos, int currentPlayer)
+{
+ int i;
+ int j;
+
+ 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 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:
+ return doMine(choice1, choice2, state, handPos, currentPlayer);
+
+ 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:
+ doBaron(choice1, state, currentPlayer);
+ 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:
+ doMinion(choice1, choice2, state, handPos, currentPlayer);
+ 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:
+ doTribute(state, currentPlayer, nextPlayer, tributeRevealedCards);
+ return 0;
+
+ case ambassador:
+ return doAmbassador(choice1, choice2, state, handPos, currentPlayer);
+
+ 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/alghanmz/dominion/testdrawcard.c b/projects/alghanmz/dominion/testdrawcard.c
new file mode 100644
index 000000000..da5379646
--- /dev/null
+++ b/projects/alghanmz/dominion/testdrawcard.c
@@ -0,0 +1,74 @@
+#include "dominion.h"
+#include "dominion_helpers.h"
+#include
+#include
+#include
+#include "rngs.h"
+
+#define DEBUG 0
+#define NOISY_TEST 1
+
+int checkDrawCard(int p, struct gameState *post) {
+ struct gameState pre;
+ memcpy (&pre, post, sizeof(struct gameState));
+
+ int r;
+ // printf ("drawCard PRE: p %d HC %d DeC %d DiC %d\n",
+ // p, pre.handCount[p], pre.deckCount[p], pre.discardCount[p]);
+
+ r = drawCard (p, post);
+
+ //printf ("drawCard POST: p %d HC %d DeC %d DiC %d\n",
+ // p, post->handCount[p], post->deckCount[p], post->discardCount[p]);
+
+ if (pre.deckCount[p] > 0) {
+ pre.handCount[p]++;
+ pre.hand[p][pre.handCount[p]-1] = pre.deck[p][pre.deckCount[p]-1];
+ pre.deckCount[p]--;
+ } else if (pre.discardCount[p] > 0) {
+ memcpy(pre.deck[p], post->deck[p], sizeof(int) * pre.discardCount[p]);
+ memcpy(pre.discard[p], post->discard[p], sizeof(int)*pre.discardCount[p]);
+ pre.hand[p][post->handCount[p]-1] = post->hand[p][post->handCount[p]-1];
+ pre.handCount[p]++;
+ pre.deckCount[p] = pre.discardCount[p]-1;
+ pre.discardCount[p] = 0;
+ }
+
+ assert (r == 0);
+
+ assert(memcmp(&pre, post, sizeof(struct gameState)) == 0);
+}
+
+int main () {
+
+ int i, n, r, p, deckCount, discardCount, handCount;
+
+ int k[10] = {adventurer, council_room, feast, gardens, mine,
+ remodel, smithy, village, baron, great_hall
+ };
+
+ struct gameState G;
+
+ printf ("Testing drawCard.\n");
+
+ printf ("RANDOM TESTS.\n");
+
+ SelectStream(2);
+ PutSeed(3);
+
+ for (n = 0; n < 2000; n++) {
+ for (i = 0; i < sizeof(struct gameState); i++) {
+ ((char*)&G)[i] = floor(Random() * 256);
+ }
+ p = floor(Random() * 2);
+ G.deckCount[p] = floor(Random() * MAX_DECK);
+ G.discardCount[p] = floor(Random() * MAX_DECK);
+ G.handCount[p] = floor(Random() * MAX_HAND);
+ checkDrawCard(p, &G);
+ }
+
+ printf ("ALL TESTS OK\n");
+
+ exit(0);
+
+}
diff --git a/projects/alghanmz/p.txt b/projects/alghanmz/p.txt
new file mode 100644
index 000000000..44ee501f8
--- /dev/null
+++ b/projects/alghanmz/p.txt
@@ -0,0 +1 @@
+cout << "H"