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 }
void worker(int len, int output_options, char* filename) { FILE* table=table_init(filename, 1); // init orange int i; gem** pool=malloc(len*sizeof(gem*)); // if not malloc-ed 690k is the limit int* pool_length=malloc(len*sizeof(int)); pool[0]=malloc(sizeof(gem)); gem_init(pool[0],1,1); pool_length[0]=1; int prevmax=pool_from_table(pool, pool_length, len, table); // pool filling if (prevmax+1==len) { fclose(table); // close for (i=0;i<len;++i) free(pool[i]); // free free(pool); // free free(pool_length); // 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) { // more building 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++; } } 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 }
void worker(int len, int output_options, int pool_zero, char* filename) { FILE* table=table_init(filename, pool_zero); // init killgem int i; int size; 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,1); // start gem does not matter size=1000; // reasonable comb sizing } else { // spec gem_init(pool[0] ,1,1.000000,1,0); gem_init(pool[0]+1,1,1.186168,0,1); // BB has more dmg size=20000; // reasonable spec sizing } 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,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; for (l=0; l<size; ++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_crit(temp_array,length); // work starts float lastcrit=-1; int tree_cell=0; for (int l=0; l<length; ++l) { if (temp_array[l].crit == lastcrit) temp_array[l].place=tree_cell-1; else { temp_array[l].place=tree_cell++; lastcrit = temp_array[l].crit; } } gem_sort_exact(temp_array,length); int broken=0; int tree_length= 1 << (int)ceil(log2(tree_cell)); // this is pow(2, ceil()) bitwise for speed improvement float* tree=malloc((tree_length*2)*sizeof(float)); for (l=0; l<tree_length*2; ++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; if (ftree_check_after(tree, tree_length, p_gem->place, p_gem->bbound)) { ftree_add_element(tree, tree_length, p_gem->place, p_gem->bbound); } 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; 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_crit(temp_array,length); // work starts float lastcrit=-1; int tree_cell=0; for (int l=0; l<length; ++l) { if (temp_array[l].crit == lastcrit) temp_array[l].place=tree_cell-1; else { temp_array[l].place=tree_cell++; lastcrit = temp_array[l].crit; } } gem_sort_exact(temp_array,length); int broken=0; int tree_length= 1 << (int)ceil(log2(tree_cell)); // this is pow(2, ceil()) bitwise for speed improvement float* tree=malloc((tree_length*2)*sizeof(float)); for (l=0; l<tree_length*2; ++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; if (ftree_check_after(tree, tree_length, p_gem->place, p_gem->bbound)) { ftree_add_element(tree, tree_length, p_gem->place, p_gem->bbound); } 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]); } 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 }