mechanicalTurk.c - OpenLearning
/* 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)

Comments

Chat