Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int trials = 10000;
- boolean olfacted = false;
- int max_banishes = 6;
- boolean[int] trial_banishes;
- //percent out of 100 that a green smoke bomb drops. base rate is 4.
- int drop_rate = 4*(1+20);
- //maintaining drop rate is nontrivial, I guess.
- int bad_drop_rate = 4*(1+10);
- //number of green smoke bombs gotten during each trial.
- int[int] trial_bombs;
- int[int] buffer_queue;
- //similar role of in-game battlefield image but more precise.
- int battlefield_state;
- //now here's the correspondence between battlefield state and kills, assuming the nuns trick and no thanksgarden bullshit.
- int[int] state_correspondence = { 2, 2, 1, 1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2 };
- //for reference: state_correspondence[i] is the number of kills occurring in the i-th state.
- //observe that the sum of the number of kills is 34, as one would expect given familiarity with the battlefield.
- //okay, here's where we define the battlefield's monster distribution. this is a little gross and could probably be nicer if I worked with its transpose.
- int[int][int] pre_battlefield_distribution;
- pre_battlefield_distribution[1] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 };
- pre_battlefield_distribution[2] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[3] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[4] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[5] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[6] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0 };
- pre_battlefield_distribution[7] = { 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[8] = { 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
- pre_battlefield_distribution[10] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- pre_battlefield_distribution[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- pre_battlefield_distribution[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 };
- pre_battlefield_distribution[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- //14 is green ops soldier.
- pre_battlefield_distribution[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- pre_battlefield_distribution[15] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- pre_battlefield_distribution[16] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
- pre_battlefield_distribution[17] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- pre_battlefield_distribution[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- //in fact, let's take the transpose of that because it's going to be easier later.
- int[int][int] battlefield_distribution;
- foreach i,j in pre_battlefield_distribution{
- battlefield_distribution[j][i] = pre_battlefield_distribution[i][j];
- }
- //now we have battlefield_distribution[i] being the array of copies of each monster during battlefield state i.
- //let's compute the sum of copies in each state.
- //this is needed later and will be more efficient to handle here than repeatedly during iteration.
- int[int] state_copy_sum;
- for i from 0 to 21{
- foreach j in battlefield_distribution[i]{
- state_copy_sum[i] += battlefield_distribution[i][j];
- }
- }
- //these monsters are probably the best to banish.
- //yay heuristics!
- boolean[int] banishable;
- banishable[1] = false;
- banishable[2] = false;
- banishable[3] = false;
- banishable[4] = false;
- banishable[5] = false;
- banishable[6] = true;
- banishable[7] = false;
- banishable[8] = true;
- banishable[9] = true;
- banishable[10] = true;
- banishable[11] = true;
- banishable[12] = false;
- banishable[13] = false;
- banishable[14] = false;
- banishable[15] = true;
- banishable[16] = false;
- banishable[17] = true;
- banishable[18] = false;
- //here's the function that's going to be selecting encounters. It's gr8.
- //compute sum of distribution outside of function for efficiency.
- int select(int[int] copy_distribution, int distribution_sum){
- int selection = -1;
- int pre_selection = -1;
- boolean in_queue;
- boolean is_banished;
- int rejection_roll = 4;
- if(olfacted && copy_distribution[14] > 0){
- //3 from olfaction, 1 from turtle sex, 1 from latte sex
- copy_distribution[14] += 5;
- distribution_sum += 5;
- }
- //this iterates until we pass a 3/4 rejection roll.
- while(selection == -1){
- //roll a random number between 0 and [total number of copies] - 1 inclusive, shift to range [1,total]
- pre_selection = random(distribution_sum) + 1;
- //discern which monster that roll corresponds to.
- foreach i in copy_distribution{
- //decrement roll by the number of copies corresponding to monster i.
- pre_selection -= copy_distribution[i];
- //the monster that exhausts this quantity is the one we rolled.
- if(pre_selection <= 0){
- selection = i;
- break;
- }
- }
- //only check for rejection and banishing if the thing isn't olfacted.
- if(!( selection == 14 && olfacted ) ){
- //now we check if the monster is in the queue.
- in_queue = false;
- for i from 1 to 5{
- if(selection == buffer_queue[i]){
- in_queue = true;
- }
- }
- //if it is, we apply the typical 3/4 rejection rate.
- if(in_queue){
- rejection_roll = random(4);
- //if the roll isn't 1, we reject it and start over.
- if(rejection_roll != 1){
- selection = -1;
- }
- }
- //now we check if the monster is banished
- foreach i in trial_banishes{
- //if a banished monster is the same monster as the selection, we reject it.
- if(trial_banishes[i] && i == selection){
- selection = -1;
- break;
- }
- }
- }
- }
- //shift queue left.
- for i from 2 to 5 {
- buffer_queue[i-1] = buffer_queue[i];
- }
- //put selection in rightmost queue slot.
- buffer_queue[5] = selection;
- return selection;
- }
- int[int] trial_encounters;
- int[int] trial_meatballs;
- int[int] copies;
- int[int] trial_good_meatballs;
- int turns_of_good_meatballs = 10;
- boolean[int] running = {true, false};
- int remaining_effects;
- int kills_in_state;
- int selected_fight;
- int available_banishes;
- //we olfact it before because wishing/faxing.
- olfacted = true;
- //this is how long our good +item% lasts
- for x from 0 to turns_of_good_meatballs{
- //this is whether we run away to preserve our good +item%.
- foreach y in running{
- if(running[y]){
- //this is how many banishes we can use.
- for z from 3 to 6{
- //clear the maps that record each of our simulations.
- clear(trial_good_meatballs);
- clear(trial_meatballs);
- clear(trial_encounters);
- clear(trial_bombs);
- //do a bunch of simulations with the strategy specified by parameters x,y,z.
- for m from 1 to trials{
- //reset all the stuff from the previous trial.
- battlefield_state = 0;
- available_banishes = z;
- clear(buffer_queue);
- //start with empty queue
- buffer_queue[1] = -1;
- buffer_queue[2] = -1;
- buffer_queue[3] = -1;
- buffer_queue[4] = -1;
- buffer_queue[5] = -1;
- //this only matters if you allow 0 to be a monster, which I used to.
- //clear queue manipulation.
- //don't clear olfaction because we're assuming faxed/wished meatball.
- //olfacted = false;
- for i from 1 to 18{
- trial_banishes[i] = false;
- }
- //dunno why I do this.
- clear(copies);
- //this is the maximum number of good meatballs we can have. we're going to start decrementing it after state 10 begins.
- remaining_effects = x;
- //let's clear a battlefield.
- //these are the 22 battlefield states.
- for i from 0 to 21{
- kills_in_state = 0;
- //kill 1-2 things.
- while(kills_in_state < state_correspondence[i]){
- selected_fight = select(battlefield_distribution[i], state_copy_sum[i]);
- if(banishable[selected_fight] && i < 10 && available_banishes == z){
- //batter up kills the monster if we haven't banished anything yet.
- kills_in_state++;
- available_banishes += -1;
- trial_banishes[selected_fight] = true;
- }
- else{
- //this is where we do dirty things to green ops soldiers.
- if(selected_fight == 14){
- //set olfaction here if not doing it preemptively above.
- //olfacted = true;
- if(remaining_effects > 0){
- if(random(100) < drop_rate){
- trial_bombs[m]++;
- }
- //two possible green smoke bombs.
- if(random(100) < drop_rate){
- trial_bombs[m]++;
- }
- trial_good_meatballs[m]++;
- remaining_effects -= 1;
- }
- else{
- if(random(100) < bad_drop_rate){
- trial_bombs[m]++;
- }
- //two possible green smoke bombs.
- if(random(100) < bad_drop_rate){
- trial_bombs[m]++;
- }
- }
- //this gets incremented either way.
- trial_meatballs[m]++;
- kills_in_state++;
- }
- else{
- //this is where we kill useless monsters or use bombs on them.
- //using bombs on them is probably bad, but who knows.
- //kills_in_state++;
- //checks whether meatballs are available and whether preserving effects matters.
- //this is close enough to practical applications.
- if(remaining_effects > 0 && i >= 10 && running[y] && available_banishes > 0 && banishable[selected_fight] ){
- /*
- //use bombs instead of killing.
- //allows bombs to go negative because that's just as meaningful (virtually all routes will start by getting 4-8 green smoke bombs from the wished/faxed one).
- trial_bombs[m] -= 1;
- while(random(10) == 9){
- trial_bombs[m] -= 1;
- }
- */
- available_banishes += -1;
- trial_banishes[selected_fight] = true;
- }
- else{
- //just kill as usual.
- kills_in_state++;
- //decrement effects after reaching state 10.
- if(i >= 10 && remaining_effects > 0){
- remaining_effects -= 1;
- }
- }
- }
- }
- trial_encounters[m]++;
- }
- }
- if(m%(trials/5) == 0){
- //print((m.to_float() / trials.to_float())+" of the way done with "+trials+" trials.");
- }
- }
- int total_meatballs;
- foreach i in trial_meatballs{
- total_meatballs += trial_meatballs[i];
- }
- float average = total_meatballs.to_float() / trials.to_float();
- print("average: "+average);
- float variance;
- foreach i in trial_meatballs{
- variance += ( trial_meatballs[i].to_float() - average )**2;
- }
- variance /= trials.to_float();
- print("sexually transmitted disease: "+(variance**(0.5)));
- int total_bombs;
- foreach i in trial_bombs{
- total_bombs += trial_bombs[i];
- }
- average = total_bombs.to_float() / trials.to_float();
- print("average bombs: "+average);
- variance = 0.0;
- foreach i in trial_bombs{
- variance += ( trial_bombs[i].to_float() - average )**2;
- }
- variance /= trials.to_float();
- print("sexually transmitted disease bombs (gross): "+(variance**(0.5)));
- int total_encounters;
- foreach i in trial_encounters{
- total_encounters += trial_encounters[i];
- }
- average = total_encounters.to_float() / trials.to_float();
- print("average encounters: "+average);
- variance = 0.0;
- foreach i in trial_encounters{
- variance += ( trial_encounters[i].to_float() - average )**2;
- }
- variance /= trials.to_float();
- print("sexually transmitted disease encounters (gross): "+(variance**(0.5)));
- int total_good_meatballs;
- foreach i in trial_good_meatballs{
- total_good_meatballs += trial_good_meatballs[i];
- }
- average = total_good_meatballs.to_float() / trials.to_float();
- print("average good meatballs: "+average);
- variance = 0.0;
- foreach i in trial_good_meatballs{
- variance += ( trial_good_meatballs[i].to_float() - average )**2;
- }
- variance /= trials.to_float();
- print("sexually transmitted disease good meatballs: "+(variance**(0.5)));
- print("with "+z+" available banishes, \+"+(drop_rate/4-1)+"00% item for at most "+x+" meatballs (\+"+(bad_drop_rate/4-1)+"00% for the remainder),");
- if(running[y]){
- print("and running away to preserve effects");
- }
- else{
- print("and not running away to preserve effects");
- }
- print("================================");
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment