class Game: def __init__(self, conn, addr, port, name): self.serv_conn = conn self.serv_addr = addr self.serv_port = port self.game_name = name self.ai = AI() self.ai.connection = self.serv_conn #Attempt to connect to the server def connect(self): while True: try: #Attempting to connect self.serv_conn.connect((self.serv_addr, self.serv_port)) except socket.error: #Failed to connect time.sleep(1) else: #Client connected return True def receive(self): data = utility.receive_string(self.serv_conn) message = json.loads(data) if message['type'] == 'changes': self.update_game(message) elif message['type'] == 'player_id': self.ai.my_player_id = message['args']['id'] elif message['type'] == 'game_over': raise GameOverException(message["args"]["winner"], message["args"]["reason"]) return message def wait_for(self, *types): while True: message = self.receive() if message['type'] in types: return message #Attempt to login to the server def login(self): login_json = client_json.login.copy() login_json['args']['username'] = self.ai.username login_json['args']['password'] = self.ai.password utility.send_string(self.serv_conn, json.dumps(login_json)) message = self.wait_for('success', 'failure') if message['type'] == 'success': #Login success return True else: #Login failed return False #Attempt to create a game on the server def create_game(self): create_game_json = client_json.create_game.copy() if self.game_name is not None: create_game_json['args']['game_name'] = self.game_name utility.send_string(self.serv_conn, json.dumps(create_game_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": self.game_name = message['args']['name'] print("Game created: {}".format(self.game_name)) return True else: #Game creation failed return False #Receive Player ID from server def recv_player_id(self): self.wait_for('player_id') return True #Runs before main_loop has began. def init_main(self): self.wait_for('start_game') self.ai.init() return True #Runs after main_loop has finished. def end_main(self): self.ai.end() return True #Main connection loop until end of game. def main_loop(self): while True: message = self.wait_for('start_turn', 'game_over') if message['type'] == 'game_over': return True if self.ai.my_player_id == self.ai.player_id: utility.v_print("Turn Number: {}".format(self.ai.turn_number)) self.ai.run() utility.send_string(self.serv_conn, json.dumps(client_json.end_turn)) def get_log(self): log_json = client_json.get_log.copy() utility.send_string(self.serv_conn, json.dumps(log_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": file = open(self.game_name + '.glog', 'wb') file.write(message['args']['log'].encode('utf-8')) file.close() #Update game from message def update_game(self, message): if message.get("type") != "changes": return False for change in message.get("args").get("changes"): if change.get("action") == "add": self.change_add(change) elif change.get("action") == "remove": self.change_remove(change) elif change.get("action") == "update": self.change_update(change) elif change.get("action") == "global_update": self.change_global_update(change) return True #Parse the add action def change_add(self, change): values = change.get("values") if change.get("type") == "Player": temp = game_objects.Player(connection=self.serv_conn, parent_game=self, id=values.get("id"), name=values.get("name"), byte_dollars=values.get("byte_dollars"), cycles=values.get("cycles"), time=values.get("time")) self.ai.players.append(temp) if change.get("type") == "Virus": temp = game_objects.Virus(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner"), level=values.get("level"), moves_left=values.get("moves_left"), living=values.get("living")) self.ai.viruses.append(temp) if change.get("type") == "Tile": temp = game_objects.Tile(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner")) self.ai.tiles.append(temp) if change.get("type") == "Base": temp = game_objects.Base(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner"), spawns_left=values.get("spawns_left")) self.ai.bases.append(temp) return True #Parse the remove action. def change_remove(self, change): remove_id = change.get("id") for player in self.ai.players: if player.id == remove_id: self.ai.players.remove(player) return True for virus in self.ai.viruses: if virus.id == remove_id: self.ai.viruses.remove(virus) return True for tile in self.ai.tiles: if tile.id == remove_id: self.ai.tiles.remove(tile) return True for base in self.ai.bases: if base.id == remove_id: self.ai.bases.remove(base) return True return False #Parse the update action. def change_update(self, change): change_id = change.get("id") values = change.get("values") for player in self.ai.players: if player.id == change_id: player.__dict__.update(values) return True for virus in self.ai.viruses: if virus.id == change_id: virus.__dict__.update(values) return True for tile in self.ai.tiles: if tile.id == change_id: tile.__dict__.update(values) return True for base in self.ai.bases: if base.id == change_id: base.__dict__.update(values) return True return False #Parse the global_update action def change_global_update(self, change): values = change.get("values") self.ai.__dict__.update(values) return True def run(self): if not self.connect(): return False if not self.login(): return False if not self.create_game(): return False if not self.recv_player_id(): return False if not self.init_main(): return False try: self.main_loop() except GameOverException as e: if e.winner == self.ai.my_player_id: game_over_message = "You Win! - {reason}".format(reason=e.reason) else: game_over_message = "You Lose! - {reason}".format(reason=e.reason) else: game_over_message = "Game over was never reached." if not self.end_main(): return False print(game_over_message) if not self.get_log(): return False
class Quoridor(object): def __init__(self, pros): self.pros = pros self.size = 19 self.ai_num = 5 self.ai = '' def step_ai(self): if self.ai_id == 0: dis, path = self.findPath(1) x, y = path return self.step(x, y, 1) else: suc = self.ai.run(self.nw, self.ins) if type(suc) != str: if suc: return self.finish(1 - self.nw.result() if self. should_reverse else self.nw.result()) else: return self.finish(0) else: self.ins = suc self.steps += 1 return 2 def reset(self): with open('record.txt', 'w') as f: f.write("Init\n") if self.ai != '' and type(self.ai.ai) is not dict: self.ai.ai.exit() self.ai_id = random.randint(1, self.ai_num) self.err = ['', ''] self.record_json = {} self.running = True self.steps = 0 self.nw = Board(self.record_json) self.json_out = open('result' + str(self.pros) + '.json', 'w') self.should_reverse = turn = random.randint(0, 1) # self.should_reverse = turn = 0 self.record_json['id'] = [turn, 1 - turn] self.record_json['step'] = [] self.ins = "" opp_state = self.state(1) if self.ai_id == 0: self.record_json['user'] = ["training", "short_path"] else: self.ai = AI(exec_file + str(self.ai_id), 1, self.pros) suc = self.ai.load() if not suc: print("fail") return copy.deepcopy(self.state(0)), copy.deepcopy( self.finish(0)), copy.deepcopy(opp_state), copy.deepcopy( -1), copy.deepcopy(self.ai_id) suc = self.ai.init(1 - turn) if not suc: print("fail2") return copy.deepcopy(self.state(0)), copy.deepcopy( self.finish(0)), copy.deepcopy(opp_state), copy.deepcopy( -1), copy.deepcopy(self.ai_id) self.record_json['user'] = ["training", self.ai.name] if turn == 1: result = self.step_ai() if result != 2: k = -1 else: xx, yy = map(int, self.ins.split()) k = self.change_from_loc(xx, yy) if result == 2 else -1 else: result = self.nw.result() k = -1 return copy.deepcopy(self.state(0)), copy.deepcopy( result), copy.deepcopy(opp_state), copy.deepcopy(k), copy.deepcopy( self.ai_id) def state(self, id): length = 20 state = [] side = id ^ self.should_reverse if side == 0: for i in range(1, length): state.append([]) for j in range(1, length): state[i - 1].append(1 if self.nw.board[i][j] == True else 0) state[self.nw.loc[side][0] - 1][self.nw.loc[side][1] - 1] = 2 state[self.nw.loc[side ^ 1][0] - 1][self.nw.loc[side ^ 1][1] - 1] = -2 else: for i in range(1, length): state.append([]) for j in range(1, length): state[i - 1].append(1 if self.nw.board[length - i][j] == True else 0) state[length - self.nw.loc[side][0] - 1][self.nw.loc[side][1] - 1] = 2 state[length - self.nw.loc[side ^ 1][0] - 1][self.nw.loc[side ^ 1][1] - 1] = -2 return state def step(self, x, y, ai): side = ai ^ self.should_reverse if (side == 0): self.ins = str(x + 1) + ' ' + str(y + 1) res = self.nw.update([x + 1, y + 1]) else: if x % 2 == 1 and y % 2 == 0: self.ins = str(17 - x) + ' ' + str(y + 1) res = self.nw.update([17 - x, y + 1]) else: self.ins = str(19 - x) + ' ' + str(y + 1) res = self.nw.update([19 - x, y + 1]) self.steps += 1 if res != True: self.err[ai] = res return self.finish(ai ^ 1) if self.nw.result() < 2: ans = 1 - self.nw.result( ) if self.should_reverse else self.nw.result() return self.finish(ans) else: ans = 2 return ans def finish(self, winner): self.record_json['total'] = self.steps self.record_json['result'] = winner self.record_json['err'] = [self.err, ' '] if self.ai != '' and type(self.ai.ai) is not dict: self.ai.ai.exit() json_out = open('result' + str(self.pros) + '.json', 'w') json.dump(self.record_json, json_out) json_out.close() self.running = False return winner def build_graph(self, ai): state = copy.deepcopy(self.state(ai)) u = ((0, 1), (0, -1), (1, 0), (-1, 0)) G = nx.DiGraph() _G = nx.DiGraph() for i in range(1, self.size, 2): for j in range(1, self.size, 2): if state[i][j] == 2: pos = (i, j) if state[i][j] == -2: _pos = (i, j) G.add_node((i, j)) _G.add_node((i, j)) for i in range(1, self.size, 2): for j in range(1, self.size, 2): for k in range(len(u)): if (state[i + u[k][0]][j + u[k][1]]): continue x = i + u[k][0] * 2 y = j + u[k][1] * 2 _G.add_weighted_edges_from([((i, j), (x, y), 1)]) if (state[x][y] == 0 or state[x][y] == 2): G.add_weighted_edges_from([((i, j), (x, y), 1)]) else: if state[x + u[k][0]][y + u[k][1]]: for kk in range((k < 2) * 2, (k < 2) * 2 + 2): if (state[x + u[kk][0]][y + u[kk][1]]): continue G.add_weighted_edges_from([ ((i, j), (x + u[kk][0] * 2, y + u[kk][1] * 2), 1) ]) else: G.add_weighted_edges_from([ ((i, j), (x + u[k][0] * 2, y + u[k][1] * 2), 1) ]) return G, pos, _G, _pos def findPath(self, ai): G, pos, _G, _pos = self.build_graph(ai) path = nx.shortest_path(G, source=pos) dis = nx.shortest_path_length(G, source=pos) min_dis = 1000 min_path = () for i in range(1, self.size, 2): now_dis = dis.get((17, i), 1001) if now_dis < min_dis or (now_dis == min_dis and random.randint(0, 4) == 0): min_dis = now_dis min_path = path[(17, i)][1] if min_path == (): _path = nx.shortest_path(_G, source=pos) _dis = nx.shortest_path_length(_G, source=pos) for i in range(1, self.size, 2): now_dis = _dis.get((17, i), 1000) if now_dis < min_dis: min_dis = now_dis if _dis[_pos] == 1: for i in range(1, self.size, 2): for j in range(1, self.size, 2): now_dis = dis.get((i, j), 1000) if (now_dis == 1): min_path = (i, j) else: min_path = _path[_pos][1] return copy.deepcopy(min_dis), copy.deepcopy(min_path) G, pos = self.build_graph(ai) path = nx.shortest_path(G, source=pos) dis = nx.shortest_path_length(G, source=pos) min_dis = 1000 min_path = () for i in range(1, self.size, 2): now_dis = dis.get((17, i), 1000) if now_dis < min_dis: min_dis = now_dis min_path = path[(17, i)][1] if min_path == (): print(self.record_json) min_path = pos return copy.deepcopy(min_dis), copy.deepcopy(min_path) def wall_pos(self, kind): row = kind // 8 col = kind % 8 if row % 2 == 0: return row + 1, col * 2 + 2 else: return row + 1, col * 2 + 1 def change_from_loc(self, x, y): if x % 2 == 0 and y % 2 == 0: return 128 if (self.should_reverse ^ 1 == 0): return (x - 2) * 8 + (y // 2 - 1) else: if x % 2 == 0: return (16 - x) * 8 + (y // 2 - 1) else: return (18 - x) * 8 + (y // 2 - 1) def action(self, kind): if kind < 128: x, y = self.wall_pos(kind) else: dis, path = self.findPath(0) x, y = path result = self.step(x, y, 0) opp_state = self.state(1) if result != 2: return copy.deepcopy(self.state(0)), copy.deepcopy( result), copy.deepcopy(opp_state), copy.deepcopy(-1) result = self.step_ai() xx, yy = map(int, self.ins.split()) k = self.change_from_loc(xx, yy) if result == 2 else -1 return copy.deepcopy(self.state(0)), copy.deepcopy( result), copy.deepcopy(opp_state), copy.deepcopy(k)
class Game: def __init__(self, conn, addr, port, name): self.serv_conn = conn self.serv_addr = addr self.serv_port = port self.game_name = name self.ai = AI() self.ai.connection = self.serv_conn #Attempt to connect to the server def connect(self): while True: try: #Attempting to connect self.serv_conn.connect((self.serv_addr, self.serv_port)) except socket.error: #Failed to connect time.sleep(1) else: #Client connected return True def receive(self): data = utility.receive_string(self.serv_conn) message = json.loads(data) if message['type'] == 'changes': self.update_game(message) elif message['type'] == 'player_id': self.ai.my_player_id = message['args']['id'] elif message['type'] == 'game_over': raise GameOverException(message["args"]["winner"], message["args"]["reason"]) return message def wait_for(self, *types): while True: message = self.receive() if message['type'] in types: return message #Attempt to login to the server def login(self): login_json = client_json.login.copy() login_json['args']['username'] = self.ai.username login_json['args']['password'] = self.ai.password utility.send_string(self.serv_conn, json.dumps(login_json)) message = self.wait_for('success', 'failure') if message['type'] == 'success': #Login success return True else: #Login failed return False #Attempt to create a game on the server def create_game(self): create_game_json = client_json.create_game.copy() if self.game_name is not None: create_game_json['args']['game_name'] = self.game_name utility.send_string(self.serv_conn, json.dumps(create_game_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": self.game_name = message['args']['name'] print("Game created: {}".format(self.game_name)) return True else: #Game creation failed return False #Receive Player ID from server def recv_player_id(self): self.wait_for('player_id') return True #Runs before main_loop has began. def init_main(self): self.wait_for('start_game') self.ai.init() return True #Runs after main_loop has finished. def end_main(self): self.ai.end() return True #Main connection loop until end of game. def main_loop(self): while True: message = self.wait_for('start_turn', 'game_over') if message['type'] == 'game_over': return True if self.ai.my_player_id == self.ai.player_id: utility.v_print("Turn Number: {}".format(self.ai.turn_number)) self.ai.run() utility.send_string(self.serv_conn, json.dumps(client_json.end_turn)) def get_log(self): log_json = client_json.get_log.copy() utility.send_string(self.serv_conn, json.dumps(log_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": file = open(self.game_name + '.glog', 'wb') file.write(message['args']['log'].encode('utf-8')) file.close() #Update game from message def update_game(self, message): if message.get("type") != "changes": return False for change in message.get("args").get("changes"): if change.get("action") == "add": self.change_add(change) elif change.get("action") == "remove": self.change_remove(change) elif change.get("action") == "update": self.change_update(change) elif change.get("action") == "global_update": self.change_global_update(change) return True #Parse the add action def change_add(self, change): values = change.get("values") if change.get("type") == "Player": temp = game_objects.Player(connection=self.serv_conn, parent_game=self, id=values.get("id"), name=values.get("name"), time=values.get("time"), expensivium=values.get("expensivium"), money=values.get("money")) self.ai.players.append(temp) if change.get("type") == "RobotType": temp = game_objects.RobotType(connection=self.serv_conn, parent_game=self, id=values.get("id"), max_health=values.get("max_health"), range=values.get("range"), splash=values.get("splash"), damage=values.get("damage"), movement=values.get("movement"), attacks=values.get("attacks")) self.ai.robotTypes.append(temp) if change.get("type") == "Robot": temp = game_objects.Robot(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner"), type=values.get("type"), health=values.get("health"), moves_left=values.get("moves_left"), attack_left=values.get("attack_left"), max_health=values.get("max_health"), range=values.get("range"), splash=values.get("splash"), damage=values.get("damage"), movement=values.get("movement"), attacks=values.get("attacks")) self.ai.robots.append(temp) if change.get("type") == "Factory": temp = game_objects.Factory(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner")) self.ai.factorys.append(temp) if change.get("type") == "Mine": temp = game_objects.Mine(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), owner=values.get("owner")) self.ai.mines.append(temp) if change.get("type") == "Tile": temp = game_objects.Tile(connection=self.serv_conn, parent_game=self, id=values.get("id"), x=values.get("x"), y=values.get("y"), wall=values.get("wall")) self.ai.tiles.append(temp) return True #Parse the remove action. def change_remove(self, change): remove_id = change.get("id") try: index = self.ai.players.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.players.remove(index) return True try: index = self.ai.robotTypes.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.robotTypes.remove(index) return True try: index = self.ai.robots.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.robots.remove(index) return True try: index = self.ai.factorys.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.factorys.remove(index) return True try: index = self.ai.mines.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.mines.remove(index) return True try: index = self.ai.tiles.find(remove_id, key=operator.attrgetter('id')) except: pass else: self.ai.tiles.remove(index) return True return False #Parse the update action. def change_update(self, change): change_id = change.get("id") values = change.get("values") try: index = self.ai.players.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.players[index].__dict__.update(values) return True try: index = self.ai.robotTypes.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.robotTypes[index].__dict__.update(values) return True try: index = self.ai.robots.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.robots[index].__dict__.update(values) return True try: index = self.ai.factorys.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.factorys[index].__dict__.update(values) return True try: index = self.ai.mines.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.mines[index].__dict__.update(values) return True try: index = self.ai.tiles.find(change_id, key=operator.attrgetter('id')) except: pass else: self.ai.tiles[index].__dict__.update(values) return True return False #Parse the global_update action def change_global_update(self, change): values = change.get("values") self.ai.__dict__.update(values) return True def run(self): if not self.connect(): return False if not self.login(): return False if not self.create_game(): return False if not self.recv_player_id(): return False if not self.init_main(): return False try: self.main_loop() except GameOverException as e: if e.winner == self.ai.my_player_id: game_over_message = "You Win! - {reason}".format( reason=e.reason) else: game_over_message = "You Lose! - {reason}".format( reason=e.reason) else: game_over_message = "Game over was never reached." if not self.end_main(): return False print(game_over_message) if not self.get_log(): return False
class Game: def __init__(self, conn, addr, port, name): self.serv_conn = conn self.serv_addr = addr self.serv_port = port self.game_name = name self.ai = AI() self.ai.connection = self.serv_conn #Attempt to connect to the server def connect(self): while True: try: #Attempting to connect self.serv_conn.connect((self.serv_addr, self.serv_port)) except socket.error: #Failed to connect time.sleep(1) else: #Client connected return True def receive(self): data = utility.receive_string(self.serv_conn) message = json.loads(data) if message['type'] == 'changes': self.update_game(message) elif message['type'] == 'player_id': self.ai.my_player_id = message['args']['id'] elif message['type'] == 'game_over': raise GameOverException(message["args"]["winner"], message["args"]["reason"]) return message def wait_for(self, *types): while True: message = self.receive() if message['type'] in types: return message #Attempt to login to the server def login(self): login_json = client_json.login.copy() login_json['args']['username'] = self.ai.username utility.send_string(self.serv_conn, json.dumps(login_json)) message = self.wait_for('success', 'failure') if message['type'] == 'success': #Login success return True else: #Login failed return False #Attempt to create a game on the server def create_game(self): create_game_json = client_json.create_game.copy() if self.game_name is not None: create_game_json['args']['game_name'] = self.game_name utility.send_string(self.serv_conn, json.dumps(create_game_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": self.game_name = message['args']['name'] print("Game created: {}".format(self.game_name)) return True else: #Game creation failed return False #Receive Player ID from server def recv_player_id(self): self.wait_for('player_id') return True #Runs before main_loop has began. def init_main(self): self.wait_for('start_game') self.ai.init() return True #Runs after main_loop has finished. def end_main(self): self.ai.end() return True #Main connection loop until end of game. def main_loop(self): while True: message = self.wait_for('start_turn', 'game_over') if message['type'] == 'game_over': return True if self.ai.my_player_id == self.ai.player_id: utility.v_print("Turn Number: {}".format(self.ai.turn_number)) self.ai.run() utility.send_string(self.serv_conn, json.dumps(client_json.end_turn)) def get_log(self): log_json = client_json.get_log.copy() utility.send_string(self.serv_conn, json.dumps(log_json)) message = self.wait_for('success', 'failure') if message['type'] == "success": file = open(self.game_name + '.glog', 'wb') file.write(message['args']['log'].encode('utf-8')) file.close() #Update game from message def update_game(self, message): if message.get("type") != "changes": return False for change in message.get("args").get("changes"): if change.get("action") == "add": self.change_add(change) elif change.get("action") == "remove": self.change_remove(change) elif change.get("action") == "update": self.change_update(change) elif change.get("action") == "global_update": self.change_global_update(change) return True #Parse the add action def change_add(self, change): values = change.get("values")