예제 #1
0
/**
 * \param agent
 * \return The estimated construction time of the device and its components, if the agent is able to buy some components
 */
double Device::expectedConstructionTime(Agent &agent)
{
    /*
     * if the agent believes that it can buy the device, the expected time
     * to build the device is 0.
     */
    if (agent.canBuy(*this).first) {
        return 0.0;
    }
    /*
     * If the agent does not believe it can buy the device, it calculates
     * the time required to make the device based on its experience and 
     * whether or not it has a device-making device, then it recursively
     * adds the expected construction time of each of the components
     */
    device_name_t bestDevDevice = agent.bestDevDevice(type, use);
    double time;
    if (bestDevDevice != NO_DEVICE) {
        time = agent.deviceEffortCalc(use, type) / agent.getDeviceFactor(bestDevDevice);
    } else {
        time = agent.deviceEffortCalc(use, type);
    }

    for (int i = 0; i < (int) components.size(); i++) {
        int comp = components[i];
        time += glob.discoveredDevices[componentType][comp]->expectedConstructionTime(agent);
    }
    return time;
}
예제 #2
0
/**
 * \param agent
 * \return the sum of the costs of the components to the agent
 */
double Device::costs(Agent &agent)
{
    if (agent.devProp[type][use].costOfDeviceMemoryValid) {
        return agent.devProp[type][use].costOfDeviceMemory;
    } else {
        /* canBuy returns a boolean and a double */
        pair<bool, double> buy = agent.canBuy(*this);
        /*
         * canBuy is the boolean; it indicates whether or not the agent
         * believes it is able to buy the device
         */
        bool canBuy = buy.first;
        /*
         * If the agent believes it is able to buy the device, the price (in
         * utils) that it expects to pay is avgPrice
         * So, if the agent believes it is able to buy the device, the cost
         * is avgPrice.
         */
        double avgPrice = buy.second;
        if (canBuy) {
            return avgPrice;
            /*
             * If the agent does not believe that it can buy the device, it
             * calculates the cost of the device as the time required to make
             * this device plus the cost of all the components of this device
             * (so the cost function gets called recursively on lower and lower
             * order devices)
             */
        } else {
            /*
             * First the agent calculates the time required to make the
             * device based on the agent's experience and whether or not it
             * has a device-making device
             */
            double time;
            device_name_t bestDevDevice = agent.bestDevDevice(type, use);
            if (bestDevDevice != NO_DEVICE) {
                time = agent.deviceEffortCalc(use, type) / agent.getDeviceFactor(bestDevDevice);
            } else {
                time = agent.deviceEffortCalc(use, type);
            }
            /*
             * The initial cost is the required time multiplied by the gain
             * per minute that the agent was getting at the end of the last
             * work day
             */
            double cost = time * agent.endDayGPM;
            
            /*
             * Then, the agent adds the cost of each of the components of
             * this device.
             */
            for (int i = 0; i < (int) components.size(); i++) {
                int comp = components[i];
                cost += glob.discoveredDevices[componentType][comp]->costs(agent);
            }
            agent.devProp[type][use].costOfDeviceMemory = cost;
            agent.devProp[type][use].costOfDeviceMemoryValid = true;
            return cost;
        }
    }
}
예제 #3
0
/**
 * \param an agent
 * \return a pair of (timeNeeded, necessaryRes) where the necessary time and resources to make the device and its components, if the agent is not able to buy any components.
 */
