def add_change_component(self, ctl_frame, base=None, name=None, text=None, typectl=Entry, selection=None, selection_default=None, value=None, value_type=None, width=4): """ Add change control component :ctl_frame: frame in to which we add this component :base: base name e.g. "window" :name: component name e.g. "width" :selection: If present, array of selection strings :selection_default: selection default, None -> first :text: displayed text None - use name "" - no text label :typectl: Control widget type, default: Entry :value: initial value (default), if not already present :value_type: Value type default: int :width: Field width in characters """ if text is None: text = name if value is not None and value_type is None: value_type = type(value) if text != "": label_entry = Label(ctl_frame, text=" " + text, anchor="w") label_entry.pack(side="left") ctl_name = base + "_" + name if SlTrace.trace("add_change"): SlTrace.lg("add_change_component %s %s" % (ctl_name, text)) if selection is not None: selection_default = self.get_prop_value(ctl_name, selection_default) val_entry = SelectDDChoice(ctl_frame, selection=selection, default=selection_default) value_type = str self.update_control_entry(ctl_name, ctl_widget=val_entry, value=value, value_type=value_type, width=width) else: if ctl_name in self.ctl_name_d: ctn = self.ctl_name_d[ctl_name] if isinstance(ctn, ControlEntry): ctl_value = ctn.value # Get entry value elif isinstance(ctn, str): ctl_value = ctn # Use properties value else: ctl_value = value value = ctl_value val_entry = Entry(ctl_frame, width=width) self.update_control_entry(ctl_name, ctl_widget=val_entry, value=value, value_type=value_type, width=width) val_entry.pack(side="left") self.show_entry(ctl_name)
def key_press_cmd(self, ec=None, ec_code=None, ec_keysym=None): """ Keyboard key press / command processor """ if ec is None: ec = -1 if ec_code is None: ec_code = -1 if ec_keysym is None: ec_keysym = "NA" SlTrace.lg("key press: '%s' %s(x%02X)" % (ec, ec_keysym, ec_code)) if self.multi_key_cmd is None: if ec_keysym == "m": self.multi_key_cmd_str = ec_keysym if self.multi_key_cmd_str is not None: if ec_keysym == ";" or ec_keysym == " " or ec_keysym == "Return": self.multi_key_cmd() return self.multi_key_cmd_str += ec_keysym return if SlTrace.trace("selected"): self.list_selected("key_press_cmd:" + ec_keysym) if ec == "j": # Info (e.g. "i" for current edge position edge = self.get_keycmd_edge() if edge is None: self.beep() return SlTrace.lg(" %s\n%s" % (edge, edge.str_edges())) return if ec_keysym == "Return": edge = self.get_keycmd_edge() if edge is None: self.beep() return if edge.is_turned_on(): self.beep() return edge.display_clear() self.game_control.make_new_edge(edge=edge, display=True) self.game_control.display_update() # Ensure screen update return if (ec_keysym == "Up" or ec_keysym == "Down" or ec_keysym == "Left" or ec_keysym == "Right" or ec_keysym == "plus" or ec_keysym == "minus"): res = self.keycmd_move_edge(ec_keysym) return res if self.keycmd_edge: try: arg = int(ec) except: self.keycmd_edge = False return self.keycmd_args.append(arg) if len(self.keycmd_args) >= 2: self.make_new_edge(dir=self.keycmd_edge_dir, rowcols=self.keycmd_args) self.keycmd_edge = False return if ec_keysym == "h": # Help SlTrace.lg(""" space - Add multiline blank delimiter a - add delimiter with one line of text b - list blinking parts c - clear current part display d - (re)display current part f - rurn current part off h - Output this help listing i - list part, edges of current location j - List edge at current edge position k - cmds at top of cmd stack g - List on square(s) touching current edge l - List highlighted parts n - turn on current part r - redo undone command s - list selected parts t - list parts that are turned on v - set current edge Selection movement directions: UP Down Left Right "plus" - rotate selection clockwise "minus" - rotate selection counter clockwise ; - multi character command c[anvas] pattern - list canvas objects with tag "ALL" - all canvas objects p[part] pattern - List parts with tag, default all parts (one entry per part) r[ecord] pattern - Trace canvas rectangles with any tag matching pattern s[tart] number[current] - start(restart) looking at tracking number d[elete] pattern(default .*) delete canvas objects <cmd>[s]t=[<stack_length>][:<stack_bottom>]] Add stack listing <stack_length> - number of levels listed default: 2 <stack_bottom> - bottom of stack listed (0-most recent) default: 2 above Examples: pt=5 - to parts add stack list of 5 levels pt= - add default stack list to parts pt=6:3 - add stack 6 levels, omitting 3 lowest levels """) return if ec_keysym == "space": SlTrace.lg("_" * 50 + "\n\n\n") return if ec_keysym == "a": SlTrace.lg("_" * 50 + "\n\n\n") annotation = self.kbd_input("Enter annotation:") SlTrace.lg(annotation) return if ec_keysym == "b": # List "Blinking" parts self.list_blinking("blinking") if ec_keysym == "k": # cmds at top of stack self.game_control.command_manager.list_stack() if ec_keysym == "l": part_ids = list(self.game_control.board.area.highlights) SlTrace.lg("Highlighted parts(%d):" % len(part_ids)) for part_id in part_ids: part = self.get_part(id=part_id) SlTrace.lg(" %s" % part) return if ec_keysym == "s": # List those selected self.list_selected() return if ec_keysym == "t": # List those turned on part_ids = list(self.game_control.board.area.parts_by_id) n_on = 0 for part_id in part_ids: part = self.get_part(id=part_id) if part.is_turned_on(): n_on += 1 SlTrace.lg("parts turned on(%d of %d):" % (n_on, len(part_ids))) for part_id in part_ids: part = self.get_part(id=part_id) if part.is_turned_on(): SlTrace.lg(" %s" % part) return if ec == "v": self.keycmd_edge = True self.keycmd_edge_dir = ec self.keycmd_args = [] return if ec == "r": self.game_control.redo() return if ec_keysym == "g": # Do info on squares(regions) touching current edge edge = self.get_keycmd_edge() SlTrace.lg("%s" % edge.str_adjacents()) return if ec_keysym == "u": self.game_control.undo() return if ec_keysym == "semicolon": import re kbd_cmd_str = self.kbd_input("Enter cmd:").strip() SlTrace.lg("kbd_cmd: %s" % kbd_cmd_str) kbd_args = re.split(r'\s+|(?:\s*,\s*)|(?:\s*\(\s*)|(?:\s*\)\s*)', kbd_cmd_str) kbd_cmd = kbd_args.pop(0) stack_trace = False # Default stack trace stack_len = 2 # number of stack entries listed stack_bottom = 0 # lowest (most recent) listed -0 -> to most recent, 1 next most recent stack_match = re.search(r'(?:s?)t=(\d+)?(?::(\d+))?', kbd_cmd.lower()) if stack_match: stack_trace = True len_str = stack_match.group(1) if len_str: stack_len = int(len_str) end_str = stack_match.group(2) if end_str: stack_bottom = -int(end_str) stack_end = -stack_bottom-1 stack_begin = stack_end-stack_len if kbd_cmd.lower().startswith("c"): canvas = self.get_canvas() if len(kbd_args) > 0: pat = kbd_args[0] else: pat = ".*" items = canvas.get_tracked() matching_ids = [] for item in items: (rec_id, track_no, call_stack) = item tags = canvas.gettags(rec_id) for tag in tags: if re.match(pat, tag): matching_ids.append(rec_id) break SlTrace.lg("canvas %s: %s" % (pat, matching_ids)) elif kbd_cmd.lower().startswith("d"): # delete items canvas = self.get_canvas() if len(kbd_args) > 0: pat = kbd_args[0] else: pat = ".*" items = canvas.get_tracked() for item in items: (rec_id, track_no, call_stack) = item tags = canvas.gettags(rec_id) for tag in tags: SlTrace.lg("tag:%s" % tag) if re.match(pat, tag): SlTrace.lg("deleting: %s: %s" % (tags, rec_id)) canvas.delete(rec_id) break elif kbd_cmd.lower().startswith("p"): canvas = self.get_canvas() if len(kbd_args) > 0: pat = kbd_args[0] else: pat = ".*" items = canvas.get_tracked() matching_parts_by_id = {} for item in items: (rec_id, stack_no, stack) = item tags = canvas.gettags(rec_id) part = self.get_part_from_tags(tags) if part is None: continue part_str = str(part) found = re.search(pat, part_str) if found: part_item = (part, item) if part.part_id not in matching_parts_by_id: matching_parts_by_id[part.part_id] = [] # Create list of tags matching_parts_by_id[part.part_id].append(part_item) SlTrace.lg("parts pat:%s" % (pat)) for part_id, part_item_list in matching_parts_by_id.items(): part = self.get_part(part_id) SlTrace.lg(" %d (%d parts)" % (part.part_id, len(part_item_list))) for part_item in part_item_list: part, item = part_item rec_id, track_no, stack = item tags = canvas.gettags(rec_id) pt = self.get_part_from_tags(tags) SlTrace.lg(" %d %s %s" % (rec_id, track_no, pt)) if stack_trace: rec_id, stack_no, stack = item canvas.trace_item(prefix=" ", rec_id=rec_id, begin=stack_begin, end=stack_end) elif kbd_cmd.lower().startswith("r"): # trace rectangles canvas = self.get_canvas() if len(kbd_args) > 0: pat = kbd_args[0] else: pat = ".*" items = canvas.get_tracked() for item in items: (rec_id, track_no, call_stack) = item tags = canvas.gettags(rec_id) for tag in tags: if re.match(pat, tag): canvas.trace_item(rec_id=rec_id) break elif kbd_cmd.lower().startswith("s"): # start looking canvas = self.get_canvas() if len(kbd_args) > 0: num = int(kbd_args[0]) else: num = self.get_start_track() SlTrace.lg("Track no set to: %d" % num) self.set_start_track(num) return x,y = self.game_control.get_xy() parts = self.game_control.get_parts_at(x,y) if parts: SlTrace.lg("x=%d y=%d" % (x,y)) for part in parts: if ec == "i": SlTrace.lg(" %s\n%s" % (part, part.str_edges())) elif ec == "d": part.display() elif ec == "c": part.display_clear() # clear display elif ec == "n": # turn on part.turn_on(player=self.get_player()) elif ec == "f": # turn off part.turn_off()
def keycmd_move_edge(self, keysym): """ Adjust marker based on current marker state and latest keyboard input symbol User remains the same. Movement rules: 1. If keysym is (up,down,left,right) new edge will retain the same orientation and move one row/colum in the direction specified by the keysym, keep the same direction and move one in the keysym direction. 2. The new edge, wraps around to the opposite side, if the new loction is our of bounds. 3. If the keysym is (plus,minus) the new edge will be +/- 90 degrees clockwize from the left corner of the original edge 4. If the (plus,minus) rotation would place an edge outside the latice, the rotation is reversed. :keysym: keyboard key symbol(up,down,left,right,plus,minus) specifying the location of the new edge """ if SlTrace.trace("selected"): self.list_selected("keycmd_move_edge before:" + keysym) edge = self.get_keycmd_edge() edge_dir = edge.sub_type() next_dir = edge_dir next_row = edge.row next_col = edge.col if keysym == "plus": if edge_dir == "h": next_dir = "v" else: next_dir = "h" next_col -= 1 elif keysym == "minus": if edge_dir == "h": next_dir = "v" next_row -= 1 else: next_dir = "h" elif keysym == "Up": next_row -= 1 elif keysym == "Down": next_row += 1 elif keysym == "Left": next_col -= 1 elif keysym == "Right": next_col += 1 if next_row < 1: next_row = self.game_control.board.nrows if (next_row > self.game_control.board.nrows+1 or (next_row > self.game_control.board.nrows and next_dir == "v")): next_row = 1 if next_col < 1: next_col = self.game_control.board.ncols if (next_col > self.game_control.board.ncols+1 or (next_col > self.game_control.board.ncols and next_dir == "h")): next_col = 1 next_edge = self.get_part(type="edge", sub_type=next_dir, row=next_row, col=next_col) SlTrace.lg("keycmd_move_edge edge(%s) row=%d, col=%d" % (next_dir, next_row, next_col)) if next_edge is None: raise SelectError("keycmd_move_edge no edge(%s) row=%d, col=%d" % (next_dir, next_row, next_col)) self.move_edge_cmd(edge, next_edge)
def __init__(self, center=None, radius=None, start=None, arc=360., **kwargs): """ Setup object :radius: fraction of container default=.5 :center: position of center in block default Pt(width/2, height/2) :start: angle starting default=0 deg (up) :arc: arc in degrees default=360 deg (counter clockwise) Arc 0 deg == up, positive is counter clockwise * * * * : * * : * : * : * * : * : * : center * * : / * *-------------------+-------------------* * : * * : * * : * : * : * * : * * : * * * * *<--position | <--- radius ----> | center = Pt(position.x + radius, position.y + radius position = Pt(center.x - radius, center.y - radius """ if SlTrace.trace("test"): print() super().__init__(ctype=BlockType.ARC, **kwargs) width = self.width height = self.height if radius is None: if width is None: width = 1. radius = width/2. self.radius = radius if center is None: center = Pt(.5, .5) self.center = center if start is None: start = 0. self.start = start self.arc = arc pts = [] nstep = 360 # TBD - uniform separation end_angle = self.start + self.arc inc_angle = (end_angle-self.start)/nstep rad = self.radius # Circle centered in the middle ct = self.center pts.append(ct) for i in range(nstep+1): angle = self.start + i * inc_angle theta = radians(angle) # In radians pt_x = rad * sin(theta) pt_y = rad * cos(theta) pt = Pt(ct.x+pt_x, ct.y+pt_y) pts.append(pt) self.points = pts
def log_ctl_vals(self, con="=", sep=" ", trace=None): """ Log current control values See get_ctl_vals """ if SlTrace.trace(trace): # ck for trace before doing call SlTrace.lg(self.get_ctl_vals(con=con, sep=sep))
def build_path_stack(self): """ Agument path_stack with a next move :returns: True if successful, False if no such path found """ board = self.board len_ckt = self.len_ckt while True: self.time_check() ###board.update_display() # Don't let display block len_stk = len(self.path_stack) if len_stk == 0: return False # No paths if len_stk == len_ckt: if SlTrace.trace("complete_paths"): self.display_stack_path("complete_paths") self.ncomplete_path += 1 # Count all complete paths self.is_complete_tour = True if self.closed_tours: start_loc = self.path_stack[0].loc end_loc = self.path_stack[-1].loc if board.is_neighbor(start_loc, end_loc): self.is_closed_tour = True return True self.last_complete_path = self.path_stack_path() if SlTrace.trace("non-closed"): self.display_stack_path( "ignoring non-closed tour {} to {}".format( loc2desc(self.path_stack[0].loc), loc2desc(self.path_stack[-1].loc))) self.display_stack("non-closed") if self.max_try is not None and self.ntry >= self.max_try: SlTrace.lg( f"Giving up looking for closed tour after {self.ntry:d} tries" ) return True ###self.backup_move() if self.is_stop_gen or self.is_change_tour: break # Short circuit self.widen_search() continue # look again else: return True ###if self.path_stack is None or len(self.path_stack) == 0: ### raise SelectError("empty self.path_stack") if self.operator_action_check(): if self.is_change_tour: return False if self.is_stop_gen: return False continue if self.next_move(): return True # End of path search # Continue search return False # Short circuit
def set_squares_button(): global loop_no global first_set_app global app global board_frame, msg_frame, sqs, board_canvas global width, height, min_xlen, nx, ny global n_rearrange_cycles, rearrange_cycle global players, sp global move_no_label global snapshot1, snapshot2 # tracemalloc instances loop_no += 1 SlTrace.lg("\nLoop %d" % loop_no) SlTrace.lg("Memory Used: %.0f MB, Change: %.2f MB" % (SlTrace.getMemory()/1.e6, SlTrace.getMemoryChange()/1.e6)) SlTrace.lg("Squares Set Button", "button") if SlTrace.trace("pgm_stack"): stack = traceback.extract_stack() SlTrace.lg("pgm_stack depth=%d" % len(stack)) if SlTrace.trace("pgm_stack_list"): list_len = 14 print_list = traceback.format_list(stack) for line in print_list[-list_len:]: SlTrace.lg(" " + line) app = setup_app(app) if board_canvas is not None: SlTrace.lg("delete board_canvas") board_canvas.delete() board_canvas = None if board_frame is not None: board_frame.destroy() board_frame = None if msg_frame is not None: msg_frame.destroy() msg_frame = None if sp is not None: sp.destroy() sp = None app.update_form() rects = [] rects_rows = [] # So we can pass row, col rects_cols = [] min_xlen = app.get_component_val("figure_size", "min", min_xlen) min_xlen = float(min_xlen) min_xlen = str(min_xlen) min_ylen = min_xlen ###rects.append(rect1) ###rects.append(rect2) xmin = .1*float(width) xmax = .9*float(width) xlen = (xmax-xmin)/float(nx) min_xlen = float(min_xlen) if xlen < min_xlen: SlTrace.lg("nx=%d xlen(%.0f) set to %.0f" % (nx, xlen, min_xlen)) xlen = min_xlen ymin = .1*float(height) ymax = .9*float(height) ylen = (ymax-ymin)/float(ny) min_ylen = float(min_ylen) if ylen < min_ylen: SlTrace.lg("ny=%d ylen(%.0f) set to %.0f" % (ny, ylen, min_ylen)) ylen = min_ylen board_frame = Frame(mw, width=width, height=height, bg="", colormap="new") board_frame.pack() msg_frame = Frame(mw) msg_frame.pack(side="bottom") board_canvas = Canvas(board_frame, width=width, height=height) board_canvas.pack() if sp is not None and sp.cur_message is not None: sp.cur_message.destroy() sp.msg = None sqs = SelectSquares(board_canvas, mw=mw, nrows=ny, ncols=nx, width=width, height=height, check_mod=check_mod) sqs.display() sp = SelectPlay(board=sqs, msg_frame=msg_frame, mw=mw, start_run=False, game_control=game_control, on_exit=pgm_exit, on_end=end_game, move_first=1, before_move=before_move, after_move=after_move, show_ties=show_ties) sp.set_stroke_move(stroke_move) if first_set_app: if run_resets: sp.reset_score() if show_players: show_players_window() if show_score: show_score_window() first_set_app = False if SlTrace.trace("memory"): ###obj_list = objgraph.show_most_common_types(limit=20) ###SlTrace.lg("objgraph=%s" % obj_list) snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno', True) SlTrace.lg("[ Top 25 ]") for stat in top_stats[:25]: SlTrace.lg(str(stat)) nc = gc.collect() SlTrace.lg("gc.collect=%d" % nc) nc = gc.collect() SlTrace.lg("gc.collect=%d" % nc) ###obj_list = objgraph.show_most_common_types(limit=20) ###SlTrace.lg("objgraph=%s" % obj_list) objgraph.show_growth(limit=20, file=SlTrace.getLogFile()) objgraph.show_growth(limit=20) objgraph.get_new_ids(file=SlTrace.getLogFile()) objgraph.get_new_ids() ###obj = objgraph.by_type('SelectPlayer') ###objgraph.show_backrefs([obj], max_depth=10) SlTrace.lg("gc.garbage:%s" % gc.garbage) if snapshot1 is None and snapshot2 is None: snapshot1 = tracemalloc.take_snapshot() elif snapshot2 is None: snapshot2 = tracemalloc.take_snapshot() else: snapshot1 = snapshot2 snapshot2 = tracemalloc.take_snapshot() if snapshot2 is not None: top_stats = snapshot2.compare_to(snapshot1, 'lineno', True) SlTrace.lg("[ Top 25 differences]") for stat in top_stats[:25]: SlTrace.lg(str(stat)) snapshot1 = snapshot2 snapshot2 = None if run_game: mw.after(0, sp.running_loop)
def after_move(scmd): SlTrace.lg("after_move", "move") if SlTrace.trace("selected"): sp.list_selected("selected after_move")
def before_move(scmd): global move_no_label SlTrace.lg("before_move", "move") if SlTrace.trace("selected"): sp.list_selected("before_move")
nsq = nx * ny show_id = args.show_id show_players = args.show_players show_score = args.show_score speed_step = args.speed_step stroke_move = args.stroke_move trace = args.trace if trace: SlTrace.setFlags(trace) width = args.width height = args.height ew_display= args.ew_display ew_select = args.ew_select ew_standoff = args.ew_standoff if SlTrace.trace("memory"): tracemalloc.Filter(True, "select*") tracemalloc.start() tracemalloc.Filter(True, "select*") SelectPart.set_edge_width_cls(ew_display, ew_select, ew_standoff) def is_in_pgm_args(flag): """ Test if flag present in pgm args Looks for flag and -flag and --flag(=value)? :flag: flag string """