Cluster MIBs part 2 (python) by dabiri

Related: Fishing

Description: This is part 2 of the design to cluster SOSs geographically- python not razor

1#This is python not razor! It expects your journal file in a folder named 'journal' and it will return a razor script that can be run once you're back in game to target the box of all SOS's, then target each individual bag, then it moves each mib into its cluster appropriate bag. Enjoy and good luck! Depending on your programmin experience this is perhaps not for the faint of heart :)
2
3import os
4import re
5import glob
6import numpy as np
7from sklearn.metrics import pairwise_distances
8
9batch_size = 10
10
11def parse_log_file(file_path):
12    sos_data = []
13    coordinates_pattern = r'\[Razor\]: a waterstained SOS message \(located at (\d+), (\d+)\)'
14    serial_pattern = r'\[Razor\]: Added (\d+) to ignore list'
15    
16    with open(file_path, 'r') as file:
17        lines = file.readlines()
18        
19    i = 0
20    while i < len(lines):
21        coord_match = re.search(coordinates_pattern, lines[i])
22        if coord_match:
23            x, y = coord_match.groups()
24            # Look for the serial number in the next few lines
25            for j in range(i+1, min(i+5, len(lines))):
26                serial_match = re.search(serial_pattern, lines[j])
27                if serial_match:
28                    serial = serial_match.group(1)
29                    sos_data.append({
30                        'coordinates': (int(x), int(y)),
31                        'serial': serial
32                    })
33                    break
34        i += 1
35    
36    return sos_data
37
38def is_in_big_blue(coord):
39    x, y = coord
40    return 1600 <= x <= 4000 and 750 <= y <= 3000
41
42def ball_clustering(sos_data, batch_size):
43    coordinates = np.array([entry['coordinates'] for entry in sos_data])
44    
45    # Separate points into Big Blue and outside
46    big_blue_indices = [i for i, coord in enumerate(coordinates) if is_in_big_blue(coord)]
47    outside_indices = [i for i, coord in enumerate(coordinates) if not is_in_big_blue(coord)]
48    
49    # Function to cluster a set of indices
50    def cluster_indices(indices):
51        clusters = []
52        unclustered = indices.copy()
53        
54        while unclustered:
55            start_point = unclustered.pop(0)
56            current_cluster = [start_point]
57            
58            if unclustered:
59                distances = pairwise_distances([coordinates[start_point]], coordinates[unclustered])[0]
60                closest_indices = np.argsort(distances)[:min(batch_size - 1, len(distances))]
61                
62                for idx in sorted(closest_indices, reverse=True):
63                    point_idx = unclustered.pop(idx)
64                    current_cluster.append(point_idx)
65            
66            clusters.append([sos_data[i] for i in current_cluster])
67        
68        return clusters
69    
70    # Cluster Big Blue and outside separately
71    big_blue_clusters = cluster_indices(big_blue_indices)
72    outside_clusters = cluster_indices(outside_indices)
73    
74    # Combine and return all clusters
75    return big_blue_clusters + outside_clusters
76
77def cluster_coordinates(sos_data, batch_size):
78    return ball_clustering(sos_data, batch_size)
79
80
81
82def generate_razor_script(batches):
83    script = []
84    
85    # Add header
86    script.append("// You will be targeting {} bags".format(len(batches)))
87    script.append("")
88    script.append("overhead 'Target main box'")
89    script.append("@setvar main_box")
90    script.append("")
91
92    # Add bag targeting instructions
93    for i in range(len(batches)):
94        script.append(f"overhead 'Target bag {i+1}'")
95        script.append(f"@setvar bag_{i+1}")
96        script.append("")
97
98    # Process each batch
99    for i, batch in enumerate(batches):
100        script.append(f"//Process bag_{i+1}")
101        for entry in batch:
102            script.append(f"lift {entry['serial']}")
103            script.append(f"drop bag_{i+1} -1 -1 0")
104            script.append("pause 650")
105            script.append("")
106
107    # Join all lines and return
108    return "\n".join(script)
109
110def generate_map_pin_files(batches):
111    output_folder = './output'
112    os.makedirs(output_folder, exist_ok=True)
113
114    for i, batch in enumerate(batches):
115        filename = os.path.join(output_folder, f'bag_{i+1}.txt')
116        with open(filename, 'w') as f:
117            for entry in batch:
118                x, y = entry['coordinates']
119                name = f"{x}/{y}"
120                line = f"+\t{name}\t{x}\t{y}\t7\tfalse\n"
121                f.write(line)
122        
123        print(f"Map pin file for bag {i+1} has been written to {filename}")
124
125# Find the most recent log file in the 'journal' folder
126journal_folder = './journal'
127list_of_files = glob.glob(os.path.join(journal_folder, '*_journal.txt'))
128if not list_of_files:
129    print("No journal files found.")
130    exit()
131
132latest_file = max(list_of_files, key=os.path.getctime)
133
134# Parse the log file
135sos_data = parse_log_file(latest_file)
136    
137
138batches = cluster_coordinates(sos_data, batch_size)
139
140# Print the results
141for i, batch in enumerate(batches):
142    print(f"Batch {i+1}:")
143    for entry in batch:
144        print(f"  Coordinates: {entry['coordinates']}, Serial: {entry['serial']}")
145    print()
146    
147
148# After clustering
149razor_script = generate_razor_script(batches)
150
151# Write to file
152output_folder = './output'
153os.makedirs(output_folder, exist_ok=True)
154output_file = os.path.join(output_folder, 'process_bags.razor')
155
156with open(output_file, 'w') as f:
157    f.write(razor_script)
158
159print(f"Razor script has been written to {output_file}")
160
161# After clustering and generating the Razor script
162generate_map_pin_files(batches)
163
164print('\n\n~~~Map pin files have been generated~~~\n\n')
165    
166print ('\n~~~All done~~~\n')