Пример #1
0
static void test_income(CuTest *tc)
{
    race *rc;
    unit *u;
    test_setup();
    rc = test_create_race("nerd");
    u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
    CuAssertIntEquals(tc, 20, income(u));
    u->number = 5;
    CuAssertIntEquals(tc, 100, income(u));
    test_cleanup();
}
Пример #2
0
	virtual void evaluate_income(int target_size, std::ostream &os)
	{
		if (not_available(target_size, os))
		{
			return;
		}

		int remaining = target_size;
		price_t income(0);

		// start from the end of the order list to maximize profit
		// iterate over sorted orders; O(N), N/2 on average
		sorted_orders_t::iterator it = m_sorted_orders.begin();
		for (; it != m_sorted_orders.end() && remaining > 0; ++it)
		{
			order_ptr & ord = (*it);

			if (!ord->active())
			{
				continue;
			}

			int shares = std::min(remaining, ord->size());

			income += ord->price_of(shares);

			remaining -= shares;
		}
		report_income(income, os);
	}
Пример #3
0
// Lambert 面の Radiance の評価
Color PathTracer::Radiance_Lambert(const Scene &scene, const Ray &ray, Random &rnd, const int depth, Scene::IntersectionInformation &intersect, const Vector3 &normal, double russian_roulette_prob) {

  Color direct;

  // 直接光を評価する
  if (m_performNextEventEstimation && intersect.object->material.emission.lengthSq() == 0) {
    direct = DirectRadiance_Lambert(scene, ray, rnd, depth, true, intersect, normal);
  }

  Vector3 w,u,v;

  w = normal;
  if (fabs(normal.x) > EPS) {
   u = Vector3(0,1,0).cross(w);
  } else {
   u = Vector3(1,0,0).cross(w);
  }
  v = w.cross(u);
  double u1 = rnd.nextDouble(); double u2 = rnd.nextDouble();
  // pdf is 1/PI
  //double r1 = PI*u1; // Φ
  //double r2 = 1-u2; // cosθ
  //double r3 = sqrt(1-r2*r2); // sinθ
  //double pdf = 1/PI;

  // pdf is cosθ/PI
  double r1 = 2*PI*u1;
  double r2 = sqrt(u2); // cosθ
  double r3 = sqrt(1-u2); // sinθ
  double pdf = r2/PI;

  //const double r1 = 2 * PI * rnd.nextDouble();
  //const double r2 = rnd.nextDouble(), r2s = sqrt(r2);
  //Vector3 dir = u * cos(r1) * r2s + v * sin(r1) * r2s + w * sqrt(1.0-r2);
  //dir.normalize();
  //weight = intersect.object->color / russian_roulette_probability;

  Vector3 dir = u*r3*cos(r1) + v*r3*sin(r1) + w*r2;
  dir.normalize();

  //Color weight = intersect.object->color / PI * r2 / pdf / russian_roulette_prob;
  Color weight = intersect.texturedHitpointColor;
  Color income(0,0,0);
  if (intersect.object->material.emission.lengthSq() == 0) {
    income = Radiance(scene, Ray(intersect.hit.position, dir), rnd, depth + 1);
  } 
  // direct はすでに反射率が乗算済みなので、weightを掛ける必要はない
  return ( Vector3(weight.x*income.x, weight.y*income.y, weight.z*income.z) + direct ) / russian_roulette_prob;
}
Пример #4
0
void BudgetWindow::GenerateBudget(const bool &zero)
{
	// Generate a budget based on the last year's transactions
	ReportGrid income(1,0), spending(1,0);

	gDatabase.DBCommand("delete from budgetlist",
						"BudgetWindow::GenerateBudget:empty budget");

	CppSQLite3Query query;
	query = gDatabase.DBQuery("select * from categorylist order by name",
							"BudgetWindow::GenerateBudget:get categories");

	if(query.eof())
		return;

	float maxwidth=fCategoryList->StringWidth(TRANSLATE("Category"));
	while(!query.eof())
	{
		BString catname = DeescapeIllegalCharacters(query.getStringField(0));

		if(catname.ICompare(TRANSLATE("Transfer"))==0)
		{
			query.nextRow();
			continue;
		}

		bool isexpense = !query.getIntField(1);

		if(isexpense)
		{
			spending.AddItem();
			spending.SetRowTitle(spending.CountItems()-1,catname.String());
		}
		else
		{
			income.AddItem();
			income.SetRowTitle(income.CountItems()-1,catname.String());
		}
		float tempwidth = fCategoryList->StringWidth(catname.String());
		maxwidth = MAX(maxwidth,tempwidth);
		query.nextRow();
	}

	query.finalize();

	// Now that we have the list of categories, query for transactions for each
	// account from each category

	BString querystring;
	Fixed cattotal;
	for(int32 i=0; i<income.CountItems(); i++)
	{
		querystring = "";
		cattotal = 0;

		if(!zero)
		{
			for(int32 j=0; j<gDatabase.CountAccounts(); j++)
			{
				Account *acc = gDatabase.AccountAt(j);
				querystring = "select sum(amount) from account_" ;
				querystring << acc->GetID()	<< " where category = '"
							<< EscapeIllegalCharacters(income.RowTitle(i))
							<< "' and date > " << DecrementDateByYear(GetCurrentDate()) << ";";
				query = gDatabase.DBQuery(querystring.String(),
										"BudgetWindow::GenerateBudget:get category");
				cattotal.AddPremultiplied(query.getInt64Field(0));
				query.finalize();
			}
			cattotal /= 12;
			cattotal.Round();
		}
		income.SetValue(0,i,cattotal);
		gDatabase.AddBudgetEntry(BudgetEntry(income.RowTitle(i),cattotal,BUDGET_MONTHLY,false));
	}

	for(int32 i=0; i<spending.CountItems(); i++)
	{
		querystring = "";
		cattotal = 0;

		if(!zero)
		{
			for(int32 j=0; j<gDatabase.CountAccounts(); j++)
			{
				Account *acc = gDatabase.AccountAt(j);
				querystring = "select sum(amount) from account_" ;
				querystring << acc->GetID()	<< " where category = '"
							<< EscapeIllegalCharacters(spending.RowTitle(i))
							<< "';";
				query = gDatabase.DBQuery(querystring.String(),
										"BudgetWindow::GenerateBudget:get category");
				cattotal.AddPremultiplied(query.getInt64Field(0));
				query.finalize();
			}
			cattotal /= 12;
			cattotal.Round();
		}
		spending.SetValue(0,i,cattotal);
		gDatabase.AddBudgetEntry(BudgetEntry(spending.RowTitle(i),cattotal,BUDGET_MONTHLY,true));
	}
}
Пример #5
0
	void new_turn() { gold_ += income(); }
