class Core(Process): """Run visuals and show them in Overview and Master windows""" def __init__(self): Process.__init__(self) visuals = Visuals() self.graphic = Graphic(visuals) self.threads = [ Loader(visuals), Osc(visuals) ] self._stop = False def run(self): print 'starting pineal.core' for th in self.threads: th.start() try: while not self._stop: self.graphic.update() except KeyboardInterrupt: None self.threads.reverse() for th in self.threads: th.stop() def stop(self): print 'stopping pineal.core' self._stop = True
def show_kinds(self): #원하는 컴퓨터의 종류를 입력받고 그 종류의 기본성능들을 COMPUTER로 넘긴다. self.show_menu() #메뉴를 보여주자 global order_num order_num = int(input("원하시는 종류를 선택하세요. >> ")) if order_num == 0: #문서용 컴퓨터를 원할 때 Document.basic(self) #Document에 있는 기본성능 출력하는 함수basic 불러오기 Computer.price = Document.price #Computer클래스에 있는 price 변수에 Doument에 들어있는 기본 가격 넣어주기 Computer.CPU = Document.CPU #Computer클래스에 있는 CPU 변수에 Doument에 들어있는 기본 CPU값 넣어주기 Computer.GPU = Document.GPU #Computer클래스에 있는 GPU 변수에 Doument에 들어있는 기본 GPU값 넣어주기 Computer.RAM = Document.RAM #Computer클래스에 있는 RAM 변수에 Doument에 들어있는 기본 RAM값 넣어주기 elif order_num == 1: # 게임용 컴퓨터를 원할 때 Game.basic(self) #Game에 있는 기본성능 출력하는 함수basic 불러오기 Computer.price = Game.price #Computer클래스에 있는 price 변수에 Game에 들어있는 기본 가격 넣어주기 Computer.CPU = Game.CPU #Computer클래스에 있는 CPU 변수에 Game에 들어있는 기본 CPU값 넣어주기 Computer.GPU = Game.GPU #Computer클래스에 있는 GPU 변수에 Game에 들어있는 기본 GPU값 넣어주기 Computer.RAM = Game.RAM #Computer클래스에 있는 RAM 변수에 Game에 들어있는 기본 RAM값 넣어주기 elif order_num == 2: #그래픽작업용 컴퓨터를 원할 때 Graphic.basic(self) #Graphic에 있는 기본성능 출력하는 함수basic 불러오기 Computer.price = Graphic.price #Computer클래스에 있는 price 변수에 Graphic에 들어있는 기본 가격 넣어주기 Computer.CPU = Graphic.CPU #Computer클래스에 있는 CPU 변수에 Graphic에 들어있는 기본 CPU값 넣어주기 Computer.GPU = Graphic.GPU #Computer클래스에 있는 GPU 변수에 Graphic에 들어있는 기본 GPU값 넣어주기 Computer.RAM = Graphic.RAM #Computer클래스에 있는 RAM 변수에 Graphic에 들어있는 기본 RAM값 넣어주기 else: #0,1,2가 아닌 다른 것을 입력했을 때 다시 입력받자. print("잘못된 입력입니다.") self.show_kinds() #함수 재실행 self.budget( Computer.price) #예산을 입력받는 함수인 budget에 위에서 넘겨받은 기본 가격을 넘겨준다.
def update_cardinals(self): aux = flatten(tuple(element.corners() for element in self.elements)) self.cardinals = get_cardinals(aux) for key in self.cardinals.keys(): self.cardinals[key] = translate(self.cardinals[key], scale(-1, self.anchor)) self.change_anchor_to(self.nw()) Graphic.update_cardinals(self)
def set_graphic(self,svg): """Sets the SVG graphic that is used in the plot. Returns None.""" self.graphic = Graphic(svg,plot=self) if self.graphic.get_height() > self.get_available_height(): self.graphic = None raise SizeError("The height (%s) of this graphic is too large to fit on the material (%s)." %(self.graphic.get_height(),self.get_available_height())) elif self.graphic.get_width() > self.get_available_width(): self.graphic = None raise SizeError("The width (%s) of this graphic is too large to fit on the material (%s)." %(self.graphic.get_width(),self.get_available_width())) self.update()
def start(self): """Iterate over generations and print them.""" if self.console_display: while self.generation_counter <= self.max_gen: self._console_display() self.next_generation() else: graphic = Graphic(self) graphic.main_loop()
def update_epochs(self): if self.elements == []: print("WARNING."), print("Object %s of class '%s' contains no element." % (self.name, self.__class__.__name__)), print("Set epochs to default value.") self.epochs = dict(DEFAULT_EPOCHS) return subelements = get_subelements_by_class(self.elements, [], Graphic) self.epochs['begin time'] = min([element.epochs['begin time'] for element in subelements]) self.epochs['end time'] = max([element.epochs['end time'] for element in subelements]) Graphic.update_epochs(self)
def __init__(self, anchor=ORIGIN, coords=DEFAULT_COORDS, commands=DEFAULT_COMMANDS): self.coords = coords self.cardinals = get_cardinals(self.coords) Graphic.__init__(self, anchor, self.cardinals) self.commands = self.initialize_commands(commands) self.drawing_kit = dict(DEFAULT_DRAWING_KIT) self.decoration = [] self.effects = []
class Panel(): def __init__(self, width, height): self._g = Graphic(width, height) self._components = list() def add_component(self, component): self._components.append(component) def draw(self): self._g.clear() for component in self._components: component.draw(self._g) self._g.draw()
class Enemy(Object): def __init__(self, game, position, size, armour=100, health=100, graphic=False): super().__init__(game, position, size, graphic) self.armour = armour self.health = health self.weapon = 5 self.alive = True self.choices = [self.attack, self.defend] self.weights = [0.9, 0.1] self.defending = False self.armour_image = Graphic([self.game.graphics.enemy_armour], [0]) def get_armour(self): if self.defending: armour = self.armour + 20 self.defending = False else: armour = self.armour return armour def act(self): random.choices(self.choices, self.weights, k=1)[0](self.game.player) self.game.turn_counter.turn_advance() def attack(self, player): # hurt player player.damage(self.weapon) def defend(self, player): # increase armour self.defending = True def damage(self, weight): print("Enemy damaged") if self.armour > 0: new_armour = self.get_armour() - weight if self.armour > new_armour: self.armour = new_armour else: self.health -= weight if self.health <= 0: self.alive = False def render(self): super().render() if self.armour > 0: self.armour_image.render(self.game.canvas.surface, self.position)
def __init__(self): pg.init() pg.display.set_caption("TicTacToe") self.WIDTH = 600 self.HEIGHT = self.WIDTH self.screen = pg.display.set_mode((self.WIDTH, self.HEIGHT)) self.board = [[None for i in range(3)] for i in range(3)] Graphic.__init__(self, self.screen, self.board) self.player = 1 # x = 1, o = 0 self.run = True self.result = None self.whoiswho = {} self.begin_screen() self.game()
def new_state(self, state): self.state.set_state(state) if state == State.STATE_GAME_BATTLE: self.player.velocity = [0, 0] self.player.graphic.graphics = [self.graphics.player_idle] self.player.graphic.times = [1] self.player.position = ( ((self.screen_width / self.sprite_width) / 2) * self.sprite_width, self.screen_height - self.sprite_height) self.player.floor += 1 self.turn_counter.enemies = [ Enemy(self, ((self.screen_width / 2) - (self.sprite_width / 2), self.sprite_height), (32, 32), 100, 50, Graphic([self.graphics.enemy_bug_1], [0])) ] for e in self.turn_counter.enemies: self.game_objects[State.STATE_GAME_BATTLE].append(e) if state == State.STATE_GAME_CLIMB: if self.player.floor > 1: self.background.graphic.graphics[ 0] = self.graphics.background_blank else: self.background.graphic.graphics[0] = self.graphics.background self.ladder.__init__(self, int(self.screen_width / self.sprite_width), int(self.screen_height / self.sprite_height), (0, 0)) self.player.set_health(100) self.player.previous_rung = (0, 0) self.player.velocity = (0, 0) self.player.position = ( ((self.screen_width / self.sprite_width) / 2) * self.sprite_width, self.screen_height - self.sprite_height)
def __init__(self, game, position, size, armour=100, health=100, graphic=False): super().__init__(game, position, size, graphic) self.armour = armour self.health = health self.weapon = 5 self.alive = True self.choices = [self.attack, self.defend] self.weights = [0.9, 0.1] self.defending = False self.armour_image = Graphic([self.game.graphics.enemy_armour], [0])
def set_graphic(self, svg): """Sets the SVG graphic that is used in the plot. Returns False.""" self.graphic = Graphic(svg, plot=self) if self.graphic.get_height() > self.get_available_height(): h1, h2 = self.graphic.get_height(), self.get_available_height() self.graphic = None raise Exception( "The height (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." % (h1, h2)) elif self.graphic.get_width() > self.get_available_width(): w1, w2 = self.graphic.get_width(), self.get_available_width() self.graphic = None raise Exception( "The width (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." % (w1, w2)) self.update() return False
def run(self): """ Converts an SVG into HPGL. """ # Set initial HPGL commands hpgl = ['IN', 'SP1'] hpgl.extend(self.commands['send_before']) if self.device['cutting_force'][1]: hpgl.append('FS%d' % self.device['cutting_force'][0]) if self.device['cutting_speed'][1]: hpgl.append('VS%d' % self.device['cutting_speed'][0]) # Read the input SVG into a Graphic to provide easy manipulation. g = Graphic(self.input) g.set_rotation(self.device['axis_rotation']) g.set_scale(self.device['axis_scale'][0] * HPGL_SCALE, self.device['axis_scale'][1] * HPGL_SCALE) g.set_position(self.device['axis_translate'][0], self.device['axis_translate'][1]) # Create the HPGL data paths = g.get_polyline() # Apply device specific settings if self.device['cutting_overlap'][1]: Plugin.apply_cutting_overlap(paths, self.device['cutting_overlap'][0]) if self.device['cutting_blade_offset'][1]: Plugin.apply_cutting_blade_offset( paths, self.device['cutting_blade_offset'][0]) data = [] for path in paths: x, y = path.pop(0)[1] data.append('PU%i,%i' % (round(x), round(y))) cmd = "PD" for line in path: x, y = line[1] cmd += '%i,%i,' % (round(x), round(y)) data.append(cmd[:-1]) hpgl.extend(data) hpgl.extend(self.commands['send_after']) # Not friendly for large files! self.output = ";\n".join(hpgl) + ";"
def __init__(self): Process.__init__(self) visuals = Visuals() self.graphic = Graphic(visuals) self.threads = [ Loader(visuals), Osc(visuals) ] self._stop = False
def main(): setting = Setting() npuzzle = NPuzzle(setting) if setting.graphic and setting.size < 9: Graphic(npuzzle) elif setting.graphic and setting.size >= 9: print("The puzzle size is too big for graphic mode, " "switching to normal mode") npuzzle.report() else: npuzzle.report()
def __init__(self, root): self.root = root self.g = Graphic(self.root) # 落下判定用のメンバ変数を初期化 self.fall_count = 0 self.speed = self.DEFAULT_FALL_SPEED self.speed_backup = self.DEFAULT_FALL_SPEED self.speed_up_count = 0 # ぷよ動作のキーイベントを設定 self.key_events = ( # (key, event) ('Left', self.left_move), ('Right', self.right_move), ('6', self.rolling_right), ('4', self.rolling_left), ) self.start_key = 'Return' # Enterキーでゲームスタート self.restart_key = 'r' # Rキーでりスタート
def main(): config = Config() storage = Storage() graphic = Graphic(config.get("courses")) graphic_cfg = config.get("graphic") all_params = get_graphic_params(graphic_cfg) courses = list() seen_courses = list() for params in all_params: if params[1] == 1: weeks = graphic.weeks(params[0], params[1], params[2]) for week in weeks: new_courses = graphic.courses(week) for new_course in new_courses: check_new_course = new_course['start_date'].strftime("%d%m%Y%H") + '-' + new_course['end_date'].strftime("%d%m%Y%H") + '-' + new_course['course_name'] if check_new_course not in seen_courses: seen_courses.append(check_new_course) courses.append(new_course) else: distance_learning_weeks = graphic.distance_learning_weeks(params[0], params[1], params[2]) for week in distance_learning_weeks: new_courses = graphic.distance_learning_courses(week) for new_course in new_courses['courses']: check_new_course = new_course['start_date'].strftime("%d%m%Y%H") + '-' + new_course['end_date'].strftime("%d%m%Y%H") + '-' + new_course['course_name'] if check_new_course not in seen_courses: seen_courses.append(check_new_course) courses.append(new_course) storage.save(courses) print_actions(storage.get_actions()) print('Calendar sync finished.')
def set_graphic(self,svg): """Sets the SVG graphic that is used in the plot. Returns False.""" self.graphic = Graphic(svg,plot=self) if self.graphic.get_height() > self.get_available_height(): h1, h2 = self.graphic.get_height(),self.get_available_height() self.graphic = None raise Exception("The height (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." %(h1,h2)) elif self.graphic.get_width() > self.get_available_width(): w1, w2 = self.graphic.get_width(),self.get_available_width() self.graphic = None raise Exception("The width (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." %(w1,w2)) self.update() return False
def create_analyze(): text = request.POST.get('text', '').strip() if len(text) == 0: return {'message': 'error, you must provide `text` parameter'} analyze = Analyzer(text) analyzed = analyze.parse_text() graphic_fabric = Graphic(analyzed.letters_occur, analyzed.most_used_words, analyzed.letters_count) graphic_fabric.graph_letter_occurrence() graphic_fabric.graph_words_occurrence() analyzed = analyze.format_before_save() conn = sqlite3.connect('analyzes.db') c = conn.cursor() c.execute("INSERT INTO analyzes (analyzed_text, creation_date, words_occur, letters_count, letters_occur, most_used_words, letter_occur_graph_name, words_occur_graph_name) VALUES(?,?,?,?,?,?,?,?)", (analyzed.text, analyzed.creation_date, analyzed.words_occur, analyzed.letters_count, analyzed.letters_occur, analyzed.most_used_words, graphic_fabric.letter_occur_graph_name, graphic_fabric.words_occur_graph_name)) conn.commit() c.close() return analyzed.to_json()
def main(): g = Graphic() game = Game(g) game.display_instruct() enemy = game.ask_who_is_enemy() player1 = game.get_human_player() player2 = None if enemy == Players.human: player2 = game.get_human_player() elif enemy == Players.comp: player2 = game.get_computer_player() player1.setup_ships() player2.setup_ships() game.begin(player1, player2)
def run(self): """ Converts an SVG into HPGL. """ # Set initial HPGL commands hpgl = ['IN','SP1'] hpgl.extend(self.commands['send_before']) if self.device['cutting_force'][1]: hpgl.append('FS%d'%self.device['cutting_force'][0]) if self.device['cutting_speed'][1]: hpgl.append('VS%d'%self.device['cutting_speed'][0]) # Read the input SVG into a Graphic to provide easy manipulation. g = Graphic(self.input) g.set_rotation(self.device['axis_rotation']) g.set_scale(self.device['axis_scale'][0]*HPGL_SCALE,self.device['axis_scale'][1]*HPGL_SCALE) g.set_position(self.device['axis_translate'][0],self.device['axis_translate'][1]) # Create the HPGL data paths = g.get_polyline() # Apply device specific settings if self.device['cutting_overlap'][1]: Plugin.apply_cutting_overlap(paths,self.device['cutting_overlap'][0]) if self.device['cutting_blade_offset'][1]: Plugin.apply_cutting_blade_offset(paths,self.device['cutting_blade_offset'][0]) data = [] for path in paths: x,y = path.pop(0)[1] data.append('PU%i,%i'%(round(x),round(y))) cmd = "PD" for line in path: x,y = line[1] cmd +='%i,%i,'%(round(x),round(y)) data.append(cmd[:-1]) hpgl.extend(data) hpgl.extend(self.commands['send_after']) # Not friendly for large files! self.output = ";\n".join(hpgl)+";"
def __init__(self, largeur = 600, hauteur = 400): """ Initialisation de pygame. Intialisation de Graphic. hauteur et largeur de la fenêtre attendue en paramètres. """ # initialisation de pygame pygame.display.init() # module graphique pygame.font.init() # module de texte # Création de l'écran self.ecran = pygame.display.set_mode((largeur, hauteur)) # création du graphic, simplifiant les affichages self.graphics = Graphic() # autre attributs self.logs = ["IHM initialisée"] self.joueur = 0 # pas de joueur au départ self.carte = 0 # pas de carte au départ self.termine = False # vrai si jeu terminé
def play_game(self, snake, food, button_direction, score, screen, clock): """Launch the snake game. Parameters ---------- snake : tuple[int] The snake coordinates. food : tuple[int] The food coordinates. button_direction : int The direction the snake will follow. score : int The score value. screen : type The scene. clock : int The speed of the snake. Returns ------- snake: tuple[int] The snake's coordinates. food: tuple[int] The food's coordinates. score: int The updated score value. """ gr = Graphic(scene_width=self.width, scene_height=self.height, info_zone=self.info_zone, block=self.block, bg_color=self.bg, food_color=self.pink, wall_color=self.black, snake_color=self.blue) alive = True while alive: for event in pygame.event.get(): if event.type == pygame.QUIT: alive = False scene = gr.draw_scene(scene=screen, score=score) gr.draw_food(scene=scene, food=food) snake, food, score = self.move( snake, food, button_direction, score) scene = gr.draw_snake(scene=scene, snake=snake) pygame.display.update() pygame.time.Clock().tick(clock) return snake, food, score
def main(type='console', path='results/all_print.txt'): if type != 'console': orig_stdout = sys.stdout f = open(path, 'w') sys.stdout = f stat = Statistic() stat.load_data("data.txt") # print(stat.get_data()) gr = Graphic() gr.build_hist_and_emp(stat.get_data()) print( "Гистограмма и график эмпирической функции распределения построены.\n") print("Среднее значение выборки: %.3f" % (stat.find_average_sample_value())) print("Выборочная дисперсия: %.3f" % (stat.find_selective_dispersion())) print("Стандартная ошибка: %.3f" % (stat.find_standard_error())) print("Мода: ", stat.find_mode()) print("Медиана: ", stat.find_median()) print("Квартили: ", (stat.find_quartiles())) q1, q2, q3 = stat.find_quartiles() gr.build_box_plot(stat.get_data(), q1, q2, q3, stat.find_min(), stat.find_max()) print("Ящик с усами построен. ") print("Стандартное отклонени: %.3f" % (stat.find_standard_deviation())) print("Эксцесс: %.3f" % (stat.find_kurtosis())) print("Асимметричность: %.3f (%s)" % (stat.find_skewness())) print("Минимум: ", (stat.find_min())) print("Максимум: ", (stat.find_max())) print("\nПроверка гипотезы H_0:") stat.pearson_criterion() print("\nДоверительный интервал матожидания: (%.3f; %.3f)" % (stat.expected_value_interval())) print("\nДоверительный интервал среднеквадратичного " "отклонения: (%.3f; %.3f)" % (stat.standard_deviation_interval())) if type != 'console': sys.stdout = orig_stdout f.close()
def update(self): """ Builds the plot from the graphic. Uses all the current properties. Raises exceptions if it cannot create the plot given the current values. This needs done whenever a property of self.graphic is changed. """ # Check that there is enough room to fit all the copies. copies_left = self.get_copies() fit_x, fit_y = [self.get_stack_size_x(), self.get_stack_size_y()] rotate = False if fit_x * fit_y < copies_left: if self.get_auto_rotate(): fit_x, fit_y = [ self.get_stack_size_x(rotate=True), self.get_stack_size_y(rotate=True) ] if fit_x * fit_y < copies_left: raise Exception( "%s graphics are to be made but only %s will fit on the current material. Please adjust settings and try again." % (copies_left, fit_x * fit_y)) else: rotate = True # This should only be set if the only way for it to fit is to rotate! # ==================== Generate the list of graphic positions, note that these are absolute.================================ # positions, not relative to the plot padding like plot.set_position(). x, y = self.get_position(absolute=True) if self.get_weedline_status( ): # If plot weedlines are enabled, we have to shift the graphics so the weedline fits. x += self.get_weedline_padding() y += self.get_weedline_padding() if rotate: self.graphic.set_rotation(90) # 90 should be a variable! dx, dy = self.graphic.get_width() + self.get_spacing( )[0], self.graphic.get_height() + self.get_spacing()[1] positions = [] if self.get_rotation() == 90: # Stack in positive x direction. while copies_left >= fit_y: for i in range(0, fit_y): # Fill a vertical stack. positions.append([x, i * dy + y]) # Add a new stack. x += dx copies_left -= fit_y # Fill leftover copies. for i in range(0, copies_left): positions.append([x, i * dy + y]) else: # Stack in positive y direction. while copies_left >= fit_x: for i in range(0, fit_x): # Fill a horizontal stack. positions.append([i * dx + x, y]) # Add a new stack. y += dy copies_left -= fit_x # Fill leftover copies. for i in range(0, copies_left): positions.append([i * dx + x, y]) # ==================== Create the plot from the given graphic positions ================================ len_data = len(self._data) - (self.get_weedline_status() and 1 or 0) if self.graphic.get_changed_flag() or len( self._data) == 0 or len_data != len( positions): # Only make new copies if the graphic changed self._data = [] # Bugfix self.graphic._plot = None for pos in positions: x, y = pos g = deepcopy(self.graphic) g.set_position(x, y) self._data.append(g) self.graphic._plot = self else: # Just reposition the current data. This should skip the weedline if it's enabled. for pos, g in zip(positions, self._data): x, y = pos g.set_position(x, y) if len( self._data ) == self.get_copies() + 1: # weedlines were previously enabled! self._data.pop() if self.get_weedline_status(): # add it to the data minx, maxx, miny, maxy = self.get_bounding_box() p = self.get_weedline_padding() d = "M%f,%f V%f H%f V%f Z" % (minx - p, miny - p, maxy + p, maxx + p, miny - p) svg = etree.fromstring(SVG) path = etree.Element('path') path.set('d', d) svg.append(path) g = Graphic(etree.tostring(svg)) self._data.append(g)
class Plot: """ A class representing a Plot. Includes methods for creating multiple copies of a graphic and positioning them on the plot. Has plot wide path manipulation methods such as scaling, mirroring, rotating, and translating. Has the ability to create weedlines. Raises exceptions if the graphic or number of copies is too large for the material area. """ def __init__(self, width, height=None, color='#FFFFFF'): """ Creates the base plot properties and defines the plot material. """ self.graphic = None self._data = [] self._properties = { 'copies': 1, 'position': (0, 0), # This relative position to get_start_position() 'spacing': (9, 9), 'padding': (35, 0, 35, 0), 'weedline': False, 'weedline_padding': 0, 'axis_mirror_x': False, 'axis_mirror_y': False, 'axis_rotation': 0, 'axis_scale': 1, 'align_center_x': False, 'align_center_y': False, 'auto_rotate': False, 'finish_position': (0, 0), # Not implemented, used by higher level } self.set_material(width, height, color) # ================================ Export ================================ def get_properties(self): """ Returns the properties used to build the plot. """ return self._properties def get_data(self): """ Returns the data as a list of etree Elements. """ elements = [] for g in self._data: elements.append(g.get_data()) return elements def get_xml(self): """Returns the data as an SVG string.""" svg = etree.fromstring(SVG) layer = etree.Element('g') layer.set('id', unicode("plot.%s" % id(self))) layer.set('{http://www.inkscape.org/namespaces/inkscape}label', 'Plot') layer.set('{http://www.inkscape.org/namespaces/inkscape}groupmode', 'layer') layer.extend(self.get_data()) svg.append(layer) return etree.tostring(svg, pretty_print=True, xml_declaration=True, encoding="UTF-8", standalone=False) def get_preview_xml(self): """ Creates a visual representation of the svg as it would look if it were plotted on the material. """ svg = etree.fromstring(SVG) svg.set( 'width', unicode( self.get_material_width(limited=self.get_rotation() == 90) + 20)) svg.set( 'height', unicode( self.get_material_height(limited=self.get_rotation() == 0) + 20)) layer = etree.Element('g') layer.set('id', 'material') layer.set('{http://www.inkscape.org/namespaces/inkscape}label', 'Material') layer.set('{http://www.inkscape.org/namespaces/inkscape}groupmode', 'layer') layer.set('transform', 'translate(%f,%f)' % (10, 10)) layer.set('x', '0') layer.set('y', '0') layer.set( 'width', str(self.get_material_width(limited=self.get_rotation() == 90))) layer.set( 'height', str(self.get_material_height(limited=self.get_rotation() == 0))) vinyl = etree.Element('rect') vinyl.set('x', '0') vinyl.set('y', '0') vinyl.set( 'width', unicode( self.get_material_width(limited=self.get_rotation() == 90))) vinyl.set( 'height', unicode( self.get_material_height(limited=self.get_rotation() == 0))) vinyl.set('style', "fill:%s;" % self.get_material_color()) shadow = deepcopy(vinyl) shadow.set('y', '8') shadow.set('style', "fill:#000000;filter:url(#filter1);") layer.append(shadow) layer.append(vinyl) layer.extend(self.get_data()) svg.append(layer) return etree.tostring(svg, pretty_print=True, xml_declaration=True, encoding="UTF-8", standalone=False) # ================================ Properties ================================ def get_material_width(self, limited=False): """ Returns the plot x-size boundary or simulated material width as a float. If limited is set to True, this will return the total plot length, which is useful for eliminated lots of empty space on a preview. """ if limited: return self.get_bounding_box()[1] + self.get_padding()[ 1] # maxx + right padding else: return self._material['width'] def get_material_height(self, limited=False): """ Returns the plot y-size boundary or simulated material height as a float. If limited is set to True, this will return the total plot length, which is useful for eliminated lots of empty space on a preview. """ if limited: return self.get_bounding_box()[3] + self.get_padding()[ 2] # maxy + bottom padding else: return self._material['height'] def get_material_color(self): """ Returns the material color as a string. """ return self._material['color'] def _get_available_bounding_box(self): """ Returns the plottable bounding box of the material, or corner points of the area to be plotted on as a list in the format [minx,maxx,miny,maxy]. """ width, height = self.get_material_width(), self.get_material_height() top, right, bottom, left = self.get_padding() return [left, width - right, bottom, height - top] def get_available_width(self): """ Returns the plottable width (x-dimension) of the material. """ bbox = self._get_available_bounding_box() return bbox[1] - bbox[0] def get_available_height(self): """ Returns the plottable height (y-dimension) of the material. """ bbox = self._get_available_bounding_box() return bbox[3] - bbox[2] def get_start_position(self): """ Convience method. Returns the starting point of the plottable area as a list in the form [minx,miny]. """ bbox = self._get_available_bounding_box() return [bbox[0], bbox[2]] def get_position(self, absolute=False): """ Convience method. Returns the point upper left most point of the plot relative to get_start_position() as a list in the form [minx,miny]. If absoulte is true, this returns the absolute position in the same form. This includes the plot weedline position. """ pos = [0, 0] out = self._properties['position'] if absolute: pos = self.get_start_position() return (out[0] + pos[0], out[1] + pos[1]) def get_bounding_box(self): """ Returns the bounding box, or corner points of the plot as a list in the format [minx,maxx,miny,maxy]. This should always be within the available_bounding_box()! """ if len(self._data) < 1: raise IndexError("No graphic data has been found.") else: bbox = self._data[0].get_bounding_box() for g in self._data: bbox = simpletransform.boxunion(g.get_bounding_box(), bbox) minx, maxx, miny, maxy = self._get_available_bounding_box() #assert (bbox[0] >= minx) and (bbox[1] <= maxx) and (bbox[2] >= miny) and (bbox[3] <= maxy), "The plot bounding box %s should always be within the available bounding box %s!" % (bbox, self._get_available_bounding_box()) return bbox def get_height(self): """Returns the height (y-size) of the entire plot. """ bbox = self.get_bounding_box() return bbox[3] - bbox[2] def get_width(self): """Returns the width (x-size) of the entire plot. """ bbox = self.get_bounding_box() return bbox[1] - bbox[0] def get_padding(self): """Returns the padding set on the outside of the plot as a list [top,right,bottom,left].""" return self._properties['padding'] def get_spacing(self): """Returns the spacing to be used between copies as a list [col_x,row_y]. """ return self._properties['spacing'] def get_stack_size_x(self, rotated=False): """ Returns the number of graphics that fit within the get_available_width() as an int. If rotated=True, it returns the stack size if the graphic was rotated 90 degrees. """ assert self.graphic, "A graphic must be set on this plot first!" needed = self.graphic.get_width() + self.get_spacing()[0] if rotated: needed = self.graphic.get_height() + self.get_spacing()[0] # The last spacing we don't need, adding spacing takes care of that. available = self.get_available_width() + self.get_spacing( )[0] - self.get_position()[0] if self.get_weedline_status( ): # allocate space for weedline padding if enabled available -= 2 * self.get_weedline_padding() return int(math.floor(available / needed)) def get_stack_size_y(self, rotated=False): """ Returns the number of graphics that fit within the get_available_height() as an int. If rotated=True, it returns the stack size if the graphic was rotated 90 degrees. """ assert self.graphic, "A graphic must be set on this plot first!" needed = self.graphic.get_height() + self.get_spacing()[1] if rotated: needed = self.graphic.get_width() + self.get_spacing()[1] # The last spacing we don't need, adding spacing takes care of that. available = self.get_available_height() + self.get_spacing( )[1] - self.get_position()[1] if self.get_weedline_status( ): # allocate space for weedline padding if enabled available -= 2 * self.get_weedline_padding() return int(math.floor(float(available) / needed)) def get_rotation(self): """ Returns the degrees the plot has been rotated relative to the original. Designed for devices that use a rotated axis relative to the SVG spec. """ return self._properties['axis_rotation'] def get_copies(self): """ Returns the number of graphic copies to be created. """ return self._properties['copies'] def get_auto_rotate(self): """ Returns true if auto_rotate is enabled. """ return self._properties['auto_rotate'] def get_weedline_status(self): """ Returns true if a weedline is drawn around the plot.""" return self._properties['weedline'] def get_weedline_padding(self): """ Returns the weedline padding around the plot as a float.""" return self._properties['weedline_padding'] # ================================ Manipulation ================================ def set_graphic(self, svg): """Sets the SVG graphic that is used in the plot. Returns False.""" self.graphic = Graphic(svg, plot=self) if self.graphic.get_height() > self.get_available_height(): h1, h2 = self.graphic.get_height(), self.get_available_height() self.graphic = None raise Exception( "The height (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." % (h1, h2)) elif self.graphic.get_width() > self.get_available_width(): w1, w2 = self.graphic.get_width(), self.get_available_width() self.graphic = None raise Exception( "The width (%s) of this graphic is too large to fit on the material (%s). \n Please resize the graphic or choose a new material." % (w1, w2)) self.update() return False def set_position(self, x, y): """ Sets where the top left corner of the plot is positioned relative to get_start_position(). Disables set_align_center_x() and set_align_center_y(). Returns False. """ assert type(x) in [int, float] and type(y) in [ int, float ], "x and y must be an int or a float" assert x >= 0 and y >= 0, "x and y must be 0 or more." log.debug("set_position(%s,%s)" % (x, y)) pos = self.get_position() # update the properties if pos[0] != x: self._properties['align_center_x'] = False if pos[1] != y: self._properties['align_center_y'] = False if x != pos[0] or y != pos[1]: if self.graphic: if x+self.get_width() > self.get_available_width() or\ y+self.get_height() > self.get_available_height(): raise Exception( "This will position the plot off of the material! \n Please resize the graphic or choose a new material." ) else: self._properties['position'] = (x, y) self.update() # check to make sure it was set right for debugging purposes #pos = self.get_start_position() #bbox = self.get_bounding_box() #assert (round(bbox[0]-pos[0],10),round(bbox[2]-pos[1],10)) == (round(x,10),round(y,10)),"The position (%s,%s) was set incorrectly to (%s,%s)! \n If the problem persists, please contact the developer."%(round(x,10),round(y,10),round(bbox[0]-pos[0],10),round(bbox[2]-pos[1],10)) else: # no graphic set the property so it's there for first time use self._properties['position'] = (x, y) return False def set_align_center_x(self, enabled): """ If enabled, the plot is positioned to be centered horizontally in the get_available_width(). If disabled, resets to x to 0. Returns False. """ assert self.graphic, "A graphic must be set on this plot first!" assert type(enabled) == bool, "enable must be a bool" log.debug("set_align_center_x(%s)" % enabled) x, y = self.get_position() if enabled: extra_space = self.get_available_width() - self.get_width() self.set_position(float(extra_space) / 2, y) self._properties['align_center_x'] = True else: self.set_position(0, y) self._properties['align_center_x'] = False return False def set_align_center_y(self, enabled): """ If enabled, the plot is positioned to be centered vertically in the get_available_height(). If disabled, resets to y to 0. Returns False. """ assert self.graphic, "A graphic must be set on this plot first!" assert type(enabled) == bool, "enabled must be a bool." log.debug("set_align_center_y(%s)" % enabled) x, y = self.get_position() if enabled: extra_space = self.get_available_height() - self.get_height() self.set_position(x, float(extra_space) / 2) self._properties['align_center_y'] = True else: self.set_position(x, 0) self._properties['align_center_y'] = False return False def set_padding(self, top=None, right=None, bottom=None, left=None): """ Sets the padding or distance between the materials bounding box and the plottable bounding box _get_available_bounding_box(). Similar to padding in the css box structure or printing margins. Returns False. """ log.debug("set_padding(%s,%s,%s,%s)" % (top, right, bottom, left)) updated = [top, right, bottom, left] pad = self.get_padding() for i in range(0, len(updated)): assert type(updated[i]) in [ type(None), int, float ], "%s must be of type int or float. Given %s" % (it, type(it)) if type(updated[i]) == type(None): updated[i] = pad[i] if pad != updated: for it in updated: assert it >= 0, "padding must be at least 0." top, right, bottom, left = updated if top + bottom >= self.get_material_height(): raise ValueError if left + right >= self.get_material_width(): raise ValueError self._properties['padding'] = updated if self.graphic: self.update() return False def set_copies(self, n): """ Makes n copies of a path and spaces them out on the plot. Raises a SizeError exception if n copies will not fit on the material with the current settings. Returns False. """ assert type(n) == int, "n must be an integer value." assert n > 0, "n must be 1 or more." log.debug("set_copies(%s)" % n) if self.get_copies() != n: self._properties['copies'] = n if self.graphic: self.update() return False def set_spacing(self, x=None, y=None): """ Sets the spacing between columns (x) and rows (y). Returns False.""" spacing = self.get_spacing() if x is None: x = spacing[0] if y is None: y = spacing[1] assert type(x) in [int, float], "x spacing must be an int or float." assert type(y) in [int, float], "y spacing must be an int or float." log.debug("set_spacing(%s,%s)" % (x, y)) if x != spacing[0] or y != spacing[1]: self._properties['spacing'] = (x, y) self.update() # error checking in update! return False def set_weedline(self, enabled): """If enabled, a box is drawn around the entire plot. Returns False. """ assert type(enabled) == bool, "enabled must be a bool" log.debug("set_weedline(%s)" % (enabled)) if enabled != self.get_weedline_status(): # a change needs made: self._properties['weedline'] = enabled if self.graphic: self.update() return False def set_weedline_padding(self, padding): """ Sets the padding between the weedline and plot. If the plot originally had a weedline the padding will be added immediately, otherwise it will be added the next time it is enabled. Returns False. """ assert type(padding) in [int, float], "padding must be an int or float" assert padding >= 0, "padding must be 0 or more" log.debug("set_weedline_padding(%s)" % (padding)) if padding != self.get_weedline_padding(): self._properties['weedline_padding'] = padding if self.graphic: self.update() return False def set_rotation(self, degrees): """ Set's the axis rotation of the material. If rotation = 90, the materials width and height will be swapped. This does not rotate the graphics or swap any padding/spacings. Returns False. """ assert int(degrees) in [ 0, 90 ], "The axis can only be rotated 0 or 90 degrees." log.debug("set_rotation(%s)" % (degrees)) if degrees != self._properties['axis_rotation']: w = self.get_material_width() h = self.get_material_height() self._material['width'] = h # Swap them self._material['height'] = w self._properties['axis_rotation'] = degrees if self.graphic: self.update() return False def set_auto_rotate(self, enabled): """If enabled, graphics will be automatically rotated to save material. """ assert type(enabled) == bool, "enabled must be a bool." log.debug("set_auto_rotate(%s)" % enabled) if enabled != self._properties['auto_rotate']: self._properties['auto_rotate'] == enabled if self.graphic: self.update() return False def set_cutting_order(self, mode=None): """ """ assert mode in [ None, 'One copy at a time', 'Best tracking', 'Shortest Path' ] return False def set_material(self, width, height=None, color="#FFFFFF"): """ Set the width, length, and color of the plot. """ assert type(width) in [ int, float ], "Material width must be an int or float, given %s." % type(width) assert type(height) in [ type(None), int, float ], "If the material has a limited height (length), it must be an int or float, otherwise set it to None. Given %s" % type( length) assert type(color) in [ str, unicode ], "The material color must be a css style color (eg. #FFFFFF or \"white\"). Given %s." % type( color) assert width > 0, "Material width must be greater than 0, given %s." % width if height: assert height > 0, "Material height (length) must be greater than 0, given %s." % height else: height = 354330 # I'm just going to assume nobody will cut anything over 100 meters long!. self._material = {"width": width, "height": height, "color": color} if self.graphic: self.update() return False # ================================ Processing ================================ def update(self): """ Builds the plot from the graphic. Uses all the current properties. Raises exceptions if it cannot create the plot given the current values. This needs done whenever a property of self.graphic is changed. """ # Check that there is enough room to fit all the copies. copies_left = self.get_copies() fit_x, fit_y = [self.get_stack_size_x(), self.get_stack_size_y()] rotate = False if fit_x * fit_y < copies_left: if self.get_auto_rotate(): fit_x, fit_y = [ self.get_stack_size_x(rotate=True), self.get_stack_size_y(rotate=True) ] if fit_x * fit_y < copies_left: raise Exception( "%s graphics are to be made but only %s will fit on the current material. Please adjust settings and try again." % (copies_left, fit_x * fit_y)) else: rotate = True # This should only be set if the only way for it to fit is to rotate! # ==================== Generate the list of graphic positions, note that these are absolute.================================ # positions, not relative to the plot padding like plot.set_position(). x, y = self.get_position(absolute=True) if self.get_weedline_status( ): # If plot weedlines are enabled, we have to shift the graphics so the weedline fits. x += self.get_weedline_padding() y += self.get_weedline_padding() if rotate: self.graphic.set_rotation(90) # 90 should be a variable! dx, dy = self.graphic.get_width() + self.get_spacing( )[0], self.graphic.get_height() + self.get_spacing()[1] positions = [] if self.get_rotation() == 90: # Stack in positive x direction. while copies_left >= fit_y: for i in range(0, fit_y): # Fill a vertical stack. positions.append([x, i * dy + y]) # Add a new stack. x += dx copies_left -= fit_y # Fill leftover copies. for i in range(0, copies_left): positions.append([x, i * dy + y]) else: # Stack in positive y direction. while copies_left >= fit_x: for i in range(0, fit_x): # Fill a horizontal stack. positions.append([i * dx + x, y]) # Add a new stack. y += dy copies_left -= fit_x # Fill leftover copies. for i in range(0, copies_left): positions.append([i * dx + x, y]) # ==================== Create the plot from the given graphic positions ================================ len_data = len(self._data) - (self.get_weedline_status() and 1 or 0) if self.graphic.get_changed_flag() or len( self._data) == 0 or len_data != len( positions): # Only make new copies if the graphic changed self._data = [] # Bugfix self.graphic._plot = None for pos in positions: x, y = pos g = deepcopy(self.graphic) g.set_position(x, y) self._data.append(g) self.graphic._plot = self else: # Just reposition the current data. This should skip the weedline if it's enabled. for pos, g in zip(positions, self._data): x, y = pos g.set_position(x, y) if len( self._data ) == self.get_copies() + 1: # weedlines were previously enabled! self._data.pop() if self.get_weedline_status(): # add it to the data minx, maxx, miny, maxy = self.get_bounding_box() p = self.get_weedline_padding() d = "M%f,%f V%f H%f V%f Z" % (minx - p, miny - p, maxy + p, maxx + p, miny - p) svg = etree.fromstring(SVG) path = etree.Element('path') path.set('d', d) svg.append(path) g = Graphic(etree.tostring(svg)) self._data.append(g)
class IHM(): """ # DOC IHM Ce document retrace les méthodes d'accès de l'IHM. Intérêt : savoir comment faire pour interagir, et permettre au developpeur d'avoir les idées claires (ce qui est très important à trois heures du mat') ## principe l'IHM fonctionne selon un principe simple : Elle fait ce que vous lui demandez. D'abord, créez là, ça paraît logique. Ensuite, appelez menuDemarrage(), histoire de savoir quel personnage veux le joueur. Elle vous renverras ce que le joueur veut pour personnage, sous la forme d'un tuple : ('nom', carSec, carIhm, carKernel, carHard) Ensuite, appelez initialiserJeu(), avec le joueur et la carte en arguments. L'IHM se souviendra alors de ces références qu'elle gardera pour afficher le jeu avec les données toujours actualisées. Enfin, dites lui ce que vous voulez : vous pouvez lui faire afficher le jeu, lui faire afficher une boite de dialog pour savoir si le joueur veut l'objet que vous lui envoyez en argument,... L'IHM vous renverra des actions correspondant à la volonté de l'utilisateur. A FAIRE: tester utilisateurQuitte() le plus souvent possible, car il renvois vrai quand l'utilisateur veut quitter. Il faudra alors tout arrêter. **Méthodes d'accès :** - __init__(): créé l'IHM. Charge les ressource et pygame. - menuDemarrage(): retourne un dico contenant les données permettant d'initialiser un joueur; - initialiserJeu(joueur, carte): prend les ref vers la carte et le joueur; - afficherJeu(): affiche le jeu selon les valeurs connues - mouvement(): demande un mouvement à l'utilisateur, renvois 'haut', 'bas', 'gauche' ou 'droite'. - dialogObjet(): attends un objet, retourne vrai si l'utilisateur veux s'en équiper - dialogCombat(): attends un combat, retourne l'action du joueur dans ce combat, (combattre ou fuire, dans un premier temps) - finCombat(): attends le combat, considéré terminé. Affiche un écran de fin de combat, et se termine sans rien renvoyer quand l'utilisateur quitte l'écran de fin de combat. - gameOver(): affiche l'écran de fin de jeu, s'arrête quand l'utilisateur quitte l'écran de fin de jeu, en ne renvoyant rien. - logs(logs): attent une liste de chaînes. Chaque chaîne sera ajoutée à la liste de logs de l'IHM. - utilisateurQuitte(): retourne vrai si l'utilisateur veut quitter le joueur et la carte sont les mêmes que ceux manipulés par le jeu. Donc, pas besoin de les actualiser. L'IHM ne modifie jamais les valeurs envoyées, la carte ou le joueur. """ def __init__(self, largeur = 600, hauteur = 400): """ Initialisation de pygame. Intialisation de Graphic. hauteur et largeur de la fenêtre attendue en paramètres. """ # initialisation de pygame pygame.display.init() # module graphique pygame.font.init() # module de texte # Création de l'écran self.ecran = pygame.display.set_mode((largeur, hauteur)) # création du graphic, simplifiant les affichages self.graphics = Graphic() # autre attributs self.logs = ["IHM initialisée"] self.joueur = 0 # pas de joueur au départ self.carte = 0 # pas de carte au départ self.termine = False # vrai si jeu terminé def menuDemarrage(self): """ Gère un menu où l'utilisateur peut entrer : - nom - caracs Renvois un dico indiquant ces données. (le jeu pourra alors créer un joueur ayant ces carac et ce nom) format du dico : {'carSec':int, 'carIhm':int, 'carKer':int, 'carHar':int} """ # event termine = False carSec = 10 carIhm = 10 carKer = 10 carHar = 10 selection = 1 reservePoint = 6 while not termine: # AFFICHAGES self.graphics.afficherMenu(self.ecran, selection, carSec, carIhm, carKer, carHar) # ÉVÈNEMENTS for event in pygame.event.get(): time.sleep(0.1) if event.type == pygame.QUIT: termine = True self.termine = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: termine = True self.termine = True elif event.key == pygame.K_UP: selection -= 1 # si on est arrivés en bout de menu, on va en bas if selection == 0: selection = 5 elif event.key == pygame.K_DOWN: selection += 1 # si on est arrivés en bout de menu, on va en haut if selection == 6: selection = 1 elif event.key == pygame.K_RIGHT: if selection == 1 and reservePoint > 0: carSec += 1 reservePoint -= 1 elif selection == 2 and reservePoint > 0: carIhm += 1 reservePoint -= 1 elif selection == 3 and reservePoint > 0: carKer += 1 reservePoint -= 1 elif selection == 4 and reservePoint > 0: carHar += 1 reservePoint -= 1 elif selection == 5: termine = True elif event.key == pygame.K_LEFT: if selection == 1 and reservePoint <= 6: carSec -= 1 reservePoint += 1 elif selection == 2 and reservePoint <= 6: carIhm -= 1 reservePoint += 1 elif selection == 3 and reservePoint <= 6: carKer -= 1 reservePoint += 1 elif selection == 4 and reservePoint <= 6: carHar -= 1 reservePoint += 1 elif event.key == pygame.K_RETURN and selection == 5: termine = True # retour return {'secu':carSec,'ihm':carIhm,'kernel':carKer,'hardware':carHar} def initialiserJeu(self, joueur, carte): """ Prend les ref vers la carte et le joueur. Oui, c'est tout. Mais si vous oubliez de l'appeler, l'IHM va merder sec. """ self.joueur = joueur self.carte = carte def afficherJeu(self): """ Affiche le jeu selon les valeurs connues (joueur et carte) Retourne faux si l'utilisateur veut quitter """ # appel à graphic pour le jeu self.graphics.afficherJeu(self.ecran, self.carte, self.joueur, self.logs) pygame.display.flip() return not self.termine # retour de l'état du jeu (faux pour quitter) def mouvement(self): """ demande un mouvement à l'utilisateur, renvois 'haut', 'bas', 'gauche' ou 'droite'. Ou False si l'utilisateur veut quitter. """ # affichage du jeu self.afficherJeu() # boucle event while not self.termine: for event in pygame.event.get(): if event.type == pygame.QUIT: self.termine = True # pression de touches elif event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: return 'haut' elif event.key == pygame.K_DOWN: return 'bas' elif event.key == pygame.K_RIGHT: return 'droite' elif event.key == pygame.K_LEFT: return 'gauche' elif event.key == pygame.K_ESCAPE: self.termine = True return False def dialogObjet(self, objet): """ Attends un objet, retourne True si l'utilisateur veux s'en équiper False si il ne veux pas """ reponse = 'oui' while not self.termine: self.graphics.afficherDialogObjet(self.ecran, objet, reponse) for event in pygame.event.get(): if event.type == pygame.QUIT: termine = True self.termine = True # pression de touches elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: return reponse elif event.key ==pygame.K_RIGHT: reponse = 'non' elif event.key == pygame.K_LEFT: reponse = 'oui' elif event.key == pygame.K_ESCAPE: self.termine = True return False def dialogCombat(self, combat): """ Attends un combat, retourne l'action du joueur dans ce combat, (combattre ou fuire, dans un premier temps) actions possibles : - 'fuite' - 'combat' """ # valeurs par défaut reponse = 'fuite' while not self.termine: self.graphics.afficherDialogCombat(self.ecran, combat, reponse) for event in pygame.event.get(): if event.type == pygame.QUIT: self.termine = True # pression de touches elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: return reponse elif event.key ==pygame.K_RIGHT: reponse = 'fuite' elif event.key == pygame.K_LEFT: reponse = 'combat' elif event.key == pygame.K_ESCAPE: self.termine = True reponse = 'fuite' return reponse def finCombat(self, combat): """ Attends le combat, considéré terminé. Affiche un écran de fin de combat, et se termine sans rien renvoyer quand l'utilisateur quitte l'écran de fin de combat. """ pass def gameOver(self): """ Affiche l'écran de fin de jeu, s'arrête quand l'utilisateur quitte l'écran de fin de jeu, en ne renvoyant rien. """ pass def log(self, logs): """ Attend une liste de chaînes. Chaque chaîne sera ajoutée à la liste de logs de l'IHM, et affichée dans la sortie standard. """ # on rajoute les éléments de logs dans les logs de l'IHM for log in logs: self.logs.append(log) # ajout dans les logs print log # affichage dans la sortie standard def utilisateurQuitte(self): """ Retourne vrai si l'utilisateur quitte le jeu """ return self.termine
# __author__ = Liu bn # 2018/8/20 import make_tree as mt from graphic import Graphic ltt = mt.get_tree("call.txt") graph = {0: Graphic(ltt[1]).join_funcs()} depth = sorted(ltt.keys())[-1] i = 1 width = len(graph[0][2]) logic_path = { 0: lambda x, y: x[0], 1: Graphic.join_block, } sep = " " while i <= depth: gr_list = [] for n in ltt[i]: if n.son_list: gr_list.append(Graphic(n.son_list).join_funcs()) if gr_list: w = logic_path[0 if len(gr_list) == 0 else 1](gr_list, sep) graph[i] = w if width < len(w[0]): width = len(w[0]) print(width) i += 1
for r in results[1::2]: counter += 1 (a, s) = r print('[' + str(counter) + '] ' + '{0:.2f}'.format(a) + ' ' + s) save(Result(args['layoutName'], cars), args['save']) else: mapLayout = args['layout'] gene = Gene(mapLayout.getTrafficLights()) geneInfo = GeneInfo(gene) carmap = CarMap(mapLayout, geneInfo) cars = randomStartEndPoint(args['number']) carmap = CarMap(mapLayout, geneInfo) simulation = Simulation(cars, carmap) app = Graphic(mapLayout.mapInfo, carmap.cars, carmap.trafficlights, args['size']) start_new_thread(run, ()) app.run() else: r = load(args['load']) mapLayout = getLayout(r.layout) geneStr = raw_input('Input Gene String: ') gene = Gene(mapLayout.getTrafficLights(), False, geneStr) geneInfo = GeneInfo(gene) carmap = CarMap(mapLayout, geneInfo) cars = r.cars simulation = Simulation(cars, carmap) if args['display'] is True: app = Graphic(mapLayout.mapInfo, carmap.cars, carmap.trafficlights, args['size'])
def move_to(self, p): with PostponeCurveGeometricUpdatingToEnd(self): for element in self.elements: element.move_to(add(p, subtract(element.anchor, self.anchor))) Graphic.move_to(self, p)
def rotate(self, center, angle): with PostponeCurveGeometricUpdatingToEnd(self): Graphic.rotate(self, center, angle) for element in self.elements: element.rotate(center, angle)
def homothety(self, center, sx, sy): with PostponeCurveGeometricUpdatingToEnd(self): Graphic.homothety(self, center, sx, sy) for element in self.elements: element.homothety(center, sx, sy)
def translate(self,v): with PostponeCurveGeometricUpdatingToEnd(self): Graphic.translate(self, v) for element in self.elements: element.translate(v)
def update_cardinals(self): Graphic.update_cardinals(self)
def sketch(self, root, cvsketch, ratio, color): Graphic.sketch(self, root, cvsketch, ratio, color = color) for graphic in self.elements: graphic.sketch(root, cvsketch, ratio)
class Plot: """ A class representing a Plot. Includes methods for creating multiple copies of a graphic and positioning them on the plot. Has plot wide path manipulation methods such as scaling, mirroring, rotating, and translating. Has the ability to create weedlines. Raises exceptions if the graphic or number of copies is too large for the material area. """ def __init__(self,width,height=None,color='#FFFFFF'): """ Creates the base plot properties and defines the plot material. """ self.graphic = None self._data = [] self._properties = { 'copies': 1, 'position':(0,0), # This relative position to get_start_position() 'spacing': (9,9), 'padding': (35,0,35,0), 'weedline': False, 'weedline_padding': 0, 'axis_mirror_x': False, 'axis_mirror_y': False, 'axis_rotation': 0, 'axis_scale': 1, 'align_center_x': False, 'align_center_y': False, 'auto_rotate':False, } self.set_material(width,height,color) # ================================ Export ================================ def get_data(self): """ Returns the data as a list of etree Elements. """ elements = [] for g in self._data: elements.append(g.get_data()) return elements def get_xml(self): """Returns the data as an SVG string.""" svg = etree.fromstring(SVG) layer = etree.Element('g') layer.set('id',unicode("plot.%s"% id(self))) layer.set('{http://www.inkscape.org/namespaces/inkscape}label','Plot') layer.set('{http://www.inkscape.org/namespaces/inkscape}groupmode','layer') layer.extend(self.get_data()) svg.append(layer) return etree.tostring(svg,pretty_print=True,xml_declaration=True,encoding="UTF-8",standalone=False) def get_preview_xml(self): """ Creates a visual representation of the svg as it would look if it were plotted on the material. """ svg = etree.fromstring(SVG) svg.set('width',unicode(self.get_material_width(limited=self.get_rotation()==90)+100)) svg.set('height',unicode(self.get_material_height(limited=self.get_rotation()==0)+100)) layer = etree.Element('g') layer.set('id','material') layer.set('{http://www.inkscape.org/namespaces/inkscape}label','Material') layer.set('{http://www.inkscape.org/namespaces/inkscape}groupmode','layer') layer.set('transform','translate(%f,%f)'%(35,35)) layer.set('x','0') layer.set('y','0') layer.set('width',str(self.get_material_width(limited=self.get_rotation()==90))) layer.set('height',str(self.get_material_height(limited=self.get_rotation()==0))) vinyl = etree.Element('rect') vinyl.set('x','0') vinyl.set('y','0') vinyl.set('width',unicode(self.get_material_width(limited=self.get_rotation()==90))) vinyl.set('height',unicode(self.get_material_height(limited=self.get_rotation()==0))) vinyl.set('style',"fill:%s;"% self.get_material_color()) shadow = deepcopy(vinyl) shadow.set('y','8') shadow.set('style',"fill:#000000;filter:url(#filter1);") layer.append(shadow) layer.append(vinyl) layer.extend(self.get_data()) svg.append(layer) return etree.tostring(svg,pretty_print=True,xml_declaration=True,encoding="UTF-8",standalone=False) # ================================ Properties ================================ def get_material_width(self,limited=False): """ Returns the plot x-size boundary or simulated material width as a float. If limited is set to True, this will return the total plot length, which is useful for eliminated lots of empty space on a preview. """ if limited: return self.get_bounding_box()[1]+self.get_padding()[1] # maxx + right padding else: return self._material['width'] def get_material_height(self,limited=False): """ Returns the plot y-size boundary or simulated material height as a float. If limited is set to True, this will return the total plot length, which is useful for eliminated lots of empty space on a preview. """ if limited: return self.get_bounding_box()[3]+self.get_padding()[2] # maxy + bottom padding else: return self._material['height'] def get_material_color(self): """ Returns the material color as a string. """ return self._material['color'] def _get_available_bounding_box(self): """ Returns the plottable bounding box of the material, or corner points of the area to be plotted on as a list in the format [minx,maxx,miny,maxy]. """ width, height = self.get_material_width(),self.get_material_height() top, right, bottom, left = self.get_padding() return [left,width-right,bottom,height-top] def get_available_width(self): """ Returns the plottable width (x-dimension) of the material. """ bbox = self._get_available_bounding_box() return bbox[1]-bbox[0] def get_available_height(self): """ Returns the plottable height (y-dimension) of the material. """ bbox = self._get_available_bounding_box() return bbox[3]-bbox[2] def get_start_position(self): """ Convience method. Returns the starting point of the plottable area as a list in the form [minx,miny]. """ bbox = self._get_available_bounding_box() return [bbox[0],bbox[2]] def get_position(self,absolute=False): """ Convience method. Returns the point upper left most point of the plot relative to get_start_position() as a list in the form [minx,miny]. If absoulte is true, this returns the absolute position in the same form. This includes the plot weedline position. """ pos = [0,0] out = self._properties['position'] if absolute: pos = self.get_start_position() return (out[0]+pos[0],out[1]+pos[1]) def get_bounding_box(self): """ Returns the bounding box, or corner points of the plot as a list in the format [minx,maxx,miny,maxy]. This should always be within the available_bounding_box()! """ if len(self._data) < 1: raise IndexError("No graphic data has been found.") else: bbox = self._data[0].get_bounding_box() for g in self._data: bbox = simpletransform.boxunion(g.get_bounding_box(),bbox) minx,maxx,miny,maxy = self._get_available_bounding_box() assert (bbox[0] >= minx) and (bbox[1] <= maxx) and (bbox[2] >= miny) and (bbox[3] <= maxy), "The plot bounding box %s should always be within the available bounding box %s!" % (bbox, self._get_available_bounding_box()) return bbox def get_height(self): """Returns the height (y-size) of the entire plot. """ bbox = self.get_bounding_box() return bbox[3]-bbox[2] def get_width(self): """Returns the width (x-size) of the entire plot. """ bbox = self.get_bounding_box() return bbox[1]-bbox[0] def get_padding(self): """Returns the padding set on the outside of the plot as a list [top,right,bottom,left].""" return self._properties['padding'] def get_spacing(self): """Returns the spacing to be used between copies as a list [col_x,row_y]. """ return self._properties['spacing'] def get_stack_size_x(self,rotated=False): """ Returns the number of graphics that fit within the get_available_width() as an int. If rotated=True, it returns the stack size if the graphic was rotated 90 degrees. """ assert self.graphic, "A graphic must be set on this plot first!" needed = self.graphic.get_width()+self.get_spacing()[0] if rotated: needed = self.graphic.get_height()+self.get_spacing()[0] # The last spacing we don't need, adding spacing takes care of that. available = self.get_available_width()+self.get_spacing()[0]-self.get_position()[0] if self.get_weedline_status(): # allocate space for weedline padding if enabled available -= 2*self.get_weedline_padding() return int(math.floor(available/needed)) def get_stack_size_y(self,rotated=False): """ Returns the number of graphics that fit within the get_available_height() as an int. If rotated=True, it returns the stack size if the graphic was rotated 90 degrees. """ assert self.graphic, "A graphic must be set on this plot first!" needed = self.graphic.get_height()+self.get_spacing()[1] if rotated: needed = self.graphic.get_width()+self.get_spacing()[1] # The last spacing we don't need, adding spacing takes care of that. available = self.get_available_height()+self.get_spacing()[1]-self.get_position()[1] if self.get_weedline_status(): # allocate space for weedline padding if enabled available -= 2*self.get_weedline_padding() return int(math.floor(float(available)/needed)) def get_rotation(self): """ Returns the degrees the plot has been rotated relative to the original. Designed for devices that use a rotated axis relative to the SVG spec. """ return self._properties['axis_rotation'] def get_copies(self): """ Returns the number of graphic copies to be created. """ return self._properties['copies'] def get_auto_rotate(self): """ Returns true if auto_rotate is enabled. """ return self._properties['auto_rotate'] def get_weedline_status(self): """ Returns true if a weedline is drawn around the plot.""" return self._properties['weedline'] def get_weedline_padding(self): """ Returns the weedline padding around the plot as a float.""" return self._properties['weedline_padding'] # ================================ Manipulation ================================ def set_graphic(self,svg): """Sets the SVG graphic that is used in the plot. Returns None.""" self.graphic = Graphic(svg,plot=self) if self.graphic.get_height() > self.get_available_height(): self.graphic = None raise SizeError("The height (%s) of this graphic is too large to fit on the material (%s)." %(self.graphic.get_height(),self.get_available_height())) elif self.graphic.get_width() > self.get_available_width(): self.graphic = None raise SizeError("The width (%s) of this graphic is too large to fit on the material (%s)." %(self.graphic.get_width(),self.get_available_width())) self.update() def set_position(self,x,y): """ Sets where the top left corner of the plot is positioned relative to get_start_position(). Disables set_align_center_x() and set_align_center_y(). Returns None. """ assert type(x) in [int,float] and type(y) in [int,float], "x and y must be an int or a float" assert x >= 0 and y >= 0 , "x and y must be 0 or more." pos = self.get_position() # update the properties if pos[0] != x: self._properties['align_center_x'] = False if pos[1] != y: self._properties['align_center_y'] = False if x != pos[0] or y != pos[1]: if self.graphic: if x+self.get_width() > self.get_available_width() or\ y+self.get_height() > self.get_available_height(): raise PositionError("This will position the plot off of the material!") else: self._properties['position'] = (x,y) self.update() # check to make sure it was set right for debugging purposes pos = self.get_start_position() bbox = self.get_bounding_box() assert (round(bbox[0]-pos[0],10),round(bbox[2]-pos[1],10)) == (round(x,10),round(y,10)),"The position (%s,%s) was set incorrectly to (%s,%s)!"%(round(x,10),round(y,10),round(bbox[0]-pos[0],10),round(bbox[2]-pos[1],10)) else: # no graphic set the property so it's there for first time use self._properties['position'] = (x,y) def set_align_center_x(self,enabled): """ If enabled, the plot is positioned to be centered horizontally in the get_available_width(). Returns None. """ assert self.graphic, "A graphic must be set on this plot first!" assert type(enabled) == bool, "enable must be a bool" if enabled: extra_space = self.get_available_width()-self.get_width() x,y = self.get_position() self.set_position(float(extra_space)/2,y) self._properties['align_center_x'] = True def set_align_center_y(self,enabled): """ If enabled, the plot is positioned to be centered vertically in the get_available_height(). Returns None. """ assert self.graphic, "A graphic must be set on this plot first!" assert type(enabled) == bool, "enabled must be a bool." if enabled: extra_space = self.get_available_height()-self.get_height() x,y = self.get_position() self.set_position(x,float(extra_space)/2) self._properties['align_center_y'] = True def set_padding(self,top=None,right=None,bottom=None,left=None): """ Sets the padding or distance between the materials bounding box and the plottable bounding box _get_available_bounding_box(). Similar to padding in the css box structure or printing margins. Returns None. """ updated = [top,right,bottom,left] pad = self.get_padding() for i in range(0,len(updated)): assert type(updated[i]) in [type(None),int,float],"%s must be of type int or float. Given %s" % (it,type(it)) if type(updated[i]) == type(None): updated[i] = pad[i] if pad != updated: for it in updated: assert it >= 0, "padding must be at least 0." top,right,bottom,left = updated if top+bottom >= self.get_material_height(): raise ValueError if left+right >= self.get_material_width(): raise ValueError self._properties['padding'] = updated if self.graphic: self.update() def set_copies(self,n): """ Makes n copies of a path and spaces them out on the plot. Raises a SizeError exception if n copies will not fit on the material with the current settings. Returns None. """ assert type(n) == int, "n must be an integer value." assert n > 0, "n must be 1 or more." if n != self.get_copies(): self._properties['copies'] = n if self.graphic: self.update() def set_spacing(self,x=None,y=None): """ Sets the spacing between columns (x) and rows (y). Returns None.""" spacing = self.get_spacing() if x is None: x = spacing[0] if y is None: y = spacing[1] assert type(x) in [int, float], "x spacing must be an int or float." assert type(y) in [int, float], "y spacing must be an int or float." if x != spacing[0] or y != spacing[1]: self._properties['spacing'] = (x,y) self.update() # error checking in update! def set_weedline(self,enabled): """If enabled, a box is drawn around the entire plot. Returns None. """ assert type(enabled) == bool, "enabled must be a bool" if enabled != self.get_weedline_status(): # a change needs made: self._properties['weedline'] = enabled if self.graphic: self.update() def set_weedline_padding(self,padding): """ Sets the padding between the weedline and plot. If the plot originally had a weedline the padding will be added immediately, otherwise it will be added the next time it is enabled. Returns None. """ assert type(padding) in [int,float], "padding must be an int or float" assert padding >= 0, "padding must be 0 or more" if padding != self.get_weedline_padding(): self._properties['weedline_padding'] = padding if self.graphic: self.update() def set_rotation(self,degrees): """ Set's the axis rotation of the material. If rotation = 90, the materials width and height will be swapped. This does not rotate the graphics or swap any padding/spacings. """ assert int(degrees) in [0,90], "The axis can only be rotated 0 or 90 degrees." if degrees != self._properties['axis_rotation']: w = self.get_material_width() h = self.get_material_height() self._material['width'] = h # Swap them self._material['height'] = w self._properties['axis_rotation'] = degrees if self.graphic: self.update() def set_auto_rotate(self,enabled): """If enabled, graphics will be automatically rotated to save material. """ assert type(enabled) == bool, "enabled must be a bool." if enabled != self._properties['auto_rotate']: self._properties['auto_rotate'] == enabled if self.graphic: self.update() def set_cutting_order(self,mode=None): """ """ assert mode in [None,'One copy at a time', 'Best tracking', 'Shortest Path'] pass def set_material(self,width,height=None,color="#FFFFFF"): """ Set the width, length, and color of the plot. """ assert type(width) in [int,float], "Material width must be an int or float, given %s."%type(width) assert type(height) in [type(None), int, float], "If the material has a limited height (length), it must be an int or float, otherwise set it to None. Given %s" % type(length) assert type(color) == str, "The material color must be a css style color (eg. #FFFFFF or \"white\"). Given %s." % type(color) assert width > 0, "Material width must be greater than 0, given %s."% width if height: assert height > 0, "Material height (length) must be greater than 0, given %s."% height else: height = 354330 # I'm just going to assume nobody will cut anything over 100 meters long!. self._material = {"width":width,"height":height,"color":color} if self.graphic: self.update() # ================================ Processing ================================ def update(self): """ Builds the plot from the graphic. Uses all the current properties. Raises exceptions if it cannot create the plot given the current values. This needs done whenever a property of self.graphic is changed. """ # Check that there is enough room to fit all the copies. copies_left = self.get_copies() fit_x,fit_y = [self.get_stack_size_x(),self.get_stack_size_y()] rotate = False if fit_x*fit_y < copies_left: if self.get_auto_rotate(): fit_x,fit_y = [self.get_stack_size_x(rotate=True),self.get_stack_size_y(rotate=True)] if fit_x*fit_y < copies_left: raise SizeError("%s graphics are to be made but only %s will fit on the current material. Please adjust settings and try again." % (copies_left,fit_x*fit_y)) else: rotate = True # This should only be set if the only way for it to fit is to rotate! # ==================== Generate the list of graphic positions, note that these are absolute.================================ # positions, not relative to the plot padding like plot.set_position(). x,y = self.get_position(absolute=True) if self.get_weedline_status():# If plot weedlines are enabled, we have to shift the graphics so the weedline fits. x += self.get_weedline_padding() y += self.get_weedline_padding() if rotate: self.graphic.set_rotation(90) # 90 should be a variable! dx,dy = self.graphic.get_width()+self.get_spacing()[0],self.graphic.get_height()+self.get_spacing()[1] positions = [] if self.get_rotation() == 90: # Stack in positive x direction. while copies_left >= fit_y: for i in range(0,fit_y): # Fill a vertical stack. positions.append([x,i*dy+y]) # Add a new stack. x += dx copies_left -= fit_y # Fill leftover copies. for i in range(0,copies_left): positions.append([x,i*dy+y]) else: # Stack in positive y direction. while copies_left >= fit_x: for i in range(0,fit_x): # Fill a horizontal stack. positions.append([i*dx+x,y]) # Add a new stack. y += dy copies_left -= fit_x # Fill leftover copies. for i in range(0,copies_left): positions.append([i*dx+x,y]) # ==================== Create the plot from the given graphic positions ================================ if self.graphic.get_changed_flag() or len(self._data)==0: # Only make new copies if the graphic changed self._data = [] for pos in positions: x,y = pos g = deepcopy(self.graphic) g.set_position(x,y) self._data.append(g) else: # Just reposition the current data. This should skip the weedline if it's enabled. for pos,g in zip(positions,self._data): x,y = pos g.set_position(x,y) if len(self._data) == self.get_copies()+1: # weedlines were previously enabled! self._data.pop() if self.get_weedline_status(): # add it to the data minx,maxx,miny,maxy = self.get_bounding_box() p = self.get_weedline_padding() d = "M%f,%f V%f H%f V%f Z" % (minx-p,miny-p,maxy+p,maxx+p,miny-p) svg = etree.fromstring(SVG) path = etree.Element('path') path.set('d',d) svg.append(path) g = Graphic(etree.tostring(svg)) self._data.append(g)
def __init__(self, *elements): Graphic.__init__(self) self.elements = [] self.initialize_elements(*elements) self.update_epochs() self.external_call = False
def game_restart(self, event): self.root.unbind_all('<Key-' + self.restart_key + '>') self.root.bind_all('<Key-' + self.start_key + '>', self.game_start) self.g = Graphic(self.root)