Example #1
0
void worker(int len, int output_options)
{
	printf("\n");
	int i;
	gem* gems=malloc(len*sizeof(gem));      // if not malloc-ed 230k is the limit
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(sizeof(gem));
	gem_init(gems,1,1);
	gem_init(pool[0],1,1);
	pool_length[0]=1;
	if (!(output_options & mask_quiet)) gem_print(gems);

	for (i=1; i<len; ++i) {
		int j,k,h;
		const int eoc=(i+1)/ (1+1);      // end of combining
		const int j0 =(i+1)/(10+1);      // value ratio < 10
		int comb_tot=0;

		const int grade_max=(int)(log2(i+1)+1);    // gems with max grade cannot be destroyed, so this is a max, not a sup
		gem temp_array[grade_max-1];         // this will have all the grades
		for (j=0; j<grade_max-1; ++j) temp_array[j]=(gem){0};

		for (j=j0; j<eoc; ++j) {         // combine gems and put them in temp array
			for (k=0; k< pool_length[j]; ++k) {
				int g1=(pool[j]+k)->grade;
				for (h=0; h< pool_length[i-1-j]; ++h) {
					int delta=g1 - (pool[i-1-j]+h)->grade;
					if (abs(delta)<=2) {        // grade difference <= 2
						comb_tot++;
						gem temp;
						gem_combine(pool[j]+k, pool[i-1-j]+h, &temp);
						int grd=temp.grade-2;
						if (gem_better(temp, temp_array[grd])) {
							temp_array[grd]=temp;
						}
					}
				}
			}
		}
		int gemNum=0;
		for (j=0; j<grade_max-1; ++j) if (temp_array[j].grade!=0) gemNum++;
		pool_length[i]=gemNum;
		pool[i]=malloc(pool_length[i]*sizeof(gem));
		
		int place=0;
		for (j=0; j<grade_max-1; ++j) {      // copying to pool
			if (temp_array[j].grade!=0) {
				pool[i][place]=temp_array[j];
				place++;
			}
		}
		
		gems[i]=pool[i][0];
		for (j=1;j<pool_length[i];++j) if (gem_better(pool[i][j],gems[i])) {
			gems[i]=pool[i][j];
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_info)
				printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1));
			if (output_options & mask_debug) {
				printf("Raw:\t%d\n",comb_tot);
				printf("Pool:\t%d\n",pool_length[i]);
			}
			gem_print(gems+i);
		}
	}
	
	if (output_options & mask_quiet) {    // outputs last if we never seen any
		printf("Value:\t%d\n",len);
		printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len));
		if (output_options & mask_debug)
			printf("Pool:\t%d\n",pool_length[len-1]);
		gem_print(gems+len-1);
	}

	gem* gemf=gems+len-1;  // gem that will be displayed

	if (output_options & mask_upto) {
		double best_growth=-INFINITY;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (log(gem_power(gems[i]))/log(i+1) > best_growth) {
				best_index=i;
				best_growth=log(gem_power(gems[i]))/log(i+1);
			}
		}
		printf("Best gem up to %d:\n\n", len);
		printf("Value:\t%d\n",best_index+1);
		printf("Growth:\t%f\n", best_growth);
		gem_print(gems+best_index);
		gemf = gems+best_index;
	}

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 2) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array);
			printf("Gem with red added:\n\n");
			printf("Value:\t%d\n", value);    // made to work well with -u
			printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value));
			gem_print(gemf);
		}
	}

	if (output_options & mask_parens) {
		printf("Compressed combining scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Gem tree:\n");
		print_tree(gemf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_table(gems, len);
	
	if (output_options & mask_equations) {   // it ruins gems, must be last
		printf("Equations:\n");
		print_equations(gemf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);    // free
	free(gems);
	if (output_options & mask_red && len > 1) {
		free(gem_array);
	}
}
Example #2
0
void worker(int len, int output_options, char* filename)
{
	FILE* table=table_init(filename, 1);		// init killgem
	int i;
	gem** pool=malloc(len*sizeof(gem*));		// win 262k
	int* pool_length=malloc(len*sizeof(int));
	pool[0]=malloc(sizeof(gem));
	pool_length[0]=1;
	gem_init(pool[0],1,1,1,1);		// grade damage crit bbound
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// pool filling
	if (prevmax+1==len) {
		fclose(table);
		for (i=0;i<len;++i) free(pool[i]);		// free
		printf("Table is longer than %d, no need to do anything\n\n",prevmax+1);
		exit(1);
	}
	table=freopen(filename,"a", table);		// append -> updating possible

	for (i=prevmax+1; i<len; ++i) {
		int j,k,h;
		const int eoc=(i+1)/ (1+1);       // end of combining
		const int j0 =(i+1)/(10+1);       // value ratio < 10
		int comb_tot=0;

		const int ngrades=(int)log2(i+1);
		const int temp_length=nchecks*ngrades;
		gem temp_array[temp_length];      // this will have all the grades
		for (j=0; j<temp_length; ++j) temp_array[j]=(gem){0};
		double pow_array[temp_length];    // this will have all the powers
		for (j=0; j<temp_length; ++j) pow_array[j]=0;

		for (j=j0; j<eoc; ++j) {          // combine gems and put them in temp array
			for (k=0; k< pool_length[j]; ++k) {
				int g1=(pool[j]+k)->grade;
				for (h=0; h< pool_length[i-1-j]; ++h) {
					int delta=g1 - (pool[i-1-j]+h)->grade;
					if (abs(delta)<=2) {     // grade difference <= 2
						comb_tot++;
						gem temp;
						gem_combine(pool[j]+k, pool[i-1-j]+h, &temp);
						int grd=temp.grade-2;
						int p0 = grd*nchecks;
						
						if      ( gem_rk511(temp) >= pow_array[p0] ) {			// rk511 check
							pow_array[p0]=gem_rk511(temp);
							temp_array[p0]=temp;
						}
						else if ( gem_power(temp) >= pow_array[p0+1] ) {		// rk211 check
							pow_array[p0+1]=gem_power(temp);
							temp_array[p0+1]=temp;
						}
						else if ( gem_rk411(temp) >= pow_array[p0+2] ) {		// rk411 check
							pow_array[p0+2]=gem_rk411(temp);
							temp_array[p0+2]=temp;
						}
						else if ( gem_rk311(temp) >= pow_array[p0+3] ) {		// rk311 check
							pow_array[p0+3]=gem_rk311(temp);
							temp_array[p0+3]=temp;
						}
						else if ( gem_power(temp) >= pow_array[p0+4] ) {		// rk211 check
							pow_array[p0+4]=gem_power(temp);
							temp_array[p0+4]=temp;
						}
						else if ( gem_power(temp) >= pow_array[p0+5] ) {		// rk211 check
							pow_array[p0+5]=gem_power(temp);
							temp_array[p0+5]=temp;
						}
					}
				}
			}
		}
		int gemNum=0;
		for (j=0; j<temp_length; ++j) if (temp_array[j].grade!=0) gemNum++;
		pool_length[i]=gemNum;
		pool[i]=malloc(pool_length[i]*sizeof(gem));
		
		int place=0;
		for (j=0; j<temp_length; ++j) {				// copying to pool
			if (temp_array[j].grade!=0) {
				pool[i][place]=temp_array[j];
				place++;
			}
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_debug) {
				printf("Raw:\t%d\n",comb_tot);
				printf("Pool:\t%d\n\n",pool_length[i]);
			}
		}
		table_write_iteration(pool, pool_length, i, table);			// write on file
	}
	
	fclose(table);      // close
	for (i=0;i<len;++i) free(pool[i]);   // free
	free(pool);         // free
	free(pool_length);  // free
}
Example #3
0
void worker(int len, int lenc, int output_options, char* filename, char* filenamec, char* filenameA, int TC, int As, int GT, int Namps)
{
	FILE* table=file_check(filename);			// file is open to read
	if (table==NULL) exit(1);						// if the file is not good we exit
	int i;
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(2*sizeof(gem));
	pool_length[0]=2;
	gem_init(pool[0]  ,1,1.000000,1,0);		// grade damage crit bbound
	gem_init(pool[0]+1,1,1.186168,0,1);		// BB has more dmg
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// killgem spec pool filling
	fclose(table);
	if (prevmax<len-1) {										// if the killgems are not enough
		for (i=0;i<=prevmax;++i) free(pool[i]);		// free
		if (prevmax>0) printf("Gem table stops at %d, not %d\n",prevmax+1,len);
		exit(1);
	}

	gem* poolf[len];
	int poolf_length[len];
	
	KGSPEC_COMPRESSION
	printf("Gem speccing pool compression done!\n");

	FILE* tableA=file_check(filenameA);		// fileA is open to read
	if (tableA==NULL) exit(1);					// if the file is not good we exit
	int lena=len;									// as long as the spec length
	gemY** poolY=malloc(lena*sizeof(gemY*));
	int* poolY_length=malloc(lena*sizeof(int));
	poolY[0]=malloc(sizeof(gemY));
	poolY_length[0]=1;
	gem_init_Y(poolY[0],1,1,1);
	
	int prevmaxA=pool_from_table_Y(poolY, poolY_length, lena, tableA);		// amps pool filling
	fclose(tableA);
	if (prevmaxA<lena-1) {
		for (i=0;i<=prevmaxA;++i) free(poolY[i]);		// free
		if (prevmaxA>0) printf("Amp table stops at %d, not %d\n",prevmaxA+1,lena);
		exit(1);
	}
	
	gemY** poolYf=malloc(lena*sizeof(gemY*));		// if not malloc-ed 140k is the limit
	int poolYf_length[lena];
	
	AMPS_COMPRESSION
	printf("Amp pool compression done!\n");

	FILE* tablec=file_check(filenamec);		// file is open to read
	if (tablec==NULL) exit(1);					// if the file is not good we exit
	gem** poolc=malloc(lenc*sizeof(gem*));
	int* poolc_length=malloc(lenc*sizeof(int));
	poolc[0]=malloc(sizeof(gem));
	poolc_length[0]=1;
	gem_init(poolc[0],1,1,1,1);
	
	int prevmaxc=pool_from_table(poolc, poolc_length, lenc, tablec);		// killgem comb pool filling
	fclose(tablec);
	if (prevmaxc<lenc-1) {									// if the killgems are not enough
		for (i=0;i<=prevmaxc;++i) free(poolc[i]);		// free
		if (prevmaxc>0) printf("Gem table stops at %d, not %d\n",prevmaxc+1,lenc);
		exit(1);
	}
	
	gem bestc=(gem){0};				// choosing best combine
	
	for (i=0;i<poolc_length[lenc-1];++i) {
		if (gem_more_powerful(poolc[lenc-1][i], bestc)) {
			bestc=poolc[lenc-1][i];
		}
	}
	double bestc_growth=log(gem_power(bestc))/log(lenc);
	
	printf("Combining pool compression done!\n\n");

	int j,k,h;								// let's choose the right gem-amp combo
	gem gems[len];							// for every speccing value
	gemY amps[len];						// we'll choose the best amps
	double powers[len];
	gem_init(gems,1,1,1,0);
	gem_init_Y(amps,0,0,0);
	powers[0]=0;
	double crit_ratio  =Namps*(0.15+As/3*0.004)*2*(1+0.03*TC)/(1.0+TC/3*0.1);
	double damage_ratio=Namps*(0.20+As/3*0.004) * (1+0.03*TC)/(1.2+TC/3*0.1);
	double NT=pow(2, GT-1);
	if (!(output_options & mask_quiet)) {
		printf("Killgem spec\n");
		gem_print(gems);
		printf("Amplifier spec (x%d)\n", Namps);
		gem_print_Y(amps);
		printf("Spec base power:    \t0\n\n\n");
	}

	for (i=1;i<len;++i) {													// for every gem value
		gems[i]=(gem){0};														// we init the gems
		amps[i]=(gemY){0};													// to extremely weak ones
		
		for (k=0;k<poolf_length[i];++k) {								// first we compare the gem alone
			if (gem_power(poolf[i][k]) > gem_power(gems[i])) {
				gems[i]=poolf[i][k];
			}
		}
		int NS=i+1;
		double C0 = pow(NT/(i+1), bestc_growth);						// last we compute the combination number
		powers[i] = C0 * gem_power(gems[i]);
																					// now we compare the whole setup
		for (j=0, NS+=Namps; j<i+1; ++j, NS+=Namps) {				// for every amp value from 1 to to gem_value
			double Cg = pow(NT/NS, bestc_growth);						// we compute the combination number
			for (k=0;k<poolf_length[i];++k) {							// then in the gem pool
				double Pb2 = poolf[i][k].bbound * poolf[i][k].bbound;
				double Pdg = poolf[i][k].damage;
				double Pcg = poolf[i][k].crit  ;
				for (h=0;h<poolYf_length[j];++h) {					// and in the reduced amp pool
					double Pdamage = Pdg + damage_ratio* poolYf[j][h].damage ;
					double Pcrit   = Pcg + crit_ratio  * poolYf[j][h].crit   ;
					double Pbase   = Pb2 * Pdamage * Pcrit ;
					double power   = Cg * Pbase;
					if (power>powers[i]) {
						powers[i]=power;
						gems[i]=poolf[i][k];
						amps[i]=poolYf[j][h];
					}
				}
			}
		}
		if (!(output_options & mask_quiet)) {
			printf("Killgem spec\n");
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolf_length[i]);
			gem_print(gems+i);
			printf("Amplifier spec (x%d)\n", Namps);
			printf("Value:\t%d\n",gem_getvalue_Y(amps+i));
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolYf_length[gem_getvalue_Y(amps+i)-1]);
			gem_print_Y(amps+i);
			printf("Setup combine\n");
			printf("Comb:\t%d\n",lenc);
			gem_print(&bestc);
			printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[i], amps[i], damage_ratio, crit_ratio));
			printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[i]);
		}
	}
	
	if (output_options & mask_quiet) {		// outputs last if we never seen any
		printf("Killgem spec\n");
		printf("Value:\t%d\n",len);
		gem_print(gems+len-1);
		printf("Amplifier spec (x%d)\n", Namps);
		printf("Value:\t%d\n",gem_getvalue_Y(amps+len-1));
		gem_print_Y(amps+len-1);
		printf("Setup combine\n");
		printf("Comb:\t%d\n",lenc);
		printf("Growth:\t%f\n", bestc_growth);
		gem_print(&bestc);
		printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[len-1], amps[len-1], damage_ratio, crit_ratio));
		printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[len-1]);
	}

	gem*  gemf = gems+len-1;  // gem  that will be displayed
	gemY* ampf = amps+len-1;  // amp  that will be displayed
	gem*  gemfc= &bestc;      // gemc that will be displayed

	if (output_options & mask_upto) {
		double best_pow=0;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (powers[i] > best_pow) {
				best_index=i;
				best_pow=powers[i];
			}
		}
		printf("Best setup up to %d:\n\n", len);
		printf("Killgem spec\n");
		printf("Value:\t%d\n", gem_getvalue(gems+best_index));
		gem_print(gems+best_index);
		printf("Amplifier spec (x%d)\n", Namps);
		printf("Value:\t%d\n", gem_getvalue_Y(amps+best_index));
		gem_print_Y(amps+best_index);
		printf("Setup combine\n");
		printf("Comb:\t%d\n",lenc);
		gem_print(gemfc);
		printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[best_index], amps[best_index], damage_ratio, crit_ratio));
		printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[best_index]);
		gemf = gems+best_index;
		ampf = amps+best_index;
	}

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 3) printf("I could not add red!\n\n");
		else {
			int value = gem_getvalue(gemf);
			int valueA= gem_getvalue_Y(ampf);
			double NS = value + Namps*valueA;
			double amp_damage_scaled = damage_ratio * ampf->damage;
			double amp_crit_scaled = crit_ratio * ampf->crit;
			gemf = gem_putred(poolf[value-1], poolf_length[value-1], value, &red, &gem_array, amp_damage_scaled, amp_crit_scaled);
			printf("Setup with red added:\n\n");
			printf("Killgem spec\n");
			printf("Value:\t%d\n", value);		// made to work well with -u
			gem_print(gemf);
			printf("Amplifier spec (x%d)\n", Namps);
			printf("Value:\t%d\n", valueA);
			gem_print_Y(ampf);
			printf("Setup combine\n");
			printf("Comb:\t%d\n",lenc);
			gem_print(gemfc);
			printf("Spec base power with red:\t%#.7g\n", gem_amp_power(*gemf, *ampf, damage_ratio, crit_ratio));
			double CgP = pow(NT/NS, bestc_growth);
			printf("Global power w. red at g%d:\t%#.7g\n\n\n", GT, CgP*gem_cfr_power(*gemf, amp_damage_scaled, amp_crit_scaled));
		}
	}

	if (output_options & mask_parens) {
		printf("Killgem speccing scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
		printf("Amplifier speccing scheme:\n");
		print_parens_compressed_Y(ampf);
		printf("\n\n");
		printf("Setup combining scheme:\n");
		print_parens_compressed(gemfc);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Killgem speccing tree:\n");
		print_tree(gemf, "");
		printf("\n");
		printf("Amplifier speccing tree:\n");
		print_tree_Y(ampf, "");
		printf("\n");
		printf("Setup combining tree:\n");
		print_tree(gemfc, "");
		printf("\n");
	}
	if (output_options & mask_table) print_omnia_table(gems, amps, powers, len);
	
	if (output_options & mask_equations) {		// it ruins gems, must be last
		printf("Killgem speccing equations:\n");
		print_equations(gemf);
		printf("\n");
		printf("Amplifier speccing equations:\n");
		print_equations_Y(ampf);
		printf("\n");
		printf("Setup combining equations:\n");
		print_equations(gemfc);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);			// free gems
	for (i=0;i<len;++i) free(poolf[i]);			// free gems compressed
	for (i=0;i<lenc;++i) free(poolc[i]);		// free gems
	free(poolc);
	free(poolc_length);
	for (i=0;i<lena;++i) free(poolY[i]);		// free amps
	for (i=0;i<lena;++i) free(poolYf[i]);		// free amps compressed
	free(poolY);
	free(poolY_length);
	free(poolYf);
	if (output_options & mask_red && len > 2) {
		free(gem_array);
	}
}
Example #4
0
void worker(int len, int output_options, double growth_comb, char* filename, char* filenameA, int TC, int As, int Namps)
{
	FILE* table=file_check(filename);			// file is open to read
	if (table==NULL) exit(1);						// if the file is not good we exit
	int i;
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(2*sizeof(gem));
	pool_length[0]=2;
	gem_init(pool[0]  ,1,1,0);
	gem_init(pool[0]+1,1,0,1);
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// managem pool filling
	fclose(table);
	if (prevmax<len-1) {										// if the managems are not enough
		for (i=0;i<=prevmax;++i) free(pool[i]);		// free
		if (prevmax>0) printf("Gem table stops at %d, not %d\n",prevmax+1,len);
		exit(1);
	}
	
	gem* poolf[len];
	int poolf_length[len];
	
	MGSPEC_COMPRESSION
	if (!(output_options & mask_quiet)) printf("Gem speccing pool compression done!\n");

	FILE* tableA=file_check(filenameA);		// fileA is open to read
	if (tableA==NULL) exit(1);					// if the file is not good we exit
	int lena=len;
	gemO* poolO[lena];
	int poolO_length[lena];
	poolO[0]=malloc(sizeof(gemO));
	poolO_length[0]=1;
	gem_init_O(poolO[0],1,1);
	
	int prevmaxA=pool_from_table_O(poolO, poolO_length, lena, tableA);		// amps pool filling
	fclose(tableA);
	if (prevmaxA<lena-1) {
		for (i=0;i<=prevmaxA;++i) free(poolO[i]);		// free
		if (prevmaxA>0) printf("Amp table stops at %d, not %d\n",prevmaxA+1,lena);
		exit(1);
	}

	gemO* bestO=malloc(lena*sizeof(gemO));		// if not malloc-ed 140k is the limit
	
	AMPS_COMPRESSION
	if (!(output_options & mask_quiet)) printf("Amp pool compression done!\n\n");

	int j,k;									// let's choose the right gem-amp combo
	gem gems[len];
	gemO amps[len];
	double spec_coeffs[len];
	gem_init(gems,1,1,0);
	amps[0]=(gemO){0};
	spec_coeffs[0]=0;
	double leech_ratio=Namps*(0.15+As/3*0.004)*2*(1+0.03*TC)/(1+TC/3*0.1);
	
	int skip_computations = (output_options & mask_quiet) && !((output_options & mask_table) || (output_options & mask_upto));
	int first = skip_computations ? len-1 : 0;
	for (i=first; i<len; ++i) {								// for every gem value
		gems[i]=(gem){0};									// we init the gems
		amps[i]=(gemO){0};									// to extremely weak ones
		for (k=0;k<poolf_length[i];++k) {					// first we compare the gem alone
			if (gem_power(poolf[i][k]) > gem_power(gems[i])) {
				gems[i]=poolf[i][k];
			}
		}
		int NS=i+1;
		double comb_coeff=pow(NS, -growth_comb);
		spec_coeffs[i]=comb_coeff*gem_power(gems[i]);
															// now with amps
		for (j=0, NS+=Namps; j<i+1; ++j, NS+=Namps) {		// for every amp value from 1 to to gem_value
			double comb_coeff=pow(NS, -growth_comb);		// we compute comb_coeff
			double Pa= leech_ratio * bestO[j].leech;		// <- this is ok only for mg
			for (k=0; k<poolf_length[i]; ++k) {				// then we search in the reduced gem pool
				double Palone = gem_power(poolf[i][k]);
				double power = Palone + poolf[i][k].bbound * Pa;
				double spec_coeff=power*comb_coeff;
				if (spec_coeff>spec_coeffs[i]) {
					spec_coeffs[i]=spec_coeff;
					gems[i]=poolf[i][k];
					amps[i]=bestO[j];
				}
			}
		}
		if (!(output_options & mask_quiet)) {
			printf("Total value:\t%d\n\n", i+1+Namps*gem_getvalue_O(amps+i));
			printf("Managem\n");
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolf_length[i]);
			gem_print(gems+i);
			printf("Amplifier (x%d)\n", Namps);
			printf("Value:\t%d\n",gem_getvalue_O(amps+i));
			gem_print_O(amps+i);
			printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[i], amps[i], leech_ratio));
			printf("Spec coefficient:\t%f\n\n", spec_coeffs[i]);
		}
	}
	
	if (output_options & mask_quiet) {		// outputs last if we never seen any
		printf("Total value:\t%d\n\n", len+Namps*gem_getvalue_O(amps+len-1));
		printf("Managem\n");
		printf("Value:\t%d\n", len);
		gem_print(gems+len-1);
		printf("Amplifier (x%d)\n", Namps);
		printf("Value:\t%d\n", gem_getvalue_O(amps+len-1));
		gem_print_O(amps+len-1);
		printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[len-1], amps[len-1], leech_ratio));
		printf("Spec coefficient:\t%f\n\n", spec_coeffs[len-1]);
	}

	gem*  gemf=gems+len-1;  // gem that will be displayed
	gemO* ampf=amps+len-1;  // amp that will be displayed

	if (output_options & mask_upto) {
		double best_sc=0;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (spec_coeffs[i] > best_sc) {
				best_index=i;
				best_sc=spec_coeffs[i];
			}
		}
		printf("Best setup up to %d:\n\n", len);
		printf("Total value:\t%d\n\n", gem_getvalue(gems+best_index)+Namps*gem_getvalue_O(amps+best_index));
		printf("Managem\n");
		printf("Value:\t%d\n", gem_getvalue(gems+best_index));
		gem_print(gems+best_index);
		printf("Amplifier (x%d)\n", Namps);
		printf("Value:\t%d\n", gem_getvalue_O(amps+best_index));
		gem_print_O(amps+best_index);
		printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[best_index], amps[best_index], leech_ratio));
		printf("Spec coefficient:\t%f\n\n", best_sc);
		gemf = gems+best_index;
		ampf = amps+best_index;
	}

	gem* gem_array = NULL;
	gem red;
	if (output_options & mask_red) {
		if (len < 3) printf("I could not add red!\n\n");
		else {
			int value = gem_getvalue(gemf);
			int valueA= gem_getvalue_O(ampf);
			double NS = value + Namps*valueA;
			double amp_leech_scaled = leech_ratio * ampf->leech;
			gemf = gem_putred(poolf[value-1], poolf_length[value-1], value, &red, &gem_array, amp_leech_scaled);
			printf("Setup with red added:\n\n");
			printf("Total value:\t%d\n\n", value+Namps*gem_getvalue_O(ampf));
			printf("Managem\n");
			printf("Value:\t%d\n", value);
			gem_print(gemf);
			printf("Amplifier (x%d)\n", Namps);
			printf("Value:\t%d\n", gem_getvalue_O(ampf));
			gem_print_O(ampf);
			printf("Spec base power w. red:\t%#.7g\n", gem_amp_power(*gemf, *ampf, leech_ratio));
			double CgP = pow(NS, -growth_comb);
			printf("Spec coefficient:\t%f\n\n", CgP*gem_cfr_power(*gemf, amp_leech_scaled));
		}
	}

	if (output_options & mask_parens) {
		printf("Managem speccing scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
		printf("Amplifier speccing scheme:\n");
		print_parens_compressed_O(ampf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Managem tree:\n");
		print_tree(gemf, "");
		printf("\n");
		printf("Amplifier tree:\n");
		print_tree_O(ampf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_amps_table(gems, amps, spec_coeffs, leech_ratio, len);
	
	if (output_options & mask_equations) {		// it ruins gems, must be last
		printf("Managem equations:\n");
		print_equations(gemf);
		printf("\n");
		printf("Amplifier equations:\n");
		print_equations_O(ampf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);			// free gems
	for (i=0;i<len;++i) free(poolf[i]);			// free gems compressed
	for (i=0;i<lena;++i) free(poolO[i]);		// free amps
	free(bestO);										// free amps compressed
	if (output_options & mask_red && len > 2) {
		free(gem_array);
	}
}
Example #5
0
void worker(int len, int output_options, char* filename)
{
	FILE* table=file_check(filename);      // file is open to read
	if (table==NULL) exit(1);              // if the file is not good we exit
	int i;
	gem* gems=malloc(len*sizeof(gem));     // if not malloc-ed 230k is the limit
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(sizeof(gem));
	gem_init(gems,1,1,1);
	gem_init(pool[0],1,1,1);
	pool_length[0]=1;
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// pool filling
	fclose(table);				// close
	if (prevmax<len-1) {
		for (i=0;i<=prevmax;++i) free(pool[i]);		// free
		free(gems);				// free
		if (prevmax>0) printf("Table stops at %d, not %d\n",prevmax+1,len);
		exit(1);
	}
	if (!(output_options & mask_quiet)) gem_print(gems);

	for (i=1;i<len;++i) {
		int j;
		gems[i]=pool[i][0];
		for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) {
			gems[i]=pool[i][j];
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_info)
				printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1));
			if (output_options & mask_debug)
				printf("Pool:\t%d\n",pool_length[i]);
			gem_print(gems+i);
		}
	}
	
	if (output_options & mask_quiet) {    // outputs last if we never seen any
		printf("Value:\t%d\n",len);
		printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len));
		if (output_options & mask_debug)
			printf("Pool:\t%d\n",pool_length[len-1]);
		gem_print(gems+len-1);
	}

	gem* gemf=gems+len-1;  // gem that will be displayed

	if (output_options & mask_upto) {
		double best_growth=-INFINITY;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (log(gem_power(gems[i]))/log(i+1) > best_growth) {
				best_index=i;
				best_growth=log(gem_power(gems[i]))/log(i+1);
			}
		}
		printf("Best gem up to %d:\n\n", len);
		printf("Value:\t%d\n",best_index+1);
		printf("Growth:\t%f\n", best_growth);
		gem_print(gems+best_index);
		gemf = gems+best_index;
	}

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 2) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array);
			printf("Gem with red added:\n\n");
			printf("Value:\t%d\n", value);    // made to work well with -u
			printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value));
			gem_print(gemf);
		}
	}

	if (output_options & mask_parens) {
		printf("Compressed combining scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Gem tree:\n");
		print_tree(gemf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_table(gems, len);
	
	if (output_options & mask_equations) {		// it ruins gems, must be last
		printf("Equations:\n");
		print_equations(gemf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);		// free
	free(gems);		// free
	if (output_options & mask_red && len > 1) {
		free(gem_array);
	}
}
Example #6
0
void worker(int len, int output_options, int gem_limit, char* filename, char* filenameA, int TC, int As, int Namps)
{
	FILE* table=file_check(filename);			// file is open to read
	if (table==NULL) exit(1);						// if the file is not good we exit
	int i;
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(2*sizeof(gem));
	pool_length[0]=2;
	gem_init(pool[0]  ,1,1.000000,1,0);		// grade damage crit bbound
	gem_init(pool[0]+1,1,1.186168,0,1);		// BB has more dmg
	
	int prevmax=pool_from_table(pool, pool_length, gem_limit, table);		// killgem pool filling
	fclose(table);
	if (prevmax<len-1) {					// if the killgems are not enough
		for (i=prevmax+1; i<len; ++i) {
			pool_length[i]=0;
			pool[i]=NULL;
		}
	}

	gem* poolf[len];
	int poolf_length[len];
	
	KGSPEC_COMPRESSION
	printf("Gem speccing pool compression done!\n");

	FILE* tableA=file_check(filenameA);		// fileA is open to read
	if (tableA==NULL) exit(1);					// if the file is not good we exit
	int lena = Namps ? len/Namps : 1;		// if Namps==0 let lena=1
	gemY* poolY[lena];
	int poolY_length[lena];
	poolY[0]=malloc(sizeof(gemY));
	poolY_length[0]=1;
	gem_init_Y(poolY[0],1,1,1);
	
	int prevmaxA=pool_from_table_Y(poolY, poolY_length, lena, tableA);		// amps pool filling
	fclose(tableA);
	if (prevmaxA<lena-1) {
		for (i=0;i<=prevmaxA;++i) free(poolY[i]);		// free
		if (prevmaxA>0) printf("Amp table stops at %d, not %d\n",prevmaxA+1,lena);
		exit(1);
	}

	gemY* poolYf[lena];
	int poolYf_length[lena];
	
	AMPS_COMPRESSION
	printf("Amp pool compression done!\n\n");

	int j,k,h;											// let's choose the right gem-amp combo
	gem gems[len];
	gemY amps[len];
	gem_init(gems,1,1,1,0);
	amps[0]=(gemY){0};
	double crit_ratio  =Namps*(0.15+As/3*0.004)*2*(1+0.03*TC)/(1.0+TC/3*0.1);
	double damage_ratio=Namps*(0.20+As/3*0.004) * (1+0.03*TC)/(1.2+TC/3*0.1);
	if (!(output_options & mask_quiet)) {
		printf("Total value:\t1\n\n");
		printf("Killgem\n");
		gem_print(gems);
		printf("Amplifier (x%d)\n", Namps);
		gem_print_Y(amps);
	}
	
	for (i=1;i<len;++i) {												// for every total value
		gems[i]=(gem){0};													// we init the gems
		amps[i]=(gemY){0};												// to extremely weak ones
		for (k=0;k<poolf_length[i];++k) {							// first we compare the gem alone
			if (gem_power(poolf[i][k]) > gem_power(gems[i])) {
				gems[i]=poolf[i][k];
			}
		}
		double power = gem_power(gems[i]);
		if (Namps!=0)
		for (j=1;j<=i/Namps;++j) {										// for every amount of amps we can fit in
			int value = i-Namps*j;										// this is the amount of gems we have left
			for (k=0;k<poolf_length[value];++k) {					// we search in that pool
				for (h=0;h<poolYf_length[j-1];++h) {				// and we look in the amp pool
					if (gem_amp_power(poolf[value][k], poolYf[j-1][h], damage_ratio, crit_ratio) > power)
					{
						power = gem_amp_power(poolf[value][k], poolYf[j-1][h], damage_ratio, crit_ratio);
						gems[i]=poolf[value][k];
						amps[i]=poolYf[j-1][h];
					}
				}
			}
		}
		if (!(output_options & mask_quiet)) {
			printf("Total value:\t%d\n\n", i+1);
			if (prevmax<len-1) printf("Killgem limit:\t%d\n", prevmax+1);
			printf("Killgem\n");
			printf("Value:\t%d\n",gem_getvalue(gems+i));
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolf_length[gem_getvalue(gems+i)-1]);
			gem_print(gems+i);
			printf("Amplifier (x%d)\n", Namps);
			printf("Value:\t%d\n",gem_getvalue_Y(amps+i));
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolYf_length[gem_getvalue_Y(amps+i)-1]);
			gem_print_Y(amps+i);
			printf("Spec base power: \t%#.7g\n\n", gem_amp_power(gems[i], amps[i], damage_ratio, crit_ratio));
		}
	}
	
	if (output_options & mask_quiet) {		// outputs last if we never seen any
		printf("Total value:\t%d\n\n", len);
		if (prevmax<len-1) printf("Killgem limit:\t%d\n", prevmax+1);
		printf("Killgem\n");
		printf("Value:\t%d\n", gem_getvalue(gems+len-1));
		gem_print(gems+len-1);
		printf("Amplifier (x%d)\n", Namps);
		printf("Value:\t%d\n", gem_getvalue_Y(amps+len-1));
		gem_print_Y(amps+len-1);
		printf("Spec base power: \t%#.7g\n\n", gem_amp_power(gems[len-1], amps[len-1], damage_ratio, crit_ratio));
	}

	gem*  gemf=gems+len-1;  // gem that will be displayed
	gemY* ampf=amps+len-1;  // amp that will be displayed

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 3) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(poolf[value-1], poolf_length[value-1], value, &red, &gem_array, damage_ratio*ampf->damage, crit_ratio*ampf->crit);
			printf("Setup with red added:\n\n");
			printf("Total value:\t%d\n\n", value+Namps*gem_getvalue_Y(ampf));
			printf("Killgem\n");
			printf("Value:\t%d\n", value);
			gem_print(gemf);
			printf("Amplifier (x%d)\n", Namps);
			printf("Value:\t%d\n", gem_getvalue_Y(ampf));
			gem_print_Y(ampf);
			printf("Spec base power with red:\t%#.7g\n\n", gem_amp_power(*gemf, *ampf, damage_ratio, crit_ratio));
		}
	}

	if (output_options & mask_parens) {
		printf("Killgem speccing scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
		printf("Amplifier speccing scheme:\n");
		print_parens_compressed_Y(ampf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Killgem tree:\n");
		print_tree(gemf, "");
		printf("\n");
		printf("Amplifier tree:\n");
		print_tree_Y(ampf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_ngems_table(gems, amps, damage_ratio, crit_ratio, len);

	
	if (output_options & mask_equations) {		// it ruins gems, must be last
		printf("Killgem equations:\n");
		print_equations(gemf);
		printf("\n");
		printf("Amplifier equations:\n");
		print_equations_Y(ampf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);			// free gems
	for (i=0;i<len;++i) free(poolf[i]);			// free gems compressed
	for (i=0;i<lena;++i) free(poolY[i]);		// free amps
	for (i=0;i<lena;++i) free(poolYf[i]);		// free amps compressed
	if (output_options & mask_red && len > 2) {
		free(gem_array);
	}
}
Example #7
0
void worker(int len, int output_options, int pool_zero)
{
	printf("\n");
	int i;
	int size;
	const int ACC_TR=750;				//   750  ACC_TR is for bbound comparisons inside tree
	gem gems[len];
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(pool_zero*sizeof(gem));
	pool_length[0]=pool_zero;

	if (pool_zero==1) {					// combine
		ACC=80;								// ACC is for z-axis sorting and for the length of the interval tree
		gem_init(pool[0],1,1,1,1);		// start gem does not matter
		gem_init(gems   ,1,1,1,1);		// grade damage crit bbound
		size=1000;							// reasonable comb sizing
	}
	else {									// spec
		ACC=60;								// ACC is for z-axis sorting and for the length of the interval tree
		gem_init(pool[0]  ,1,1.000000,1,0);
		gem_init(pool[0]+1,1,1.186168,0,1);		// BB has more dmg
		gem_init(gems     ,1,1.000000,1,0);		// grade damage crit bbound
		size=20000;							// reasonable spec sizing
	}
	if (!(output_options & mask_quiet)) gem_print(gems);

	for (i=1; i<len; ++i) {
		int j,k,h,l;
		const int eoc=(i+1)/ (1+1);      // end of combining
		const int j0 =(i+1)/(10+1);      // value ratio < 10
		int comb_tot=0;

		int grade_max=(int)(log2(i+1)+1);          // gems with max grade cannot be destroyed, so this is a max, not a sup
		gem* temp_pools[grade_max-1];              // get the temp pools for every grade
		int  temp_index[grade_max-1];              // index of work point in temp pools
		gem* subpools[grade_max-1];                // get subpools for every grade
		int  subpools_length[grade_max-1];
		for (j=0; j<grade_max-1; ++j) {            // init everything
			temp_pools[j]=malloc(size*sizeof(gem));
			temp_index[j]=0;
			subpools[j]=NULL;                       // just to be able to free it
			subpools_length[j]=0;
		}

		for (j=j0; j<eoc; ++j) {         // combine gems and put them in temp array
			for (k=0; k< pool_length[j]; ++k) {
				int g1=(pool[j]+k)->grade;
				for (h=0; h< pool_length[i-1-j]; ++h) {
					int delta=g1 - (pool[i-1-j]+h)->grade;
					if (abs(delta)<=2) {        // grade difference <= 2
						comb_tot++;
						gem temp;
						gem_combine(pool[j]+k, pool[i-1-j]+h, &temp);
						int grd=temp.grade-2;
						temp_pools[grd][temp_index[grd]]=temp;
						temp_index[grd]++;
						if (temp_index[grd]==size) {							// let's skim a pool
							int length=size+subpools_length[grd];
							gem* temp_array=malloc(length*sizeof(gem));
							int index=0;
							float maxcrit=0;				// this will help me create the minimum tree
							for (l=0; l<size; ++l) {					// copy new gems
								temp_array[index]=temp_pools[grd][l];
								maxcrit=max(maxcrit, (temp_array+index)->crit);
								index++;
							}
							temp_index[grd]=0;			// temp index reset
							for (l=0; l<subpools_length[grd]; ++l) {		// copy old gems
								temp_array[index]=subpools[grd][l];
								maxcrit=max(maxcrit, (temp_array+index)->crit);
								index++;
							}
							free(subpools[grd]);		// free
							
							gem_sort(temp_array,length);						// work starts
							int broken=0;
							int crit_cells=(int)(maxcrit*ACC)+1;		// this pool will be big from the beginning, but we avoid binary search
							int tree_length= 1 << (int)ceil(log2(crit_cells));					// this is pow(2, ceil()) bitwise for speed improvement
							int* tree=malloc((tree_length+crit_cells+1)*sizeof(int));		// memory improvement, 2* is not needed
							for (l=0; l<tree_length+crit_cells+1; ++l) tree[l]=-1;			// init also tree[0], it's faster
							for (l=length-1;l>=0;--l) {												// start from large z
								gem* p_gem=temp_array+l;
								int index=(int)(p_gem->crit*ACC);									// find its place in x
								if (tree_check_after(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR))) {		// look at y
									tree_add_element(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR));
								}
								else {
									p_gem->grade=0;
									broken++;
								}
							}												// all unnecessary gems destroyed
							free(tree);									// free
							
							subpools_length[grd]=length-broken;
							subpools[grd]=malloc(subpools_length[grd]*sizeof(gem));		// pool init via broken
							
							index=0;
							for (l=0; l<length; ++l) {			// copying to subpool
								if (temp_array[l].grade!=0) {
									subpools[grd][index]=temp_array[l];
									index++;
								}   
							}
							free(temp_array);			// free
						}												// rebuilt subpool[grd], work restarts
					}
				}
			}
		}
		int grd;
		for (grd=0; grd<grade_max-1; ++grd) {						// let's put remaining gems on
			if (temp_index[grd] != 0) {
				int length=temp_index[grd]+subpools_length[grd];
				gem* temp_array=malloc(length*sizeof(gem));
				int index=0;
				float maxcrit=0;				// this will help me create the minimum tree
				for (l=0; l<temp_index[grd]; ++l) {					// copy new gems
					temp_array[index]=temp_pools[grd][l];
					maxcrit=max(maxcrit, (temp_array+index)->crit);
					index++;
				}
				for (l=0; l<subpools_length[grd]; ++l) {		// copy old gems
					temp_array[index]=subpools[grd][l];
					maxcrit=max(maxcrit, (temp_array+index)->crit);
					index++;
				}
				free(subpools[grd]);		// free
				
				gem_sort(temp_array,length);								// work starts
				int broken=0;
				int crit_cells=(int)(maxcrit*ACC)+1;					// this pool will be big from the beginning, but we avoid binary search
				int tree_length= 1 << (int)ceil(log2(crit_cells));					// this is pow(2, ceil()) bitwise for speed improvement
				int* tree=malloc((tree_length+crit_cells+1)*sizeof(int));		// memory improvement, 2* is not needed
					for (l=0; l<tree_length+crit_cells+1; ++l) tree[l]=-1;		// init also tree[0], it's faster
					for (l=length-1;l>=0;--l) {											// start from large z
						gem* p_gem=temp_array+l;
						int index=(int)(p_gem->crit*ACC);								// find its place in x
						if (tree_check_after(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR))) {		// look at y
							tree_add_element(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR));
						}
						else {
						p_gem->grade=0;
						broken++;
					}
				}												// all unnecessary gems destroyed
				free(tree);									// free
			
				subpools_length[grd]=length-broken;
				subpools[grd]=malloc(subpools_length[grd]*sizeof(gem));		// pool init via broken
				index=0;
				for (l=0; l<length; ++l) {			// copying to subpool
					if (temp_array[l].grade!=0) {
						subpools[grd][index]=temp_array[l];
						index++;
					}   
				}
				free(temp_array);			// free
			}									// subpool[grd] is now full
		}
		pool_length[i]=0;
		for (grd=0; grd<grade_max-1; ++grd) pool_length[i]+=subpools_length[grd];
		pool[i]=malloc(pool_length[i]*sizeof(gem));
		
		int place=0;
		for (grd=0;grd<grade_max-1;++grd) {			// copying to pool
			for (j=0; j<subpools_length[grd]; ++j) {
				pool[i][place]=subpools[grd][j];
				place++;
			}   
		}
		for (grd=0;grd<grade_max-1;++grd) {			// free
			free(temp_pools[grd]);
			free(subpools[grd]);
		}
		gems[i]=pool[i][0];						// choosing gem (criteria moved to more_power def)
		for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) {
			gems[i]=pool[i][j];
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_info)
				printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1));
			if (output_options & mask_debug) {
				printf("Raw:\t%d\n",comb_tot);
				printf("Pool:\t%d\n",pool_length[i]);
			}
			gem_print(gems+i);
		}
	}
	
	if (output_options & mask_quiet) {     // outputs last if we never seen any
		printf("Value:\t%d\n",len);
		printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len));
		if (output_options & mask_debug)
			printf("Pool:\t%d\n",pool_length[len-1]);
		gem_print(gems+len-1);
	}

	gem* gemf=gems+len-1;  // gem that will be displayed

	if (output_options & mask_upto) {
		double best_growth=-INFINITY;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (log(gem_power(gems[i]))/log(i+1) > best_growth) {
				best_index=i;
				best_growth=log(gem_power(gems[i]))/log(i+1);
			}
		}
		printf("Best gem up to %d:\n\n", len);
		printf("Value:\t%d\n",best_index+1);
		printf("Growth:\t%f\n", best_growth);
		gem_print(gems+best_index);
		gemf = gems+best_index;
	}

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0, 0);
			printf("Gem with red added:\n\n");
			printf("Value:\t%d\n", value);    // made to work well with -u
			printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value));
			gem_print(gemf);
		}
	}

	if (output_options & mask_parens) {
		printf("Compressed combining scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Gem tree:\n");
		print_tree(gemf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_table(gems, len);
	
	if (output_options & mask_equations) {   // it ruins gems, must be last
		printf("Equations:\n");
		print_equations(gemf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);		// free
	if (output_options & mask_red && len > 2 && pool_zero==2) {
		free(gem_array);
	}
}
Example #8
0
void worker(int len, int output_options, int pool_zero)
{
	printf("\n");
	int i;
	int size;
	gem gems[len];
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(pool_zero*sizeof(gem));
	pool_length[0]=pool_zero;
	
	if (pool_zero==1) {             // combine
		gem_init(pool[0],1,1,1);
		gem_init(gems   ,1,1,1);
		size=100;                    // reasonable comb sizing
	}
	else {                          // spec
		gem_init(pool[0]  ,1,1,0);
		gem_init(pool[0]+1,1,0,1);
		gem_init(gems     ,1,1,0);
		size=2000;                   // reasonable spec sizing
	}
	if (!(output_options & mask_quiet)) gem_print(gems);

	for (i=1; i<len; ++i) {
		int j,k,h,l;
		const int eoc=(i+1)/ (1+1);      // end of combining
		const int j0 =(i+1)/(10+1);      // value ratio < 10
		int comb_tot=0;

		const int grade_max=(int)(log2(i+1)+1);    // gems with max grade cannot be destroyed, so this is a max, not a sup
		gem* temp_pools[grade_max-1];              // get the temp pools for every grade
		int  temp_index[grade_max-1];              // index of work point in temp pools
		gem* subpools[grade_max-1];                // get subpools for every grade
		int  subpools_length[grade_max-1];
		for (j=0; j<grade_max-1; ++j) {            // init everything
			temp_pools[j]=malloc(size*sizeof(gem));
			temp_index[j]=0;
			subpools[j]=NULL;                       // just to be able to free it
			subpools_length[j]=0;
		}

		for (j=j0; j<eoc; ++j) {         // combine gems and put them in temp array
			for (k=0; k< pool_length[j]; ++k) {
				int g1=(pool[j]+k)->grade;
				for (h=0; h< pool_length[i-1-j]; ++h) {
					int delta=g1 - (pool[i-1-j]+h)->grade;
					if (abs(delta)<=2) {        // grade difference <= 2
						comb_tot++;
						gem temp;
						gem_combine(pool[j]+k, pool[i-1-j]+h, &temp);
						int grd=temp.grade-2;
						temp_pools[grd][temp_index[grd]]=temp;
						temp_index[grd]++;
						if (temp_index[grd]==size) {                     // let's skim a pool
							int length=size+subpools_length[grd];
							gem* temp_array=malloc(length*sizeof(gem));
							int index=0;
							for (l=0; l<temp_index[grd]; ++l) {           // copy new gems
								temp_array[index]=temp_pools[grd][l];
								index++;
							}
							temp_index[grd]=0;            // temp index reset
							for (l=0; l<subpools_length[grd]; ++l) {      // copy old gems
								temp_array[index]=subpools[grd][l];
								index++;
							}
							free(subpools[grd]);          // free
							gem_sort(temp_array,length);                  // work starts
	
							int broken=0;
							float lim_bbound=-1;
							for (l=length-1;l>=0;--l) {
								if ((int)(ACC*temp_array[l].bbound)<=(int)(ACC*lim_bbound)) {
									temp_array[l].grade=0;
									broken++;
								}
								else lim_bbound=temp_array[l].bbound;
							}                                // all unnecessary gems destroyed
	
							subpools_length[grd]=length-broken;
							subpools[grd]=malloc(subpools_length[grd]*sizeof(gem));     // pool init via broken
	
							index=0;
							for (l=0; l<length; ++l) {       // copying to subpool
								if (temp_array[l].grade!=0) {
									subpools[grd][index]=temp_array[l];
									index++;
								}
							}
							free(temp_array);     // free
						}                                   // rebuilt subpool[grd], work restarts
					}
				}
			}
		}
		int grd;
		for (grd=0; grd<grade_max-1; ++grd) {                 // let's put remaining gems on
			if (temp_index[grd] != 0) {
				int length=temp_index[grd]+subpools_length[grd];
				gem* temp_array=malloc(length*sizeof(gem));
				int index=0;
				for (l=0; l<temp_index[grd]; ++l) {             // copy new gems
					temp_array[index]=temp_pools[grd][l];
					index++;
				}
				for (l=0; l<subpools_length[grd]; ++l) {        // copy old gems
					temp_array[index]=subpools[grd][l];
					index++;
				}
				free(subpools[grd]);    // free
				gem_sort(temp_array,length);                    // work starts
				int broken=0;
				float lim_bbound=-1;
				for (l=length-1;l>=0;--l) {
					if ((int)(ACC*temp_array[l].bbound)<=(int)(ACC*lim_bbound)) {
						temp_array[l].grade=0;
						broken++;
					}
					else lim_bbound=temp_array[l].bbound;
				}                                      // all unnecessary gems destroyed
				subpools_length[grd]=length-broken;
				subpools[grd]=malloc(subpools_length[grd]*sizeof(gem));     // pool init via broken
				index=0;
				for (l=0; l<length; ++l) {      // copying to subpool
					if (temp_array[l].grade!=0) {
						subpools[grd][index]=temp_array[l];
						index++;
					}
				}
				free(temp_array);     // free
			}                        // subpool[grd] is now full
		}
		pool_length[i]=0;
		for (grd=0; grd<grade_max-1; ++grd) pool_length[i]+=subpools_length[grd];
		pool[i]=malloc(pool_length[i]*sizeof(gem));

		int place=0;
		for (grd=0;grd<grade_max-1;++grd) {       // copying to pool
			for (j=0; j<subpools_length[grd]; ++j) {
				pool[i][place]=subpools[grd][j];
				place++;
			}
		}
		for (grd=0;grd<grade_max-1;++grd) {       // free
			free(temp_pools[grd]);
			free(subpools[grd]);
		}
		gems[i]=pool[i][0];                 // choosing gem (criteria moved to more_power def)
		for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) {
			gems[i]=pool[i][j];
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_info)
				printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1));
			if (output_options & mask_debug) {
				printf("Raw:\t%d\n",comb_tot);
				printf("Pool:\t%d\n",pool_length[i]);
			}
			gem_print(gems+i);
		}
	}
	
	if (output_options & mask_quiet) {     // outputs last if we never seen any
		printf("Value:\t%d\n",len);
		printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len));
		if (output_options & mask_debug)
			printf("Pool:\t%d\n",pool_length[len-1]);
		gem_print(gems+len-1);
	}

	gem* gemf=gems+len-1;  // gem that will be displayed

	if (output_options & mask_upto) {
		double best_growth=-INFINITY;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (log(gem_power(gems[i]))/log(i+1) > best_growth) {
				best_index=i;
				best_growth=log(gem_power(gems[i]))/log(i+1);
			}
		}
		printf("Best gem up to %d:\n\n", len);
		printf("Value:\t%d\n",best_index+1);
		printf("Growth:\t%f\n", best_growth);
		gem_print(gems+best_index);
		gemf = gems+best_index;
	}

	gem* gem_array = NULL;
	gem red;
	if (output_options & mask_red) {
		if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0);
			printf("Gem with red added:\n\n");
			printf("Value:\t%d\n", value);    // made to work well with -u
			printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value));
			gem_print(gemf);
		}
	}

	if (output_options & mask_parens) {
		printf("Compressed combining scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Gem tree:\n");
		print_tree(gemf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_table(gems, len);
	
	if (output_options & mask_equations) {   // it ruins gems, must be last
		printf("Equations:\n");
		print_equations(gemf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);     // free
	if (output_options & mask_red && len > 2 && pool_zero==2) {
		free(gem_array);
	}
}
Example #9
0
void worker(int len, int output_options, int pool_zero, char* filename)
{
	FILE* table=file_check(filename);		// file is open to read
	if (table==NULL) exit(1);				// if the file is not good we exit
	int i;
	gem* gems=malloc(len*sizeof(gem));		// if not malloc-ed 230k is the limit
	gem** pool=malloc(len*sizeof(gem*));
	int* pool_length=malloc(len*sizeof(int));
	pool[0]=malloc(pool_zero*sizeof(gem));
	pool_length[0]=pool_zero;

	if (pool_zero==1) {					// combine
		gem_init(pool[0],1,1,1,1);		// start gem does not matter
		gem_init(gems   ,1,1,1,1);		// grade damage crit bbound
	}
	else {											// spec
		gem_init(pool[0]  ,1,DAMAGE_CRIT  ,1,0);
		gem_init(pool[0]+1,1,DAMAGE_BBOUND,0,1);	// BB has more dmg
		gem_init(gems     ,1,DAMAGE_CRIT  ,1,0);	// grade damage crit bbound
	}
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// pool filling
	fclose(table);				// close
	if (prevmax<len-1) {
		for (i=0;i<=prevmax;++i) free(pool[i]);      // free
		free(pool);				// free
		free(pool_length);	// free
		free(gems);				// free
		if (prevmax>0) printf("Table stops at %d, not %d\n",prevmax+1,len);
		exit(1);
	}
	
	int skip_computations = (output_options & mask_quiet) && !((output_options & mask_table) || (output_options & mask_upto));
	int first = skip_computations ? len-1 : 0;
	for (i=first; i<len; ++i) {
		gems[i]=pool[i][0];
		for (int j=1; j<pool_length[i]; ++j) {
			if (gem_more_powerful(pool[i][j],gems[i])) {
				gems[i]=pool[i][j];
			}
		}
		
		if (!(output_options & mask_quiet)) {
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_info)
				printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1));
			if (output_options & mask_debug)
				printf("Pool:\t%d\n",pool_length[i]);
			gem_print(gems+i);
		}
	}
	
	if (output_options & mask_quiet) {     // outputs last if we never seen any
		printf("Value:\t%d\n",len);
		printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len));
		if (output_options & mask_debug)
			printf("Pool:\t%d\n",pool_length[len-1]);
		gem_print(gems+len-1);
	}

	gem* gemf=gems+len-1;  // gem that will be displayed

	if (output_options & mask_upto) {
		double best_growth=-INFINITY;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (log(gem_power(gems[i]))/log(i+1) > best_growth) {
				best_index=i;
				best_growth=log(gem_power(gems[i]))/log(i+1);
			}
		}
		printf("Best gem up to %d:\n\n", len);
		printf("Value:\t%d\n",best_index+1);
		printf("Growth:\t%f\n", best_growth);
		gem_print(gems+best_index);
		gemf = gems+best_index;
	}

	gem* gem_array = NULL;
	gem red;
	if (output_options & mask_red) {
		if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0, 0);
			printf("Gem with red added:\n\n");
			printf("Value:\t%d\n", value);    // made to work well with -u
			printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value));
			gem_print(gemf);
		}
	}

	if (output_options & mask_parens) {
		printf("Compressed combining scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Gem tree:\n");
		print_tree(gemf, "");
		printf("\n");
	}
	if (output_options & mask_table) print_table(gems, len);
	
	if (output_options & mask_equations) {   // it ruins gems, must be last
		printf("Equations:\n");
		print_equations(gemf);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);		// free
	free(pool);
	free(pool_length);
	free(gems);
	if (output_options & mask_red && len > 2 && pool_zero==2) {
		free(gem_array);
	}
}
Example #10
0
void worker(int len, int lenc, int output_options, char* filename, char* filenamec, char* filenameA, int TC, int As, int GT, int Namps)
{
	FILE* table=file_check(filename);			// file is open to read
	if (table==NULL) exit(1);						// if the file is not good we exit
	int i;
	gem* pool[len];
	int pool_length[len];
	pool[0]=malloc(2*sizeof(gem));
	pool_length[0]=2;
	gem_init(pool[0]  ,1,1.000000,1,0);		// grade damage crit bbound
	gem_init(pool[0]+1,1,1.186168,0,1);		// BB has more dmg
	
	int prevmax=pool_from_table(pool, pool_length, len, table);		// killgem spec pool filling
	fclose(table);
	if (prevmax<len-1) {										// if the killgems are not enough
		for (i=0;i<=prevmax;++i) free(pool[i]);		// free
		if (prevmax>0) printf("Gem table stops at %d, not %d\n",prevmax+1,len);
		exit(1);
	}

	gem* poolf[len];
	int poolf_length[len];
	
	KGSPEC_COMPRESSION
	printf("Gem speccing pool compression done!\n");

	FILE* tableA=file_check(filenameA);		// fileA is open to read
	if (tableA==NULL) exit(1);					// if the file is not good we exit
	int lena=len;									// see which is bigger between spec len and comb len
	if (lenc > len) lena=lenc;					// and we'll get the amp pool till there
	gemY** poolY=malloc(lena*sizeof(gemY*));
	int* poolY_length=malloc(lena*sizeof(int));
	poolY[0]=malloc(sizeof(gemY));
	poolY_length[0]=1;
	gem_init_Y(poolY[0],1,1,1);
	
	int prevmaxA=pool_from_table_Y(poolY, poolY_length, lena, tableA);		// amps pool filling
	fclose(tableA);
	if (prevmaxA<lena-1) {
		for (i=0;i<=prevmaxA;++i) free(poolY[i]);		// free
		if (prevmaxA>0) printf("Amp table stops at %d, not %d\n",prevmaxA+1,lena);
		exit(1);
	}
	
	gemY** poolYf=malloc(lena*sizeof(gemY*));		// if not malloc-ed 140k is the limit
	int poolYf_length[lena];
	
	AMPS_COMPRESSION
	gemY poolYc[poolYf_length[lenc-1]];
	int poolYc_length=poolYf_length[lenc-1];
	
	for (i=0; i<poolYf_length[lenc-1]; ++i) {		// amps fast access combining pool
		poolYc[i]=poolYf[lenc-1][i];
	}
	printf("Amp combining pool compression done!\n");

	FILE* tablec=file_check(filenamec);		// file is open to read
	if (tablec==NULL) exit(1);					// if the file is not good we exit
	gem** poolc=malloc(lenc*sizeof(gem*));
	int* poolc_length=malloc(lenc*sizeof(int));
	poolc[0]=malloc(sizeof(gem));
	poolc_length[0]=1;
	gem_init(poolc[0],1,1,1,1);
	
	int prevmaxc=pool_from_table(poolc, poolc_length, lenc, tablec);		// killgem comb pool filling
	fclose(tablec);
	if (prevmaxc<lenc-1) {									// if the killgems are not enough
		for (i=0;i<=prevmaxc;++i) free(poolc[i]);		// free
		if (prevmaxc>0) printf("Gem table stops at %d, not %d\n",prevmaxc+1,lenc);
		exit(1);
	}
	
	gem* poolcf;
	int poolcf_length;
	
	KGCOMB_COMPRESSION
	printf("Killgem comb compressed pool size:\t%d\n",poolcf_length);

	int cpairs_length;
	cpair* cpairs;
	
	{				// cpair compression
		int length = poolcf_length*poolYc_length;
		cpair* temp_array=malloc(length*sizeof(cpair));
		int index=0;
		for (int l=0; l<poolcf_length; ++l) {
			for (int m=0; m<poolYc_length; ++m) {
				double power = gem_power(poolcf[l]);
				double rdmg  = poolYc[m].damage/poolcf[l].damage;
				double rcrit = poolYc[m].crit / poolcf[l].crit;
				temp_array[index++] = (cpair){power, rdmg, rcrit, poolcf+l, poolYc+m, 0};
			}
		}
		cpair_sort_rcrit(temp_array,length);				/* work starts */
		double lastrcrit=-1;
		int tree_cell=0;
		for (int l=0; l<length; ++l) {
			if (temp_array[l].rcrit == lastrcrit) temp_array[l].place=tree_cell-1;
			else {
				temp_array[l].place=tree_cell++;
				lastrcrit = temp_array[l].rcrit;
			}
		}
		cpair_sort_xyz(temp_array,length);
		int broken=0;
		int tree_length= 1 << (int)ceil(log2(tree_cell));		/* this is pow(2, ceil()) bitwise */
		double* tree=malloc((tree_length*2)*sizeof(double));
		for (int l=0; l<tree_length*2; ++l) tree[l]=0;			/* init also tree[0], it's faster */
		for (int l=length-1; l>=0; --l) {							/* start from large rdmg */
			cpair* p_cpair=temp_array+l;
			if (dtree_check_after(tree, tree_length, p_cpair->place, p_cpair->power)) {
				dtree_add_element(tree, tree_length, p_cpair->place, p_cpair->power);
			}
			else {
				p_cpair->combg=NULL;
				broken++;
			}
		}
		for (int l=0; l<tree_length*2; ++l) tree[l]=0;			/* BgDaCa - iDa - iCa  compression */
		for (int l=0; l<length; ++l) {								/* start from low rdmg */
			cpair* p_cpair=temp_array+l;
			if (p_cpair->combg==NULL) continue;
			int place = tree_length -1 - p_cpair->place;			/* reverse crit order */
			if (dtree_check_after(tree, tree_length, place, cpair_BgDaCa(*p_cpair))) {
				dtree_add_element(tree, tree_length, place, cpair_BgDaCa(*p_cpair));
			}
			else {
				p_cpair->combg=NULL;
				broken++;
			}
		}
		for (int l=0; l<tree_length*2; ++l) tree[l]=0;			/* BgDaCg - iDa - Ca  compression */
		for (int l=0; l<length; ++l) {								/* start from low rdmg */
			cpair* p_cpair=temp_array+l;
			if (p_cpair->combg==NULL) continue;
			int place = p_cpair->place;								/* regular crit order */
			if (dtree_check_after(tree, tree_length, place, cpair_BgDaCg(*p_cpair))) {
				dtree_add_element(tree, tree_length, place, cpair_BgDaCg(*p_cpair));
			}
			else {
				p_cpair->combg=NULL;
				broken++;
			}
		}
		for (int l=0; l<tree_length*2; ++l) tree[l]=0;			/* BgDgCa - Da - iCa  compression */
		for (int l=length-1; l>=0; --l) {							/* start from large rdmg */
			cpair* p_cpair=temp_array+l;
			if (p_cpair->combg==NULL) continue;
			int place = tree_length -1 - p_cpair->place;			/* reverse crit order */
			if (dtree_check_after(tree, tree_length, place, cpair_BgDgCa(*p_cpair))) {
				dtree_add_element(tree, tree_length, place, cpair_BgDgCa(*p_cpair));
			}
			else {
				p_cpair->combg=NULL;
				broken++;
			}
		}
		free(tree);
		
		cpairs_length=length-broken;
		cpairs=malloc(cpairs_length*sizeof(cpair));
		index=0;
		for (int j=0; j<length; ++j) {
			if (temp_array[j].combg!=NULL) {
				cpairs[index] = temp_array[j];
				index++;
			}
		}
		free(temp_array);
	}
	printf("Combine pairs pool size:\t%d\n\n",cpairs_length);

	int j,k,h,l;							// let's choose the right gem-amp combo
	gem gems[len];							// for every speccing value
	gemY amps[len];						// we'll choose the best amps
	gem gemsc[len];						// and the best NC combine
	gemY ampsc[len];						// for both
	double powers[len];
	gem_init(gems,1,1,1,0);
	gem_init_Y(amps,0,0,0);
	gem_init(gemsc,1,1,0,0);
	gem_init_Y(ampsc,0,0,0);
	powers[0]=0;
	double iloglenc=1/log(lenc);
	double crit_ratio  =Namps*(0.15+As/3*0.004)*2*(1+0.03*TC)/(1.0+TC/3*0.1);
	double damage_ratio=Namps*(0.20+As/3*0.004) * (1+0.03*TC)/(1.2+TC/3*0.1);
	double NT=pow(2, GT-1);
	if (!(output_options & mask_quiet)) {
		printf("Killgem spec\n");
		gem_print(gems);
		printf("Amplifier spec (x%d)\n", Namps);
		gem_print_Y(amps);
		printf("Spec base power:    \t0\n\n\n");
	}

	for (i=1;i<len;++i) {														// for every gem value
		gems[i]=(gem){0};															// we init the gems
		amps[i]=(gemY){0};														// to extremely weak ones
		gemsc[i]=(gem){0};
		ampsc[i]=(gemY){0};
																						// first we compare the gem alone
		for (l=0; l<poolcf_length; ++l) {									// first search in the NC gem comb pool
			if (gem_power(poolcf[l]) > gem_power(gemsc[i])) {
				gemsc[i]=poolcf[l];
			}
		}
		for (k=0;k<poolf_length[i];++k) {									// and then in the compressed gem pool
			if (gem_power(poolf[i][k]) > gem_power(gems[i])) {
				gems[i]=poolf[i][k];
			}
		}
		int NS=i+1;
		double c0 = log(NT/(i+1))*iloglenc;									// last we compute the combination number
		powers[i] = pow(gem_power(gemsc[i]),c0) * gem_power(gems[i]);
																						// now we compare the whole setup
		for (j=0, NS+=Namps; j<i+1; ++j, NS+=Namps) {					// for every amp value from 1 to to gem_value
			double c = log(NT/NS)*iloglenc;									// we compute the combination number
			for (l=0; l<cpairs_length; ++l) {								// then we search in the comb pair pool
				double Cg = pow(cpairs[l].power,c);
				double Rd = damage_ratio*pow(cpairs[l].rdmg, c);
				double Rc = crit_ratio * pow(cpairs[l].rcrit,c);
				for (h=0; h<poolYf_length[j]; ++h) {						// then in the reduced amp pool
					double Pad = Rd * poolYf[j][h].damage;
					double Pac = Rc * poolYf[j][h].crit  ;
					for (k=0; k<poolf_length[i]; ++k) {						// and in the gem pool
						double Pext = Cg * poolf[i][k].bbound * poolf[i][k].bbound;
						double Pdamage = poolf[i][k].damage + Pad;
						double Pcrit   = poolf[i][k].crit   + Pac;
						double power   = Pext * Pdamage * Pcrit ;
						if (power>powers[i]) {
							powers[i]=power;
							gems[i]=poolf[i][k];
							amps[i]=poolYf[j][h];
							gemsc[i]=*(cpairs[l].combg);
							ampsc[i]=*(cpairs[l].comba);
						}
					}
				}
			}
		}
		if (!(output_options & mask_quiet)) {
			printf("Killgem spec\n");
			printf("Value:\t%d\n",i+1);
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolf_length[i]);
			gem_print(gems+i);
			printf("Amplifier spec (x%d)\n", Namps);
			printf("Value:\t%d\n",gem_getvalue_Y(amps+i));
			if (output_options & mask_debug) printf("Pool:\t%d\n",poolYf_length[gem_getvalue_Y(amps+i)-1]);
			gem_print_Y(amps+i);
			printf("Killgem combine\n");
			printf("Comb:\t%d\n",lenc);
			if (output_options & mask_debug) printf("P.pool:\t%d\n", cpairs_length);
			gem_print(gemsc+i);
			printf("Amplifier combine\n");
			printf("Comb:\t%d\n",lenc);
			gem_print_Y(ampsc+i);
			printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[i], amps[i], damage_ratio, crit_ratio));
			printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[i]);
		}
	}
	
	if (output_options & mask_quiet) {		// outputs last if we never seen any
		printf("Killgem spec\n");
		printf("Value:\t%d\n",len);
		gem_print(gems+len-1);
		printf("Amplifier spec (x%d)\n", Namps);
		printf("Value:\t%d\n",gem_getvalue_Y(amps+len-1));
		gem_print_Y(amps+len-1);
		printf("Killgem combine\n");
		printf("Comb:\t%d\n",lenc);
		if (output_options & mask_debug) printf("P.pool:\t%d\n", cpairs_length);
		gem_print(gemsc+len-1);
		printf("Amplifier combine\n");
		printf("Comb:\t%d\n",lenc);
		gem_print_Y(ampsc+len-1);
		printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[len-1], amps[len-1], damage_ratio, crit_ratio));
		printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[len-1]);
	}

	gem*  gemf = gems+len-1;  // gem  that will be displayed
	gemY* ampf = amps+len-1;  // amp  that will be displayed
	gem*  gemfc=gemsc+len-1;  // gemc that will be displayed
	gemY* ampfc=ampsc+len-1;  // ampc that will be displayed

	if (output_options & mask_upto) {
		double best_pow=0;
		int best_index=0;
		for (i=0; i<len; ++i) {
			if (powers[i] > best_pow) {
				best_index=i;
				best_pow=powers[i];
			}
		}
		printf("Best setup up to %d:\n\n", len);
		printf("Killgem spec\n");
		printf("Value:\t%d\n", gem_getvalue(gems+best_index));
		gem_print(gems+best_index);
		printf("Amplifier spec (x%d)\n", Namps);
		printf("Value:\t%d\n", gem_getvalue_Y(amps+best_index));
		gem_print_Y(amps+best_index);
		printf("Killgem combine\n");
		printf("Comb:\t%d\n",lenc);
		gem_print(gemsc+best_index);
		printf("Amplifier combine\n");
		printf("Comb:\t%d\n",lenc);
		gem_print_Y(ampsc+best_index);
		printf("Spec base power:    \t%#.7g\n", gem_amp_power(gems[best_index], amps[best_index], damage_ratio, crit_ratio));
		printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[best_index]);
		gemf = gems+best_index;
		ampf = amps+best_index;
		gemfc = gemsc+best_index;
		ampfc = ampsc+best_index;
	}

	gem* gem_array;
	gem red;
	if (output_options & mask_red) {
		if (len < 3) printf("I could not add red!\n\n");
		else {
			int value=gem_getvalue(gemf);
			int valueA= gem_getvalue_Y(ampf);
			double NS = value + Namps*valueA;
			double c = log(NT/NS)*iloglenc;
			double ampd_resc_coeff = pow((ampfc->damage/gemfc->damage), c);
			double ampc_resc_coeff = pow((ampfc->crit/gemfc->crit), c);
			double amp_damage_scaled = damage_ratio * ampd_resc_coeff * ampf->damage;
			double amp_crit_scaled = crit_ratio * ampc_resc_coeff * ampf->crit;
			gemf = gem_putred(poolf[value-1], poolf_length[value-1], value, &red, &gem_array, amp_damage_scaled, amp_crit_scaled);
			printf("Setup with red added:\n\n");
			printf("Killgem spec\n");
			printf("Value:\t%d\n", value);		// made to work well with -u
			gem_print(gemf);
			printf("Amplifier spec (x%d)\n", Namps);
			printf("Value:\t%d\n", valueA);
			gem_print_Y(ampf);
			printf("Killgem combine\n");
			printf("Comb:\t%d\n",lenc);
			gem_print(gemfc);
			printf("Amplifier combine\n");
			printf("Comb:\t%d\n",lenc);
			gem_print_Y(ampfc);
			if (output_options & mask_debug) printf("Damage rescaling coeff.: \t%f\n", ampd_resc_coeff);
			if (output_options & mask_debug) printf("Crit rescaling coeff.:   \t%f\n", ampc_resc_coeff);
			printf("Spec base power with red:\t%#.7g\n", gem_amp_power(*gemf, *ampf, damage_ratio, crit_ratio));
			double CgP = pow(gem_power(*gemfc), c);
			printf("Global power w. red at g%d:\t%#.7g\n\n\n", GT, CgP*gem_cfr_power(*gemf, amp_damage_scaled, amp_crit_scaled));
		}
	}

	if (output_options & mask_parens) {
		printf("Killgem speccing scheme:\n");
		print_parens_compressed(gemf);
		printf("\n\n");
		printf("Amplifier speccing scheme:\n");
		print_parens_compressed_Y(ampf);
		printf("\n\n");
		printf("Killgem combining scheme:\n");
		print_parens_compressed(gemfc);
		printf("\n\n");
		printf("Amplifier combining scheme:\n");
		print_parens_compressed_Y(ampfc);
		printf("\n\n");
	}
	if (output_options & mask_tree) {
		printf("Killgem speccing tree:\n");
		print_tree(gemf, "");
		printf("\n");
		printf("Amplifier speccing tree:\n");
		print_tree_Y(ampf, "");
		printf("\n");
		printf("Killgem combining tree:\n");
		print_tree(gemfc, "");
		printf("\n");
		printf("Amplifier combining tree:\n");
		print_tree_Y(ampfc, "");
		printf("\n");
	}
	if (output_options & mask_table) print_omnia_table(gems, amps, powers, len);
	
	if (output_options & mask_equations) {		// it ruins gems, must be last
		printf("Killgem speccing equations:\n");
		print_equations(gemf);
		printf("\n");
		printf("Amplifier speccing equations:\n");
		print_equations_Y(ampf);
		printf("\n");
		printf("Killgem combining equations:\n");
		print_equations(gemfc);
		printf("\n");
		printf("Amplifier combining equations:\n");
		print_equations_Y(ampfc);
		printf("\n");
	}
	
	for (i=0;i<len;++i) free(pool[i]);			// free gems
	for (i=0;i<len;++i) free(poolf[i]);			// free gems compressed
	for (i=0;i<lenc;++i) free(poolc[i]);		// free gems
	free(poolc);
	free(poolc_length);
	free(poolcf);
	for (i=0;i<lena;++i) free(poolY[i]);		// free amps
	for (i=0;i<lena;++i) free(poolYf[i]);		// free amps compressed
	free(poolY);
	free(poolY_length);
	free(poolYf);
	free(cpairs);
	if (output_options & mask_red && len > 2) {
		free(gem_array);
	}
}