/* Game.h #defines and prototypes
* NUM_UNIS
*
* // player ID of each university
* NO_ONE, UNI_A, UNI_B, UNI_C
*
* // contents of an ARC
* VACANT_ARC, ARC_A, ARC_B, ARC_C
*
* // contents of a VERTEX
* VACANT_VERTEX, CAMPUS_A, CAMPUS_B, CAMPUS_C, GO8_A, GO8_B, GO8_C
*
* // action codes
* PASS, BUILD_CAMPUS, BUILD_GO8, OBTAIN_ARC, START_SPINOFF,
* OBTAIN_PUBLICATION, OBTAIN_IP_PATENT, RETRAIN_STUDENTS
*
* // disciplines
* STUDENT_THD, STUDENT_BPS, STUDENT_BQN, STUDENT_MJ, STUDENT_MTV,
* STUDENT_MMONEY
*
* NUM_REGIONS, PATH_LIMIT
*
* TRUE, FALSE
*
* // structs
* typedef char path[PATH_LIMIT];
*
* typedef struct _action {
* int actionCode;
* path destination;
* int disciplineFrom;
* int disciplineTo;
* } action;
*
* // function prototypes
*
* void makeAction (Game g, action a); //Amelia
* void throwDice (Game g, int diceScore); //Jesse
* int getDiscipline (Game g, int regionID);
* int getDiceValue (Game g, int regionID);
* int getMostARCs (Game g);
* int getMostPublications (Game g);
* int getTurnNumber (Game g);
* int getWhoseTurn (Game g);
* int getCampus (Game g, path pathToVertex);
* int getARC (Game g, path pathToEdge);
* int isLegalAction (Game g, action a);
*
* --- get data about a specified player ---
* int getKPIpoints (Game g, int player);
* int getARCs (Game g, int player);
* int getGO8s (Game g, int player);
* int getCampuses (Game g, int player);
* int getIPs (Game g, int player);
* int getPublications (Game g, int player);
* int getStudents (Game g, int player, int discipline);
* int getExchangeRate (Game g, int player,
* int disciplineFrom, int disciplineTo);
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "Game.h"
#include "mechanicalTurk.h"
/* PATH_TO_TILE contains the first (top) arc of each tile oriented in
* the left to right direction. To obtain all arcs simply append R to
* circumnavigate the tile (moving clockwise).
*/
// Tile Num: 0 1 2 3 4
#define PATHS_TO_TILE "RRLRB", "RRLRLLL", "RRLRLLRLL", "RRB", "RRLLL", \
/* 5 6 7 8 9 10
*/ "RRLRLLLRL", "RRLRLLRLLRL", "L", "RLL", "RRLLLRL", "RRLRLLLRLRL", \
/* 11 12 13 14 15
*/ "RRLRLLRLLRLRL", "LRL", "RLLRL", "RRLLLRLRL", "RRLRLLLRLRLRL", \
/* 16 17 18
*/ "LRLRL", "LRLRRLL", "RRLLLRLRLRL"
#define NUM_VERTEXES 54
#define NUM_ARCS 72
typedef struct _resources {
int BPS;
int BQN;
int MJ;
int MTV;
int MMONEY;
} resources;
typedef struct _score {
int tileScores[NUM_REGIONS];
} score;
static action prioritiseActions (Game g, resources stu, path toCampus,
path toARC);
static score tileScores (Game g, int playerMe);
static action bestTrade (Game g, resources stu, int me);
static int canSpinoff (Game g, resources stu);
static int canBuildCampus (Game g, resources stu, path location);
static int canObtainArc (Game g, resources stu, path tilePath);
//takes input typedef Game, outputs typedef action
action decideAction (Game g) {
printf ("Starting to decide my action!\n");
//Find out which player I am and create an action
int me = getWhoseTurn (g);
action nextAction = {PASS};
resources stu;
// find out what resources I have and what to trade to in the end
// if I have left over MTV or MMONEY
stu.BPS = getStudents (g, me, STUDENT_BPS);
stu.BQN = getStudents (g, me, STUDENT_BQN);
stu.MJ = getStudents (g, me, STUDENT_MJ);
stu.MTV = getStudents (g, me, STUDENT_MTV);
stu.MMONEY = getStudents (g, me, STUDENT_MMONEY);
printf ("Got student resources\n");
score s = tileScores (g, me);
path tilePaths[NUM_REGIONS] = {PATHS_TO_TILE};
// determine the best location to build a campus
path bestCampus;
int bestCampusTileScore = 500;
// determine the best location to build an arc
path bestARC;
int bestArcTileScore = 500;
int count = 0;
while (count < NUM_REGIONS) {
path testPath;
strcpy (testPath, tilePaths[count]);
int currentTileScore = s.tileScores[count];
if (canObtainArc (g, stu, testPath)) {
if (currentTileScore < bestArcTileScore) {
strcpy (bestARC, testPath);
bestArcTileScore = currentTileScore;
printf ("ARC: %s\n", bestARC);
printf ("%d\n", bestArcTileScore);
}
}
if (canBuildCampus (g, stu, testPath) &&
currentTileScore < bestCampusTileScore) {
strcpy (bestCampus, testPath);
bestCampusTileScore = currentTileScore;
printf ("Campus: %s\n", bestCampus);
printf ("%d\n", bestCampusTileScore);
}
int c = 0;
while (c < 5) {
sprintf (testPath, "%s%c", testPath, 'R');
if (canObtainArc (g, stu, testPath)) {
if (currentTileScore < bestArcTileScore) {
strcpy (bestARC, testPath);
bestArcTileScore = currentTileScore;
printf ("ARC: %s\n", bestARC);
printf ("%d\n", bestArcTileScore);
}
}
if (canBuildCampus (g, stu, testPath) &&
currentTileScore < bestCampusTileScore) {
strcpy (bestCampus, testPath);
bestCampusTileScore = currentTileScore;
printf ("Campus: %s\n", bestCampus);
printf ("%d\n", bestCampusTileScore);
}
c++;
}
count++;
}
printf ("Found best paths\n");
// decide my action!
nextAction = prioritiseActions (g, stu, bestCampus,
bestARC);
return nextAction;
}
static action prioritiseActions (Game g, resources stu, path toCampus,
path toARC) {
action a;
int me = getWhoseTurn (g);
action trade = bestTrade (g, stu, me);
if (strcmp (trade.destination, "") == 0) {
// no action trading towards, simply prioritise
if (canBuildCampus (g, stu, toCampus)) {
a.actionCode = BUILD_CAMPUS;
strcpy (a.destination, toCampus);
} else if (canObtainArc (g, stu, toARC)) {
a.actionCode = OBTAIN_ARC;
strcpy (a.destination, toARC);
} else if (canSpinoff (g, stu)) {
a.actionCode = START_SPINOFF;
} else if ((isLegalAction (g, trade)) &&
(trade.actionCode != PASS)) {
a = trade;
} else {
a.actionCode = PASS;
}
} else {
// trading towards a particular action
if (canBuildCampus (g, stu, toCampus) &&
(strcmp (trade.destination, "CAMPUS") == 0)) {
a.actionCode = BUILD_CAMPUS;
strcpy (a.destination, toCampus);
} else if (canObtainArc (g, stu, toARC) &&
(strcmp (trade.destination, "ARC") == 0)) {
a.actionCode = OBTAIN_ARC;
strcpy (a.destination, toARC);
} else if (canSpinoff (g, stu) &&
(strcmp (trade.destination, "SPINOFF") == 0)) {
a.actionCode = START_SPINOFF;
} else if (isLegalAction (g, trade) &&
(trade.actionCode != PASS)) {
a = trade;
} else {
a.actionCode = PASS;
}
}
return a;
}
static action bestTrade (Game g, resources stu, int me) {
action trade = {RETRAIN_STUDENTS, ""};
trade.disciplineTo = STUDENT_BPS;
resources er;
er.BPS = getExchangeRate (g, me, STUDENT_BPS, 1);
er.BQN = getExchangeRate (g, me, STUDENT_BQN, 1);
er.MJ = getExchangeRate (g, me, STUDENT_MJ, 1);
er.MTV = getExchangeRate (g, me, STUDENT_MTV, 1);
er.MMONEY = getExchangeRate (g, me, STUDENT_MMONEY, 1);
int campusResources = stu.BPS/er.BPS + stu.BPS % er.BPS
+ stu.BQN/er.BQN + stu.BQN % er.BQN
+ stu.MJ/er.MJ + stu.MJ % er.MJ
+ stu.MTV/er.MTV + stu.MTV % er.MTV
+ stu.MMONEY/er.MMONEY;
int arcResources = stu.BPS/er.BPS + stu.BPS % er.BPS
+ stu.BQN/er.BQN + stu.BQN % er.BQN
+ stu.MJ/er.MJ
+ stu.MTV/er.MTV
+ stu.MMONEY/er.MMONEY;
int spinoffResources = stu.BPS/er.BPS
+ stu.BQN/er.BQN
+ stu.MJ/er.MJ + stu.MJ % er.MJ
+ stu.MTV/er.MTV + stu.MTV % er.MTV
+ stu.MMONEY/er.MMONEY + stu.MMONEY % er.MMONEY;
if (campusResources == 4) {
if (stu.MJ == 0) {
trade.disciplineTo = STUDENT_MJ;
} else if (stu.MTV == 0) {
trade.disciplineTo = STUDENT_MTV;
} else if (stu.BQN == 0) {
trade.disciplineTo = STUDENT_BQN;
} else if (stu.BPS == 0) {
trade.disciplineTo = STUDENT_BPS;
}
strcpy (trade.destination, "CAMPUS");
} else if (arcResources == 2) {
if (stu.BPS == 0) {
trade.disciplineTo = STUDENT_BPS;
} else if (stu.BQN == 0) {
trade.disciplineTo = STUDENT_BQN;
}
strcpy (trade.destination, "ARC");
} else if (spinoffResources == 3) {
if (stu.MJ == 0) {
trade.disciplineTo = STUDENT_MJ;
} else if (stu.MTV == 0) {
trade.disciplineTo = STUDENT_MTV;
} else if (stu.MMONEY == 0) {
trade.disciplineTo = STUDENT_MMONEY;
}
strcpy (trade.destination, "SPINOFF");
} else if (stu.MMONEY >= er.MMONEY) {
trade.disciplineTo = STUDENT_BPS;
trade.disciplineFrom = STUDENT_MMONEY;
} else if (stu.MTV >= er.MTV) {
trade.disciplineTo = STUDENT_BPS;
trade.disciplineFrom = STUDENT_MTV;
} else {
trade.actionCode = PASS;
}
if (stu.MMONEY > er.MMONEY &&
trade.disciplineTo != STUDENT_MMONEY) {
trade.disciplineFrom = STUDENT_MMONEY;
} else if (stu.MTV >= er.MTV &&
trade.disciplineTo != STUDENT_MTV) {
trade.disciplineFrom = STUDENT_MTV;
} else if (stu.MJ >= er.MJ &&
trade.disciplineTo != STUDENT_MJ) {
trade.disciplineFrom = STUDENT_MJ;
} else if (stu.BPS >= er.BPS &&
trade.disciplineTo != STUDENT_BPS) {
trade.disciplineFrom = STUDENT_BPS;
} else if (stu.BQN >= er.BQN &&
trade.disciplineTo != STUDENT_BQN) {
trade.disciplineFrom = STUDENT_BQN;
}
return trade;
}
static int canSpinoff (Game g, resources stu) {
action testAction = {START_SPINOFF};
return isLegalAction (g, testAction);
}
static int canBuildCampus (Game g, resources stu, path location) {
action test = {BUILD_CAMPUS};
strcpy (test.destination, location);
return isLegalAction (g, test);
}
static int canObtainArc (Game g, resources stu, path toARC) {
action test = {OBTAIN_ARC};
strcpy (test.destination, toARC);
return isLegalAction (g, test);
}
// Much like golf the lower the score the better. This function returns
// a struct called score that stores an array of tileScores. Each score
// is a sum of...
// A: the dice value of that tile (the closer it is to 7 the better)
// B: the exchange rate of the student type on that tile for that player
// (again, lower is better)
// C: the distance away from one of the starting campuses (defined above)
static score tileScores (Game g, int playerMe) {
score s;
int count = 0;
while (count < NUM_REGIONS) {
int disFrom7 = abs (getDiceValue (g, count) - 7);
int discipline = getDiscipline (g, count);
if (disFrom7 == 0 ) {
if ((discipline == STUDENT_MTV) ||
(discipline == STUDENT_MMONEY) ||
(discipline == STUDENT_THD)) {
disFrom7 = 7;
}
}
int exchangeRate = getExchangeRate (g, playerMe, discipline, 2);
s.tileScores[count] += disFrom7 + exchangeRate;
count++;
}
return s;
}
Download file:
mechanicalTurk.c
(11.8 KB)