예제 #1
0
// renvoie le XOR de n_bytes octets de flux
uint64_t GrayCounterMode(int n_bytes){
  v32 Poly[8], Prod[8];
  uint64_t x=0, Gray_counter=0;
  int count = 0;

  uint64_t FinalOutput = 0;

  // Setup
  for(int i=0; i < 8; i++){
    Prod[i] = A[i];
  }

  while(count < n_bytes) {
    ConvertEvalToCoefficients(Prod, Poly);
    for(int i = 0; i < 8; i++) {
      const v32 a = Poly[i];
      if (!reject(a)) {
          FinalOutput ^= rounding(a);
          count += 8;
      }
    }
    Gray_counter++;
    x = UpdateCounterMode(x, Prod, Gray_counter);
  }

  return FinalOutput;
}
예제 #2
0
파일: fnnumeric.cpp 프로젝트: itmm/myLisp
EPtr FunctionNumeric::apply_evaled(EPtr arguments, State &state) {
    Number *value = Element::as_number(Pair::car(arguments));
    if (! value) return state.error("first argument must be numeric");
    Fractional v = value->value();
    BigInt fractions(5);
    Element *next = Pair::cdr(arguments);
    if (next) {
        Number *digits = Element::as_number(Pair::car(next));
        if (! digits) return state.error("second argument must be numeric");
        if (Pair::cdr(next)) return state.error("too many arguments");
        if (digits->value().denominator() != BigInt(1)) return state.error("digits must be integer");
        fractions = digits->value().numerator();
    }
    Fractional rounding(1, 2);
    Fractional ten(10);
    Fractional one(1);
    Fractional zero(0);
    
    for (Fractional i = fractions; zero < i; i = i - one) {
        rounding = rounding / ten;
    }
    v = v + rounding;
    
    std::ostringstream buffer;
    Fractional fraction(0);
    if (v.denominator() > BigInt(1)) {
        BigInt rest = v.numerator() % v.denominator();
        Fractional full = v - Fractional(rest, v.denominator(), v.isNegative());
        buffer << full;
        fraction = v - full;
    } else {
        buffer << v;
        fraction = Fractional(0);
    }
    buffer << ".";
    
    BigInt bi_one(1);
    for (BigInt cur(0); cur < fractions; cur = cur + bi_one) {
        fraction = fraction * ten;
        BigInt rest = fraction.numerator() % fraction.denominator();
        Fractional full = fraction - Fractional(rest, fraction.denominator(), fraction.isNegative());
        buffer << full;
        fraction = fraction - full;
    }
    
    return state.creator()->new_string(buffer.str());
}
예제 #3
0
void
WaypointAltitudeFromTerrain(WAYPOINT* Temp, RasterTerrain &terrain)
{
  double myalt = -1;
  if (terrain.GetMap()) {
    RasterRounding rounding(*terrain.GetMap(),0,0);

    myalt =
      terrain.GetTerrainHeight(Temp->Location, rounding);
  }

  if (myalt>0) {
    Temp->Altitude = myalt;
  } else {
    // error, can't find altitude for waypoint!
  }
}
예제 #4
0
/**
 * Update the measurements if new level reached
 * @param Basic NMEA_INFO for temperature and humidity
 * @param Calculated DERIVED_INFO for Flying status
 */
