int check_direction( int dir ) { int pos, tile; if( !dir ) { msg("You have to specify a direction when building a mine (i.e. 'build mine to the north')."); return -1; } set_direction(SINVERT_C(dir)); // Multiply up. dir = SMAKE_C(SCX(dir)*5, SCY(dir)*3, 0); pos = OFFSET_C(this_player()->query_coord(), dir); // Snap to grid pos = MAKE_C(((CX(pos)-1) / 5) * 5 + 1, ((CY(pos)-1) / 3) * 3 + 1, 0); // Now check to see if the tiletype is valid. Query the center of the tile // to make life a bit easier. tile = environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)+1); if( !tile ) { msg("You can't build off the edge of the map."); return -1; } tile -= '0'; // get_tiletype uses the zbuffer, which offsets by '0' ... if( tile != LAYER_MOUNTAIN ) { //debug("tile=="+as_string(tile)+", pos = "+MAKE_CSTR(pos)); msg( "Mines must be built against a mountain face. Find a mountainous place." ); return -1; } // Offset horizontally a bit to make the entrance stick out... if( SCX(dir) ) pos = OFFSET_C(pos, SMAKE_C(-SCX(dir) / 5,0,0)); // If facing south, adjust to find the entrance. // The mountain tiles have funny patterns, and this helps // to compensate. if( query_direction() == SMAKE_C(0,1,0) ) { pos = MAKE_C(CX(pos), CY(pos)-1, CZ(pos) ); while( environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)+3) == '0' + LAYER_MOUNTAIN ) { pos = MAKE_C(CX(pos),CY(pos)+1,CZ(pos)); } } // This is a north-facing version to snug the mine up as close as it can go. if( query_direction() == SMAKE_C(0,-1,0) ) { pos = MAKE_C(CX(pos), CY(pos)-1, CZ(pos) ); while( environment(this_player())->get_tiletype(CX(pos)+2, CY(pos)) != '0' + LAYER_MOUNTAIN ) { pos = MAKE_C(CX(pos),CY(pos)+1,CZ(pos)); } } set_coord( pos ); return 0; }
void Star(short a, double zmeas, double z0, double d0, double L, double u, double delta, double M, double N, double R, double *var, double *c, double *z0v, double (*Psi)(double z), double (*roughness)(double x, double y, double z) ){ *z0v=z0*(*roughness)(M, N, R); //if(*z0v<1.0E-5) *z0v=1.0E-5; *c=CZ(a,zmeas,*z0v,d0,L,(Psi)); *var=delta*ka/(*c); }
double PathDepOption::PriceByMC(BSModel Model, long N, double epsilon) { double H=0.0; double Hsq=0.0; int d = Model.S0.size(); SamplePath S(m); Matrix C = Model.C; Matrix CZ(d); for(int i=0;i<d;i++) CZ[i].resize(m); delta.resize(d); rho.resize(d); vega.resize(d); theta.resize(d); gamma.resize(d); Vector Hdelta(d), Hvega(d), Hrho(d), Htheta(d), Hgamma(d); for (int i=0; i<d; i++) { delta[i] = 0.0; Hdelta[i] = 0.0; Hvega[i] = 0.0; Hrho[i] = 0.0; Htheta[i] = 0.0; } for(long i=0; i<N; i++) { Model.GenerateSamplePath(T,m,S); GetZ(CZ, S, C, Model.S0, Model.r, T/m); H = (i*H + Payoff(S))/(i+1.0); Hsq = (i*Hsq + pow(Payoff(S),2.0))/(i+1.0); for (int j=0; j<d; j++) { Vector S0tmp = Model.S0; S0tmp[j] = (1.0+epsilon)*S0tmp[j]; Matrix Cvega = C; Cvega[j] = (1.0 + epsilon)*C[j]; Rescale(S, CZ, C, S0tmp, Model.r, T/m); Hdelta[j] = (i*Hdelta[j] + Payoff(S)) / (i+1.0); Rescale(S, CZ, C, Model.S0, Model.r*(1.0+epsilon), T/m); Hrho[j] = (i*Hrho[j] + Payoff(S)) / (i+1.0); Rescale(S, CZ, Cvega, Model.S0, Model.r, T/m); Hvega[j] = (i*Hvega[j] + Payoff(S)) / (i+1.0); Rescale(S, CZ, C, Model.S0, Model.r, T*(1.0+epsilon)/m); Htheta[j] = (i*Htheta[j] + Payoff(S)) / (i+1.0); S0tmp[j] = (1.0-epsilon)*Model.S0[j]; Rescale(S, CZ, C, S0tmp, Model.r, T/m); Hgamma[j] = (i*Hgamma[j] + Payoff(S)) / (i+1.0); Rescale(S, CZ, C, Model.S0, Model.r, T/m); } } for(int i=0; i<d; i++) { delta[i] = exp(-Model.r*T) * ( Hdelta[i] - H ) / (epsilon*Model.S0[i]); rho[i] = (exp(-Model.r*T*(1.0+epsilon))*Hrho[i] - exp(-Model.r*T)*H)/(epsilon*Model.r); vega[i] = exp(-Model.r*T) * (Hvega[i] - H) / (epsilon*sqrt(C[i]^C[i])); theta[i] = -1.0*(exp(-Model.r*T*(1.0+epsilon))*Htheta[i] - exp(-Model.r*T)*H)/(epsilon*T); gamma[i] = exp(-Model.r*T)*(Hdelta[i]-2.0*H+Hgamma[i])/(Model.S0[i]*Model.S0[i]*epsilon*epsilon); } Price = exp(-Model.r*T)*H; PricingError = exp(-Model.r*T)*sqrt(Hsq-H*H)/sqrt(N-1.0); return Price; }