pair<double, vector<int> > Device::worstCaseConstruction(Agent &agent)
{
    /*
     * If the memory of this calculation that the agent has is valid, return
     * the value in memory
     */
    if (agent.devProp[type][use].worstCaseConstructionMemoryValid) {
        return agent.devProp[type][use].worstCaseConstructionMemory;
    } else {
        /*
         * highOrderNeeded will be a list of the number of typeToCheck
         * devices needed for the corresponding resId
         */
        vector<int> highOrderNeeded(glob.NUM_RESOURCES, 0);
        /*
         * Begin by requiring one device of the type that is currently under
         * consideration
         */
        highOrderNeeded[use] = 1;
        /* typeToCheck begins as the type of device under consideration */
        device_name_t typeToCheck = type;
        /* compType is the component type of typeToCheck */
        device_name_t compType = componentType;
        /*
         * timeNeeded will be the total, worst case time for this device and
         * its components.
         */
        double timeNeeded = 0.0;
        if (devDevice != NO_DEVICE &&
            agent.devProp[devDevice][use].deviceHeld > 0.0) {
            timeNeeded = agent.deviceEffortCalc(use, type) / agent.getDeviceFactor(devDevice);
        } else {
            timeNeeded = agent.deviceEffortCalc(use, type);
        }

        /*
         * Loop through so that typeToCheck and compType become lower and
         * lower order device types; stop when there are no more lower order
         * devices to consider.
         */
        while (compType != NO_DEVICE) {
            /*
             * Given the number of typeToCheck devices in highOrderNeeded,
             * compNeeded is the number of compType devices needed for each
             * corresponding resId.
             */
            vector<int> compNeeded(glob.NUM_RESOURCES, 0);
            /*
             * Begin by simply adding the components of devices in
             * highOrderNeeded
             */
            for (int resId = 0; resId < glob.NUM_RESOURCES; resId++) {
                if (highOrderNeeded[resId] > 0) {
                    for (int i = 0; i < (int) glob.discoveredDevices[typeToCheck][resId]->components.size(); i++) {
                        int compId = glob.discoveredDevices[typeToCheck][resId]->components[i];
                        compNeeded[compId] += highOrderNeeded[resId];
                    }
                }
            }
            
            for (int resId = 0; resId < glob.NUM_RESOURCES; resId++) {
                if (compNeeded[resId] > 0) {
                    /*
                     * Remove devices from compNeeded if enough of the
                     * device is held by the agent; the number removed is
                     * the number of devices held (i.e. lifetime held
                     * divided by lifetime per device)
                     */
                    compNeeded[resId] = max(0, compNeeded[resId] -
                                                (int(agent.devProp[compType][resId].deviceHeld)
                                                        / int(agent.getDeviceLifetime(compType))));
                }
            }
            
            /*
             * The time needed to make each of these components is added to
             * timeNeeded
             */
            for (int resId = 0; resId < glob.NUM_RESOURCES; resId++) {
                if (compNeeded[resId] > 0) {

                    device_name_t devDevice = glob.discoveredDevices[compType][resId]->devDevice;
                    /*
                     * If the device-making device is not invented or if
                     * the agent doesn't hold any, the devDeviceFactor
                     * is 1 (i.e. no effect on production)
                     */
                    double devDeviceFactor = 1.0;
                    if (devDevice != NO_DEVICE &&
                        agent.devProp[devDevice][resId].deviceHeld > 0.0) {
                        devDeviceFactor = agent.getDeviceFactor(devDevice);
                    }
                    for (int i = 0; i < compNeeded[resId]; i++) {
                        timeNeeded += agent.tempDeviceEffortCalc(resId, compType, i) / devDeviceFactor;
                    }
                }
            }
            
            /*
             * Once held devices have been removed from compNeeded, the
             * values in highOrderNeeded become the values from compNeeded,
             * and the loop starts again.
             */
            for (int resId = 0; resId < glob.NUM_RESOURCES; resId++) {
                highOrderNeeded[resId] = compNeeded[resId];
            }
            // typeToCheck and compType move one order down			
            typeToCheck = compType;
            compType = glob.discoveredDevices[typeToCheck][use]->componentType;
        }
        /*
         * When compType is None, typeToCheck is 'Tool', so the
         * highOrderNeeded list is the list of the number of tools needed
         * for each corresponding resId, so the necessary resources for this
         * device is the sum of necessary resources for each tool
         */
        vector<int> necessaryRes(glob.NUM_RESOURCES, 0);
        for (int resIdA = 0; resIdA < glob.NUM_RESOURCES; resIdA++) {
            if (highOrderNeeded[resIdA] > 0) {
                vector<int> thisToolNeeds = glob.discoveredDevices[TOOL][resIdA]->necessaryResources;
                for (int resIdB = 0; resIdB < glob.NUM_RESOURCES; resIdB++) {
                    necessaryRes[resIdB] += highOrderNeeded[resIdA] * thisToolNeeds[resIdB];
                }
            }
        }

        // Agents remember this calculated list
        agent.devProp[type][use].worstCaseConstructionMemory = make_pair(timeNeeded, necessaryRes);
        agent.devProp[type][use].worstCaseConstructionMemoryValid = true;
        return pair<double, vector<int> >(timeNeeded, necessaryRes);
    }
}