void
CuSonde::updateMeasurements(const NMEA_INFO *Basic,
                            const DERIVED_INFO *Calculated)
{
  // if (not flying) nothing to update...
  if (!Calculated->Flying)
    return;

  // if (no temperature or humidity available) nothing to update...
  if (!Basic->TemperatureAvailable ||
      !Basic->HumidityAvailable) {
    return;
  }

  // find appropriate level
  unsigned short level = (unsigned short)(((int)(max(Basic->Altitude,0))) / CUSONDE_HEIGHTSTEP);
  // if (level out of range) cancel update
  if (level>=CUSONDE_NUMLEVELS) {
    return;
  }

  // if (level skipped) cancel update
  if (abs(level-last_level)>1) {
    last_level = level;
    return;
  }

  // if (no level transition yet) wait for transition
  if (abs(level-last_level)==0) {
    // QUESTION TB: no need for next line?!
    last_level = level;
    return;
  }

  // calculate ground height
  terrain.Lock();
  if (terrain.GetMap()) {
    RasterRounding rounding(*terrain.GetMap(),0,0);
    hGround =
      terrain.GetTerrainHeight(Basic->Location, rounding);
  }
  terrain.Unlock();

  // if (going up)
  if (level>last_level) {
    cslevels[level].updateTemps(Basic->RelativeHumidity,
				Basic->OutsideAirTemperature);
    cslevels[level].updateThermalIndex(level);

    if (level>0) {
      findThermalHeight((unsigned short)(level-1));
      findCloudBase((unsigned short)(level-1));
    }

  // if (going down)
  } else {
    // QUESTION TB: why level+1 and not level?
    cslevels[level+1].updateTemps(Basic->RelativeHumidity,
				Basic->OutsideAirTemperature);
    cslevels[level+1].updateThermalIndex((unsigned short)(level+1));

    if (level<CUSONDE_NUMLEVELS-1) {
      findThermalHeight(level);
      findCloudBase(level);
    }
  }

  last_level = level;
}
예제 #5
0
double
FinalGlideThroughTerrain(const double this_bearing,
                         const NMEA_INFO *Basic,
                         const DERIVED_INFO *Calculated,
                         const SETTINGS_COMPUTER &settings,
                         GEOPOINT *retloc,
                         const double max_range,
                         bool *out_of_range,
                         double *TerrainBase)
{
  double mc = GlidePolar::GetMacCready();
  double irange = GlidePolar::MacCreadyAltitude(mc,
						1.0, this_bearing,
						Calculated->WindSpeed,
						Calculated->WindBearing,
						0, 0, true, 0);
  const GEOPOINT start_loc = Basic->Location;
  if (retloc) {
    *retloc = start_loc;
  }
  *out_of_range = false;

  if ((irange <= 0.0) || (Calculated->NavAltitude <= 0)) {
    // can't make progress in this direction at the current windspeed/mc
    return 0;
  }

  if (!terrain.GetMap()) {
    return 0;
  }

  const double glide_max_range = Calculated->NavAltitude/irange;

  // returns distance one would arrive at altitude in straight glide
  // first estimate max range at this altitude
  GEOPOINT loc, last_loc;
  double h=0.0, dh=0.0;
  // int imax=0;
  double last_dh=0;
  double altitude;

  terrain.Lock();
  double retval = 0;
  int i=0;
  bool start_under = false;

  // calculate terrain rounding factor

  FindLatitudeLongitude(start_loc, 0,
                        glide_max_range/NUMFINALGLIDETERRAIN, &loc);

  double Xrounding = fabs(loc.Longitude-start_loc.Longitude)/2;
  double Yrounding = fabs(loc.Latitude-start_loc.Latitude)/2;
  RasterRounding rounding(*terrain.GetMap(),Xrounding,Yrounding);

  loc = last_loc = start_loc;

  altitude = Calculated->NavAltitude;
  h =  max(0, terrain.GetTerrainHeight(loc,rounding));
  dh = altitude - h - settings.SAFETYALTITUDETERRAIN;
  last_dh = dh;
  if (dh<0) {
    start_under = true;
    // already below safety terrain height
    //    retval = 0;
    //    goto OnExit;
  }

  // find grid
  GEOPOINT dloc;

  FindLatitudeLongitude(loc, this_bearing, glide_max_range, &dloc);
  dloc.Latitude -= start_loc.Latitude;
  dloc.Longitude -= start_loc.Longitude;

  double f_scale = 1.0/NUMFINALGLIDETERRAIN;
  if ((max_range>0) && (max_range<glide_max_range)) {
    f_scale *= max_range/glide_max_range;
  }

  double delta_alt = -f_scale*Calculated->NavAltitude;

  dloc.Latitude *= f_scale;
  dloc.Longitude *= f_scale;

  for (i=1; i<=NUMFINALGLIDETERRAIN; i++) {
    double f;
    bool solution_found = false;
    double fi = i*f_scale;
    // fraction of glide_max_range

    if ((max_range>0)&&(fi>=1.0)) {
      // early exit
      *out_of_range = true;
      retval = max_range;
      goto OnExit;
    }

    if (start_under) {
      altitude += 2.0*delta_alt;
    } else {
      altitude += delta_alt;
    }

    // find lat, lon of point of interest

    loc.Latitude += dloc.Latitude;
    loc.Longitude += dloc.Longitude;

    // find height over terrain
    h =  max(0,terrain.GetTerrainHeight(loc, rounding));

    dh = altitude - h - settings.SAFETYALTITUDETERRAIN;

    if (TerrainBase && (dh>0) && (h>0)) {
      *TerrainBase = min(*TerrainBase, h);
    }

    if (start_under) {
      if (dh>last_dh) {
        // better solution found, ok to continue...
        if (dh>0) {
          // we've now found a terrain point above safety altitude,
          // so consider rest of track to search for safety altitude
          start_under = false;
        }
      } else {
        f= 0.0;
        solution_found = true;
      }
    } else if (dh<=0) {
      if ((dh<last_dh) && (last_dh>0)) {
        f = max(0,min(1,(-last_dh)/(dh-last_dh)));
      } else {
        f = 0.0;
      }
      solution_found = true;
    }
    if (solution_found) {
      loc.Latitude = last_loc.Latitude*(1.0-f)+loc.Latitude*f;
      loc.Longitude = last_loc.Longitude*(1.0-f)+loc.Longitude*f;
      if (retloc) {
        *retloc = loc;
      }
      retval = Distance(start_loc, loc);
      goto OnExit;
    }
    last_dh = dh;
    last_loc = loc;
  }

  *out_of_range = true;
  retval = glide_max_range;

OnExit:
  terrain.Unlock();
  return retval;
}
예제 #6
0
int main(int argc, char* argv[])
{

	// Print help if necessary
	bool help = read_bool(argc, argv, "--help", false);
	if ((argc < 2) || (help)) {
		usage(argv);
		return 0;
	}

	// Use parameters struct for passing parameters to kernels efficiently
	parameters prm;

	// Parse inputs
	prm.matDims[0] = read_int(argc, argv, "--m", 2);
	prm.matDims[1] = read_int(argc, argv, "--k", 2);
	prm.matDims[2] = read_int(argc, argv, "--n", 2);
	prm.rank = read_int(argc, argv, "--rank", 7);
	prm.method = read_string(argc, argv, "--method", (char *)"als");
	int maxIters = read_int(argc, argv, "--maxiters", 1000);
	int maxSecs = read_int(argc, argv, "--maxsecs", 1000);
	double tol = read_double(argc, argv, "--tol", 1e-8);
	int printItn = read_int(argc, argv, "--printitn", 0);
	double printTol = read_double(argc, argv, "--printtol", 1.0);
	int seed = read_int(argc, argv, "--seed", 0);
	int numSeeds = read_int(argc, argv, "--numseeds", 1);
	bool verbose = read_bool(argc, argv, "--verbose", false);
	prm.rnd_maxVal = read_double(argc,argv,"--maxval",1.0);
	prm.rnd_pwrOfTwo = read_int(argc,argv,"--pwrof2",0);
	bool roundFinal = read_bool(argc, argv, "--rndfin",false);
	prm.alpha = read_double(argc,argv, "--alpha", 0.1);
	int M = read_int(argc,argv, "--M", 0);
	if (M)
	{
		prm.M[0] = M;
		prm.M[1] = M;
		prm.M[2] = M;
	} else {	    
		prm.M[0] = read_int(argc, argv, "--M0", -1);
		prm.M[1] = read_int(argc, argv, "--M1", -1);
		prm.M[2] = read_int(argc, argv, "--M2", -1);
	}
	char * infile = read_string(argc, argv, "--input", NULL);
	char * outfile = read_string(argc, argv, "--output", NULL);

	if (verbose) {
		setbuf(stdout, NULL);
		printf("\n\n---------------------------------------------------------\n");
		printf("PARAMETERS\n");
		printf("dimensions = %d %d %d\n",prm.matDims[0],prm.matDims[1],prm.matDims[2]);
		printf("rank       = %d\n",prm.rank);
		printf("method     = %s\n",prm.method);
		if (infile)
			printf("input      = %s\n",infile);
		else
		{
			if (numSeeds == 1)
				printf("input      = seed %d\n",seed); 
			else
				printf("inputs     = seeds %d-%d\n",seed,seed+numSeeds-1);
		}
		if (outfile)
			printf("output     = %s\n",outfile);
		else
			printf("output     = none\n"); 
		if (!strcmp(prm.method,"als"))
		{
			printf("tol        = %1.2e\n",tol);
			printf("alpha      = %1.2e\n",prm.alpha);
			printf("maval      = %1.2e\n",prm.rnd_maxVal);
			printf("M's        = (%d,%d,%d)\n",prm.M[0],prm.M[1],prm.M[2]);
			printf("maxiters   = %d\n",maxIters);
			printf("maxsecs    = %d\n",maxSecs);
			printf("printitn   = %d\n",printItn);
			printf("printtol   = %1.2e\n",printTol);
		}
		printf("---------------------------------------------------------\n");
	}

	// Initialize other variables
	int i, j, k, numIters, mkn, tidx[3];
	double err, errOld, errChange = 0.0, start_als, start_search, elapsed, threshold;

	// Compute tensor dimensions
	prm.dims[0] = prm.matDims[0]*prm.matDims[1];
	prm.dims[1] = prm.matDims[1]*prm.matDims[2];
	prm.dims[2] = prm.matDims[0]*prm.matDims[2];

	// Compute tensor's nnz, total number of entries, and Frobenius norm
	mkn = prm.matDims[0]*prm.matDims[1]*prm.matDims[2];
	prm.mkn2 = mkn*mkn;
	prm.xNorm = sqrt(mkn);

	// Compute number of columns in matricized tensors
	for (i = 0; i < 3; i++)
		prm.mtCols[i] = prm.mkn2 / prm.dims[i];

	// Construct three matricizations of matmul tensor
	prm.X = (double**) malloc( 3 * sizeof(double*) );
	for (i = 0; i < 3; i++)
		prm.X[i] = (double*) calloc( prm.mkn2, sizeof(double) );
	for (int mm = 0; mm < prm.matDims[0]; mm++)
		for (int kk = 0; kk < prm.matDims[1]; kk++)
			for (int nn = 0; nn < prm.matDims[2]; nn++)
			{
				tidx[0] = mm + kk*prm.matDims[0];
				tidx[1] = kk + nn*prm.matDims[1];
				tidx[2] = mm + nn*prm.matDims[0];
				prm.X[0][tidx[0]+prm.dims[0]*(tidx[1]+prm.dims[1]*tidx[2])] = 1;
				prm.X[1][tidx[1]+prm.dims[1]*(tidx[0]+prm.dims[0]*tidx[2])] = 1;
				prm.X[2][tidx[2]+prm.dims[2]*(tidx[0]+prm.dims[0]*tidx[1])] = 1;
			}

	// Allocate factor weights and matrices: working, initial, and model
	prm.lambda = (double*) malloc( prm.rank * sizeof(double) );
	prm.U  = (double**) malloc( 3 * sizeof(double*) );
	double** U0 = (double**) malloc( 3 * sizeof(double*) );
	prm.model = (double**) malloc( 3 * sizeof(double*) );
	for (i = 0; i < 3; i++)
	{
		prm.U[i] =  (double*) calloc( prm.mkn2, sizeof(double) );
		U0[i] = (double*) calloc( prm.dims[i]*prm.rank, sizeof(double) );
		prm.model[i] = (double*) calloc( prm.dims[i]*prm.rank, sizeof(double) );
	}

	// Allocate coefficient matrix within ALS (Khatri-Rao product) 
	int maxMatDim = prm.matDims[0];
	if (maxMatDim < prm.matDims[1]) maxMatDim = prm.matDims[1];
	if (maxMatDim < prm.matDims[2]) maxMatDim = prm.matDims[2];
	prm.A = (double*) malloc( maxMatDim*mkn*prm.rank * sizeof(double) );

	// Allocate workspaces
	prm.tau = (double*) malloc( mkn * sizeof(double) );
	prm.lwork = maxMatDim*mkn*prm.rank;
	prm.work = (double*) malloc( prm.lwork * sizeof(double) );
	prm.iwork = (int*) malloc( prm.mkn2 * sizeof(int) );    

	// Allocate matrices for normal equations 
	int maxDim = prm.dims[0];
	if (maxDim < prm.dims[1]) maxDim = prm.dims[1];
	if (maxDim < prm.dims[2]) maxDim = prm.dims[2];
	prm.NE_coeff = (double*) malloc( prm.rank*prm.rank * sizeof(double) );
	prm.NE_rhs = (double*) malloc( maxDim*prm.rank * sizeof(double) );
	prm.residual = (double*) malloc( prm.mkn2 * sizeof(double) );

	//--------------------------------------------------
	// Search Loop
	//--------------------------------------------------
	int mySeed = seed, numGoodSeeds = 0, statusCnt = 0, status = 1;
	start_search = wall_time(); 
	for (int seed_cnt = 0; seed_cnt < numSeeds; ++seed_cnt)
	{
		// Set starting point from random seed (match Matlab Tensor Toolbox)
		RandomMT cRMT(mySeed);
		for (i = 0; i < 3; i++)
			for (j = 0; j < prm.dims[i]; j++)
				for (k = 0; k < prm.rank; k++)
					U0[i][j+k*prm.dims[i]] = cRMT.genMatlabMT();
		for (i = 0; i < prm.rank; i++)
			prm.lambda[i] = 1.0;  

		// Copy starting point
		for (i = 0; i < 3; i++)
			cblas_dcopy(prm.dims[i]*prm.rank,U0[i],1,prm.U[i],1); 

		// read from file if input is given    
		if( infile )
			read_input( infile, prm ); 

		if (verbose)
		{ 
			printf("\nSTARTING POINT...\n");
			for (i = 0; i < 3; i++)
			{
				printf("Factor matrix %d:\n",i);
				print_matrix(prm.U[i],prm.dims[i],prm.rank,prm.dims[i]);
			}
			printf("\n");
		}   

		//--------------------------------------------------
		// Main ALS Loop
		//--------------------------------------------------
		start_als = wall_time();
		err = 1.0; 
		threshold = 1e-4;
		for (numIters = 0; numIters < maxIters && (wall_time()-start_als) < maxSecs; numIters++)
		{
			errOld = err;

			if (!strcmp(prm.method,"als"))
			{
				// Perform an iteration of ALS using NE with Smirnov's penalty term
				err = als( prm );
			}
			else if (!strcmp(prm.method,"sparsify"))
			{   
				// print stats before sparsifying
				printf("Old residual: %1.2e\n",compute_residual(prm,2,true));
				printf("Old nnz (larger than %1.1e): %d %d %d\n", threshold, nnz(prm.U[0],prm.dims[0]*prm.rank,threshold), nnz(prm.U[1],prm.dims[1]*prm.rank,threshold), nnz(prm.U[2],prm.dims[2]*prm.rank,threshold) );

				// sparsify and return
				printf("\nSparsifying...\n\n");
				sparsify( prm );
				numIters = maxIters;

				// print stats after sparsifying
				printf("New residual: %1.2e\n",compute_residual(prm,2,true));
				printf("New nnz (larger than %1.1e): %d %d %d\n", threshold, nnz(prm.U[0],prm.dims[0]*prm.rank,threshold), nnz(prm.U[1],prm.dims[1]*prm.rank,threshold), nnz(prm.U[2],prm.dims[2]*prm.rank,threshold) );
			}
			else if (!strcmp(prm.method,"round"))
			{
				// print stats before rounding
				printf("Old residual: %1.2e\n",compute_residual(prm,2,true));
				printf("Old nnz (larger than %1.1e): %d %d %d\n", threshold, nnz(prm.U[0],prm.dims[0]*prm.rank,threshold), nnz(prm.U[1],prm.dims[1]*prm.rank,threshold), nnz(prm.U[2],prm.dims[2]*prm.rank,threshold) );
				// round and return
				for (i = 0; i < 3; i++)
				{
					capping(prm.U[i],prm.dims[i]*prm.rank,prm.rnd_maxVal);
					rounding(prm.U[i],prm.dims[i]*prm.rank,prm.rnd_pwrOfTwo);
				}
				numIters = maxIters;

				// print stats after rounding
				printf("New residual: %1.2e\n",compute_residual(prm,2,true));
				printf("New nnz (larger than %1.1e): %d %d %d\n", threshold, nnz(prm.U[0],prm.dims[0]*prm.rank,threshold), nnz(prm.U[1],prm.dims[1]*prm.rank,threshold), nnz(prm.U[2],prm.dims[2]*prm.rank,threshold) );
			}
			else
				die("Invalid method\n");   

			// Compute change in relative residual norm
			errChange = fabs(err - errOld);          

			// Print info at current iteration
			if ((printItn > 0) && (((numIters + 1) % printItn) == 0))
			{                
				// print info                    
				printf ("Iter %d: residual = %1.5e change = %1.5e\n", numIters + 1, err, errChange);
			} 

			// Check for convergence 
			if ( numIters > 0 && errChange < tol )
				break;

		}

		// If rounding, round final solution and re-compute residual
		if(roundFinal)
		{
			// normalize columns in A and B factors, put arbitrary weights into C
			normalize_model( prm, 2 );

			// cap large values and round to nearest power of 2
			for (i = 0; i < 3; i++)
			{
				capping(prm.U[i],prm.dims[i]*prm.rank,prm.rnd_maxVal);
				rounding(prm.U[i],prm.dims[i]*prm.rank,prm.rnd_pwrOfTwo);
			}

			err = compute_residual(prm,0,true);
		}    

		// Print status if searching over many seeds
		statusCnt++;
		if (numSeeds > 1000 && statusCnt == numSeeds/10)
		{
			printf("...%d%% complete...\n",10*status);
			status++;
			statusCnt = 0;
		}

		// Print final info
		elapsed = wall_time() - start_als;
		if ((printItn > 0 || verbose) && !strcmp(prm.method,"als"))
		{
			if (infile)
				printf("\nInput %s ",infile);
			else
				printf("\nInitial seed %d ",mySeed);
			printf("achieved residual %1.3e in %d iterations and %1.3e seconds\n \t final residual change: %1.3e\n \t average time per iteration: %1.3e s\n", err, numIters, elapsed, errChange, elapsed/numIters);
		}

		if (verbose)
		{
			printf("\nSOLUTION...\n");
			for (i = 0; i < 3; i++)
			{
				printf("Factor matrix %d:\n",i);
				if (roundFinal || !strcmp(prm.method,"round"))
					print_int_matrix(prm.U[i], prm.dims[i], prm.rank, prm.dims[i], prm.rnd_pwrOfTwo);
				else
					print_matrix(prm.U[i],prm.dims[i],prm.rank,prm.dims[i]);
			}
			
			if (err < printTol)
				numGoodSeeds++;
		}
		else if (err < printTol)
		{
			numGoodSeeds++;

			printf("\n\n***************************************\n");
			if (infile)
				printf("Input %s: ",infile);
			else
				printf("Initial seed %d: ",mySeed);
			printf("after %d iterations, achieved residual %1.3e with final residual change of %1.3e\n", numIters, err, errChange);
			if (roundFinal)
			{

				for (i = 0; i < 3; i++)
				{
					printf("Factor matrix %d:\n",i);
					print_int_matrix(prm.U[i], prm.dims[i], prm.rank, prm.dims[i], prm.rnd_pwrOfTwo);
				}

				int count = 0;
				for (i = 0; i < 3; i++)
					count += nnz(prm.U[i],prm.dims[i]*prm.rank);
				printf("\ttotal nnz in solution: %d\n",count);
				printf("\tnaive adds/subs:       %d\n",count - prm.dims[2] - 2*prm.rank);
			}
			printf("***************************************\n\n\n");
		}

		// write to output
		if( outfile )
			write_output( outfile, prm ); 

		mySeed++;
	}      

	// Final report of processor statistics
	elapsed = wall_time()-start_search;

	// Print stats
	if (!strcmp(prm.method,"als"))
	{
		printf("\n\n------------------------------------------------------------\n");
		printf("Time elapsed:                \t%1.1e\tseconds\n",elapsed);
		printf("Total number of seeds tried: \t%d\n",numSeeds);
		printf("Total number of good seeds:  \t%d",numGoodSeeds);
		printf("\t(residual < %2.1e)\n",printTol);   
		printf("------------------------------------------------------------\n");
	}


	// free allocated memory
	for (i = 0; i < 3; i++)
	{
		free( prm.X[i] );
		free( prm.U[i] );
		free( U0[i] );
		free( prm.model[i] );
	} 
	free( prm.X );
	free( prm.U );
	free( U0 );
	free( prm.model );
	free( prm.lambda );
	free( prm.A );
	free( prm.NE_coeff );
	free( prm.NE_rhs );
	free( prm.residual );
	free( prm.tau );
	free( prm.work );
	free( prm.iwork );

	return 0;

}
예제 #7
0
Encount Map::Move(MapState *mapstate, Directionkey direction){

	int rnd;

	//一マス分の移動先決定
	if (elevator_UP == FALSE && elevator_DOWN == FALSE && moving == FALSE && direction != NOTPRESS &&
		direction != ENTER && direction != TWOPRESS && direction != CANCEL){
		direction_move = direction;
		if (direction_move == LEFT){
			if (src_theta == 0)src_theta = 360;
			m_theta = src_theta - 90;
		}
		if (direction_move == RIGHT){
			if (src_theta == 360)src_theta = 0;
			m_theta = src_theta + 90;
		}
		if (direction_move == UP){
			if (src_theta == 0 || src_theta == 360){
				stepx = cax1; stepy = cay1 - 100;
			}
			if (src_theta == 90){
				stepx = cax1 + 100; stepy = cay1;
			}
			if (src_theta == 180){
				stepx = cax1; stepy = cay1 + 100;
			}
			if (src_theta == 270){
				stepx = cax1 - 100; stepy = cay1;
			}
		}
		if (direction_move == DOWN){
			if (src_theta == 0 || src_theta == 360){
				stepx = cax1; stepy = cay1 + 100;
			}
			if (src_theta == 90){
				stepx = cax1 - 100; stepy = cay1;
			}
			if (src_theta == 180){
				stepx = cax1; stepy = cay1 - 100;
			}
			if (src_theta == 270){
				stepx = cax1 + 100; stepy = cay1;
			}
		}
		moving = TRUE;
	}

	//エレベータA上到達
	if (elevator_UP == FALSE && mxy.m[POS_CE] == 65){
		elevator_UP = TRUE;
	}
	if (elevator_UP == TRUE){
		if ((elevator_step += tfloat.Add(1.0f)) > 300.0f){
			posz += 3;
			elevator_step = 0.0f;
			elevator_UP = FALSE;
		}
		return NOENCOUNT;
	}
	//エレベータB下到達
	if (elevator_DOWN == FALSE && mxy.m[POS_CE] == 66){
		elevator_DOWN = TRUE;
	}
	if (elevator_DOWN == TRUE){
		if ((elevator_step -= tfloat.Add(1.0f)) < -300.0f){
			posz -= 3;
			elevator_step = 0.0f;
			elevator_DOWN = FALSE;
		}
		return NOENCOUNT;
	}

	//出口1ポイント到達
	if (mxy.m[POS_CE] == 54){
		*mapstate = CHANGE_MAP;
		switch (map_no){
		case 0:
			map_no_s = 1;
			MPos = POS_ST;
			break;
		case 1:
			map_no_s = 2;
			MPos = POS_ST;
			break;
		case 2:
			map_no_s = 3;
			MPos = POS_ST;
			break;
		}
		return NOENCOUNT;
	}

	//出口2ポイント到達
	if (mxy.m[POS_CE] == 56){
		*mapstate = CHANGE_MAP;
		switch (map_no){
		case 0:
			break;
		case 1:
			map_no_s = 4;
			MPos = POS_ST;
			break;
		}
		return NOENCOUNT;
	}

	//入口ポイント到達
	if (mxy.m[POS_CE] == 55){
		*mapstate = CHANGE_MAP;
		switch (map_no){
		case 0:
			break;
		case 1:
			map_no_s = 0;
			MPos = POS_EN1;
			break;
		case 2:
			map_no_s = 1;
			MPos = POS_EN1;
			break;
		case 3:
			map_no_s = 2;
			MPos = POS_EN1;
			break;
		case 4:
			map_no_s = 1;
			MPos = POS_EN2;
			break;
		}
		return NOENCOUNT;
	}

	//回復ポイント処理
	if (mxy.m[POS_CE] == 50 && recover_p_f == FALSE){
		recover_p_f = TRUE;
		map_text_f = 300;
		_tcscpy_s(m_tx, L"HPMP全回復!!");
		*mapstate = RECOV_MAP;
	}
	else if (mxy.m[POS_CE] != 50)recover_p_f = FALSE;

	//当たり判定
	if (direction_move == UP){
		if (((src_theta == 0 || src_theta == 360) &&
			(posy == 0 || MoveUpCond(POSY_D1))) ||
			(src_theta == 90 &&
			(posx == mxy.x - 1 || MoveUpCond(POSX_U1))) ||
			(src_theta == 180 &&
			(posy == mxy.y - 1 || MoveUpCond(POSY_U1))) ||
			(src_theta == 270 &&
			(posx == 0 || MoveUpCond(POSX_D1)))){
			moving = FALSE; return NOENCOUNT;
		}
	}
	if (direction_move == DOWN){
		if (((src_theta == 0 || src_theta == 360) &&
			(posy == mxy.y - 1 || MoveDownCond(POSY_U1))) ||
			(src_theta == 90 &&
			(posx == 0 || MoveDownCond(POSX_D1))) ||
			(src_theta == 180 &&
			(posy == 0 || MoveDownCond(POSY_D1))) ||
			(src_theta == 270 &&
			(posx == mxy.x - 1 || MoveDownCond(POSX_U1)))){
			moving = FALSE; return NOENCOUNT;
		}
	}

	//移動処理
	bool movf;
	float m = tfloat.Add(0.3f);
	switch (direction_move){

	case LEFT:
		src_theta = src_theta - m;
		cay2 = cay1 - (int)(cos(src_theta * 3.14f / 180.0f) * 70.0f);
		cax2 = cax1 + (int)(sin(src_theta * 3.14f / 180.0f) * 70.0f);
		if (src_theta <= m_theta){
			src_theta = m_theta;
			moving = FALSE;
			direction_move = NOTPRESS;
			cay2 = (float)rounding((int)cay2, 1);
			cax2 = (float)rounding((int)cax2, 1);
		}
		break;

	case RIGHT:
		src_theta = src_theta + m;
		cay2 = cay1 - (int)(cos(src_theta * 3.14f / 180.0f) * 70.0f);
		cax2 = cax1 + (int)(sin(src_theta * 3.14f / 180.0f) * 70.0f);
		if (src_theta >= m_theta){
			src_theta = m_theta;
			moving = FALSE;
			direction_move = NOTPRESS;
			cay2 = (float)rounding((int)cay2, 1);
			cax2 = (float)rounding((int)cax2, 1);
		}
		break;

	case UP:
		movf = FALSE;
		if (src_theta == 0 || src_theta == 360){
			cay1 -= m; cay2 -= m;
			if (stepy >= cay1){
				cay1 = stepy;
				cay2 = cay1 - 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 90){
			cax1 += m; cax2 += m;
			if (stepx <= cax1){
				cax1 = stepx;
				cax2 = cax1 + 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 180){
			cay1 += m; cay2 += m;
			if (stepy <= cay1){
				cay1 = stepy;
				cay2 = cay1 + 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 270){
			cax1 -= m; cax2 -= m;
			if (stepx >= cax1){
				cax1 = stepx;
				cax2 = cax1 - 70.0f;
				movf = TRUE;
			}
		}
		if (movf == TRUE){
			if (src_theta == 0 || src_theta == 360)posy -= 1;
			if (src_theta == 90)posx += 1;
			if (src_theta == 180)posy += 1;
			if (src_theta == 270)posx -= 1;
			moving = FALSE;
			direction_move = NOTPRESS;
			//ボスエンカウント
			if (mxy.m[POS_CE] == 51 && boss_p_f == FALSE){
				if (((src_theta == 0 || src_theta == 360) && mxy.m[POSY_D1] == 48) ||//アスキーコード48 = 0
					(src_theta == 90 && mxy.m[POSX_U1] == 48) ||
					(src_theta == 180 && mxy.m[POSY_U1] == 48) ||
					(src_theta == 270 && mxy.m[POSX_D1] == 48)){
					boss_p_f = TRUE;
					return BOSS;
				}
			}
			else if (mxy.m[POS_CE] != 51)boss_p_f = FALSE;
			//通常エンカウント
			rnd = rand() % 10;
			if (rnd == 1){
				if (mxy.m[POS_CE] != 50 && mxy.m[POS_CE] != 51 && mxy.m[POS_CE] != 65 && mxy.m[POS_CE] != 66){
					if (((src_theta == 0 || src_theta == 360) && mxy.m[POSY_D1] == 48) ||//アスキーコード48 = 0
						(src_theta == 90 && mxy.m[POSX_U1] == 48) ||
						(src_theta == 180 && mxy.m[POSY_U1] == 48) ||
						(src_theta == 270 && mxy.m[POSX_D1] == 48))return SIDE;
				}
			}
		}
		break;

	case DOWN:
		movf = FALSE;
		if (src_theta == 0 || src_theta == 360){
			cay1 += m; cay2 += m;
			if (stepy <= cay1){
				cay1 = stepy;
				cay2 = cay1 - 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 90){
			cax1 -= m; cax2 -= m;
			if (stepx >= cax1){
				cax1 = stepx;
				cax2 = cax1 + 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 180){
			cay1 -= m; cay2 -= m;
			if (stepy >= cay1){
				cay1 = stepy;
				cay2 = cay1 + 70.0f;
				movf = TRUE;
			}
		}
		if (src_theta == 270){
			cax1 += m; cax2 += m;
			if (stepx <= cax1){
				cax1 = stepx;
				cax2 = cax1 - 70.0f;
				movf = TRUE;
			}
		}
		if (movf == TRUE){
			if (src_theta == 0 || src_theta == 360)posy += 1;
			if (src_theta == 90)posx -= 1;
			if (src_theta == 180)posy -= 1;
			if (src_theta == 270)posx += 1;
			moving = FALSE;
			direction_move = NOTPRESS;
			//通常エンカウント
			rnd = rand() % 3;
			if (rnd == 1){
				if (mxy.m[POS_CE] != 50 && mxy.m[POS_CE] != 51 && mxy.m[POS_CE] != 65 && mxy.m[POS_CE] != 66){
					if (((src_theta == 0 || src_theta == 360) && mxy.m[POSY_D1] == 48) ||
						(src_theta == 90 && mxy.m[POSX_U1] == 48) ||
						(src_theta == 180 && mxy.m[POSY_U1] == 48) ||
						(src_theta == 270 && mxy.m[POSX_D1] == 48))return SIDE;
				}
			}
		}
		break;
	}
	return NOENCOUNT;
}