Пример #6
0
vec3 DirectLightIntegrator::income(const Ray &r,
	const shared_ptr<Scene> &scene,
	int level) {

	vec3 L(0.0f);

	Intersection hit(NULL, NULL, CONST_FAR);

	// Is there intersection?
	if (!scene->intersect(r, hit)) {
		return L;
	}

    // Is this intersection on the light?
    if (hit.type == INTERSECTION_LIGHT) {
        // Simply return the color from the light.
        const Light *light = static_cast<const Light *>(hit.intersectable);
        return light->Le(hit.point) * clamp(dot(hit.normal, -r.d), 0.0f, 1.0f);
    }

	// Sample for one light.
    if (!hit.m->bsdf->isDelta()) {

        // This is not a delta brdf. Randomly pick one light.
        int lightId = floor(Sampler::sample1D(0.0f, (float)scene->lights.size() - 0.1f));
        const shared_ptr<Light> &light = scene->lights[lightId];

        // Get the shadow ray and the distance to the light.
        vec3 Lo(0.0f);
        for (int i = 0; i < nLightSamples; ++i) {
            auto sample = light->genShadowRay(hit);

            Ray shadowRay = sample.first;
            float lightPDF = sample.second;

            if (lightPDF < CONST_EPSILON) {
                continue;
            }

            // Use the shadow ray to find intersect.
            if (scene->occlude(shadowRay)) {
                continue;
            }

            // Get the light color.
            vec3 pointOnLight = shadowRay.o + shadowRay.tmax * shadowRay.d;
            vec3 Le = light->Le(pointOnLight);
            vec3 f = hit.m->bsdf->bsdf(hit, r.d, shadowRay.d);
            float w = powerHeuristec(lightPDF, nLightSamples, hit.m->bsdf->pdf(hit, r.d, shadowRay.d), nBSDFSamples);

            // Here the geometry term is inside the pdf.
            // Use power heuristic.
            Lo += f * Le * w / lightPDF;
        }
        Lo /= nLightSamples;
        L += Lo;

        // Sample for BSDF.
        if (level < maxDepth - 1) {

            vec3 LBSDF(0.0f);
            for (int i = 0; i < nBSDFSamples; ++i) {
                while (true) {
                    auto sample = hit.m->bsdf->sample(hit, r.d);
                    if (sample.second > 0.1f) {
                        auto Li = income(sample.first, scene, level + 1);
                        vec3 f = hit.m->bsdf->bsdf(hit, r.d, sample.first.d);

                        float w = powerHeuristec(sample.second, nBSDFSamples, light->pdfRay(hit, sample.first.d), nLightSamples);
                        //float w = 1.0f;
                        LBSDF += w * f * Li / sample.second;
                        break;
                    }
                }
            }
            LBSDF /= nBSDFSamples;
            L += clamp(LBSDF, 0.0f, 1.0f);

        }
    }
    else {
        // This is a delta brdf. Just sample the delta direction.
        if (level < maxDepth - 1) {
            auto sample = hit.m->bsdf->sample(hit, r.d);
            auto Li = income(sample.first, scene, level + 1);
            vec3 f = hit.m->bsdf->bsdf(hit, r.d, sample.first.d);
            L += f * Li;
        }
    }

	return L;
}
Пример #7
0
static order *plan_dragon(unit * u)
{
    attrib *ta = a_find(u->attribs, &at_targetregion);
    region *r = u->region;
    region *tr = NULL;
    bool move = false;
    order *long_order = NULL;

    if (ta == NULL) {
        move |= (r->land == 0 || r->land->peasants == 0);   /* when no peasants, move */
        move |= (r->land == 0 || r->land->money == 0);      /* when no money, move */
    }
    move |= chance(0.04);         /* 4% chance to change your mind */

    if (u_race(u) == get_race(RC_WYRM) && !move) {
        unit *u2;
        for (u2 = r->units; u2; u2 = u2->next) {
            /* wyrme sind einzelgänger */
            if (u2 == u) {
                /* we do not make room for newcomers, so we don't need to look at them */
                break;
            }
            if (u2 != u && u_race(u2) == u_race(u) && chance(0.5)) {
                move = true;
                break;
            }
        }
    }

    if (move) {
        /* dragon gets bored and looks for a different place to go */
        ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
    }
    else
        ta = a_find(u->attribs, &at_targetregion);
    if (ta != NULL) {
        tr = (region *)ta->data.v;
        if (tr == NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) {
            ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
            if (ta)
                tr = findregion(ta->data.sa[0], ta->data.sa[1]);
        }
    }
    if (tr != NULL) {
        assert(long_order == NULL);
        switch (old_race(u_race(u))) {
        case RC_FIREDRAGON:
            long_order = make_movement_order(u, tr, 4, allowed_dragon);
            break;
        case RC_DRAGON:
            long_order = make_movement_order(u, tr, 3, allowed_dragon);
            break;
        case RC_WYRM:
            long_order = make_movement_order(u, tr, 1, allowed_dragon);
            break;
        default:
            break;
        }
        if (long_order) {
            reduce_weight(u);
        }
        if (rng_int() % 100 < 15) {
            const struct locale *lang = u->faction->locale;
            /* do a growl */
            if (rname(tr, lang)) {
                addlist(&u->orders,
                    create_order(K_MAIL, lang, "%s '%s... %s %s %s'",
                    LOC(lang, parameters[P_REGION]),
                    random_growl(),
                    u->number ==
                    1 ? "Ich rieche" : "Wir riechen",
                    "etwas in", rname(tr, u->faction->locale)));
            }
        }
    }
    else {
        /* we have no target. do we like it here, then? */
        long_order = get_money_for_dragon(u->region, u, income(u));
        if (long_order == NULL) {
            /* money is gone, need a new target */
            set_new_dragon_target(u, u->region, DRAGON_RANGE);
        }
        else if (u_race(u) != get_race(RC_FIREDRAGON)) {
            /* neue dracoiden! */
            if (r->land && !fval(r->terrain, FORBIDDEN_REGION)) {
                int ra = 20 + rng_int() % 100;
                if (get_money(u) > ra * 50 + 100 && rng_int() % 100 < 50) {
                    recruit_dracoids(u, ra);
                }
            }
        }
    }
    if (long_order == NULL) {
        skill_t sk = SK_PERCEPTION;
        /* study perception (or a random useful skill) */
        while (!skill_enabled(sk) || u_race(u)->bonus[sk] < -5) {
            sk = (skill_t)(rng_int() % MAXSKILLS);
        }
        long_order = create_order(K_STUDY, u->faction->locale, "'%s'",
            skillname(sk, u->faction->locale));
    }
    return long_order;
}