Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- since r15020;
- boolean setting_farm_tailings_after_fuel_rods = false; //This will intentionally farm out tailings once you have enough crimbonium to match the number of cylindrical molds you have. Almost certainly a bad idea with the mining oil change.
- boolean setting_debug_one_at_a_time = false;
- /*
- WARNING: This script will use up all of your Oily Legs effect. It won't mine without that effect.
- This script will attempt to mine crimbonium as efficiently as it can, without spending turns.
- It targets the largest group of crimbonium it can find, and mines for that. Once there's no more crimbonium, it changes caverns.
- It also tries to avoid cave-ins on the way, but only if it's possible without taking a longer path.
- Will equip the xiblaxian holo-wrist-puter if necessary.
- It does have some ineffiencies - there are certain spots that will be more likely to contain crimbonium than others, in certain situations. But that would require a more complicated implementation so it doesn't do that. Apologies. (the exact situation is that you'd want to target spots that have more promising spots "behind" it, as they're more likely to be part of the group than edge pieces.)
- It restores HP using Doc Galatik for ten meat. Seems the cheapest option.
- Also the script outputs lots of debug text to watch.
- This script is in the public domain.
- */
- string [int][int] __mine_layout;
- //X, Y conversion formula is y * 8 + x
- //X and Y vary from 0 to 7, top-left dominate
- //Usable area is x = [1, 6] and y = [1, 7]
- int mineComboPositionForXY(int x, int y)
- {
- return y * 8 + x;
- }
- int abs(int v)
- {
- if (v < 0)
- return -v;
- return v;
- }
- boolean mineComboPositionsAreAdjacent(int combo_position_1, int combo_position_2)
- {
- //Adjacent means above, below, left of, or right of.
- int x_1 = combo_position_1 % 8;
- int x_2 = combo_position_2 % 8;
- int y_1 = combo_position_1 / 8;
- int y_2 = combo_position_2 / 8;
- if (y_1 == y_2)
- {
- //same row
- if (x_1 == x_2 - 1)
- return true;
- if (x_1 == x_2 + 1)
- return true;
- }
- if (x_1 == x_2)
- {
- //same column
- if (y_1 == y_2 - 1)
- return true;
- if (y_1 == y_2 + 1)
- return true;
- }
- return false;
- }
- int manhattanDistanceBetweenComboPositions(int combo_position_1, int combo_position_2)
- {
- int x_1 = combo_position_1 % 8;
- int x_2 = combo_position_2 % 8;
- int y_1 = combo_position_1 / 8;
- int y_2 = combo_position_2 / 8;
- return abs(x_2 - x_1) + abs(y_2 - y_1);
- }
- void listAppend(string [int] list, string entry)
- {
- int position = list.count();
- while (list contains position)
- position += 1;
- list[position] = entry;
- }
- void listAppend(int [int] list, int entry)
- {
- int position = list.count();
- while (list contains position)
- position += 1;
- list[position] = entry;
- }
- void listAppend(int [int][int] list, int [int] entry)
- {
- int position = list.count();
- while (list contains position)
- position += 1;
- list[position] = entry;
- }
- void listAppendList(int [int] list, int [int] entries)
- {
- foreach key in entries
- list.listAppend(entries[key]);
- }
- boolean listEqualsList(int [int] l1, int [int] l2)
- {
- //if (l1 == l2) return true; //not sure how this works
- if (l1.count() != l2.count()) return false;
- foreach key, entry in l1
- {
- if (!(l2 contains key))
- return false;
- if (l1[key] != l2[key])
- return false;
- }
- return true;
- }
- string listJoinComponents(string [int] list, string joining_string, string and_string)
- {
- buffer result;
- boolean first = true;
- int number_seen = 0;
- foreach i in list
- {
- if (first)
- {
- result.append(list[i]);
- first = false;
- }
- else
- {
- if (!(list.count() == 2 && and_string.length() > 0))
- result.append(joining_string);
- if (and_string.length() > 0 && number_seen == list.count() - 1)
- {
- result.append(" ");
- result.append(and_string);
- result.append(" ");
- }
- result.append(list[i]);
- }
- number_seen = number_seen + 1;
- }
- return result.to_string();
- }
- string listJoinComponents(string [int] list, string joining_string)
- {
- return listJoinComponents(list, joining_string, "");
- }
- void queryMineLayout(int mine_id)
- {
- string [int] base_layout;
- string mine_page_text = visit_url("mining.php?mine=" + mine_id);
- string [int][int] page_matches = group_string(mine_page_text, "alt='([^\\(]*) \\(([0-7]),([0-7])\\)'");
- if (page_matches.count() == 0)
- {
- abort("Unable to parse mine.");
- return;
- }
- foreach key in page_matches
- {
- string [int] match = page_matches[key];
- string type = match[1];
- int x = match[2].to_int();
- int y = match[3].to_int();
- int a_converted_position_in_venice_italy = mineComboPositionForXY(x, y);
- base_layout[a_converted_position_in_venice_italy] = type;
- //print_html("(" + x + ", " + y + " - " + a_converted_position_in_venice_italy + "): " + type);
- }
- //Now the property:
- string layout_property_value = get_property("mineLayout" + mine_id);
- string [int][int] layout_matches = layout_property_value.group_string("#([0-9]*)<img src=\"[^\"]*\" alt=\"([^\"]*)\"[^>]*>");
- foreach key in layout_matches
- {
- string [int] match = layout_matches[key];
- int position = match[1].to_int();
- string type = match[2];
- //print_html(position + ": " + type);
- if (base_layout[position] != "Open Cavern")
- {
- abort("parse error");
- return;
- }
- base_layout[position] = type;
- }
- __mine_layout[mine_id] = base_layout;
- //print_html("__mine_layout = " + __mine_layout.to_json());
- }
- int [int][int] findSetMatches(int mine_id)
- {
- //FIXME other than nugget of Crimbonium
- int [int][int] area_sets;
- for y from 1 to 7
- {
- for x from 1 to 6
- {
- int combo_position = mineComboPositionForXY(x, y);
- string type = __mine_layout[mine_id][combo_position];
- if (!(type == "Promising Chunk of Wall" || type == "nugget of Crimbonium"))
- continue;
- //Make a single set of us. We'll combine later.
- int [int] single_set;
- single_set.listAppend(combo_position);
- area_sets.listAppend(single_set);
- }
- }
- //Combine sets that are adjacent to each other.
- while (true)
- {
- boolean should_combine = false;
- int c1_to_combine = -1;
- int c2_to_combine = -1;
- foreach c1_key1 in area_sets
- {
- foreach c1_key2 in area_sets[c1_key1]
- {
- int combo_position_1 = area_sets[c1_key1][c1_key2];
- foreach c2_key1 in area_sets
- {
- if (c2_key1 == c1_key1)
- continue;
- foreach c2_key2 in area_sets[c2_key1]
- {
- int combo_position_2 = area_sets[c2_key1][c2_key2];
- if (mineComboPositionsAreAdjacent(combo_position_1, combo_position_2))
- {
- should_combine = true;
- break;
- }
- }
- if (should_combine)
- {
- c1_to_combine = c1_key1;
- c2_to_combine = c2_key1;
- break;
- }
- }
- if (should_combine)
- break;
- }
- if (should_combine)
- break;
- }
- if (should_combine)
- {
- area_sets[c1_to_combine].listAppendList(area_sets[c2_to_combine]);
- remove area_sets[c2_to_combine];
- }
- else //no more
- break;
- }
- //Re-order the keys properly:
- int [int][int] area_sets_result;
- foreach key in area_sets
- {
- area_sets_result.listAppend(area_sets[key]);
- }
- area_sets = area_sets_result;
- print_html("area_sets = " + area_sets.to_json());
- return area_sets;
- }
- int [int][int] __flsm_area_sets;
- int [int] findLargestSetMatch(int mine_id)
- {
- int [int][int] area_sets = findSetMatches(mine_id);
- __flsm_area_sets = area_sets;
- int largest_count = 0;
- foreach key in area_sets
- {
- largest_count = MAX(area_sets[key].count(), largest_count);
- }
- foreach key in area_sets
- {
- if (area_sets[key].count() == largest_count)
- return area_sets[key];
- }
- int [int] empty;
- return empty;
- }
- boolean [int] __probable_cave_ins;
- int [int] findNotYetMinedAreasOfCrimbonium()
- {
- boolean should_mine_out_area = (setting_farm_tailings_after_fuel_rods && $item[cylindrical mold].available_amount() <= $item[nugget of crimbonium].available_amount());
- if (true)
- {
- boolean [int] empty;
- __probable_cave_ins = empty;
- }
- int mine_id = 5;
- int crimbonium_count = 0;
- for y from 1 to 7
- {
- for x from 1 to 6
- {
- int combo_position = mineComboPositionForXY(x, y);
- string type = __mine_layout[mine_id][combo_position];
- if (type != "nugget of Crimbonium")
- continue;
- crimbonium_count += 1;
- }
- }
- if (crimbonium_count >= 6 && !should_mine_out_area)
- {
- int [int] empty;
- return empty;
- }
- int [int] largest_set_match = findLargestSetMatch(mine_id);
- print_html("largest_set_match = " + largest_set_match.to_json());
- //Find cave-ins:
- foreach key in __flsm_area_sets
- {
- if (listEqualsList(__flsm_area_sets[key], largest_set_match))
- {
- continue;
- }
- foreach key2, combo_position in __flsm_area_sets[key]
- {
- __probable_cave_ins[combo_position] = true;
- }
- }
- print_html("__probable_cave_ins = " + __probable_cave_ins.to_json());
- int [int] result;
- if (crimbonium_count < 6)
- {
- foreach key, combo_position in largest_set_match
- {
- string type = __mine_layout[mine_id][combo_position];
- if (type == "Promising Chunk of Wall")
- result.listAppend(combo_position);
- }
- }
- if (should_mine_out_area && result.count() == 0)
- {
- for y from 1 to 7
- {
- for x from 1 to 6
- {
- int combo_position = mineComboPositionForXY(x, y);
- string type = __mine_layout[mine_id][combo_position];
- if ((type == "Rocky Wall") && !__probable_cave_ins[combo_position])
- result.listAppend(combo_position);
- }
- }
- }
- return result;
- }
- int [int] findEmptyMiningSpots(int mine_id)
- {
- int [int] results;
- for y from 1 to 7
- {
- for x from 1 to 6
- {
- int combo_position = mineComboPositionForXY(x, y);
- string type = __mine_layout[mine_id][combo_position];
- if (!(type == "Promising Chunk of Wall" || type == "Rocky Wall"))
- results.listAppend(combo_position);
- }
- }
- return results;
- }
- int [int] pathFromSpotToSpot(int combo_position_1, int combo_position_2)
- {
- int [int] result;
- if (combo_position_1 == combo_position_2)
- return result;
- int current_position = combo_position_1;
- int breakout = 100;
- while (current_position != combo_position_2 && breakout > 0)
- {
- breakout -= 1;
- int spot_x = combo_position_2 % 8;
- int empty_x = current_position % 8;
- int spot_y = combo_position_2 / 8;
- int empty_y = current_position / 8;
- int x_delta = spot_x - empty_x;
- int y_delta = spot_y - empty_y;
- if (y_delta < 0)
- {
- current_position = mineComboPositionForXY(empty_x, empty_y - 1);
- }
- else if (y_delta > 0)
- {
- current_position = mineComboPositionForXY(empty_x, empty_y + 1);
- }
- else if (x_delta < 0)
- {
- current_position = mineComboPositionForXY(empty_x - 1, empty_y);
- }
- else if (x_delta > 0)
- {
- current_position = mineComboPositionForXY(empty_x + 1, empty_y);
- }
- else
- break;
- result.listAppend(current_position);
- }
- return result;
- }
- int caveInCountFromSpotToSpot(int combo_position_1, int combo_position_2)
- {
- int cave_in_count = 0;
- int [int] path = pathFromSpotToSpot(combo_position_1, combo_position_2);
- foreach key, combo_position in path
- {
- if (__probable_cave_ins contains combo_position)
- cave_in_count += 1;
- }
- //print_html("shortest_path = " + path.to_json());
- //print_html("cave_in_count = " + cave_in_count);
- return cave_in_count;
- }
- int pickPositionToMineToReachOneOfTheseSpots(int mine_id, int [int] spots)
- {
- //We go through each spot, and find the [spot, empty space] combination with the shortest manhattan distance.
- //Then pick the mining direction that heads towards that spot.
- int [int] mine_empty_spots = findEmptyMiningSpots(mine_id);
- print_html("mine_empty_spots = " + mine_empty_spots.to_json());
- int spot_position = -1;
- int empty_position = -1;
- int cached_manhattan_distance = -1;
- int cached_cave_ins = -1;
- foreach key, combo_position_spot in spots
- {
- foreach key2, combo_position_empty in mine_empty_spots
- {
- int manhattan_distance = manhattanDistanceBetweenComboPositions(combo_position_spot, combo_position_empty);
- int cave_ins = -1;
- boolean should_replace = false;
- if (cached_manhattan_distance == -1)
- should_replace = true;
- else if (manhattan_distance < cached_manhattan_distance)
- should_replace = true;
- else if (manhattan_distance == cached_manhattan_distance)
- {
- cave_ins = caveInCountFromSpotToSpot(combo_position_spot, combo_position_empty);
- if (cave_ins < cached_cave_ins)
- should_replace = true;
- }
- if (should_replace)
- {
- spot_position = combo_position_spot;
- empty_position = combo_position_empty;
- cached_manhattan_distance = manhattan_distance;
- if (cave_ins == -1)
- cave_ins = caveInCountFromSpotToSpot(combo_position_spot, combo_position_empty);
- cached_cave_ins = cave_ins;
- }
- }
- }
- print_html("Best combination from " + empty_position + " to " + spot_position + " (distance " + cached_manhattan_distance + ", " + cached_cave_ins + " known cave-ins)");
- //Now determine how to mine for that:
- int spot_x = spot_position % 8;
- int empty_x = empty_position % 8;
- int spot_y = spot_position / 8;
- int empty_y = empty_position / 8;
- int x_delta = spot_x - empty_x;
- int y_delta = spot_y - empty_y;
- //print_html("x_delta = " + x_delta + ", y_delta = " + y_delta);
- //Very simple. Mine up, then across:
- if (y_delta < 0)
- {
- return mineComboPositionForXY(empty_x, empty_y - 1);
- }
- else if (y_delta > 0)
- {
- return mineComboPositionForXY(empty_x, empty_y + 1);
- }
- else if (x_delta < 0)
- {
- return mineComboPositionForXY(empty_x - 1, empty_y);
- }
- else if (x_delta > 0)
- {
- return mineComboPositionForXY(empty_x + 1, empty_y);
- }
- return -1;
- }
- void HPCheck()
- {
- if (my_hp() == 0)
- {
- if (my_meat() < 10)
- {
- abort("No meat to restore HP to mine.");
- return;
- }
- cli_execute("galaktik hp 1");
- }
- }
- boolean __need_to_switch_to_backup = false;
- boolean __mining_init_inited = false;
- void MiningInit()
- {
- if (__mining_init_inited)
- return;
- __mining_init_inited = true;
- if (!is_wearing_outfit("High-Radiation Mining Gear"))
- {
- if (!have_outfit("High-Radiation Mining Gear"))
- {
- abort("Need High-Radiation Mining Gear outfit first.");
- return;
- }
- __need_to_switch_to_backup = true;
- cli_execute("outfit save Backup");
- cli_execute("outfit High-Radiation Mining Gear");
- }
- if (!is_wearing_outfit("High-Radiation Mining Gear"))
- {
- if (__need_to_switch_to_backup)
- cli_execute("outfit Backup");
- abort("Unable to wear mining gear?");
- return;
- }
- if ($item[xiblaxian holo-wrist-puter].available_amount() > 0 && $item[xiblaxian holo-wrist-puter].equipped_amount() == 0)
- {
- if (!__need_to_switch_to_backup)
- {
- cli_execute("outfit save Backup");
- __need_to_switch_to_backup = true;
- }
- cli_execute("equip acc1 xiblaxian holo-wrist-puter");
- }
- }
- void main()
- {
- if (my_inebriety() > inebriety_limit())
- {
- print_html("You are too mine to drunk.");
- return;
- }
- int starting_adventures = my_adventures();
- HPCheck();
- boolean just_tried_changing_cavern = false;
- int starting_oily_legs_turns = $effect[oily legs].have_effect();
- boolean [item] items_to_track = $items[peppermint tailings, nugget of crimbonium, xiblaxian crystal];
- int [item] starting_item_amounts;
- foreach it in items_to_track
- {
- starting_item_amounts[it] = it.item_amount();
- }
- int dynamite_closeted = 0;
- if ($item[minin' dynamite].item_amount() > 0) //'
- {
- print_html("Closeting minin' dynamite for safety...");
- dynamite_closeted = $item[minin' dynamite].item_amount();
- put_closet(dynamite_closeted, $item[minin' dynamite]);
- }
- int max_loops = $effect[oily legs].have_effect() * 2 + 1;
- while ($effect[oily legs].have_effect() > 0 && ($effect[crimbonar].have_effect() > 0 || $effect[object detection].have_effect() > 0) && max_loops > 0)
- {
- max_loops -= 1;
- if (my_adventures() != starting_adventures) //in case effect tracking is off
- {
- print_html("We spent a turn by accident! Apologies. Stopping.");
- break;
- }
- MiningInit();
- queryMineLayout(5);
- int [int] areas_still_to_mine = findNotYetMinedAreasOfCrimbonium();
- print_html("areas_still_to_mine = " + areas_still_to_mine.to_json());
- if (areas_still_to_mine.count() == 0)
- {
- if (setting_debug_one_at_a_time)
- {
- print_html("Time to change caverns.");
- break;
- }
- if (just_tried_changing_cavern)
- {
- abort("Problems changing cavern.");
- return;
- }
- print_html("Changing caverns...");
- visit_url("mining.php?mine=5&reset=1&pwd");
- just_tried_changing_cavern = true;
- continue;
- }
- just_tried_changing_cavern = false;
- int mining_position = pickPositionToMineToReachOneOfTheseSpots(5, areas_still_to_mine);
- if (mining_position < 0)
- {
- abort("Unable to find a spot to mine. Apologies.");
- return;
- }
- print_html("mining_position = " + mining_position);
- visit_url("mining.php?mine=5&which=" + mining_position + "&pwd");
- HPCheck();
- if (setting_debug_one_at_a_time)
- break;
- }
- if (__need_to_switch_to_backup)
- cli_execute("outfit Backup");
- string [int] found_types;
- foreach it in items_to_track
- {
- int amount_gained = it.item_amount() - starting_item_amounts[it];
- if (amount_gained <= 0)
- continue;
- if (amount_gained == 1)
- found_types.listAppend(amount_gained + " " + it);
- else
- found_types.listAppend(amount_gained + " " + it.plural);
- }
- if (found_types.count() > 0)
- {
- string line = "Found " + found_types.listJoinComponents(", ", "and") + " over " + starting_oily_legs_turns + " mining attempt";
- if (starting_oily_legs_turns > 1)
- line += "s";
- line += ".";
- print_html(line);
- }
- if (dynamite_closeted > 0)
- {
- take_closet(dynamite_closeted, $item[minin' dynamite]); //'
- }
- if ($effect[oily legs].have_effect() == 0)
- print_html("Out of the oily legs effect.");
- else if (!($effect[crimbonar].have_effect() > 0 || $effect[object detection].have_effect() > 0))
- print_html("Out of the crimbonar/object detection effect.");
- if ($item[flask of mining oil].available_amount() > 0)
- print_html($item[flask of mining oil].available_amount() + " flasks of mining oil available. Use them for more mining!");
- else
- print_html("Head to the mining camp for more mining oil.");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement