def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name, 'is_first': is_first})) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights']
def __init__(self, name, is_player): self.name = name self.is_player = is_player self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_player': self.is_player }))
def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name, 'is_first': is_first})) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] self.myWeight = dict() for i in range(1, int(self.num_weights)): self.myWeight[i] = 1; self.gameState = game.PyGameState()
class Player(object): def __init__(self, name, is_player): self.name = name self.is_player = is_player self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_player': self.is_player })) @abstractclassmethod def play_game(self): pass
class NoTippingClient(object): def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name, 'is_first': is_first})) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] def play_game(self): # pass response = {} while True: response = json.loads(self.client.receive_data()) if 'game_over' in response and response['game_over'] == "1": print("Game Over!") exit(0) board_state = map(lambda x: int(x), response['board_state'].split(' ')) if response['move_type'] == 'place': position, weight = self.place(board_state) self.client.send_data(json.dumps({"position": position, "weight": weight})) else: position = self.remove(board_state) self.client.send_data(json.dumps({"position": position})) def place(self, current_board_state): """ PLACE YOUR PLACING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer), weight (Integer) """ return 1, 1 def remove(self, current_board_state): """ PLACE YOUR REMOVING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer) """ return 1
def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_first': is_first })) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] self.magic_point = min(int(self.num_weights), min(5, math.floor(int(self.num_weights) / 2))) self.myWeight = dict() self.place_turn = 0 #self turns self.remove_turn = 0 #self turns for i in range(1, int(self.num_weights) + 1): self.myWeight[i] = 1
def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_first': is_first })) response = json.loads(self.client.receive_data()) self.board_length = int(response['board_length']) self.num_weights = int(response['num_weights']) self.myWeight = dict() self.is_first = is_first for i in range(1, int(self.num_weights) + 1): self.myWeight[i] = 1 if is_first: self.position = -1 else: self.position = -2 self.nextWeight = 1
class NoTippingClient(object): def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name, 'is_first': is_first})) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] self.myWeight = dict() for i in range(1, int(self.num_weights)): self.myWeight[i] = 1; self.gameState = game.PyGameState() def play_game(self): # pass response = {} while True: response = json.loads(self.client.receive_data()) if 'game_over' in response and response['game_over'] == "1": print("Game Over!") exit(0) if not response: self.board_state = [0]*60 else: self.board_state = board_state = [int(state) for state in filter(None,list(response['board_state'].split(' ')))] self.gameState.absorb(self.board_state) if response['move_type'] == 'place': position, weight = self.gameState.play(2) print("sending " + str(position) + " " + str(weight)) self.client.send_data(json.dumps({"position": position, "weight": weight})) else: position = self.gameState.play(6) print("sending " + str(position)) self.client.send_data(json.dumps({"position": position}))
def __init__(self, name): self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name}))
class Player(object): def __init__(self, name): self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name})) def play_game(self): buffer_size_message = json.loads(self.client.receive_data(size=2048)) buffer_size = int(buffer_size_message['buffer_size']) game_state = json.loads(self.client.receive_data(size=buffer_size)) self.patients = { int(key): value for key, value in game_state['patients'].items() } self.hospitals = { int(key): value for key, value in game_state['hospitals'].items() } self.ambulances = { int(key): value for key, value in game_state['ambulances'].items() } # Get hospital locations and ambulance routes (hos_locations, amb_routes) = self.your_algorithm() response = { 'hospital_loc': hos_locations, 'ambulance_moves': amb_routes } print('sending data') min_buffer_size = sys.getsizeof(json.dumps(response)) print(min_buffer_size) print(response) buff_size_needed = 1 << (min_buffer_size - 1).bit_length() buff_size_needed = max(buff_size_needed, 2048) buff_size_message = {'buffer_size': buff_size_needed} self.client.send_data(json.dumps(buff_size_message)) time.sleep(2) self.client.send_data(json.dumps(response)) # Get results of game game_result = json.loads(self.client.receive_data(size=8192)) if game_result['game_completed']: print(game_result['message']) print('Patients that lived:') print(game_result['patients_saved']) print('---------------') print('Number of patients saved = ' + str(game_result['number_saved'])) else: print('Game failed run/validate ; reason:') print(game_result['message']) def your_algorithm(self): def get_pos_list(): pos_list = [] for p in self.patients: pos_list.append( [self.patients[p]['xloc'], self.patients[p]['yloc']]) return pos_list def parse_clusters(pos_list, labels): clusters = [[], [], [], [], []] for p in range(len(pos_list)): index = labels[p] clusters[index].append(pos_list[p] + [self.patients[p]['rescuetime']] + [p]) return clusters def get_total_urgency(clusters, centroids): urgency = [] for c in range(5): centroid = centroids[c] cluster = clusters[c] distance = 0 survival = 0 for p in cluster: distance += abs(p[0] - centroid[0]) + abs(p[1] - centroid[1]) #survival += p[2] survival += p[2] / len(cluster) urgency.append(distance / float(survival)) return urgency def distance(pos1, pos2): return abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1]) def get_next_patient(cluster, amb_pos, hosp_pos, riders, t, dis_bool, death_bool): if len(riders) == 4: return 0 possibles = [] distance_list = [] death_list = [] for patient in cluster: pos = [patient[0], patient[1]] d = distance(amb_pos, pos) time_to_save = d + distance(pos, hosp_pos) + 2 rescue_times = [r[2] for r in riders] + [patient[2]] possible = True for rt in rescue_times: if rt < time_to_save + t: possible = False if possible: possibles.append(patient) distance_list.append(d) death_list.append(patient[2] - t) if len(possibles) == 0: return 0 if min(distance_list) < 3: return possibles[np.argmin(distance_list)] if dist_bool and not death_bool: return possibles[np.argmin(distance_list)] if death_bool and not dist_bool: return possibles[np.argmin(death_list)] if death_bool and dist_bool: index = np.random.choice([0, 1], 1, [.6, .4])[0] return [ possibles[np.argmin(distance_list)], possibles[np.argmin(death_list)] ][index] if len(possibles) > 30: dist_index = np.argsort(distance_list)[-15:] death_index = np.argsort(death_list)[-15:] index_list = list(dist_index) + list(death_index) possibles = [possibles[i] for i in index_list] #MESS AROUND WITH PROB_LIST prob_list = np.array([ 1 / float(((distance_list[i]) * death_list[i])) for i in range(len(possibles)) ]) prob_list = list(prob_list / float(np.sum(prob_list))) index_list = list(range(len(possibles))) index = np.random.choice(index_list, 1, prob_list)[0] #index = random.choice(index_list) return possibles[index] def converge(my_list, thresh): bool = True for l in my_list: for other in my_list: if abs(l - other) > thresh: bool = False return bool def get_u2a_ratio(cluster_urgency, hospitals_sorted, urgency, amb_num_list): u2a_ratio = [] for i in range(5): index = list(cluster_urgency).index(i) hosp = hospitals_sorted[index] u2a_ratio.append(urgency[i] / float(amb_num_list[hosp])) return u2a_ratio def adjust_clusters(clusters, centroids, urgency, cluster_urgency, amb_num_list, hospitals_sorted): u2a_ratio = get_u2a_ratio(cluster_urgency, hospitals_sorted, urgency, amb_num_list) clusters_new = copy.deepcopy(clusters) bool = False t0 = time.time() while not bool: mean_u = np.mean(u2a_ratio) index_list = [i for i in range(5) if u2a_ratio[i] < mean_u] for c in index_list: clust = clusters_new[c] others = copy.deepcopy(clusters_new) min_dist = 2000 for o in range(len(others)): if o == c or o in index_list: continue for p in range(len(others[o])): dist = distance(others[o][p], centroids[c]) if dist < min_dist: min_index = [o, p] min_dist = dist clusters_new[c].append( copy.deepcopy( clusters_new[min_index[0]][min_index[1]])) del clusters_new[min_index[0]][min_index[1]] urgency = get_total_urgency(clusters_new, centroids) cluster_urgency = np.argsort(urgency) u2a_ratio = get_u2a_ratio(cluster_urgency, hospitals_sorted, urgency, amb_num_list) bool = converge(u2a_ratio, .1) if time.time() - t0 > 1: break return clusters_new res_hos = {} res_amb = {} res_hos_max_outer = {} res_amb_max_outer = {} off_count = 0 saved_max_outer = 0 previous_centroids = [] for trials in range(40): res_hos_temp = {} pos_list = get_pos_list() kmeans = KMeans(init='k-means++', n_clusters=5, n_init=1) kmeans.fit(pos_list) centroids = np.empty(shape=(5, 2)) centroids_d = kmeans.cluster_centers_ for i in range(len(centroids_d)): for j in range(len(centroids_d[i])): centroids[i, j] = int(round(centroids_d[i][j])) clusters = parse_clusters(pos_list, kmeans.labels_) urgency = get_total_urgency(clusters, centroids) cluster_urgency = np.argsort(urgency) amb_num_list = [] for i in range(5): amb_num_list.append( len(self.hospitals[i]['ambulances_at_start'])) hospitals_sorted = np.argsort(amb_num_list) for i in range(5): centroid_x = int(centroids[cluster_urgency[i], 0]) centroid_y = int(centroids[cluster_urgency[i], 1]) int(centroids[cluster_urgency[i], 1]) res_hos_temp[int(hospitals_sorted[i])] = { 'xloc': centroid_x, 'yloc': centroid_y } max_rescue = 0 for p in self.patients: if self.patients[p]['rescuetime'] > max_rescue: max_rescue = self.patients[p]['rescuetime'] print(cluster_urgency) print(hospitals_sorted) print() #u2a_ratio = get_u2a_ratio(cluster_urgency,hospitals_sorted,urgency,amb_num_list) for i in range(5): ''' print("hospital location :" ,res_hos_temp[i]) print("hospital amb number: " , amb_num_list[i]) index = list(hospitals_sorted).index(i) clust_num = cluster_urgency[index] print("cluster number: " , clust_num) print("centroid:" , centroids[clust_num]) print("urgency at loction: " , urgency[clust_num]) #print("u2a: " , u2a_ratio[clust_num]) print() ''' cluster_urgency_copy = copy.deepcopy(cluster_urgency) print(len(clusters[0])) centroids_new = copy.deepcopy(centroids) urgency_new = copy.deepcopy(urgency) cluster_urgency_new = copy.deepcopy(cluster_urgency) amb_num_list_new = copy.deepcopy(amb_num_list) hospitals_sorted_new = copy.deepcopy(hospitals_sorted) clusters_new = copy.deepcopy(clusters) if trials < 20: clusters_new = adjust_clusters(clusters_new,centroids_new\ ,urgency_new,cluster_urgency_new,amb_num_list_new,hospitals_sorted_new) print(len(clusters_new[0])) ''' for i in range(5): print("hospital location :" ,res_hos_temp[i]) print("hospital amb number: " , amb_num_list[i]) index = list(hospitals_sorted).index(i) clust_num = cluster_urgency[index] print("cluster number: " , clust_num) print("centroid:" , centroids[clust_num]) print("urgency at loction: " , urgency[clust_num]) #print("u2a: " , u2a_ratio[clust_num]) print() ''' res_amb_max = {} saved_max = 0 t0 = time.time() t1 = 0 max_time = 2 count = 0 while t1 < max_time: if count < 5: dist_bool = True death_bool = False elif count < 10: dist_bool = False death_bool = True elif t1 < 2 * max_time / float(4): dist_bool = False death_bool = False else: dist_bool = True death_bool = True count += 1 res_amb_temp = {} saved = 0 saved_riders = [] for i in range(5): clusters_copy = copy.deepcopy(clusters_new) hosp = self.hospitals[hospitals_sorted[i]] clust = clusters_copy[cluster_urgency_new[i]] hosp_pos = centroids[cluster_urgency_new[i]] for amb in hosp['ambulances_at_start']: t = 0 route = [] riders = [] amb_pos = hosp_pos while t < max_rescue: while True: next_patient = get_next_patient( clust, amb_pos, hosp_pos, riders, t, dist_bool, death_bool) if next_patient == 0: break riders.append(next_patient) route.append('p' + str(next_patient[-1])) clust.remove(next_patient) t += distance(amb_pos, next_patient[0:2]) + 1 amb_pos = next_patient[0:2] if len(riders) == 0: break route.append('h' + str(hospitals_sorted[i])) t += distance(amb_pos, hosp_pos) + len(riders) amb_pos = hosp_pos saved += len(riders) saved_riders += riders riders = [] if route == []: route = ['h0'] res_amb_temp[amb] = route #print("saved: ", saved) saved_riders = [r[-1] for r in saved_riders] #print(saved_riders) #print("number saved: " , len(saved_riders)) if saved > saved_max: saved_max = saved res_amb_max = res_amb_temp t1 = time.time() - t0 print("max saved with this cluster: ", saved_max) print("previous max: ", saved_max_outer) if saved_max > saved_max_outer: saved_max_outer = saved_max res_amb_max_outer = res_amb_max res_hos_max_outer = res_hos_temp res_amb = res_amb_max_outer res_hos = res_hos_max_outer return (res_hos, res_amb)
class Player(object): def __init__(self, name): self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name})) def play_game(self): buffer_size_message = json.loads(self.client.receive_data(size=2048)) buffer_size = int(buffer_size_message['buffer_size']) game_state = json.loads(self.client.receive_data(size=buffer_size)) self.patients = game_state['patients'] self.hospitals = game_state['hospitals'] self.ambulances = game_state['ambulances'] # Get hospital locations and ambulance routes (hos_locations, amb_routes) = self.your_algorithm() response = { 'hospital_loc': hos_locations, 'ambulance_moves': amb_routes } print('sending data') min_buffer_size = sys.getsizeof(json.dumps(response)) print(min_buffer_size) print(response) buff_size_needed = 1 << (min_buffer_size - 1).bit_length() buff_size_needed = max(buff_size_needed, 2048) buff_size_message = {'buffer_size': buff_size_needed} self.client.send_data(json.dumps(buff_size_message)) time.sleep(2) self.client.send_data(json.dumps(response)) # Get results of game game_result = json.loads(self.client.receive_data(size=8192)) if game_result['game_completed']: print(game_result['message']) print('Patients that lived:') print(game_result['patients_saved']) print('---------------') print('Number of patients saved = ' + str(game_result['number_saved'])) else: print('Game failed run/validate ; reason:') print(game_result['message']) def your_algorithm(self): """ PLACE YOUR ALGORITHM HERE You have access to the dictionaries 'patients', 'hospitals', and 'ambulances' These dictionaries are structured as follows: patients[patient_id] = {'xloc': x, 'yloc': y, 'rescuetime': rescuetime} hospitals[hospital_id] = {'xloc': None, 'yloc': None, 'ambulances_at_start': [array of ambulance_ids]} ambulances[ambulance_id] = {'starting_hospital': hospital_id, 'route': None} IMPORTANT: Although all values are integers (inlcuding ids) JSON converts everything into strings. Hence, if you wish to use the values as integers, please remember to cast them into ints. Likewise, to index into the dictionaries please remember to cast numeric ids into strings i.e. self.patients[str(p_id)] RETURN INFO ----------- You must return a tuple of dictionaries (hospital_locations, ambulance_routes). These MUST be structured as: hospital_locations[hospital_id] = {'xloc': x, 'yloc': y} These values indicate where you want the hospital with hospital_id to start on the grid ambulance_routes[ambulance_id] = {[array of stops along route]} This array follows the following rules: - The starting location of each ambulance is known so array must start with first patient that it must pick up (or hospital location that it will head to) - There can only ever be up to 4 patients in an ambulance at a time so any more than 4 patient stops in a row will result in an invalid input - A stop for a patient is a string starting with 'p' followed by the id of the patient i.e. 'p32' + The 'p' can be uppercase or lowercase + There can be no whitespace, i.e. 'p 32' will not be accepted - A stop for a hospital is the same as the patient except with an 'h', i.e. 'h3' + The 'h' can also be uppercase or lowercase Example: ambulance_routes[3] = ['p0', 'p43', 'h4', 'p102', 'p145', 'p241', 'p32', 'h1'] This will be read as ambulance #3 starts at it's designated hospital, goes to patient #0, then to patient #43, then drops both off at hospital #4, then picks up patients #102, #145, #241, #32 in that order then drops all of them off at hospital #1 """ res_hos = {} res_amb = {} res_hos[0] = {'xloc': 36, 'yloc': 52} res_hos[1] = {'xloc': 18, 'yloc': 20} res_hos[2] = {'xloc': 70, 'yloc': 85} # testing no movement/time increment res_amb[0] = ['p0', 'p1', 'p2', 'p3', 'h0', 'p4', 'h0'] # testing more than 4 pickups res_amb[1] = ['p5', 'p6', 'p7', 'p8', 'h1'] # testing duplicate person id res_amb[2] = ['p9', 'p10', 'p11', 'h2'] res_amb[3] = ['p12', 'p11', 'h2'] # testing rescue overtime (t = 0 before unloading) res_amb[4] = ['p13', 'h0'] # testing rescue barely making it (t = 0 after unloading counts as rescued) res_amb[5] = ['p14', 'h0'] return (res_hos, res_amb)
class Player(object): def __init__(self, name): self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name})) def play_game(self): buffer_size_message = json.loads(self.client.receive_data(size=2048)) buffer_size = int(buffer_size_message['buffer_size']) game_state = json.loads(self.client.receive_data(size=buffer_size)) self.patients = { int(key): value for key, value in game_state['patients'].items() } self.hospitals = { int(key): value for key, value in game_state['hospitals'].items() } self.ambulances = { int(key): value for key, value in game_state['ambulances'].items() } # Get hospital locations and ambulance routes (hos_locations, amb_routes) = self.your_algorithm() response = { 'hospital_loc': hos_locations, 'ambulance_moves': amb_routes } print('sending data') min_buffer_size = sys.getsizeof(json.dumps(response)) print(min_buffer_size) print(response) buff_size_needed = 1 << (min_buffer_size - 1).bit_length() buff_size_needed = max(buff_size_needed, 2048) buff_size_message = {'buffer_size': buff_size_needed} self.client.send_data(json.dumps(buff_size_message)) time.sleep(2) self.client.send_data(json.dumps(response)) # Get results of game game_result = json.loads(self.client.receive_data(size=8192)) if game_result['game_completed']: print(game_result['message']) print('Patients that lived:') print(game_result['patients_saved']) print('---------------') print('Number of patients saved = ' + str(game_result['number_saved'])) else: print('Game failed run/validate ; reason:') print(game_result['message']) def your_algorithm(self): """ PLACE YOUR ALGORITHM HERE You have access to the dictionaries 'patients', 'hospitals', and 'ambulances' These dictionaries are structured as follows: patients[patient_id] = {'xloc': x, 'yloc': y, 'rescuetime': rescuetime} hospitals[hospital_id] = {'xloc': None, 'yloc': None, 'ambulances_at_start': [array of ambulance_ids]} ambulances[ambulance_id] = {'starting_hospital': hospital_id} RETURN INFO ----------- You must return a tuple of dictionaries (hospital_locations, ambulance_routes). These MUST be structured as: hospital_locations[hospital_id] = {'xloc': x, 'yloc': y} These values indicate where you want the hospital with hospital_id to start on the grid ambulance_routes[ambulance_id] = {[array of stops along route]} This array follows the following rules: - The starting location of each ambulance is known so array must start with first patient that it must pick up (or hospital location that it will head to) - There can only ever be up to 4 patients in an ambulance at a time so any more than 4 patient stops in a row will result in an invalid input - A stop for a patient is a string starting with 'p' followed by the id of the patient i.e. 'p32' + The 'p' can be uppercase or lowercase + There can be no whitespace, i.e. 'p 32' will not be accepted - A stop for a hospital is the same as the patient except with an 'h', i.e. 'h3' + The 'h' can also be uppercase or lowercase Example: ambulance_routes[3] = ['p0', 'p43', 'h4', 'p102', 'p145', 'p241', 'p32', 'h1'] This will be read as ambulance #3 starts at it's designated hospital, goes to patient #0, then to patient #43, then drops both off at hospital #4, then picks up patients #102, #145, #241, #32 in that order then drops all of them off at hospital #1 """ res_hos = {} res_amb = {} counter = 0 p_count = 0 total_patients = len(self.patients) for hos_id, hos in self.hospitals.items(): res_hos[hos_id] = { 'xloc': self.patients[counter]['xloc'], 'yloc': self.patients[counter]['yloc'] } counter += 4 for amb_id, amb in self.ambulances.items(): if p_count < total_patients - 4: res_amb[amb_id] = [ 'p' + str(i) for i in range(p_count, p_count + 4) ] + ['h' + str(self.ambulances[amb_id]['starting_hospital'])] else: res_amb[amb_id] = [ 'h' + str(self.ambulances[amb_id]['starting_hospital']) ] p_count += 4 return (res_hos, res_amb)
class NoTippingClient(object): def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_first': is_first })) response = json.loads(self.client.receive_data()) self.board_length = int(response['board_length']) self.num_weights = int(response['num_weights']) self.myWeight = dict() self.is_first = is_first for i in range(1, int(self.num_weights) + 1): self.myWeight[i] = 1 if is_first: self.position = -1 else: self.position = -2 self.nextWeight = 1 def play_game(self): # pass response = {} while True: response = json.loads(self.client.receive_data()) if 'game_over' in response and response['game_over'] == "1": print("Game Over!") exit(0) # Indices start at zero but are actually board_state = [ int(state) for state in filter( None, list(response['board_state'].split(' '))) ] if response['move_type'] == 'place': position, weight = self.place(board_state) self.client.send_data( json.dumps({ "position": position, "weight": weight })) else: position = self.remove(board_state) self.client.send_data(json.dumps({"position": position})) def place(self, board_state): """ PLACE YOUR PLACING ALGORITHM HERE Inputs: board_state - array of what weight is at a given position on the board Output: position (Integer), weight (Integer) """ # position = randint(-self.board_length, self.board_length) # weight = self.myWeight[randint(1, self.num_weights)] # num_tries = 0 # self.check_balance(self.copy_board_with_updated_move(board_state, position, weight)) # # import pdb; pdb.set_trace() # while board_state[(position + self.board_length) % self.board_length] != 0 and self.myWeight[weight] != 1 and num_tries < 10 and not self.check_balance(self.copy_board_with_updated_move(board_state, position, weight)): # import pdb; pdb.set_trace() # position = randint(-self.board_length, self.board_length) # weight = self.myWeight[randint(1, self.num_weights)] # num_tries += 1 # self.myWeight[weight] = 0 sleep(2) curr_position, weight = self.position, self.nextWeight while board_state[(curr_position + self.board_length) % self.board_length] != 0: # import pdb; pdb.set_trace() curr_position += 1 if self.is_first else -1 self.position = curr_position self.nextWeight = weight + 1 return curr_position, weight def remove(self, board_state): """ PLACE YOUR REMOVING ALGORITHM HERE Inputs: board_state - array of what weight is at a given position on the board Output: position (Integer) """ position = randint(-self.board_length, self.board_length) while board_state[str(position)] != 0: position = randint(-self.board_length, self.board_length) return position def copy_board_with_updated_move(self, old_board, position, weight): new_board = old_board.copy() new_board[position] = weight return new_board def check_balance(self, board): left_torque = 0 right_torque = 0 for i in range(0, 61): left_torque += (i - 30 + 3) * board[i] right_torque += (i - 30 + 1) * board[i] left_torque += 3 * 3 right_torque += 1 * 3 return left_torque >= 0 and right_torque <= 0
class NoTippingClient(object): def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_first': is_first })) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] self.magic_point = min(int(self.num_weights), min(5, math.floor(int(self.num_weights) / 2))) self.myWeight = dict() self.place_turn = 0 #self turns self.remove_turn = 0 #self turns for i in range(1, int(self.num_weights) + 1): self.myWeight[i] = 1 def play_game(self): # pass response = {} while True: response = json.loads(self.client.receive_data()) if 'game_over' in response and response['game_over'] == "1": print("Game Over!") exit(0) self.board_state = [ int(state) for state in filter( None, list(response['board_state'].split(' '))) ] if response['move_type'] == 'place': position, weight = self.place(self.board_state) self.client.send_data( json.dumps({ "position": position, "weight": weight })) self.place_turn = self.place_turn + 1 else: position = self.remove(self.board_state) self.client.send_data(json.dumps({"position": position})) self.remove_turn = self.remove_turn + 1 def check_balance(self, board_state): left_torque = 0 right_torque = 0 for i in range(0, 61): left_torque += (i - 30 + 3) * int(self.board_state[i]) right_torque += (i - 30 + 1) * int(self.board_state[i]) left_torque += 3 * 3 right_torque += 1 * 3 return left_torque >= 0 and right_torque <= 0 def find_place_position(self, key, board_state): for i in range(0, 61): if self.board_state[i] == 0: self.board_state[i] = key if self.check_balance(self.board_state): self.board_state[i] = 0 return i self.board_state[i] = 0 return -100 def possible_remove_moves(self, board): possible_positions = [] for i in range(0, 61): if self.board_state[i] != 0: tempWeight = self.board_state[i] self.board_state[i] = 0 if self.check_balance(self.board_state): possible_positions.append(i - 30) self.board_state[i] = tempWeight if len(possible_positions) == 0: return 1 best_position = 100 for i in possible_positions: if abs(i) < abs(best_position): best_position = i self.board_state[i + 30] = 0 return best_position #returns a list from right to left of the board weights in increasing order def possible_moves(self, board): moves = [] potential_last_move = 0 potential_last_weight = 0 for i in range(0, 61): for j in self.myWeight: if self.myWeight[j] == 1: potential_last_weight = j if self.board_state[i] == '0' or self.board_state[i] == 0: potential_last_move = i self.board_state[i] = j if self.check_balance(self.board_state): move = {} move['position'] = i move['weight'] = j moves.append(move) self.board_state[i] = 0 last_move = { "position": potential_last_move, "weight": potential_last_weight } moves.append(last_move) return moves def place(self, current_board_state): """ PLACE YOUR PLACING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer), weight (Integer) """ moves = self.possible_moves(self.board_state) #hope this works if (self.place_turn == self.magic_point): smallest_position = 100 largest_weight = 0 for i in moves: if abs(i['position'] - 30) < smallest_position: smallest_position = i['position'] - 30 for i in moves: if i['position'] - 30 == smallest_position: if i['weight'] > largest_weight: largest_weight = i['weight'] self.myWeight[largest_weight] = 0 return smallest_position, largest_weight target_move = moves[ 0] #should not be empty, and already furthest right with heaviest weight self.myWeight[target_move['weight']] = 0 return target_move['position'] - 30, target_move['weight'] def remove(self, current_board_state): """ PLACE YOUR REMOVING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer) """ moves = self.possible_remove_moves(self.board_state) return moves
class Player(object): def __init__(self, name): self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data(json.dumps({'name': self.name})) def play_game(self): buffer_size_message = json.loads(self.client.receive_data(size=2048)) buffer_size = int(buffer_size_message['buffer_size']) game_state = json.loads(self.client.receive_data(size=buffer_size)) self.patients = { int(key): value for key, value in game_state['patients'].items() } self.hospitals = { int(key): value for key, value in game_state['hospitals'].items() } self.ambulances = { int(key): value for key, value in game_state['ambulances'].items() } # Get hospital locations and ambulance routes (hos_locations, amb_routes) = self.your_algorithm() response = { 'hospital_loc': hos_locations, 'ambulance_moves': amb_routes } print('sending data') min_buffer_size = sys.getsizeof(json.dumps(response)) print(min_buffer_size) print(response) buff_size_needed = 1 << (min_buffer_size - 1).bit_length() buff_size_needed = max(buff_size_needed, 2048) buff_size_message = {'buffer_size': buff_size_needed} self.client.send_data(json.dumps(buff_size_message)) time.sleep(2) self.client.send_data(json.dumps(response)) # Get results of game game_result = json.loads(self.client.receive_data(size=8192)) if game_result['game_completed']: print(game_result['message']) print('Patients that lived:') print(game_result['patients_saved']) print('---------------') print('Number of patients saved = ' + str(game_result['number_saved'])) else: print('Game failed run/validate ; reason:') print(game_result['message']) def your_algorithm(self): """ PLACE YOUR ALGORITHM HERE You have access to the dictionaries 'patients', 'hospitals', and 'ambulances' These dictionaries are structured as follows: patients[patient_id] = {'xloc': x, 'yloc': y, 'rescuetime': rescuetime} hospitals[hospital_id] = {'xloc': None, 'yloc': None, 'ambulances_at_start': [array of ambulance_ids]} ambulances[ambulance_id] = {'starting_hospital': hospital_id} RETURN INFO ----------- You must return a tuple of dictionaries (hospital_locations, ambulance_routes). These MUST be structured as: hospital_locations[hospital_id] = {'xloc': x, 'yloc': y} These values indicate where you want the hospital with hospital_id to start on the grid ambulance_routes[ambulance_id] = {[array of stops along route]} This array follows the following rules: - The starting location of each ambulance is known so array must start with first patient that it must pick up (or hospital location that it will head to) - There can only ever be up to 4 patients in an ambulance at a time so any more than 4 patient stops in a row will result in an invalid input - A stop for a patient is a string starting with 'p' followed by the id of the patient i.e. 'p32' + The 'p' can be uppercase or lowercase + There can be no whitespace, i.e. 'p 32' will not be accepted - A stop for a hospital is the same as the patient except with an 'h', i.e. 'h3' + The 'h' can also be uppercase or lowercase Example: ambulance_routes[3] = ['p0', 'p43', 'h4', 'p102', 'p145', 'p241', 'p32', 'h1'] This will be read as ambulance #3 starts at it's designated hospital, goes to patient #0, then to patient #43, then drops both off at hospital #4, then picks up patients #102, #145, #241, #32 in that order then drops all of them off at hospital #1 """ res_hos = {} res_amb = {} counter = 0 p_count = 0 total_patients = len(self.patients) ## create data for clustering locData = [] for patient_id in self.patients: patient = self.patients[patient_id] locData.append((patient['xloc'], patient['yloc'])) locData = np.array(locData) ## cluster kmeans = KMeans(n_clusters=5, random_state=0).fit(locData) ## assign hospitals labels = kmeans.labels_ centers = kmeans.cluster_centers_ clustering = {i: np.where(labels == i)[0] for i in range(5)} sorted_by_number_elements_cluster = sorted(clustering.items(), key=lambda kv: len(kv[1])) ## creating res_hos [i.e. which hospital to place where, based on num of avail ambulances] hospitalsByNumber = {} for hospital_id in self.hospitals: hospitalsByNumber[hospital_id] = self.hospitals[hospital_id][ 'ambulances_at_start'] sorted_by_number_ambulances = sorted(hospitalsByNumber.items(), key=lambda kv: len(kv[1])) ## cluster with min number of patients matched with hospital with min number of avail ambulances mappingCenterToAmbulances = {} for i in range(len(sorted_by_number_ambulances)): x, y = centers[sorted_by_number_elements_cluster[i][0]] res_hos[sorted_by_number_ambulances[i][0]] = { 'xloc': int(x), 'yloc': int(y) } mappingCenterToAmbulances[( int(x), int(y))] = sorted_by_number_ambulances[i][1] # can do this because labels are 0,1,2,3,4 for i in range(len(clustering)): #print("clustering") cluster = clustering[i] #print(len(cluster)) center = tuple(centers[i]) center = (int(center[0]), int(center[1])) ambulancesOperatingInThisCluster = mappingCenterToAmbulances[ center] ambulanceBucketPatient = self.radDivide( cluster, ambulancesOperatingInThisCluster, center) # decide on order for ambulance using search for ambulance_id in ambulanceBucketPatient: patientsToVisit = ambulanceBucketPatient[ambulance_id] sorted(patientsToVisit, key=lambda patient_id: self.patients[patient_id][ 'rescuetime']) #aa #print(ambulance_id) #print(center) #print(patientsToVisit) numBuckets = math.ceil(len(patientsToVisit) / 6) nn = len(patientsToVisit) / numBuckets globalOrder = [] ii = 0 tt = 0 while ii < numBuckets: #print(ii) #print(nn) ll = patientsToVisit[int(ii * nn):int((ii + 1) * nn)] #print(ll) order, tt = self.orderOfPatients(ll, center, tt) #order.append(-1) #order = [ll[x] if x is not -1 else -1 for x in order] globalOrder += order ii += 1 #print("bestPath") #print(order) res_amb[ambulance_id] = self.parse( globalOrder, self.ambulances[ambulance_id]['starting_hospital']) return (res_hos, res_amb) def orderOfPatients(self, patientsToVisit, center, time): self.onPath = [0] * len(patientsToVisit) self.path = [] self.bestPath = [] self.pathLen = 0 self.bestPathValue = 0 self.timeT = 0 visited = [0] * len(patientsToVisit) for i in range(len(patientsToVisit)): self.dfs(i, patientsToVisit, center, time) print("saved " + str(self.bestPathValue) + "/" + str(len(patientsToVisit))) #print(self.bestPath) return self.bestPath, time + self.timeT # nextPatientToSaveIndex might also cater hospital def dfs(self, nextPatientToSaveIndex, patientsToVisitIndices, center, ttt): self.path.append(nextPatientToSaveIndex) if nextPatientToSaveIndex != -1: self.onPath[nextPatientToSaveIndex] = 1 self.pathLen += 1 if self.pathLen == len(patientsToVisitIndices): translatedPath = [ patientsToVisitIndices[x] if x is not -1 else -1 for x in self.path ] translatedPath.append(-1) value, timetaken = self.peopleSaved(translatedPath, center, ttt) if value > self.bestPathValue: self.bestPath = copy.deepcopy(translatedPath) self.bestPathValue = value self.timeT = timetaken else: for i in range(len(patientsToVisitIndices)): if self.onPath[i] == 0: self.dfs(i, patientsToVisitIndices, center, ttt) # hospital to hospital case if nextPatientToSaveIndex != -1: self.dfs(-1, patientsToVisitIndices, center, ttt) self.path.pop() if nextPatientToSaveIndex != -1: self.onPath[nextPatientToSaveIndex] = 0 self.pathLen -= 1 def dist(self, a, b): return int(abs(a[0] - b[0]) + abs(a[1] - b[1])) def canBeSaved(self, hosp, patient, time): return True def parse(self, order, hospital_id): return [('p' + str(x)) if x is not -1 else ('h' + str(hospital_id)) for x in order] def radDivide(self, patientsIndexList, ambulances, hospital): num_ambulances = len(ambulances) num_patients = len(patientsIndexList) ret = {} angle = [] for pID in range(0, num_patients): pat = self.patients[patientsIndexList[pID]] theta = math.atan2(pat['yloc'] - hospital[1], pat['xloc'] - hospital[0]) if theta < 0.0: theta += 2 * math.pi angle.append([patientsIndexList[pID], theta]) angle = sorted(angle, key=lambda x: x[1]) n = num_patients / num_ambulances for i in range(0, num_ambulances): ambID = ambulances[i] ambPat = [] for j in range(int(i * n), int((i + 1) * n)): ambPat.append(angle[j][0]) ret[ambID] = ambPat return ret def peopleSaved(self, path, hospital, tt): ret = 0 time = 0 locX = hospital[0] locY = hospital[1] p1, p2, p3, p4 = [-1] * 4 for p in path: if p == -1: num_p = (p1 > -1) + (p2 > -1) + (p3 > -1) + (p4 > -1) time += self.dist([hospital[0], hospital[1]], [locX, locY]) + num_p locX = hospital[0] locY = hospital[1] if p4 != -1: ret += self.saved(self.patients[p4], time + tt) if p3 != -1: ret += self.saved(self.patients[p3], time + tt) if p2 != -1: ret += self.saved(self.patients[p2], time + tt) if p1 != -1: ret += self.saved(self.patients[p1], time + tt) p1 = -1 p2 = -1 p3 = -1 p4 = -1 else: if p4 != -1: return -1, 0 p4 = p3 p3 = p2 p2 = p1 p1 = p time += self.dist( [self.patients[p]['xloc'], self.patients[p]['yloc']], [locX, locY]) + 1 locX = self.patients[p]['xloc'] locY = self.patients[p]['yloc'] return ret, time def saved(self, pID, time): if time > pID['rescuetime']: return 0 else: return 1
class NoTippingClient(object): def __init__(self, name, is_first): self.first_resp_recv = False self.name = name self.client = SocketClient(HOST, PORT) self.client.send_data( json.dumps({ 'name': self.name, 'is_first': is_first })) response = json.loads(self.client.receive_data()) self.board_length = response['board_length'] self.num_weights = response['num_weights'] self.myWeight = dict() for i in range(1, int(self.num_weights)): self.myWeight[i] = 1 def play_game(self): # pass response = {} while True: response = json.loads(self.client.receive_data()) if 'game_over' in response and response['game_over'] == "1": print("Game Over!") exit(0) self.board_state = [ 0 ] * 30 if not response else response['board_state'].split(' ') if response['move_type'] == 'place': position, weight = self.place(self.board_state) self.client.send_data( json.dumps({ "position": position, "weight": weight })) else: position = self.remove(self.board_state) self.client.send_data(json.dumps({"position": position})) def place(self, board_state): """ PLACE YOUR PLACING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer), weight (Integer) """ allPosition = [] for key, value in self.myWeight.items(): if value == 1: position = self.find_place_position(key, self.board_state) if position != -100: allPosition.append((key, position - 30)) if position != -100: allPosition.append((key, position - 30)) break if len(allPosition) == 0: choice = (1, 0) else: choice = random.choice(allPosition) self.myWeight[choice[0]] = 0 print("Added: " + str(choice)) return choice[0], choice[1] def remove(self, board_state): """ PLACE YOUR REMOVING ALGORITHM HERE Inputs: current_board_state - array of what weight is at a given position on the board Output: position (Integer) """ allPossiblePosition = [] for i in range(0, 61): if self.board_state[i] != 0: tempWeight = self.board_state[i] self.board_state[i] = 0 if self.check_balance(self.board_state): allPossiblePosition.append(i - 30) self.board_state[i] = tempWeight if len(allPossiblePosition) == 0: choice = 1 else: choice = random.choice(allPossiblePosition) random.jumpahead(1) print("Removed:" + str(choice)) return choice def check_balance(self, board_state): left_torque = 0 right_torque = 0 for i in range(0, 61): left_torque += (i - 30 + 3) * self.board_state[i] right_torque += (i - 30 + 1) * self.board_state[i] left_torque += 3 * 3 right_torque += 1 * 3 return left_torque >= 0 and right_torque <= 0 def find_place_position(self, key, board_state): for i in range(0, 61): if self.board_state[i] == 0: self.board_state[i] = key if self.check_balance(self.board_state): self.board_state[i] = 0 return i self.board_state[i] = 0 return -100