def __init__(self, conf): self._conf = conf self._map = Map(conf.map_rows + 2, conf.map_cols + 2) self._snake = Snake(self._map, conf.init_direc, conf.init_bodies, conf.init_types) self._pause = False self._solver = globals()[self._conf.solver_name](self._snake) self._episode = 1 self._init_log_file()
def get(self, url, params): url = self.add_query(url, params) req = urllib2.Request(url) resp = self.opener.open(req) data = Map(json.loads(resp.read())) if data.errcode: msg = "%(errcode)d %(errmsg)s" % data raise WeixinLoginError(msg) return data
def fetch(self, method, url, params=None, data=None, headers=None): req = requests.Request(method, url, params=params, data=data, headers=headers) prepped = req.prepare() resp = self.session.send(prepped, timeout=20) data = Map(resp.json()) if data.errcode: msg = "%(errcode)d %(errmsg)s" % data raise WeixinMPError(msg) return data
class WeixinPay(object): def __init__(self, app_id, mch_id, mch_key, notify_url): self.opener = urllib2.build_opener(urllib2.HTTPSHandler()) self.app_id = app_id self.mch_id = mch_id self.mch_key = mch_key self.notify_url = notify_url @property def remote_addr(self): if request is not None: return request.remote_addr return "" @property def nonce_str(self): char = string.ascii_letters + string.digits return "".join(random.choice(char) for _ in range(32)) to_utf8 = lambda self, x: x.encode("utf8") if isinstance(x, unicode) else x def sign(self, raw): raw = [(k, str(raw[k]) if isinstance(raw[k], int) else raw[k]) for k in sorted(raw.keys())] s = "&".join("=".join(kv) for kv in raw if kv[1]) s += "&key={0}".format(self.mch_key) return hashlib.md5(self.to_utf8(s)).hexdigest().upper() def check(self, data): sign = data.pop("sign") return sign == self.sign(data) def to_xml(self, raw): s = "" for k, v in raw.iteritems(): s += "<{0}>{1}</{0}>".format(k, self.to_utf8(v), k) return "<xml>{0}</xml>".format(s) def to_dict(self, content): raw = {} root = etree.fromstring(content) for child in root: raw[child.tag] = child.text return raw def fetch(self, url, data): req = urllib2.Request(url, data=self.to_xml(data)) try: resp = self.opener.open(req, timeout=20) except urllib2.HTTPError, e: resp = e data = Map(self.to_dict(resp.read())) if data.return_code == "FAIL": raise WeixinPayError(data.return_msg) return data
def jsapi_sign(self, url='', **kwargs): """ 生成签名给js使用 """ timestamp = str(int(time.time())) nonce_str = self.nonce_str kwargs.setdefault("jsapi_ticket", self.jsapi_ticket) kwargs.setdefault("timestamp", timestamp) kwargs.setdefault("noncestr", nonce_str) raw = [(k, kwargs[k]) for k in sorted(kwargs.keys())] s = "&".join("=".join(kv) for kv in raw if kv[1]) sign = hashlib.sha1(s.encode("utf-8")).hexdigest().lower() return Map(sign=sign, timestamp=timestamp, noncestr=nonce_str)
class Game: def __init__(self, conf): self._conf = conf self._map = Map(conf.map_rows + 2, conf.map_cols + 2) self._snake = Snake(self._map, conf.init_direc, conf.init_bodies, conf.init_types) self._pause = False self._solver = globals()[self._conf.solver_name](self._snake) self._episode = 1 self._init_log_file() @property def snake(self): return self._snake @property def episode(self): return self._episode def run(self): if self._conf.mode == GameMode.BENCHMARK: self._run_benchmarks() elif self._conf.mode == GameMode.TRAIN_DQN: self._run_dqn_train() self._plot_history() else: window = GameWindow( "Snake", self._conf, self._map, self, self._on_exit, (('<w>', lambda e: self._update_direc(Direc.UP)), ('<a>', lambda e: self._update_direc(Direc.LEFT)), ('<s>', lambda e: self._update_direc(Direc.DOWN)), ('<d>', lambda e: self._update_direc(Direc.RIGHT)), ('<r>', lambda e: self._reset()), ('<space>', lambda e: self._toggle_pause()))) if self._conf.mode == GameMode.NORMAL: window.show(self._game_main_normal) elif self._conf.mode == GameMode.TRAIN_DQN_GUI: window.show(self._game_main_dqn_train) self._plot_history() def _run_benchmarks(self): STEPS_LIMIT = 5000 NUM_EPISODES = int(input("Please input the number of episodes: ")) print("\nMap size: %dx%d" % (self._conf.map_rows, self._conf.map_cols)) print("Solver: %s\n" % self._conf.solver_name[:-6].lower()) tot_len, tot_steps = 0, 0 for _ in range(NUM_EPISODES): print("Episode %d - " % self._episode, end="") while True: self._game_main_normal() if self._map.is_full(): print("FULL (len: %d | steps: %d)" % (self._snake.len(), self._snake.steps)) break elif self._snake.dead: print("DEAD (len: %d | steps: %d)" % (self._snake.len(), self._snake.steps)) break elif self._snake.steps >= STEPS_LIMIT: print("STEP LIMIT (len: %d | steps: %d)" % (self._snake.len(), self._snake.steps)) self._write_logs() # Write the last step break tot_len += self._snake.len() tot_steps += self._snake.steps self._reset() avg_len = tot_len / NUM_EPISODES avg_steps = tot_steps / NUM_EPISODES print("\n[Summary]\nAverage Length: %.2f\nAverage Steps: %.2f\n" % (avg_len, avg_steps)) self._on_exit() def _run_dqn_train(self): try: while not self._game_main_dqn_train(): pass except KeyboardInterrupt: pass except Exception: traceback.print_exc() finally: self._on_exit() def _game_main_dqn_train(self): if not self._map.has_food(): self._map.create_rand_food() if self._pause: return episode_end, learn_end = self._solver.train() if episode_end: self._reset() return learn_end def _game_main_normal(self): if not self._map.has_food(): self._map.create_rand_food() if self._pause or self._is_episode_end(): return self._update_direc(self._solver.next_direc()) if self._conf.mode == GameMode.NORMAL and self._snake.direc_next != Direc.NONE: self._write_logs() self._snake.move() if self._is_episode_end(): self._write_logs() # Write the last step def _plot_history(self): self._solver.plot() def _update_direc(self, new_direc): self._snake.direc_next = new_direc if self._pause: self._snake.move() def _toggle_pause(self): self._pause = not self._pause def _is_episode_end(self): return self._snake.dead or self._map.is_full() def _reset(self): self._snake.reset() self._episode += 1 def _on_exit(self): if self._log_file: self._log_file.close() if self._solver: self._solver.close() def _init_log_file(self): try: os.makedirs("logs") except OSError as e: if e.errno != errno.EEXIST: raise try: self._log_file = None self._log_file = open('logs/snake.log', 'w') except FileNotFoundError: if self._log_file: self._log_file.close() def _write_logs(self): self._log_file.write("[ Episode %d / Step %d ]\n" % \ (self._episode, self._snake.steps)) for i in range(self._map.num_rows): for j in range(self._map.num_cols): pos = Pos(i, j) t = self._map.point(pos).type if t == PointType.EMPTY: self._log_file.write(" ") elif t == PointType.WALL: self._log_file.write("# ") elif t == PointType.FOOD: self._log_file.write("F ") elif t == PointType.HEAD_L or t == PointType.HEAD_U or \ t == PointType.HEAD_R or t == PointType.HEAD_D: self._log_file.write("H ") elif pos == self._snake.tail(): self._log_file.write("T ") else: self._log_file.write("B ") self._log_file.write("\n") self._log_file.write("[ last/next direc: %s/%s ]\n" % \ (self._snake.direc, self._snake.direc_next)) self._log_file.write("\n")
def standard_game_map(): return Map(width=5, height=5)