def __init__(self, game): self.game = game self.player_control = PlayerControl(self) self.ai_control = AIControl(self) self.mark_drawer = MarkDrawer(self) self.player = None self.actors = [] self.killed = [] self._ai_turn = False
def __init__(self, board=None, mw=None, run=True, on_end=None, on_exit=None, auto_play_check_ms=10, cmd_stream=None, btmove=.1, player_control=None, move_first=None, before_move=None, after_move=None): """ Setup play :board: playing board (SelectSquares) :mw: Instance of Tk, if one, else created here :run: Game is running default: True True - auto players continue to make moves False - auto player plays are ignored :on_exit: function to call on exit / window destroy :on_end: function, if present, to call at end of game :before_move: function, if any, to call before move :after_move: function, if any, to call after move """ self.playing = True # Hack to suppress activity on exit event self.board = board self.cmd_stream = cmd_stream self.command_manager = SelectCommandManager(self) SelectCommandPlay.set_management(self.command_manager, self) if mw is None: mw = Tk() self.mw = mw self.mw.protocol("WM_DELETE_WINDOW", self.delete_window) self.score_win = None # iff not None score win self.in_game = False self.run = run self.on_exit = on_exit self.auto_play_check_ms = auto_play_check_ms self.auto_delay_waiting = False self.btmove = btmove if player_control is None: player_control = PlayerControl(display=False) self.player_control = player_control self.player_index = 0 self.msg = None # message widget, if any self.messages = [] # Command messages, if any self.first_time = True # flag showing first time self.moves = [] board.add_down_click_call(self.down_click) board.add_new_edge_call(self.new_edge) self.cur_message = None # Currently displaying message, if any self.select_cmd = None self.before_move = before_move self.after_move = after_move self.clear_mods() self.move_no_label = None # Move no label, if displayed self.waiting_for_message = False self.mw.protocol("WM_DELETE_WINDOW", self.on_exit) self.mw.bind("<KeyPress>", self.key_press) self.mw.bind("<KeyRelease>", self.key_release) ###self.board.set_down_click_call(self.down_click_made) """ Keyboard command control """ self.keycmd_edge = False self.keycmd_args = [] self.keycmd_edge_mark = None # Current marker edge self.multi_key_cmd_str = None # Current multi key cmd str if self.run: self.do_first_time() self.on_end = on_end
class Logic(object): def __init__(self, game): self.game = game self.player_control = PlayerControl(self) self.ai_control = AIControl(self) self.mark_drawer = MarkDrawer(self) self.player = None self.actors = [] self.killed = [] self._ai_turn = False def init(self): self.mark_drawer.init() self.initialize_player() self.add_actor(self.player) self.add_actor(Soldier(self.game, (-1, 2))) self.add_actor(Archer(self.game, (-3, 0))) self.add_actor(Archer(self.game, (0, -2))) self.add_actor(Hoplite(self.game, (2, 2))) map(lambda a: a.ai.alert(), filter(lambda a: a != self.player, self.actors)) def initialize_player(self): self.player = Player(self.game, (0, 0)) def add_actor(self, actor): self.actors.append(actor) actor.init(self.game.game_objects) def kill_actor(self, actor): assert actor not in self.killed assert actor in self.actors self.killed.append(actor) def update(self): if self.killed: self.clear_killed() if self._ai_turn: self.ai_control.run_turn() def clear_killed(self): for actor in self.killed: actor.node.strand_node() self.actors.remove(actor) del self.killed[:] def get_actor_at(self, pos): actor = filter(lambda a: a.pos == pos, self.actors) assert len(actor) <= 1 if actor: return actor[0] else: return None def occupied(self, pos): return self.get_actor_at(pos) is not None def foe_occupied(self, pos): actor = self.get_actor_at(pos) return actor is not None and actor != self.player def foes(self): return filter(lambda a: a != self.player, self.actors) def start_ai_turn(self): self._ai_turn = True self.ai_control.init_turn() def end_ai_turn(self): self._ai_turn = False self.player_control.start_player_turn()
def player_control(self): """ Setup player control """ if self.player_control is None: self.player_control = PlayerControl(self, display=False) self.player_control.control_display()
def __init__(self, canvas, mw=None, nrows=10, ncols=None, width=None, height=None, tbmove=.1, check_mod=None, down_click_call=None, highlight_limit=None): """ :canvas: - canvas within we are placed :nrows: number of rows of squares default: 10 :ncols: number of columns of squares default: rows :width: window width :height: window height :tbmove: minimum time(seconds) between move detection :check_mod: routine called, if present, before & after part modification :highlight_limit: limit highlighting (seconds) default: None (None - no limit) """ if ncols is None: ncols = nrows self.canvas = canvas self.nrows = nrows self.ncols = ncols if width is None: width = canvas.winfo_width() self.width = width if height is None: height = canvas.winfo_height() self.height = height self.drawn_lines = [] # lines drawn min_xlen = 10 min_ylen = min_xlen self.check_mod = check_mod self.tbmove = tbmove self.highlight_limit = highlight_limit rects = [] rects_rows = [] # So we can pass row, col rects_cols = [] self.down_click_call = down_click_call def rn(val): return int(round(val)) xmin = .1 * float(width) xmax = .9 * float(width) xlen = (xmax - xmin) / float(ncols) min_xlen = float(min_xlen) if xlen < min_xlen: SlTrace.lg("xlen(%.0f) set to %.0f" % (xlen, min_xlen)) xlen = min_xlen ymin = .1 * float(height) ymax = .9 * float(height) ylen = (ymax - ymin) / float(nrows) min_ylen = float(min_ylen) if ylen < min_ylen: SlTrace.lg("ylen(%.0f) set to %.0f" % (ylen, min_ylen)) ylen = min_ylen for i in range(int(ncols)): col = i + 1 x1 = xmin + i * xlen x2 = x1 + xlen for j in range(int(nrows)): row = j + 1 y1 = ymin + j * ylen y2 = y1 + ylen rect = ((rn(x1), rn(y1)), (rn(x2), rn(y2))) rects.append(rect) rects_rows.append(row) rects_cols.append(col) self.area = SelectArea(canvas, mw=mw, tbmove=self.tbmove, check_mod=self.check_mod, down_click_call=self.down_click_call, highlight_limit=self.highlight_limit) ###SelectRegion.reset() for i, rect in enumerate(rects): row = rects_rows[i] col = rects_cols[i] self.area.add_rect(rect, row=row, col=col, draggable_edge=False, draggable_corner=False, draggable_region=False, invisible_region=True, invisible_edge=True) for part in self.area.get_parts(): if part.is_corner(): part.set(display_shape="circle", display_size=10, color="blue") elif part.is_edge(): part.set(edge_width_select=50, edge_width_display=5, on_highlighting=True, off_highlighting=True, color="lightgreen") elif part.is_region(): part.set(color='light slate gray') top_edge = part.get_top_edge() top_edge.row = part.row top_edge.col = part.col right_edge = part.get_right_edge() right_edge.row = part.row right_edge.col = part.col + 1 botom_edge = part.get_botom_edge() botom_edge.row = part.row + 1 botom_edge.col = part.col left_edge = part.get_left_edge() left_edge.row = part.row left_edge.col = part.col self.complete_square_call = None # Setup for complete square call self.new_edge_call = None # Setup for new edge call ###self.area.add_turned_on_part_call(self.new_edge) self.player_control = PlayerControl(self, display=False)
class SelectSquares(object): """ classdocs """ ###@profile def __init__(self, canvas, mw=None, nrows=10, ncols=None, width=None, height=None, tbmove=.1, check_mod=None, down_click_call=None, highlight_limit=None): """ :canvas: - canvas within we are placed :nrows: number of rows of squares default: 10 :ncols: number of columns of squares default: rows :width: window width :height: window height :tbmove: minimum time(seconds) between move detection :check_mod: routine called, if present, before & after part modification :highlight_limit: limit highlighting (seconds) default: None (None - no limit) """ if ncols is None: ncols = nrows self.canvas = canvas self.nrows = nrows self.ncols = ncols if width is None: width = canvas.winfo_width() self.width = width if height is None: height = canvas.winfo_height() self.height = height self.drawn_lines = [] # lines drawn min_xlen = 10 min_ylen = min_xlen self.check_mod = check_mod self.tbmove = tbmove self.highlight_limit = highlight_limit rects = [] rects_rows = [] # So we can pass row, col rects_cols = [] self.down_click_call = down_click_call def rn(val): return int(round(val)) xmin = .1 * float(width) xmax = .9 * float(width) xlen = (xmax - xmin) / float(ncols) min_xlen = float(min_xlen) if xlen < min_xlen: SlTrace.lg("xlen(%.0f) set to %.0f" % (xlen, min_xlen)) xlen = min_xlen ymin = .1 * float(height) ymax = .9 * float(height) ylen = (ymax - ymin) / float(nrows) min_ylen = float(min_ylen) if ylen < min_ylen: SlTrace.lg("ylen(%.0f) set to %.0f" % (ylen, min_ylen)) ylen = min_ylen for i in range(int(ncols)): col = i + 1 x1 = xmin + i * xlen x2 = x1 + xlen for j in range(int(nrows)): row = j + 1 y1 = ymin + j * ylen y2 = y1 + ylen rect = ((rn(x1), rn(y1)), (rn(x2), rn(y2))) rects.append(rect) rects_rows.append(row) rects_cols.append(col) self.area = SelectArea(canvas, mw=mw, tbmove=self.tbmove, check_mod=self.check_mod, down_click_call=self.down_click_call, highlight_limit=self.highlight_limit) ###SelectRegion.reset() for i, rect in enumerate(rects): row = rects_rows[i] col = rects_cols[i] self.area.add_rect(rect, row=row, col=col, draggable_edge=False, draggable_corner=False, draggable_region=False, invisible_region=True, invisible_edge=True) for part in self.area.get_parts(): if part.is_corner(): part.set(display_shape="circle", display_size=10, color="blue") elif part.is_edge(): part.set(edge_width_select=50, edge_width_display=5, on_highlighting=True, off_highlighting=True, color="lightgreen") elif part.is_region(): part.set(color='light slate gray') top_edge = part.get_top_edge() top_edge.row = part.row top_edge.col = part.col right_edge = part.get_right_edge() right_edge.row = part.row right_edge.col = part.col + 1 botom_edge = part.get_botom_edge() botom_edge.row = part.row + 1 botom_edge.col = part.col left_edge = part.get_left_edge() left_edge.row = part.row left_edge.col = part.col self.complete_square_call = None # Setup for complete square call self.new_edge_call = None # Setup for new edge call ###self.area.add_turned_on_part_call(self.new_edge) self.player_control = PlayerControl(self, display=False) def get_part(self, id=None, type=None, sub_type=None, row=None, col=None): """ Get basic part :id: unique part id :type: part type e.g., edge, region, corner :row: part row :col: part column :returns: part, None if not found """ return self.area.get_part(id=id, type=type, sub_type=sub_type, row=row, col=col) def get_parts(self, pt_type=None): """ Get parts in figure :pt_type: part type, default: all parts "corner", "edge", "region" """ return self.area.get_parts(pt_type=pt_type) def get_legal_moves(self): """ Get edges that would be legal moves """ edges = self.get_parts(pt_type="edge") moves = [] for edge in edges: if not edge.is_turned_on(): moves.append(edge) return moves def get_selects(self): """ GEt list of selected parts :returns: list, empty if none """ return self.area.get_selects() def get_selected_part(self): """ Get selected part :returns: selected part, None if none selected """ return self.area.get_selected_part() def get_parts_at(self, x, y, sz_type=SelectPart.SZ_SELECT): """ Check if any part is at canvas location provided If found list of parts :Returns: SelectPart[] """ return self.area.get_parts_at(x, y, sz_type=sz_type) def get_xy(self): """ get current mouse position (or last one recongnized :returns: x,y on area canvas, None if never been anywhere """ return self.area.get_xy() def add_complete_square_call(self, call_back): """ Add function to be called upon completed square :call_back: call back (edge, region) - None - remove call back """ self.complete_square_call = call_back def add_down_click_call(self, call): """ Add down click processing function :call: down click processing function """ self.area.add_down_click_call(call) def add_new_edge_call(self, call_back): """ Add function to be called upon newly added edge :call_back: call back (edge) - None - remove call back """ self.new_edge_call = call_back def complete_square(self, edge, regions): """ Report completed square :edge: - edge that completed the region :regions: - completed region(s) """ SlTrace.lg("Completed region edge=%s" % (edge), "complete_square") if self.complete_square_call is not None: self.complete_square_call(edge, regions) def set_down_click_call(self, down_click_call): """ Direct down_click processing """ self.down_click_call = down_click_call def is_square_complete(self, edge, squares=None, ifadd=False): """ Determine if this edge completes a square(s) :edge: - potential completing edge :squares: list, to which any completed squares(regions) are added Default: no regions are added :returns: True iff one or more squares are completed """ return self.area.is_square_complete(edge, squares=squares, ifadd=ifadd) def square_complete_distance(self, edge, squares_distances=None): """ Determine minimum number of moves, including this move to complete a square :edge: - potential completing edge :squares_distances: list, of (distance, square) pairs Default: no entries returned if no connected squares - empty list returned :returns: closest distance, NOT_CLOSE if no squares """ return self.area.square_complete_distance( edge, squares_distances=squares_distances) def new_edge(self, edge): """ Report new edge added :edge: - edge that was added """ SlTrace.lg("SelectSquares.new_edge: edge=%s" % (edge), "new_edge") if self.new_edge_call is not None: self.new_edge_call(edge) self.area.stroke_info.setup() # Reset stroke search def disable_moves(self): """ Disable(ignore) moves by user """ self.area.disable_moves() def enable_moves(self): """ Enable moves by user """ self.area.enable_moves() def down_click(self, part, event=None): """ Process down click over highlighted part All highlighted parts elicit a call :part: highlighted part :event: event if available :Returns: True if processing is complete """ if self.down_click_call is not None: return self.down_click_call(part, event=event) """ Self processing """ if part.is_edge() and not part.is_turned_on(): SlTrace.lg("turning on %s" % part, "turning_on") self.drawn_lines.append(part) part.turn_on(player=self.get_player()) regions = part.get_adjacents() # Look if we completed any squares for square in regions: if square.is_complete(): self.complete_square(part, square) return True # Indicate processing is done return False def get_player(self): """ Get current player """ if self.player_control is None: return None return self.player_control.get_player() def player_control(self): """ Setup player control """ if self.player_control is None: self.player_control = PlayerControl(self, display=False) self.player_control.control_display() def stroke_call(self, part=None, x=None, y=None): """ Call back from sel_area.add_stroke_call """ self.down_click(part) def display(self): self.area.display() def destroy(self): if self.area is not None: self.area.destroy() self.area = None if self.canvas is not None: self.canvas.destroy() self.canvas = None def remove_parts(self, parts): """ Remove deleted or changed parts Only clears display, leaving part in place :parts: list of parts to be removed """ for part in parts: d_part = self.area.get_part(id=part.part_id) if d_part is None: raise SelectError("No part(id=%d) found %s" % (part.part_id, part)) continue if d_part.row == 2: pass d_part.display_clear() d_part.set(invisible=True) def insert_parts(self, parts): """ Add new or changed parts Replaces part of same id, redisplaying :parts: list of parts to be env_added """ for part in parts: d_part = self.area.get_part(id=part.part_id) if d_part is None: raise SelectError("insert_parts: No part(id=%d) found %s" % (part.part_id, part)) continue self.set_part(part) def select_clear(self, parts=None): """ Select part(s) :parts: part or list of parts default: all selected """ self.area.select_clear(parts=parts) def select_set(self, parts, keep=False): """ Select part(s) :parts: part(s) to select/deselect """ self.area.select_set(parts, keep=keep) def set_part(self, part): """ Set base part.contents to values of Part :part: part structure with new values """ pt = self.area.parts_by_id[part.part_id] if pt is None: SlTrace.lg("part %s(%d) is not in area - skipped" % (part, part.part_id)) return pt.__dict__ = part.__dict__.copy() def set_stroke_move(self, use_stroke=True): """ Enable/Disable use of stroke moves Generally for use in touch screens """ self.area.set_stroke_move(use_stroke)
def create_robots(self, read_first=True): if read_first: self.read_robots() if not self.sections: return [] robo_list = [] for robot_name in self.sections: # scale radius with tile size radius = TILE_SIZE * self.cast_with_fallback( robot_name, 'radius', float, Validators.validate_radius) position = self.assemble_position(robot_name) # If the spawn position is invalid, don't create the robot. if not position or self.spawn_position_invalid(radius, position): continue # validate body parameters a_max = self.cast_with_fallback( robot_name, 'a_max', float, Validators.validate_gr_eq_zero) a_alpha_max = self.cast_with_fallback( robot_name, 'a_alpha_max', float, Validators.validate_gr_eq_zero) v_max = self.cast_with_fallback( robot_name, 'v_max', float, Validators.validate_gr_eq_zero) v_alpha_max = self.cast_with_fallback( robot_name, 'v_alpha_max', float, Validators.validate_gr_eq_zero) fov_angle = self.cast_with_fallback( robot_name, 'fov_angle', float, Validators.validate_fov_angle) max_life = self.cast_with_fallback( robot_name, 'max_life', int, Validators.validate_greater_zero) respawn_timer = self.cast_with_fallback( robot_name, 'respawn_timer', float, Validators.validate_gr_eq_zero) immunity_timer = self.cast_with_fallback( robot_name, 'immunity_timer', float, Validators.validate_gr_eq_zero) auto_resync = self.cast_with_fallback( robot_name, 'auto_resync', ini_bool, Validators.cast_only) # validate additional position parameter alpha = self.cast_with_fallback( robot_name, 'alpha', lambda s: float(s) % 360, Validators.cast_only) # validate gun parameters gun_exists = self.cast_with_fallback( robot_name, 'gun', ini_bool, Validators.cast_only) gun_bullet_speed = self.cast_with_fallback( robot_name, 'gun_bullet_speed', float, Validators.validate_greater_zero) gun_reload_speed = self.cast_with_fallback( robot_name, 'gun_reload_speed', float, Validators.validate_gr_eq_zero) gun_options = self.assemble_gun_options(robot_name) # validate player control parameters player_control_exists = self.cast_with_fallback( robot_name, 'player_control', ini_bool, Validators.cast_only) invasive_controls = self.cast_with_fallback( robot_name, 'invasive_controls', ini_bool, Validators.cast_only) invasive_controls_turn_rate = self.cast_with_fallback( robot_name, 'invasive_controls_turn_rate', float, Validators.validate_gr_eq_zero) # key bindings keys_string = self.cast_with_fallback( robot_name, 'keys', lambda x: x, Validators.validate_keys) keys = getattr(ControlScheme, keys_string) # Finally create the robot: # ------------------------- # first create the robot's body base_robot = BaseRobot(radius, a_max, a_alpha_max, v_max, v_alpha_max, fov_angle, max_life, respawn_timer, immunity_timer) # then create the AI controller robot_control = RobotControl(base_robot) # with this, create the data representation data_robot = DataRobot(base_robot, robot_control) # create and add the defined gun object gun_object = RoboGun(gun_bullet_speed, gun_reload_speed) for decorator in gun_options: gun_object = decorator(gun_object) if gun_exists: data_robot.setup_gun(gun_object) # create and add the defined player control instance player_control_inst = PlayerControl(data_robot, keys, invasive_controls, invasive_controls_turn_rate) if player_control_exists: data_robot.setup_player_control(player_control_inst) # place the robot at the right position pos = (position[0], position[1], alpha, 0, 0) data_robot.place_robot(*pos) # add the robot to the list robo_list.append(data_robot) self.robo_name_space.append(robot_name) # after all robots are created, we can validate and add the movements for robot_name, robot in zip(self.robo_name_space, robo_list): robo_movement = self.assemble_movement(robot_name) robot.setup_movement(robo_movement) # now set the alert flags self.set_alert_flags(robo_list) return robo_list