/* 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)