def accept_player_connections(self): self.server = SocketServer(HOST, PORT, 2) self.server.establish_client_connections() self.player_attributes = [ json.loads(info) for info in self.server.receive_from_all() ] self.player_idx = 0 if self.player_attributes[0]['is_player'] else 1 self.matchmaker_idx = 1 if self.player_attributes[0]['is_player'] else 0 self.play_game()
def accept_player_connections(self, front_end=None, web_server=None): if front_end: print('~~ WE GOT A FRONT END ~~') self.server = SocketServer(HOST, PORT, 2) self.server.establish_client_connections() self.player_attributes = [ json.loads(info) for info in self.server.receive_from_all() ] self.trench_idx = 0 if self.player_attributes[0][ 'is_trench_manager'] else 1 self.submarine_idx = 1 if self.player_attributes[0][ 'is_trench_manager'] else 0 self.play_game()
class GameServer(object): def __init__(self, d=36, y=6, r=6, m=250, L=4, p=2, gui=False): self.d = d self.y = y self.r = r self.m = m self.L = L self.p = p self.trench_cost = 0 self.trench_condition_achieved = True self.red_alert = [i % 100 for i in range(d, d + 6)] self.submarine_time_left = self.trench_time_left = 120 self.submarine_location = randint(0, 99) self.is_submarine_in_red = self.submarine_location in self.red_alert self.web_server = None print('Waiting on port %s for players...' % PORT) if gui: self.web_server = WebsocketServer(WEB_PORT, host=WEB_HOST) self.web_server.new_client = self.accept_player_connections self.web_server.run_forever() else: self.accept_player_connections() def accept_player_connections(self, front_end=None, web_server=None): if front_end: print('~~ WE GOT A FRONT END ~~') self.server = SocketServer(HOST, PORT, 2) self.server.establish_client_connections() self.player_attributes = [ json.loads(info) for info in self.server.receive_from_all() ] self.trench_idx = 0 if self.player_attributes[0][ 'is_trench_manager'] else 1 self.submarine_idx = 1 if self.player_attributes[0][ 'is_trench_manager'] else 0 self.play_game() def timed_request(self, request_data, client_idx): self.server.send_to(json.dumps(request_data), client_idx) start = time() move = json.loads(self.server.receive_from(client_idx)) stop = time() return move, (stop - start) def decrement_time(self, submarine_time_spent, trench_time_spent): self.submarine_time_left -= submarine_time_spent self.trench_time_left -= trench_time_spent def check_time_left(self): if self.submarine_time_left < 0: raise Exception('Submarine Captain ran out of time') if self.trench_time_left < 0: raise Exception('Trench Manager ran out of time') def complete_submarine_move(self, submarine_move): if type(submarine_move ) != int or submarine_move > 1 or submarine_move < -1: raise ValueError('Submarine Captain made an illegal move') self.submarine_location = (self.submarine_location + submarine_move) % 100 self.is_submarine_in_red = self.submarine_location in self.red_alert def trench_region_check(self, region): if region not in ('red', 'yellow'): raise ValueError('Trench Manager chose an illegal region') if self.is_submarine_in_red and region != 'red': self.trench_condition_achieved = False self.trench_cost += self.r if region == 'red' else self.y def deploy_probes(self, probes): probe_results = [] times_submarine_probed = 0 for probe in probes: if type(probe) != int or probe < 0 or probe > 99: raise ValueError( 'Trench Manager placed a probe at an illegal position') range_start = (probe - self.L) if (probe - self.L) > 0 else ( 100 + (probe - self.L)) probe_range = [ i % 100 for i in range(range_start, range_start + (self.L * 2) + 1) ] probe_results.append(self.submarine_location in probe_range) if probe_results[-1]: times_submarine_probed += 1 self.trench_cost += self.p return probe_results, times_submarine_probed def play_game(self): submarine_move, submarine_time_spent = self.timed_request( { 'm': self.m, 'L': self.L, 'pos': self.submarine_location }, self.submarine_idx) trench_probe_move, trench_time_spent = self.timed_request( { 'd': self.d, 'y': self.y, 'r': self.r, 'm': self.m, 'L': self.L, 'p': self.p }, self.trench_idx) self.decrement_time(submarine_time_spent, trench_time_spent) m = self.m while m > 0: self.check_time_left() self.complete_submarine_move(submarine_move['move']) probe_results, times_submarine_probed = self.deploy_probes( trench_probe_move['probes']) trench_move, trench_time_spent = self.timed_request( {'probe_results': probe_results}, self.trench_idx) self.trench_region_check(trench_move['region']) if self.web_server: self.web_server.send_message_to_all( json.dumps({ 'red_region': self.d, 'position': self.submarine_location, 'is_safety_condition_achieved': self.trench_condition_achieved, 'submarine_region': 'red' if self.is_submarine_in_red else 'yellow', 'trench_alert': trench_move['region'], 'probes': trench_probe_move['probes'] })) print("**********************************************") print( f"Submarine moved by {submarine_move['move']} (current position: {self.submarine_location})" ) print( f"Submarine is {'not' if not self.is_submarine_in_red else ''} in red region" ) print(f"Probes were placed at {trench_probe_move['probes']}") print(f"The results were: {probe_results}") print(f"Trench manager sent {trench_move['region']} alert") print( f"Safety condition {'not' if not self.trench_condition_achieved else ''} achieved" ) print("**********************************************") if m > 1: submarine_move, submarine_time_spent = self.timed_request( {'times_probed': times_submarine_probed}, self.submarine_idx) trench_probe_move, trench_time_spent = self.timed_request( {}, self.trench_idx) self.decrement_time(submarine_time_spent, trench_time_spent) m -= 1 if not self.trench_condition_achieved: self.trench_cost = (self.m * self.r) + (self.m * 5 * self.p) self.server.send_to_all( json.dumps({ 'game_over': True, 'trench_cost': self.trench_cost, 'was_condition_achieved': self.trench_condition_achieved }))
def accept_player_connections(self): self.server = SocketServer(HOST, PORT, 1) self.server.establish_client_connections() self.player_attributes = json.loads(self.server.receive_from(0, size=2048)) self.player_name = self.player_attributes['name']
class GameServer(object): def __init__(self, input_file=None): if input_file is None: print('No input given') exit(1) print('Waiting on port %s for player...' % PORT) self.accept_player_connections() print('Preparing input data') parsed_data = self.input_parsing(input_file) self.patients = parsed_data[0] self.hospitals = parsed_data[1] self.ambulances = parsed_data[2] self.total_patients = parsed_data[3] self.total_hospitals = parsed_data[4] self.total_ambulances = parsed_data[5] print('Starting Game with player: ' + str(self.player_name)) self.play_game() def input_parsing(self, input_file): ### Create dictionaries of patient, hospital, and ambulances patients = {} hospitals = {} ambulances = {} patient_id = 0 hospital_id = 0 ambulance_id = 0 # Parse input txt file mode = None # 0 = patient description, 1 = hostpital ambulance number f = open(input_file, 'r') for line in f: if line == '\n': continue line = line.strip('\n') if line[0] == 'p': mode = 0 continue if line[0] == 'h': mode = 1 continue # Patient information if mode == 0: mytuple = tuple(map(int, line.split(','))) patients[patient_id] = {'xloc': mytuple[0], 'yloc': mytuple[1], 'rescuetime': mytuple[2]} patient_id += 1 elif mode == 1: hospitals[hospital_id] = {'xloc': None, 'yloc': None} num_ambulances = int(line) ambulances_at_hospital = [] for amb in range(0, num_ambulances): ambulances[ambulance_id] = {'starting_hospital': hospital_id} ambulances_at_hospital += [ambulance_id] ambulance_id += 1 hospitals[hospital_id]['ambulances_at_start'] = ambulances_at_hospital hospital_id += 1 else: print('Error parsing input file') exit(1) return (patients, hospitals, ambulances, patient_id, hospital_id, ambulance_id) def accept_player_connections(self): self.server = SocketServer(HOST, PORT, 1) self.server.establish_client_connections() self.player_attributes = json.loads(self.server.receive_from(0, size=2048)) self.player_name = self.player_attributes['name'] def route_time(self, c_loc, n_loc): return abs(n_loc[0] - c_loc[0]) + abs(n_loc[1] - c_loc[1]) def game_over(self, message, patients_saved, finished=False): self.server.send_to_all( json.dumps({ 'game_completed': finished, 'message': message, 'patients_saved': patients_saved, 'number_saved': len(patients_saved) })) exit(1) def play_game(self): input_data = {'patients': self.patients, 'hospitals': self.hospitals, 'ambulances': self.ambulances} print(input_data) print('---------') buff_size_needed = sys.getsizeof(json.dumps(input_data)) buff_size_needed = 1<<(buff_size_needed-1).bit_length() buff_size_message = {'buffer_size': buff_size_needed} self.server.send_to(json.dumps(buff_size_message), 0) time.sleep(2) self.server.send_to(json.dumps(input_data), 0) start = tm() buff_size_message = json.loads(self.server.receive_from(0, size=2048)) buff_size_needed = int(buff_size_message['buffer_size']) print(buff_size_needed) moves = json.loads(self.server.receive_from(0, size=buff_size_needed)) stop = tm() if (stop-start) > 122: m = 'Player ' + str(self.player_name) + ' ran for more than 2 minutes' self.game_over(m, []) hospital_locations = moves['hospital_loc'] ambulance_moves = moves['ambulance_moves'] print(hospital_locations) print('------') print(ambulance_moves) for hos_id in range(0, self.total_hospitals): try: xloc = hospital_locations[str(hos_id)]['xloc'] yloc = hospital_locations[str(hos_id)]['yloc'] except Exception as e: m = 'Didn\'t get hospital location for hospital #' + str(hos_id) self.game_over(m, []) if xloc < 0 or yloc < 0 or xloc > 1000 or yloc > 1000: m = 'Invalid hospital location' self.game_over(m, []) self.hospitals[hos_id]['xloc'] = xloc self.hospitals[hos_id]['yloc'] = yloc patients_saved = [] patients_picked_up = [] for amb_id in range(0, self.total_ambulances): try: amb_route = ambulance_moves[str(amb_id)] except Exception as e: continue current_loc = (self.hospitals[self.ambulances[amb_id]['starting_hospital']]['xloc'], self.hospitals[self.ambulances[amb_id]['starting_hospital']]['yloc']) time_counter = 0 p_inside_amb = [] for amb_stop in amb_route: if amb_stop[0].lower() == 'p': if len(p_inside_amb) >= 4: m = 'Cannot pick up more than 4 patients' self.game_over(m, []) try: p_id = int(amb_stop[1:]) if p_id >= self.total_patients or p_id < 0: m = 'Invalid patient id' print(p_id) self.game_over(m, []) except Exception as e: m = 'Error reading patient id' self.game_over(m, []) if p_id in patients_picked_up: print('Patient ' + str(patient) + ' has already been picked up') else: p_inside_amb += [p_id] patients_picked_up += [p_id] time_counter += 1 new_loc = (self.patients[p_id]['xloc'], self.patients[p_id]['yloc']) time_taken = self.route_time(current_loc, new_loc) time_counter += time_taken current_loc = new_loc continue elif amb_stop[0].lower() == 'h': try: h_id = int(amb_stop[1:]) if h_id >= self.total_hospitals or h_id < 0: m = 'Invalid hospital id' self.game_over(m, []) except Exception as e: m = 'Error reading hospital id' self.game_over(m, []) new_loc = (self.hospitals[h_id]['xloc'], self.hospitals[h_id]['yloc']) time_taken = self.route_time(current_loc, new_loc) time_counter += time_taken if len(p_inside_amb) > 0: time_counter += 1 current_loc = new_loc for patient in p_inside_amb: if time_counter <= self.patients[patient]['rescuetime']: print('Ambulance ' + str(amb_id) + ' saved patient ' + str(patient)) patients_saved += [patient] # else: # print('Patient ' + str(patient) + ' died before reaching the hospital') p_inside_amb = [] continue else: m = 'Invalid route stop' self.game_over(m, []) print('All ambulances have finished their routes') print('------------') print('Congratulations!') print('Patients that lived:') print(patients_saved) print('Total number of patients saved: ' + str(len(patients_saved))) self.game_over('Congratulations!', patients_saved, finished=True)
class GameServer(object): def __init__(self, n): self.n = int(n) # self.randomFile = randomFile self.iterations = 20 self.weights = None self.candidate_history = [] self.score_history = [] self.weight_history = [] self.perfect_candidate_found = False self.maxScore = 0 self.previousCandidate = [] self.player_time_left = self.matchmaker_time_left = 120 self.web_server = None print('Waiting on port %s for players...' % PORT) self.accept_player_connections() def accept_player_connections(self): self.server = SocketServer(HOST, PORT, 2) self.server.establish_client_connections() self.player_attributes = [ json.loads(info) for info in self.server.receive_from_all() ] self.player_idx = 0 if self.player_attributes[0]['is_player'] else 1 self.matchmaker_idx = 1 if self.player_attributes[0]['is_player'] else 0 self.play_game() def timed_request(self, request_data, client_idx): self.server.send_to(json.dumps(request_data), client_idx) start = time() vector = json.loads(self.server.receive_from(client_idx)) stop = time() return vector, (stop - start) def decrement_time(self, player_time_spent, matchmaker_time_spent): self.player_time_left -= player_time_spent self.matchmaker_time_left -= matchmaker_time_spent def check_time_left(self): if self.player_time_left < 0: raise Exception('Player ran out of time') if self.matchmaker_time_left < 0: raise Exception('Matchmaker ran out of time') def compute_score(self, weights, candidate): score = 0 for i in range(len(candidate)): score += weights[i] * candidate[i] return round(score, 4) def check_precision(self, candidate): getcontext().prec = 4 for i in range(0, len(candidate)): w = candidate[i] a = Decimal(w) / Decimal(1) if ((float)(a) != w): return False return True def check_weights_validity(self, orig_weights, cur_weights, prev_weights): # check weights have atmost precision 2 getcontext().prec = 2 for i in range(0, len(cur_weights)): w = cur_weights[i] a = Decimal(w) / Decimal(1) if (float)(a) != w: raise ValueError("decimals") return False # check whether change of every weight is in 20% range for i in range(0, self.n): if abs(cur_weights[i] - orig_weights[i]) > 0.2 * abs(orig_weights[i]): raise ValueError("percentage") return False # check atmost 5% of weights changed from previous turn modified_weights = 0 for i in range(self.n): if cur_weights[i] != prev_weights[i]: modified_weights += 1 if (modified_weights > 0.05 * self.n): raise ValueError("number") return False # check pos weights sum to 1, neg weights sum to -1 pos_sum = Decimal(0) neg_sum = Decimal(0) for w in cur_weights: if w > 0: pos_sum += Decimal(w) else: neg_sum += Decimal(w) if pos_sum != 1: raise ValueError("positive") return False if neg_sum != -1: raise ValueError("negative") return False return True def load_obj(self, name): with open(name, 'rb') as f: return pickle.load(f) def play_game(self): self.weights, player_time_spent = self.timed_request({'n': self.n}, self.player_idx) if not self.check_weights_validity(self.weights, self.weights, self.weights): raise ValueError('Invalid Weights provided by Player') # Generate 40 random candidates and scores random_candidates = {} for i in range(0, 40): # rand_cand = self.load_obj(self.randomFile) rand_cand = [] for j in range(0, self.n): r = randint(0, 1) rand_cand.append(r) cscore = self.compute_score(rand_cand, self.weights) random_candidates[i] = {'Score': cscore, 'Attributes': rand_cand} self.server.send_to( json.dumps({ 'n': self.n, 'randomCandidateAndScores': random_candidates }), self.matchmaker_idx) iterations = 0 new_weights = self.weights self.weight_history.append(new_weights) new_candidate = [] score = 0 while iterations < self.iterations and self.perfect_candidate_found == False: self.check_time_left() new_candidate, matchmaker_time_spent = self.timed_request( { 'prev_candidate': { 'candidate': new_candidate, 'score': score, 'iter': iterations }, 'time_left': self.matchmaker_time_left }, self.matchmaker_idx) if (not self.check_precision(new_candidate)): raise ValueError("Invalid precision of candidates") self.candidate_history.append(new_candidate) new_weights, player_time_spent = self.timed_request( { 'new_candidate': new_candidate, 'weight_history': self.weight_history, 'time_left': self.player_time_left }, self.player_idx) # check weights validity if not self.check_weights_validity(self.weights, new_weights, self.weight_history[-1]): print( 'Invalid Weights provided by Player at iteration {iterations}. Maximum score so far: {self.maxScore}' ) raise ValueError() self.weight_history.append(new_weights) score = max( self.compute_score(weights=new_weights, candidate=new_candidate), self.compute_score(weights=self.weights, candidate=new_candidate)) self.score_history.append(score) print("**********************************************") print("Iteration Number: ", iterations + 1) print("New Candidate: ", new_candidate) print("New Weights: ", new_weights) print("Score History: ", self.score_history) print("**********************************************") if score > self.maxScore: self.maxScore = score if score == 1: self.perfect_candidate_found = True self.decrement_time(player_time_spent, matchmaker_time_spent) iterations += 1 self.server.send_to_all( json.dumps({ 'game_over': True, 'final_score': self.maxScore, 'match_found': self.perfect_candidate_found, 'num_iterations': iterations, 'total_candidates': self.candidate_history.__len__() }))