Exemple #1
0
    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
Exemple #3
0
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