...

суббота, 27 января 2018 г.

[Из песочницы] Создание когнитивных связей у игроков

image

Вступление


Статья повествует о создании когнитивных связей в головах игроков логической игры
«Maze Lord». Или как перевели её различные сайты — Повелитель Подземелий. Это пошаговая логическая игра с элементами менеджмента ресурсов в roguelike сеттинге.

Сюжет


Некий дракон, по рекомендациям своих знакомых, решил посетить соседнее королевство, посмотреть достопримечательности, поразрушать всякие здания и похитить какую-нибудь принцессу. Но кто бы мог подумать, что какой-то там герой вдруг решит её спасти, разорив и уничтожив при этом практически всё подземное королевство нашего славного огнедышащего друга. Вот и строй потом лабиринты, расставляй ловушки и устраивай на работу монстров после этого.

image

Как появилась идея


Путь создания игры был тернист. Технически всё началось когда я ещё учился в школе. Дома я случайно наткнулся на детскую головоломку в газете. Как правило — это либо простенький кроссворд с картинками или «помоги кролику пройти лабиринт и добраться до морковки» (хотя то, что кролики фанатеют от моркови — является заблуждением).

Но в тот день это была совсем необычная головоломка. На всей странице располагалось неплохо нарисованное подземелье с NPC и различными предметами. Например, чтобы пройти стражника — ему надо было заплатить мешок с золотом, который при этом охраняет змея. И всё в таком духе. Сейчас бы я это назвал квестом с предметами на подобии Dizzy, но тогда я этого не знал. Подобная загадка сильно выбивалась из привычных детских головоломок, поэтому мне она сразу же запомнилась. Но затем газету кто-то выкинул и я больше таких головоломок не видел ни в одной газете.

Лишь когда мы с друзьями играли на денди в Fantastic Adventures of Dizzy я встретил похожую механику. Что и говорить — игра была шедевром: открытый мир, множества интерактивных предметов, инвентарь, хорошая музыка и антураж старой доброй сказки.

Помнится, мы проходили игру всей компанией: один управлял самим Диззи, второй вёл журнал со списком предметов и их назначением, остальные же спорили как лучше составить маршрут Диззи, чтобы все предметы применить где нужно, где какие оставить, чтобы потом захватить на обратном пути. Сейчас бы это назвали кооперативом, но тогда мы этого не знали.

Прототип


Прошло несколько лет. Я научился программировать игры. И вдруг вспомнил про ту детскую головоломку из газеты и про Дизи на денди и решил попробовать передать основы игрового процесса.

Самая первая версия прототипа называлась BoardTiles и была сделана на Flash.

image

В итоге я перешёл на Unity, уменьшил уровень до поля 6x6 клеток, упростил покупку/продажу предметов и добавил новых объектов.

image

Конвертация


Игру можно назвать конвертером ресурсов. У игрока есть список ресурсов, при этом на уровне хитрым образом расставлены различные конвертеры — они переводят одни ресурсы в другие.

Имея 3 сердечки в начале, игроку нужно добраться до выхода из уровня, посетив при этом конвертеры в правильной последовательности.

Какие же у нас есть ресурсы, спросите вы? А вот какие у нас есть ресурсы, отвечу я:

  • здоровье в виде сердечек
  • золото в виде золотых монеток
  • броня в виде брони
  • предметы в инвентаре
  • пустые слоты в инвентаре (да да, это тоже ресурс)
  • пустые клетки на уровне (и это тоже)

На уровне же в свою очередь расставлены конвертеры этих самых ресурсов, например:
  • монстр: сердечно -> клетка на уровне
  • дверь: ключ -> клетка на уровне
  • скупщик: предмет -> золотая монетка

Поиск графического стиля


Основной мыслью в графике была хорошая читаемость всех объектов. Это относилось как к форме объектов, так и к цвету. Чтобы с первого беглого взгляда игрока было сразу понятно что это за объект.

А ещё игроку должен быть видел весь уровень как на ладони (вот такой вот получился каламбур: игра хорошо подходит для мобильных устройств).

И казалось бы, я не многого прошу. Но, к сожалению, поиски нужного арта были долгими и сложными.

image

В итоге пришли вот к такому

image

Варианты, они повсюду


Как ни странно, самым сложным моментом разработки было придумывание разнообразных объектов для уровней. Хотя казалось бы чего тут сложного: монстр забирает сердечко, ключик — открывает дверку. Да и объекты довольно стандартные. Но вся сложность, как всегда, кроется в деталях. В данном случае сложностью было составление объектов именно с большой вариативностью применения, а так же с простыми и понятными сочетаниями с другими объектами. Ведь большой выбор из множества вариантов и делает логическую игру интересной.

image

Поэтому все объекты должны отвечать нескольким требованиям:

  • хорошая читаемость (форма и цвет)
  • вариативность применения (не относится к монстрам)
  • понятные взаимодействия с другими объектами
  • чтобы логично смотрелся в сеттинге подземелий, тем самым дополняя основной лор игры

Именно для вариативности все предметы применяются несколькими способами, а именно:
  • ключ открывает как дверь, так и сундук
  • факел может сжигать и дерево и паутину
  • любой предмет можно продать за одну монетку (кроме Проклятого камня, что довольно логично)
  • щит можно подставить как под обычный удар, так и под укус змеи, что не даст игроку отравиться
  • на золото можно либо купить предмет с ценником, либо пройти через жадного тролля, заплатив за проход.

Неполная схема взаимодействий большинства объектов

image

Так же в игре можно встретить несколько интересных взаимодействий, таких как:

  • паутина забирает первый предмет в инвентаре
  • проклятый камень нельзя скинуть и продать, то есть он просто занимает 1/3 инвентаря, но зато его может забрать паутина
  • предмет с ценником можно купить за монетку, которую можно либо найти на уровне, либо взять из сундука, или же продать что-то у продавца
  • свиток огня может сжечь любого надоедливого монстра
  • свиток отталкивания может оттолкнуть любого надоедливого монстра подальше от вашей зоны комфорта.

Знакомство с новыми предметами


Периодически игра знакомит игрока с новыми предметами. В этот момент, на ряду с текстовым описанием нового объекта, мы забрасываем игрока в небольшой обучающий уровень, который сделан только для того, чтобы показать на примере как работает новый объект. Причём больше на таких уровнях ничего нет. Например, для знакомства с «Зельем здоровья» на уровне есть монстр, который отнимает сердечко и само зелье. И это сделано не случайно.

Паблишер сказал, что это слишком простые уровни, но я объяснил, что в этих уровнях нет ничего лишнего — только действие объекта. Именно в эти моменты мы начинаем создавать когнитивную связь в голове игрока с новый объектом. Текстовое описание это конечно хорошо, но вот увидеть, а главное испытать предмет — намного нагляднее.

Когнитивные связи


Мета-задача была именно в создании определённых когнитивных связей (как я это называю), чтобы игрок в середине игры, запомнив все объекты и как они взаимодействуют, мог решать головоломки «на автомате», практически не задумываясь, а лишь невзначай кидая беглый взгляд на уровень.

Именно для этого были придуманы интуитивные хорошо читаемые объекты и полностью открытый уровень, чтобы сразу можно было составить план действий нашего героя.

Схема взаимодействия, которая ближе к правде

image

Удалось ли этого добиться? Этот вопрос лучше спросить у игроков, которые жаловались на якобы простые уровни во второй половине игры, хотя все они располагались от простого к сложному (пилообразной лесенкой). Притом расставлялись уровни эмпирически — чем больше раз тестер проигрывал на уровне, тем дальше этот уровень располагался в игре.

Таким образом, быстрое прохождение сложных уровней возможно и является проявлением созданных когнитивных связей у игроков. Ну, или же в конце игры действительно были простые уровни…

Слова благодарности!

image

Let's block ads! (Why?)

Оператор break и fallthrough

Как роботы помогают людям начинать инвестировать на бирже: что такое робоэдвайзинг, и как это работает

Изображение: Unsplash

В нашем блоге мы много пишем о высокочастотной торговле и создании специализированных роботов для совершения операций на бирже. Может показаться, что все это относится только к продвинутым трейдерам, однако на самом деле существует и отдельный класс роботов, которые помогают освоиться на рынке новичкам. Такие системы называются робоэдвайзерами — о них сегодня и пойдет речь.

Что это такое


Робоэдвайзинг — инструмент для начала работы на фондовом рынке. Изначально он появился в США, где разработчики финансовых сервисов стремились предложить услуги доверительного управления пенсионными накоплениями граждан.

Он нацелен на тех, кто хотел бы начать инвестировать свои средства, но сомневается в своей способности не потерять все деньги. По сути, электронные советники помогают выйти на фондовый рынок тем, кто раньше пользовался лишь банковскими депозитами.

По сути, робоэдвайзинг — это автоматизация услуги доверительного управления, в рамках которой инвесторы обращаются к профессиональным управляющим, а те совершают операции с их средствами и активами. Несмотря на заверения многих управляющих, которые утверждают, что создают для каждого клиента уникальную торговую стратегию, на практике обычно применяется от от 3 до 9 риск-профилей — из этого числа выбираются те стратегии, что наиболее подходят под задачи клиента.

Помимо прочего, это еще и самый дешевый из доступных способов инвестирования — стоимость работы робота-советника никогда не сравнится с ценой услуг профессионального управляющего.

Как это работает


Несмотря на то, что идея доверить управление своими сбережениями и активами роботу, работающему по алгоритмам, может показаться не самой очевидной, такой вид инвестиций весьма популярен на Западе. Под управлением крупнейших игроков на рынке робоэдвайзинга Wealthfront и Betterment находится порядка $10 млрд.

Важно понимать, что автоматизированные помощники для инвесторов не используются для активной торговли, здесь применяются пассивные стратегии, направленные на извлечение прибыли в долгосрочной перспективе. В классической схеме робоэдвайзинга средства в определенных пропорциях инвестируются в разные классы активов — акции, облигации, ETF и т.д. Затем в соответствии с заданными весами производится периодическая ребалансировка портфеля в зависимости от изменений цен тех или иных финансовых инструментов.

Интерфейс приложения робоэдвайзера Wealthfront

Робоэдвайзеры могут быть «заточены» под решение конкретных задач — например, увеличении пенсионных сбережений или получении суммы, необходимой для оплаты образования.

Что в России


Несмотря на то, что робоэдвайзинг впервые появился в США, в нашей стране также появляются инициативы в этом направлении. Одна из них — совместный проект брокера ITI Capital и компании ARTQUANT, в рамках которого функция робоэдвайзинга доступна клиентам прямо в личном кабинете брокерской системы.

Электронный финансовый советник задает пользователю несколько простых вопросов — на сколько лет он планирует инвестировать средства, какой уровень риска считает для себя приемлемым и т.д. На основе ответов выбирается алгоритм для инвестирования и соответствующий риск-профиль. В настоящий момент доступно два типа классов активов — акции и облигации федерального займа (ОФЗ).

Риск-профиль, по сути, отвечает за определение соотношение акций и облигаций в создаваемом портфеле — в консервативном портфеле ОФЗ занимают до 90%. В таком случае общая надежность стратегии сравнима с использованием банковского вклада, хотя важно помнить, что биржевые инвестиции не попадают под защиту государства (но в будущем ситуация может измениться).

Минимальный размер вложения — 10 тысяч рублей, но чем выше сумма, тем более диверсифицированный портфель сможет создать система.

Заключение


Робоэдвайзинг — это инструмент для знакомства с фондовым рынком, который подойдет людям, которые задумываются об инвестициях, но не уверены в своих силах. Робот может выбрать стратегию торговли, соответствующую предпочтениям пользователя с точки зрения объемов инвестиций, их срока и возможного риска. В итоге можно получить низкорисковые стратегии (с высокой долей купленных ОФЗ), которые приносят доход выше, чем обеспечивает банковский депозит.

Кроме того, при использовании робоэдвайзинга инвестор экономит на оплате услуг управления и платит только комиссию брокера за совершение транзакций.

Исходя из описанных параметров, можно сделать вывод, что робоэдвайзинг хорошо подходит, например, для работы с индивидуальными инвестиционными счетами (ИИС) и не только получать прибыль от инвестиций, но и пользоваться льготами разных типов.

Другие материалы по теме финансов и фондового рынка от ITI Capital:


Let's block ads! (Why?)

Эволюция системных вызовов архитектуры x86

[Перевод] Создание игр на Python 3 и Pygame: Часть 4

image

Это четвёртая из пяти частей туториала, посвящённого созданию игр с помощью Python 3 и Pygame. В третьей части мы углубились в сердце Breakout и узнали, как обрабатывать события, познакомились с основным классом Breakout и увидели, как перемещать разные игровые объекты.

(Остальные части туториала: первая, вторая, третья, пятая.)

В этой части мы узнаем, как распознавать коллизии и что случается, когда мяч ударяется об разные объекты: ракетку, кирпичи, стены, потолок и пол. Наконец, мы рассмотрим важную тему пользовательского интерфейса и в частности то, как создать меню из собственных кнопок.

Распознавание коллизий


В играх объекты сталкиваются друг с другом, и Breakout не является исключением. В основном с объектами сталкивается мяч. В методе handle_ball_collisions() есть встроенная функция под названием intersect(), которая используется для проверки того, ударился ли мяч об объект, и того, где он столкнулся с объектом. Она возвращает 'left', 'right', 'top', 'bottom' или None, если мяч не столкнулся с объектом.
def handle_ball_collisions(self):
    def intersect(obj, ball):
        edges = dict(
            left=Rect(obj.left, obj.top, 1, obj.height),
            right=Rect(obj.right, obj.top, 1, obj.height),
            top=Rect(obj.left, obj.top, obj.width, 1),
            bottom=Rect(obj.left, obj.bottom, obj.width, 1))
        collisions = set(edge for edge, rect in edges.items() if
                         ball.bounds.colliderect(rect))
        if not collisions:
            return None

        if len(collisions) == 1:
            return list(collisions)[0]

        if 'top' in collisions:
            if ball.centery >= obj.top:
                return 'top'
            if ball.centerx < obj.left:
                return 'left'
            else:
                return 'right'

        if 'bottom' in collisions:
            if ball.centery >= obj.bottom:
                return 'bottom'
            if ball.centerx < obj.left:
                return 'left'
            else:
                return 'right'

Столкновение мяча с ракеткой


Когда мяч стукается об ракетку, он отскакивает. Если он ударяется о верхнюю часть ракетки, то отражается обратно вверх, но сохраняет тот же компонент горизонтальной скорости.

Но если он ударяется о боковую часть ракетки, то отскакивает в противоположную сторону (влево или вправо) и продолжает движение вниз, пока не столкнётся с полом. В коде используется функция intersect().

# Удар об ракетку
s = self.ball.speed
edge = intersect(self.paddle, self.ball)
if edge is not None:
    self.sound_effects['paddle_hit'].play()
if edge == 'top':
        speed_x = s[0]
        speed_y = -s[1]
        if self.paddle.moving_left:
                speed_x -= 1
        elif self.paddle.moving_left:
                speed_x += 1
        self.ball.speed = speed_x, speed_y
elif edge in ('left', 'right'):
        self.ball.speed = (-s[0], s[1])

Столкновение с полом


Когда ракетка пропускает мяч на пути вниз (или мяч ударяется об ракетку сбоку), то мяч продолжает падать и затем ударяется об пол. В этот момент игрок теряет жизнь и мяч создаётся заново, чтобы игра могла продолжаться. Игра завершается, когда у игрока заканчиваются жизни.
# Удар об пол
if self.ball.top > c.screen_height:
    self.lives -= 1
        if self.lives == 0:
                self.game_over = True
        else:
                self.create_ball()

Столкновение с потолком и стенами


Когда мяч ударяется об стены или потолок, он просто отскакивает от них.
# Удар об потолок
if self.ball.top < 0:
    self.ball.speed = (s[0], -s[1])

# Удар об стену
if self.ball.left < 0 or self.ball.right > c.screen_width:
        self.ball.speed = (-s[0], s[1])

Столкновение с кирпичами


Когда мяч ударяется об кирпич, это является основным событием игры Breakout — кирпич исчезает, игрок получает очко, мяч отражается назад и происходят ещё несколько событий (звуковой эффект, а иногда и спецэффект), которые я рассмотрю позже.

Чтобы определить, что мяч ударился об кирпич, код проверят, пересекается ли какой-нибудь из кирпичей с мячом:

# Удар об кирпич
for brick in self.bricks:
    edge = intersect(brick, self.ball)
        if not edge:
                continue

        self.bricks.remove(brick)
        self.objects.remove(brick)
        self.score += self.points_per_brick

        if edge in ('top', 'bottom'):
                self.ball.speed = (s[0], -s[1])
        else:
                self.ball.speed = (-s[0], s[1])

Программирование игрового меню


В большинстве игр есть какой-нибудь UI. В Breakout есть простое меню с двумя кнопками, 'PLAY' и 'QUIT'. Меню отображается в начале игры и пропадает, когда игрок нажимает на 'PLAY'. Давайте посмотрим, как реализуются кнопки и меню, а также как они интегрируются в игру.

Создание кнопок


В Pygame нет встроенной библиотеки UI. Есть сторонние расширения, но для меню я решил создать свои кнопки. Кнопка — это игровой объект, имеющий три состояния: нормальное, выделенное и нажатое. Нормальное состояние — это когда мышь не находится над кнопкой, а выделенное состояние — когда мышь находится над кнопкой, но левая кнопка мыши ещё не нажата. Нажатое состояние — это когда мышь находится над кнопкой и игрок нажал на левую кнопку мыши.

Кнопка реализуется как прямоугольник с фоновым цветом и текст, отображаемый поверх него. Также кнопка получает функцию on_click (по умолчанию являющуюся пустой лямбда-функцией), которая вызывается при нажатии кнопки.

import pygame

from game_object import GameObject
from text_object import TextObject
import config as c


class Button(GameObject):
    def __init__(self, 
                 x, 
                 y, 
                 w, 
                 h, 
                 text, 
                 on_click=lambda x: None, 
                 padding=0):
        super().__init__(x, y, w, h)
        self.state = 'normal'
        self.on_click = on_click

        self.text = TextObject(x + padding, 
                               y + padding, lambda: text, 
                               c.button_text_color, 
                               c.font_name, 
                               c.font_size)

    def draw(self, surface):
        pygame.draw.rect(surface, 
                         self.back_color, 
                         self.bounds)
        self.text.draw(surface)

Кнопка обрабатывает собственные события мыши и изменяет своё внутреннее состояние на основании этих событий. Когда кнопка находится в нажатом состоянии и получает событие MOUSEBUTTONUP, это означает, что игрок нажал на кнопку, и вызывается функция on_click().
def handle_mouse_event(self, type, pos):
    if type == pygame.MOUSEMOTION:
                self.handle_mouse_move(pos)
        elif type == pygame.MOUSEBUTTONDOWN:
                self.handle_mouse_down(pos)
        elif type == pygame.MOUSEBUTTONUP:
                self.handle_mouse_up(pos)

def handle_mouse_move(self, pos):
        if self.bounds.collidepoint(pos):
                if self.state != 'pressed':
                        self.state = 'hover'
        else:
                self.state = 'normal'

def handle_mouse_down(self, pos):
        if self.bounds.collidepoint(pos):
                self.state = 'pressed'

def handle_mouse_up(self, pos):
        if self.state == 'pressed':
                self.on_click(self)
                self.state = 'hover'

Свойство back_color, используемое для отрисовки фонового прямоугольника, всегда возвращает цвет, соответствующий текущему состоянию кнопки, чтобы игроку было ясно, что кнопка активна:
@property
def back_color(self):
    return dict(normal=c.button_normal_back_color,
                hover=c.button_hover_back_color,
                pressed=c.button_pressed_back_color)[self.state]

Создание меню


Функция create_menu() создаёт меню с двумя кнопками с текстом 'PLAY' и 'QUIT'. Она имеет две встроенные функции, on_play() и on_quit(), которые она передаёт соответствующей кнопке. Каждая кнопка добавляется в список objects (для отрисовки), а также в поле menu_buttons.
def create_menu(self):
    for i, (text, handler) in enumerate((('PLAY', on_play), 
                                         ('QUIT', on_quit))):
        b = Button(c.menu_offset_x,
                   c.menu_offset_y + (c.menu_button_h + 5) * i,
                   c.menu_button_w,
                   c.menu_button_h,
                   text,
                   handler,
                   padding=5)
        self.objects.append(b)
        self.menu_buttons.append(b)
        self.mouse_handlers.append(b.handle_mouse_event)

При нажатии кнопки PLAY вызывается функция on_play(), удаляющая кнопки из списка objects, чтобы они больше не отрисовывались. Кроме того, значения булевых полей, которые запускают начало игры — is_game_running и start_level — становятся равными True.

При нажатии кнопки QUIT is_game_running принимает значение False (фактически ставя игру на паузу), а game_over присваивается значение True, что приводит к срабатыванию последовательности завершения игры.

def on_play(button):
    for b in self.menu_buttons:
                self.objects.remove(b)

        self.is_game_running = True
        self.start_level = True

def on_quit(button):
        self.game_over = True
        self.is_game_running = False

Отображение и сокрытие игрового меню


Отображение и сокрытие меню выполняются неявным образом. Когда кнопки находятся в списке objects, меню видимо; когда они удаляются, оно скрывается. Всё очень просто.

Можно создать встроенное меню с собственной поверхностью, которое рендерит свои подкомпоненты (кнопки и другие объекты), а затем просто добавлять/удалять эти компоненты меню, но для такого простого меню это не требуется.

Подводим итог


В этой части мы рассмотрели распознавание коллизий и то, что происходит, когда мяч сталкивается с разными объектами: ракеткой, кирпичами, стенами, полом и потолком. Также мы создали меню с собственными кнопками, которое можно скрывать и отображать по команде.

В последней части серии мы рассмотрим завершение игры, отслеживание очков и жизней, звуковые эффекты и музыку.

Затем мы разработаем сложную систему спецэффектов, добавляющих в игру немного специй. Наконец, мы обсудим дальнейшее развитие и возможные улучшения.

Let's block ads! (Why?)

[Перевод] Что в имени? Анализ данных названий 5820 игр в Steam


«Что в имени»? Больше, чем можно подумать. Если вы уже давно работаете над своей игрой или находитесь на этапах планирования, то в какой-то момент вам всё равно придётся выбирать ей название. Названия видеоигр могут стимулировать воображение и вызывать ностальгические воспоминания.

В Steam ежегодно выпускается больше шести тысяч игр, но какая их часть вызывает интерес игроков? Давайте рассмотрим исследование, в котором мы изучили названия игр, выпущенных в прошлом году.

Почему названия важны?


Прежде чем переходить к цифрам, давайте вкратце обсудим то, почему название видеоигры — это очень важно. Хотя оно может казаться незначительной частью общих ощущений от игры, на самом деле название является ключом, особенно когда дело доходит до маркетинга. В бешеном мире цифрового маркетинга название, рекламный слоган и одно-два изображения могут оказаться единственным, что увидит потенциальный покупатель.

В магазине Steam название и небольшая картинка — это всё, чем может привлечь к себе игра. На ранних этапах цифрового маркетинга существовало гораздо меньшее количество выпущенных игр. Увеличившийся вал выпускаемых игр с уменьшившимся маркетинговым пространством делают название важным, как никогда.

Кроме того, следует рассмотреть множество других аспектов. Маркетинг «сарафанного радио», места в поисковых движках, возможность перепутать игру с другими и многое другое — вот причины, по которым стоит вложить дополнительные усилия, чтобы обеспечить названию игры «защиту от дурака».

Ну а теперь перейдём к данным.

Весь объём статистики


Для сбора статистики мы проанализировали 5 820 игр, выпущенных в прошлом году (без учёта free-to-play). Мы рассматривали только уникальные игры, выпущенные как отдельные продукты, поэтому из набора данных были исключены DLC и прочие расширения. После графиков следует краткое описание данных и методов.

Длина названия


Для 5 820 проанализированных игр средняя длина названия равна 17,15 со стандартным отклонением 10,26. То есть в целом, длина названий игр, выпущенных в прошлом году, находилась в пределах от 7 до 27 символов, не считая выбросов.

Среднее название состояло из 2,8 слов с отклонением 1,7, что даёт общий интервал от 1 до 5 слов.

Это демонстрирует общую тенденцию к более лаконичным названиям, что позволяет нам выбрать один из вариантов: следовать тенденции или намеренно избегать её. У обоих подходов при текущем состоянии рынка есть свои преимущества, и их нужно тщательно проанализировать при выборе собственного названия.

Кроме интервалов длины в символах и словах, многие из проанализированных игр демонстрируют похожие структуры наименования. С самых первых этапов анализа было меньше двух дюжин структур названий, в которые попадал больше 90% игр. Примечательно, что самыми распространёнными структурами названий были "{существительное} of {существительное}" и "{существительное}: {прилагательное} {существительное}" (например, «West of Loathing» и «Divinity: Original Sin 2»).


Названия из нескольких частей


15,14% игр из всего набора данных имели название из нескольких частей. При анализе название считалось состоящим из нескольких частей, когда в нём присутствовал один из следующих символов: ":", "-" и "|", который при этом создавал два отдельных фрагмента информации. Например, «Yooka-Laylee» не считается состоящим из нескольких частей, а «Steel Division: Normandy 44» считается.

Использование уникальных слов


Один из самых важных аспектов собранных данных заключался в использовании «уникальных слов» в названии игры. В целях анализа слово считается уникальным, если оно не существует как словарное определение в десяти наиболее популярных языках, используемых игроками Steam. В целом, уникальное слово в названии содержали 27,93% игр.

Отсылки к другой интеллектуальной собственности


Обыскав наш набор данных на предмет отсылок к другой интеллектуальной собственности (Intellectual Properties, IP), мы получили новое подмножество, требующее дальнейшего анализа. 11,96% игр в наборе данных в той или иной степени ссылались на уже существующую IP (предыдущую игру, фильм, книгу или другие медиа).

Если использовать это подмножество для дальнейших исследований, чтобы найти взаимосвязи между сиквелами игр, играми на основе фильмов и книг, то можно создать собственный интересный проект, если кому-то это будет интересно.

Оцениваем лучших


Давайте посмотрим, как эти игры соотносятся с бестселлерами. Взяв верхние 10% игр и сравнив их с общим набором данных, мы сможем создать чёткую картинку того, что важно в названиях видеоигр.

Сравнение длин названий


Лучшие по продажам 10% игр, выпущенные в прошлом году, имеют среднюю длину названия 17,63 символов. По сравнению с 17,15 общего набора данных, можно сказать, что у бестселлеров в среднем немного более длинные названия.

Вычисление среднего длин названий в словах показывает похожие результаты. Названия лучших игр состоят в среднем из 2,92 слов, (2,8 слова в полном наборе данных). Этого достаточно, чтобы показать, что лучшие игры склонны к большей многословности.

Названия из нескольких частей


19,17% игр из лучших по продажам 10% имеют названия из нескольких частей (15,14% в полном наборе данных). Разница в этих двух значениях. показывает, что может быть выгоднее использовать более длинные названия. Возможно, так происходит из-за более оптимального использования ограниченного пространства, в котором разработчики могут привлечь потенциальных игроков.

Использование уникальных слов


Что касается использования уникальных слов, то бестселлеры отличаются разительно! В 48,19% названий используется хотя бы одно уникальное слово (в общем массиве данных таких игр всего 27,93%). Это огромная разница в данных; она предполагает, что использование уникальных слов делает игру более запоминающейся, или с большей вероятностью привлекает возможного покупателя.

Отсылки к другой интеллектуальной собственности


Лучшие по продажам игры содержали отсылки к другим видеоиграм, фильмам и книгам в 20,73% случаев — почти в два раза больше, чем показатель всего набора данных (11,96%). Это демонстрирует чёткую тенденцию к тому, что расширения существующих игр обычно показывают себя лучше, или, по крайней мере, имеют больший шанс на успех.

Наборы данных, источники и техники анализа


Использованный в этой статье массив данных полностью получен через SteamSpy и официальный Steam Web API. Если вы хотите провести собственные исследования или попробовать другие алгоритмы, то лучше всего начинать с этих источников.

При считывании данных учитывайте, что ограничения наборов данных и методов анализа могут оставлять пробелы, которые способны влиять на результаты. Например, существуют неустранимые проблемы, такие, как влияние бесплатной раздачи игр на данные продаж и игры с продажами, близкими к статистической погрешности.

Хотя эти данные всё равно полезны, такие проблемы тяжело контролировать.

Интерпретация данных: что всё это значит?


Мы обработали множество данных, но что они значат конкретно для вас? Вот самые чёткие из обнаруженных нами тенденций:

Составляйте названия из 1-5 слов


Большинство игр находятся в этом интервале, а показавшие наилучшие результаты попадают в интервал 3-4 слов. Постарайтесь внимательно подбирать слова и делайте как можно более подробное описание в этом ограниченном пространстве. Если вы уже нашли идеальное название, и оно немного короче (1 слово) или немного длиннее (6-8 слов), то не волнуйтесь — небольшие вариации — это неплохо.

Названия из нескольких частей привлекают больший интерес


Игроки обычно предпочитают названия из нескольких частей. Скорее всего, причина заключается в том, что они позволяют передать больше информации в ограниченном пространстве. Хорошим планом будет использование названия из нескольких частей, вызывающее дополнительные эмоции или содержащее описание.

Название должно быть уникальным и интересным


Названия с несловарными словами с большей вероятностью имеют хорошие результаты, поэтому нечто уникальное в названии позволяет ему выделиться из списка стандартных названий.

Сиквелы и франшизы продаются лучше


Если основать игру на уже существующей работе, то вы получите больший шанс на успех. Причина этого, скорее всего, заключается в том, что игроки знакомы с предыдущей IP. Но это и хорошая новость для инди-разработчиков, которые хотят превратить один проект в серию игр.

Дальнейшие исследования для любителей данных


Хотите поднять исследования на новый уровень? Вот два способа, которыми можно расширить выполненный анализ и получить более глубокие результаты.

Разбейте подмножества IP


Мы немного обсудили процент игр, ссылающихся на уже существующую интеллектуальную собственность, но это подмножество само по себе может содержать интересные данных. Сколько игр ссылается на предыдущие игры? Фильмы? Книги? Ещё одной интересной линией исследований может быть сравнение результатов разных игр в серии. Например, были ли четвёртые игры так же успешны, как и третьи?

А как насчёт самых плохих игр?


Мы сравнили лучше 10% игр с общим массивом данных, но как насчёт худших 10%? Сегментирование этой части данных может привести к интересным новым открытиям, особенно в том, каких названий стоит избегать.

Let's block ads! (Why?)

Майнер Monero: теперь и в рекламе YouTube

image

Осторожно: майнеры на JavaScript теперь могут быть встроены в рекламу, которую вам показывает YouTube и другие рекламные сети. Об этом сообщили сразу несколькоисточников.

Первыми сообщили о проблеме в Twitter пользователи, чьи антивирусы способны обнаруживать криптомайнеры.


Атакующие пользовались услугами сервиса Coinhive, который предоставляет возможность использовать публичный JavaScript-код с сайта для майнинга на чужих компьютерах. При этом процессоры пользователей загружались майнером до 80%.
imageАтака производилась через рекламный сервис Google DoubleClick. По данным компании Trend Micro, за счёт показанной рекламы количество веб-майнеров в сети на некоторое время выросло в три раза. В некоторых случаях пользователям вдобавок к JS-майнеру еще и отображалась реклама фейкового антивируса — и конкретно за это объявление отвечает пользователь Coinhive с ключом h7axC8ytzLJhIxxvIHMeC0Iw0SPoDwCK.

Представители Google признали, что подобную рекламу в последнее время действительно регулярно пытаются поставить недобросовестные партнеры, но с ней стараюсь активно бороться, и именно эта вредоносная реклама была удалена всего через два часа после запуска. Однако свидетельства пользователей указывают на то, что реклама показывалась как минимум неделю — согласно данным той же Trend Micro, код майнера активно работал с 18 января.

Идея атаковать YouTube связана с тем, что пользователи проводят на сайте продолжительное время, поэтому в ближайшем будущем можно ожидать подобного и на других сервисах, нацеленных на потребление контента.

Let's block ads! (Why?)

пятница, 26 января 2018 г.

Оптимизация многоступенчатых компрессоров по энергозатратам на адиабатическое сжатие газа

Введение


В 1934 году швейцарская фирма «БроунБовери» (Brown-Boveri) на основе теоретических работ Стодолы впервые создала многоступенчатый осевой компрессор с КПД 84 %. Вскоре, осевые компрессоры стали успешно использоваться этой фирмой для газотурбинных установок.

Многоступенчатые осевые компрессоры [1]

Принципиальная схема осевого многоступенчатого компрессора приведена на рисунке:

Осевой многоступенчатый компрессор состоит из ряда последовательно расположенных направляющих лопаток 6, закрепленных в корпусе 7, и рабочих лопаток 5, расположенных на барабанном роторе 11. По мере сжатия, объем воздуха уменьшается и, следовательно, уменьшаются высоты лопаток.

Вращаясь, рабочие лопатки ротора сообщают газу кинетическую энергию. При движении по расширяющимся каналам рабочих лопаток относительная скорость воздуха падает, происходит уменьшение кинетической энергии потока с соответствующим повышением давления в нем.

Изменение относительной скорости потока в канале рабочих лопаток связано с расходом энергии, подводимой к компрессору.

В расширяющихся каналах направляющих лопаток наблюдается дальнейшее повышение давления воздуха и уменьшение скорости его движения. В проточную часть компрессора воздух поступает через входной патрубок 1 и направляющий аппарат 4, откуда, пройдя каналы рабочих лопаток 5 и направляющих лопаток 6, попадает в спрямляющий аппарат 8.

Направляющий аппарат обеспечивает необходимое направление воздушному потоку перед входом в первую ступень, а спрямляющий аппарат обеспечивает осевой выход в диффузор 9 и далее в выходной патрубок 10.

Число ступеней сжатия в такой конструкции количеством рабочих лопаток 5, расположенных на барабанном роторе 11.
Многоступенчатые поршневые компрессоры [2]

Для получения сжатого газа более высокого давления (0,1-2 МПа и выше) применяются многоступенчатые компрессоры с промежуточным охлаждением газа после каждой ступени.

Сущность многоступенчатого сжатия может быть пояснена на примере двухступенчатого компрессора, схема которого и идеальная (при Vo = 0) индикаторная диаграмма представлена на рисунке:

В первой ступени 1 газ сжимается по политропе 1–2 до давления Р2, а затем он поступает в промежуточный холодильник 3, где охлаждается до начальной температуры T1. Гидравлическое сопротивление холодильника по воздушному тракту делают небольшим. Это позволяет считать процесс охлаждения 2–3 изобарным.

После холодильника газ поступает во вторую ступень 2, где сжимается по политропе 3–4 до давления Р3. Если бы сжатие до давления Р3 осуществлялось в идеальном одноступенчатом компрессоре (линия 1–2'), то величина затраченной за цикл работы определялась бы площадью 012'b0.

При двухступенчатом сжатии с промежуточным охлаждением, эта работа численно равна площади 01234b0. Заштрихованная площадь соответствует экономии работы за цикл при двухступенчатом сжатии.

Многоступенчатое сжатие газа [3]

При многоступенчатом изоэнтропическом сжатии газа от начального давления Po до конечного давления Pn, желательно, установить такие промежуточные давления, при которых суммарная энергия, израсходованная на сжатие, была бы минимальной.

Газ охлаждается изобарический до своей начальной температуры T, после каждого адиабатического сжатия. Затраты энергии на n- ступени определяются из уравнения:

где: m- число кмолей сжимаемого газа;R-универсальная газовая постоянная,;
T — начальная температура газа, K; γ — отношение удельных теплоемкостей газа при постоянном давлении и постоянном объеме, в работе принято γ=1,4; xn- давление газа после сжатия на n ступени.

Постановка задачи


1. Найти такое распределение давлений на выходе ступеней адиабатического сжатия при котором затраченная на сжатие энергия , будет минимальна;
2. Определить влияние числа степеней сжатия на минимальную энергию сжатия при одинаковых значениях начального и конечного давлений.

Решение задачи средствами библиотеки scipy. optimize


Сначала рассмотрим пять степеней сжатия в соответствии с расчётной схемой, приведенной на рисунке:

Листинг программы
#!/usr/bin/env python
#coding=utf8
import numpy as np# модуль для создания списков
from scipy.optimize import minimize# модуль оптимизации
import matplotlib.pyplot as plt# модуль для графиков
import time# модуль для контроля времени
Po=1#начальное давление газа
Pzad=64#конечное давление газа
g=1.4#отношение удельных теплоемкостей газа
m=10# число кило моль газа
R=8.314# универсальная газовая постоянная
a=(g-1)/g
T=293# температура газа
a=0.286
"Распределение энергии по ступеням сжатия:"
def E1(x1):
                return m*R*T*a*((x1/Po)**2-1)
def E2(x1,x2):
                return m*R*T*a*((x2/x1)**2-1)
def E3(x2,x3):
                return m*R*T*a*((x3/x2)**2-1)
def E4(x3,x4):
                return m*R*T*a*((x4/x3)**2-1)
def E5(x4):
                return m*R*T*a*((Pzad/x4)**2-1)        
start = time.time()
def E(x1,x2,x3,x4):#
         return E1(x1)+E2(x1,x2)+E3(x2,x3)+E4(x3,x4)+E5(x4)
def fun2(x):
   return E(*x)
x0 =[4,15,24,40] #точка начала поиска экстремума
res = minimize(fun2, x0)# распределение давления при минимуме энергии
stop = time.time()
print ("Время работы оптимизатора:",round(stop-start,3))
x1=round(res['x'][0],3)#давление на выходе I ступени
x2=round(res['x'][1],3)#давление на выходе II ступени
x3=round(res['x'][2],3)#давление на выходе III ступени
x4=round(res['x'][3],3)#давление на выходе IV ступени
x5=Pzad
"Формирование списка давлений:"
x=[]
x.append(x1)
x.append(x2)
x.append(x3)
x.append(x4)
x.append(x5)
z1=E1(x1)# затраты энергии I ступени
z2=E2(x1,x2)+z1# общие затраты энергии I+II ступени
z3=E3(x2,x3)+z2#общие затраты энергии I+II +III ступени
z4=E4(x3,x4)+z3#общие затраты энергии I+II +III +IV ступени
z5=E5(x4)+z4#общие затраты энергии I+II +III +IV+V ступени
"Формирование списка затрат энергии:"
y=[]
y.append(z1)
y.append(z2)
y.append(z3)
y.append(z4)
y.append(z5)
plt.title('Затраты энергии - %s кДж на  %s ступенчатое  \n\
адиабатическое сжатие газа с  %s до  %s ати '%(int(z5),len(y),Po,Pzad))
plt.ylabel('Затраты энергии')
plt.xlabel('Давление газа')
plt.plot(x[0],y[0],'o', label='I ступень, давление - %s'%x1)
plt.plot(x[1],y[1],'o', label='II ступень, давление - %s'%x2)
plt.plot(x[2],y[2],'o', label='III ступень, давление - %s'%x3)
plt.plot(x[3],y[3],'o', label='IV ступень, давление - %s'%x4)
plt.plot(x[4],y[4],'o', label='V ступень, давление - %s'%x5)
plt.plot(x,y,'r')
plt.legend(loc='best')
plt.grid(True)
plt.show()


Получим:
Время работы оптимизатора: 0.0

Увеличим количество ступеней сжатия на одну согласно следующего листинга:

Листинг программы
#!/usr/bin/env python
#coding=utf8
import numpy as np# модуль для создания списков
from scipy.optimize import minimize#модуль оптимизации
import matplotlib.pyplot as plt#модуль для графиков
import time# модуль для контроля времени
Po=1#начальное давление газа
Pzad=64#конечное давление газа
g=1.4#отношение удельных теплоемкостей газа
m=10# число кило моль газа
R=8.314# универсальная газовая постоянная
a=(g-1)/g
T=293# температура газа
a=0.286
"Распределение энергии по ступеням сжатия:"
def E1(x1):
                return m*R*T*a*((x1/Po)**2-1)
def E2(x1,x2):
                return m*R*T*a*((x2/x1)**2-1)
def E3(x2,x3):
                return m*R*T*a*((x3/x2)**2-1)
def E4(x3,x4):
                return m*R*T*a*((x4/x3)**2-1)
def E5(x4,x5):
                return m*R*T*a*((x5/x4)**2-1)        
def E6(x5):
                return m*R*T*a*((Pzad/x5)**2-1)  
start = time.time()
def E(x1,x2,x3,x4,x5):
         return E1(x1)+E2(x1,x2)+E3(x2,x3)+E4(x3,x4)+E5(x4,x5)+E6(x5)
def fun2(x):
   return E(*x)
x0 =[4,15,20,30,40]#точка начала поиска экстремума
res = minimize(fun2, x0)# распределение давления при минимуме энергии
stop = time.time()
print ("Время работы оптимизатора :",round(stop-start,3))
x1=round(res['x'][0],3)#давление на выходе I ступени
x2=round(res['x'][1],3)#давление на выходе II ступени
x3=round(res['x'][2],3)#давление на выходе III ступени
x4=round(res['x'][3],3)#давление на выходе IV ступени
x5=round(res['x'][4],3)#давление на выходе V ступени
x6=Pzad# давление на выходе VI ступени
"Формирование списка давлений:"
x=[]
x.append(x1)
x.append(x2)
x.append(x3)
x.append(x4)
x.append(x5)
x.append(x6)
z1=E1(x1)# затраты энергии I ступени
z2=E2(x1,x2)+z1# общие затраты энергии I+II ступени
z3=E3(x2,x3)+z2# общие затраты энергии I+II+III ступени
z4=E4(x3,x4)+z3# общие затраты энергии I+II+III+IV ступени
z5=E5(x4,x5)+z4# общие затраты энергии I+II+III+IV+V ступени
z6=E6(x5)+z5# общие затраты энергии I+II+III+IV+V +VI ступени
"Формирование списка затрат энергии:"
y=[]
y.append(z1)
y.append(z2)
y.append(z3)
y.append(z4)
y.append(z5)
y.append(z6)
plt.title('Затраты энергии - %s кДж на  %s ступенчатое  \n\
адиабатическое сжатие газа с  %s до  %s ати '%(int(z6),len(y),Po,Pzad))
plt.ylabel('Затраты энергии')
plt.xlabel('Давление газа')
plt.plot(x[0],y[0],'o', label='I ступень, давление - %s'%x1)
plt.plot(x[1],y[1],'o', label='II ступень, давление - %s'%x2)
plt.plot(x[2],y[2],'o', label='III ступень, давление - %s'%x3)
plt.plot(x[3],y[3],'o', label='IV ступень, давление - %s'%x4)
plt.plot(x[4],y[4],'o', label='V ступень, давление - %s'%x5)
plt.plot(x[5],y[5],'o', label='VI ступень, давление - %s'%x6)
plt.plot(x,y,'r')
plt.legend(loc='best')
plt.grid(True)
plt.show()


Получим:
Время работы оптимизатора: 0.005

Сравнивая приведенные графики, можно определить снижение энергозатрат на адиабатическое сжатие газа:

(149024 -125405)*100/149024=15, 85%

Вывод: увеличение числа ступеней сжатия только на единицу позволяет сэкономить почти 16 % энергии, затраченной на адиабатическое сжатие газа в многоступенчатом компрессоре.

Однако, это только один вид затрачиваемой энергии. Понятно, что введение дополнительной ступени приведёт не только к дополнительным затратам при изготовлении, но и к дополнительным эксплуатационным затратам, за счёт увеличения мощности двигателя и секции системы охлаждения.

Оптимальный вариант нужно выбирать с учётом всех видов затрат, но это уже совсем другая задача.

Выводы:


1. Найдено распределение давлений на выходе ступеней адиабатического сжатия при котором затраченная на адиабатическое сжатие энергия , минимальна;

2. Увеличение числа ступеней сжатия только на единицу позволяет сэкономить почти 16 % энергии, затраченной на адиабатическое сжатие газа в многоступенчатом компрессоре.

Ссылки:


1. Компрессоры газотурбинных установок (ГТУ).
2. Многоступенчатый компрессор.
3. Фан — Лянь — Цэнь, Ван, Чу – Сен. Дискретный принцип максимума. — М, «Мир»,1967.-176 с.

Let's block ads! (Why?)

Добываем WiFi соседа стандартными средствами MacOS

Я всегда был фанатом багов и уязвимостей «на поверхности», всегда завидовал чувакам, которые пишут эксплоиты для самых защищённых ОС, а сам умел только скрипткидить (термин из нулевых). Однако, мой пост про уязвимости в системах контроля версий набрал более 1000 лайков на хабре и остаётся топ1 постом за всю историю хабра, не смотря на то, что был написан 9 (!) лет назад.
И сегодня я хотел бы на пальцах показать и рассказать про такую штуку, как Вардрайвинг. А точнее, как стандартными средствами MacOSX можно добыть пароли от WiFi соседей. Нелёгкая забросила меня на очередную квартиру. Как-то исторически сложилось, что я ленивый. Пару лет назад я уже писал, что моя лень, новая квартира и провод beeline (бывшая corbina) помогла мне найти багу у билайна и иметь бесплатно интернет в их сети. «Сегодня» происходит «подобное», я на новой квартире, нет даже провода, но есть много сетей у соседей

Заколебавшись расходовать мобильный трафик, я решил, что «соседям надо помогать», и под «соседями» я имел введу себя…
Когда-то давно я увлекался вардрайвингом, как раз именно до того момента, пока не обнаружил в старой квартире провод билайна ;) там тоже было много сетей рядом и первое что пришло в голову — мне нужен wifi. С тех пор прошло много лет. Обновляя свои данные про вардрайвинг я нашёл в сети упоминание, что 90% работы спец. утилит «сегодня» можно сделать стандартными сервисами MacOSX. Забегая вперёд, я хотел бы отметить, что не являюсь автором данного метода, я сам нашёл его в забугорном инете, просто, скажем, это вольный перевод и подробное, художественное описание способа добыть wifi пароли стандартными методами макоси. Не более )

Принципы добычи паролей соседского WiFi


Надо понимать, что имея WiFi приёмник, который есть сегодня в любом ноутбуке, ты можешь «снифать» весь беспроводной трафик около себя. Раньше, когда сети были открыты, достаточно было прийти в макдак и за вечер можно было получить 100-200 акков к одноклассникам. Открытая сеть + отсутсвие https делали своё дело.
Сейчас всё интереснее, все переходят на https (пользуясь случаем, хочу передать привет Lets Encypt. Любимый Lets Encypt, я в телевизоре и передаю вам привет, спасибо что вы есть) и даже про WEP уже все забыли, все роутеры юзают WPA2. Но, как известно, меч был придуман раньше щита, и никакой WPA2 не помеха человеку, голодного до интернета и видящего около себя кучу WiFi.
Продолжим, имея WiFi карту, т.е. любой современный ноутбук, мы можем снифать трафик возле себя. Но он бесполезен, ибо зашифрован. Единственное, что можно разобрать из него — метаданные, типа название сетей итп и «рукопожатия», handshake, т.е. авторизации пользователей в сети. Они происходят каждый раз, когда пользователь подключается к wifi сети. Например, когда сосед приходит домой и его смартфон в кармане цепляется к wifi домашнему. Если совсем грубо, рукопожатия представляют из себя обычный хэш, типа md5. И да, я солгал в своём первом абзаце про «дешифрацию», это техническая ошибка и подмена понятий. Конечно, дешифровать хэш невозможно. Это как говорить «лицензия такси», зная, что деятельность такси в РФ не лицензируется. Но просто так удобней )
Дак вот ) всё что нам надо, это найти среди траффика радиосети вокруг себя рукопожатия и «дешифровать» их )) И раньше была куча софта для всего это. Кто-то умел грамотно сканировать радиоканал, кто-то отлично его снифал в дампы, кто-то находил хэши в дампах, кто-то умел их ломать. Сейчас всё стало проще, благодаря Тиму Куку. 90% работы за стороннее ПО делает стандартное приложение «Беспроводная диагностика». Многие его видели, когда проблемы с WiFi, мак предлагает проверить сеть. Бесполезная утилита, которая даёт советы типа «перезагрузите роутер». Ну, т.е. мне так казалось )

Добываем пароли. Соседи вешайтесь ;)


Итак, погнали. Зажимаем Alt и кликаем по логотипу WiFi в верхней панеле, вообще Alt и клик всегда открывает дополнительные опции в MacOSX, но это тема отдельного топика.

помимо прочей доп.инфы, которая порой очень полезная, мы можем запустить программу «Беспроводная диагностика». Думаю, все кто пользуются маком, помнят это окно.

Но нас интересует другое. Кликаем по пункту меню «Окно» и видим набор дополнительных утилит.

И тут прям есть всё, что надо, даже больше ) Конкретно нас интересуют 2 пункта. Сканирование и Анализатор. Первый покажет нам все сети вокруг с доп. инфой, типа на каком канале и на какой частоте работает сеть. Второй пункт позволит сниффать трафик на конкретном канале и чистоте.


Нажимая на кнопку «Начать» в Анализаторе, WiFi карточка переключится в режим приёма и начнёт сканировать радиочастоту вокруг себя, дамп будет писаться в /var/tmp.

Файлы *.wcap это наши дампы, которые содержат бесполезный для нас траффик и нужные нам рукопожатия.
Надо понимать, что нам необходимо поймать именно рукопожатия. Т.е. нам надо поймать и снифать траффик, когда сосед приходит домой вечером. Либо, если у вас есть ещё одно устройства на макосе, либо любой другой оси, вам помогут нюкеры. Программки, рассылающие поддельные команды деаунтефикации. Например, JamWiFi. Но это если прям совсем не терпится ) На моём опыте, достаточно просто запустить Анализатор в 6 вечера на часок.
Далее нам надо поставить naive-hashcat и hashcat-utils. «Стоп» скажите вы, «ты же обещал взлом сетей соседа стандартными методами?» ) Ха! И вы мне поверили?! На самом деле мы стандартными методами сделали 90% работы через GUI. У нас уже есть хэши, всё что нам надо — разбить их. Уверен, можно всё сделать и стандартными утилитами, но проще юзать hashcat. Собираем софт через brew или из сорцов. Первым делом нам надо конвертировать наш дамп, оставив в нём только наши хэши. Этим занимается бинарник cap2hccapx из пакета.

./cap2hccapx /var/tmp/2018.01.25_00-37-45-GMT+3.wcap /var/tmp/home.hccapx



Мы видим, что успели перехватить 2 рукопожатия, попробуем «сломать их». Для этого нам нужен naive-hashcat

git clone https://github.com/brannondorsey/naive-hashcat
cd naive-hashcat

# Собираем софт для osx
./build-hashcat-osx.sh

# качаем вордлист для побора wpa/wpa2 сетей пароли (134MB)
curl -L -o dicts/rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt

# указываем адрес нашего дампа и файл, куда будем писать подобранные пассы, 2500 это метка хэшкэту, что надо ломать именно WPA, ну и запускаем naive-hashcat

HASH_FILE=/var/tmp/home.hccapx POT_FILE=home-wifi.txt HASH_TYPE=2500 ./naive-hashcat.sh


Кошка пошла работать. В среднем у меня на маке я имею скорость в 2000 хешей в секунду, на скрине 7к, но это только старт. Судя по этому документу, на 1080gtx можно получить скорость в 400к хешей в секунду. Однако у меня всего 2 рукопожатия и не такой уж и большой словарь, поэтому пробежаться по нему не составило проблем. Смотрим файл home-wifi.txt, вуаля

Вот и всё. К сожалению, эта сеть через несколько квартир от меня и на другом этаже, пинг 7 секунд ) надо ловить соседа снизу или брать внешнюю wifi карту с нормальной антенной. Но принцип, думаю, понятен.
Удачных сканирований вам, юные подованы вардрайверы. И большое спасибо разработчикам Kali Linux MacOSX за такие подарки.
Ну и вы найдёте много ещё интересного тут:
https://github.com/brannondorsey/wifi-cracking/blob/master/appendix.md

Let's block ads! (Why?)

Моделирование физических процессов на примере гидропривода в SimInTech

В предыдущей статье (Конечные автоматы в SimInTech), было показано как создавать модель системы управления на основе конечных автоматов и получать из нее код Си, готовый для загрузки в контроллер. В качестве объекта управления была выбрана достаточно простая система нагреватель и была создана примитивная модель. Чем сложнее модель, объекта тем сложнее система управления и тем интереснее ее моделирования на стадии разработки.

Основное назначение данного текста – показать как создавать модели в ПО SimInTech, зная математические уравнения физических процессов. В качестве примера использовались уравнения физических процессов в гидроприводе. По аналогии так же можно решать задачу с другими физическими процессами, уравнения которых нам известны.

За основу, с любезного разрешения автора, было взято вот это методическое пособие: Андреев М.А. Математическое моделирование гидропривода: Учебное пособие. — на правах рукописи, 2017. — 61 с.
Оригинал расположен здесь: vk.com/doc2869_441829149
С автором оригинального руководства можно связаться по контактам
ВКонтакте: vk.com/max.andreev
Facebook: www.facebook.com/max.andreev
Telegram: t.me/MaximAndreev


Предисловие от Максима Андреева:

С программой SimInTech я столкнулся будучи студентом ещё в те времена, когда она называлась «МВТУ» (Моделирование В Технических Устройствах). Так что, свои первые неловкие попытки моделировать гидропривод я предпринимал именно в ней. Скажу честно, что после того как у меня появилась возможность работать в MATLAB Simulink, я постарался забыть об этом опыте как о страшном сне (впрочем, после пары лет работы в программе SimulationX я и об опыте моделирования в Simulink (включая Simscape) предпочитаю лишний раз не вспоминать).

Тем не менее, мои глубинные патриотические чувства не может не трогать тот факт, что команда разработчиков в последние годы активно принялась за совершенствование этого важного для отечественной инженерной отрасли наследия советских инженеров и существенно продвинулась в этом деле (об этом говорит хотя бы то, что модели, созданные в SimInTech, используются для моделирования работы АЭС, в т.ч. и в Германии). Поэтому, когда ко мне обратились за разрешением адаптировать текст моего учебного пособия для SimInTech, я конечно же согласился.


В советское время было написано достаточно много литературы, посвященной расчету гидропривода, в том числе описанию физических процессов и математическому моделированию. Но проблема заключается в том, что для того, чтобы эти книги принесли пользу читателю, необходимо уже уметь писать математические модели. По крайней мере мне нигде не удалось найти описания пошагового процесса создания математической̆ модели гидропривода. В лучшем случае автор подробно описывает откуда берётся каждое уравнение огромной системы, но что с ними дальше делать, обычно не очень понятно.

Здесь я постараюсь изложить общую методологию создания математической модели гидропривода различной сложности, начиная от расчетной схемы, записи уравнений и заканчивая реализацией в SimInTech, демонстрационную версию которой можно получить здесь..

После прочтения этого руководства вы будете в состоянии самостоятельно, без использования каких-либо шаблонов, смоделировать работу гидропривода с учетом основных физических процессов и понимать специальную литературу, из которой сможете опять-таки самостоятельно почерпнуть способы описания более сложных процессов.

Принципы создания моделей гидропривода можно применять для любых других систем, дифференциальные уравнения которых, вам известны.


В освоении любого незнакомого ранее ремесла, очень важно взять посильную тренировочную задачу.
В нашем случае задача будет предельно проста:

Имеется цилиндрический плунжер диаметром 10 мм, с приведенной массой 100 кг, он работает на пружину жесткостью 200 Н/мм и демпфер с коэффициентом вязкого трения — 1000 Н/(м/с). Нужно посмотреть как он будет перемещаться, если мы ступенькой подадим в полость с начальным объемом 20 см3 давление 200 бар. Чтобы плунжер не превратился в пулю, поставим между источником давления и камерой дроссель диаметром 0,2 мм.


С чего же начать? Многим может показаться, что нужно начать с выбора софта, в котором можно моделировать такую систему. Это не так. На самом деле, начать нужно с листа бумаги и карандаша. Если при помощи этих инструментов внимательно записать уравнения, то потом можно будет решить их в любом софте.

Более того, как показывает практика, если посадить человека за какую-нибудь программу, где математические модели можно писать путем перетаскивания готовых блочков из библиотек, чаще всего результат оказывается неудовлетворительным. В лучшем случае модель просто отказывается считаться. В худшем случае она выдает какой-то бредовый результат, но автору уже трудно поверить в то, что проблема не в софте, а в его кривых руках.

Поэтому я убежден, что по крайней мере на начальном этапе просто необходимо прописывать все уравнения. Этим и займёмся.

Первое правило: «Дроби задачи на подзадачи!»
В нашем случае можно выделить несколько физических процессов, поддающихся математическому описанию:
• прохождение рабочей жидкости через дроссель (дросселирование);
• её сжатие в рабочей полости плунжера;
• перемещение массы с учетом взаимодействия с пружиной и демпфером.

Второе правило: «Начинай с конца!»

Что мы хотим получить в итоге? Наверное, график зависимости перемещения плунжера x от времени t. Так давайте и начнем описание с уравнения движения этого плунжера:
(1)
где m — масса плунжера, Ap – площадь плунжера, Сpr – жесткость пружины, btr – коэффициент вязкого трения, p – давление в камере.

Здесь нет ничего нового для тех, кто учился хотя бы до 6-го класса школы. Разве что производные заменены точками для удобства. Единственное на что необходимо обратить внимание, это на выбор положительного направления перемещения и на знаки действующих сил.

На рисунке видно, что в качестве положительного направления я выбрал перемещение плунжера вправо. Тогда сила со стороны жидкости в уравнении будет со знаком «плюс», сила со стороны пружины и демпфера со знаком «минус». Вот и всё.


К черту формулы! Даешь моделирование!

Поскольку мы моделируем в SimInTech, то что бы не откладывать в долгий ящик, мы можем начинать создавать модель, в полном соответствии с правилом 1, решаем задачу по частям сначала – плунжер с пружиной.

Открываем SimInTech и создаем новый проект общего вида (Главное меню «Файл/Новый проект/Схема модели общего вида»).

Сначала запишем в качестве констант исходные данные, которые нам нужны для расчета. На схемном окне проекта вызовем редактор скрипта, здесь мы запишем все константы из исходных данных (см. рисунок 1).


Рисунок 1. Задание глобальных параметров расчета.

Константы задаются через запятую, после последней ставится точка запятой. (см. рис. 1). Для того, чтобы не путаться в дальнейшем, все константы заданы в стандартных единицах измерений.
Так же выполним расчет площади проходного сечения. Площадь мы рассчитываем в секции инициализации, которая выполняется только один раз при старте расчета.


Константы и переменные, заданные в данном окне, доступны в любой части проекта.

Разместим на схеме блоки «Ступенька» из закладки «Источники», «Язык программирования» из закладки «Динамические» и «График» из закладки «Данные». Схема должна получится сходной с рисунком 2:


Рисунок 2. Схема модели плунжера.

С помощью блока ступенька будем моделировать входное воздействие, для модели плунжера это давление.
На 1 секунде расчета значение будет меняться с 0 до 200 бар. Для этого в свойствах блока зададим значения, указанные на рисунке 3:


Рисунок 3. Настройки параметров ступеньки.

Если сейчас запустить модель на расчет (кнопка «Пуск»), то график отразит ступеньку исходных данных, блок «Язык программирования», по умолчанию просто передает сигнал без изменений:


Рисунок 4. График ступеньки.

В блоке «Язык программирования» можно записывать уравнения динамики объекта в форме Коши.

Прежде чем перейти к записи модели преобразуем уравнение (1), в систему двух уравнений, добавив новую переменную – скорость v(t) = dx(t)/dt.
Таким образом, уравнения движения примут вид 2:
(2)

Из такой системы уже можно создавать модель. Входным параметром модели будет давление p(t), выходным параметром будет перемещение плунжера х(t).
В модели будут две динамические переменные х(t) и v(t), начальные значения этих переменных принимаем равными 0.
Такую систему уже можно записывать на языке программирования, как показано на рисунке 5.


Рисунок 5. Модель плунжера с пружиной

Текст, по моему мнению, максимально понятен практически каждому человеку, кто знаком с любым языком программирования.
input P; – вход в блок (давление)
оutput x; – выхода из блока.
init x=0, v=0; – объявление динамических переменных и присвоение им начальных значений;
Дальше идет текст, который выполняется на каждом шаге моделирования.

В принципе текст на языке программирования практически повторяет систему уравнений, где производные dx(t)/dt и dv(t)/dt обозначены как x’ и v’.

Если сейчас запустить процесс моделирования, то скорее всего вы получите график как на рисунке 6. Как говорится упс! У нас получилась полная хрень, ни на что не похожая. Данный график наглядно иллюстрирует необходимость соблюдения правила номер раз. «Дроби задачи на подзадачи!»

Поскольку мы решаем уравнение, описывающее движение массы на пружинке, мы приблизительно понимаем, что ожидать. Должен быть колебательный процесс, который из-за наличия силы трения должен затухать. Мы же видим колебания, которые ведут себя очень странно.



Рисунок 6. График перемещения плунжера.

Главное здесь не пугаться и не впадать в панику, таких бессмысленных и беспощадных графиков вы еще насмотритесь. Первое, что рекомендуем сделать – изменить шаг интегрирования. Фактически эта уневерсальная рекомендация явялется третьем правилом моделирования :

Третье правило моделирования:При любых непонятных результатах уменьшай шаг интегрирования!

Нажмите кнопку с молотком и отверткой на схемном окне, найдите в параметрах расчета максимальный шаг моделирования и измените его на 0.01 (см. рис. 7.) Закройте окно настроек нажав кнопку ОК.


Рисунок 7. Настройка шага интегрирования.

Если запустить расчет с такими настройками (как показано на рисунке 7), то результат буде более похож на правду (см. рис. 8).


Рисунок 8. Результат при максимальном шаге 0,01.

Результат расчета на рисунке 8 показывает, что у нас в момент возникновения давления на 1 секунде происходит быстрый разгон плунжера, из-за инерции движения, плунжер проскакивает точку равновесия, пружина сжимается и возвращает поршень назад, возникают колебания, а поскольку у нас есть сопротивление трения, то колебания затухающие.

Решение задачи по частям дает возможность нам проверить правильность физического моделирования, путем постановки численного эксперимента.

Например, если уменьшить коэффициент вязкого трения в 10 раз, то колебания должны затухать дольше. Изменим данный параметр в основном скрипте модели (см. рис. 1) и при моделировании получим график как на рисунке 9:


Рисунок 9. Результат при Btr = 100.

Если увеличить массу плунжера в 10 раз, оставляя все остальные параметры заданными изначально, то колебания будут происходит с меньшей частотой, и время переходного процесса так же увеличится, что мы наблюдаем на рисунке 10.


Рисунок 10. Результат при m = 1000.

Еще одним способом проверки правильности модели будет сравнение конечного перемещения, полученного в модели и рассчитанного из условия равновесия системы. В случае равновесия сила, действующая на плунжер (Pst*Ap), уравновешивается силой сжатой пружины (Cpr*x_st), где:
Pst – давление статическое;
x_st – перемещение поршня (сажание пружины);
Pst*Ap = Cpr*x_st или x_st = Pst*Ap/Cpr.

Расчет конечного положения плунжера можно выполнить прямо в окне блока «Язык программирования» (см. Рисунок 11).


Рисунок 11. Проверка конечного положения плунжера.

Запись расчета стационарного положения можно внести прямо в тело программы блока, и при нажатии на кнопку «калькулятор» будет выведено окно с значениями переменных скрипта, двойной клик по линии связи на выходе из блока покажет значение сигнала на линии связи. Мы убеждаемся, что переходный процесс завершился с таким же значением, как и статический расчет (см. рис 11.) Таким образом можно убедиться, что модель выходит на правильные значения положения и при 150 бар и при 250 бар.

Получив и проверив модель плунжера с пружиной, можно переходить к модели камеры.


Уже понятно, что входным сигналом для модели плунжера является давление в рабочей камере. Неплохо было бы знать это значение давления в рабочей камере. И тут уже появляется что-то новенькое. Оказывается, то что нам рассказывали в школе и на младших курсах про несжимаемость жидкости — враньё. На самом деле она сжимается, особенно в гидроприводе с давлением от 160 бар и выше.

Да, я знаю, что вы сейчас в глубоком шоке от этой новости, но нужно как-то с этим дальше жить и описывать этот процесс уравнениями. На мой взгляд, удобнее всего это описывается следующим образом:

(3)
где: ṗ — скорость изменения давления; E — приведенный объемный модуль упругости рабочей жидкости; V — объем сжимаемой рабочей жидкости; Q — расход, поступающий в рабочую камеру; Aр*x' — скорость изменения объема камеры из-за перемещения плунжера


Вывести это выражение нетрудно из формулы для определения объемного модуля упругости:

(4)

Если разнести дифференциалы давления и объема по разные стороны знака равенства, а затем продифференцировать обе части по времени.

Логично предположить, что давление будет меняться тем быстрее, чем выше модуль упругости рабочей жидкости E, и тем медленнее, чем больше объем этой жидкости V. Поэтому модуль упругости у нас в числителе, а объем — в знаменателе. В скобки я поместил алгебраическую сумму расходов. В данном случае мы имеем дело с расходом через дроссель Q и с геометрическим расходом от перемещения плунжера. Положительное значение расхода Q при прочих равных будет приводить к росту давления (положительная скорость изменения давления), а положительная скорость перемещения плунжера к падению давления. Поэтому расход через дроссель в уравнении со знаком «плюс», а геометрический расход со знаком «минус».

Объем камеры в свою очередь можно описать формулой:
(5)

Где V0 — т.н. «мертвый» объем (объем жидкости при нулевом положении x(t) поршня).

На самом деле, влияние изменения объема жидкости очень несущественно, и во избежание лишних ошибок (например, при отрицательных x), лучше принимать просто постоянный объём, равный половине разницы объёмов в конечном и начальном положениях.

Ко мне часто приходят студенты, которые не первые сутки бьются над своей моделью, которая выдаёт какой-то бред в виде астрономических значений давления, нереальных перемещений и т.п. Очень часто мне бывает достаточно примерно одной минуты «общения» с моделью, чтобы она заработала. И дело тут не в моей гениальности, а в том, что почему-то около 80% ошибок у начинающих «моделистов» приходятся именно на неправильную расстановку знаков в уравнении баланса расходов (уравнении сжимаемости жидкости). Я не был исключением. Мне, насколько я помню, понадобилась где-то неделя, чтобы найти в своей первой̆ модели гидропривода эту ошибку.

А поскольку у нас модель плунжера в SimInTech уже отлажена, более того, у нас есть возможность проверить положение штока, мы не будем тратить недели на поиск ошибок.


Модель камеры в SimInTech

Вспоминая правило первое, решаем задачу по частям, создаем модель камеры и подключаем ее к уже испытанной и проверенной модели плунжера.


Для создания модели камеры нам в общих константах проекта понадобятся две новые величины

V0 – начальный объем камеры и Е = 13e8 – приведенный объемный модуль упругости, добавим их в нашем главном скрипте программы:


Рисунок 12. Константы в главном скрипте модели.

Обратите внимание на перенос знака «точка с запятой». Все константы разделены запятыми, секция заканчивается «точкой с запятой».

Входными параметрами для расчета является расход жидкости Q, положение поршня x и скорость перемещения v (смотри формулу 3).

Поставьте новый блок типа «Язык программирования» на схему и просто перепишите уравнения 5 и 3.


Рисунок 13. Модель камеры цилиндра.

Скорость перемещения плунжера необходимо забрать из блока плунжера с пружиной. Для этого меняем текст модели в готовом блоке, добавив еще один выход (см. рис. 14).


Рисунок 14. Модель плунжера с добавленных выходом — скоростью.

Соединяем схему как показано на рисунке 15, подписываем блоки для наглядности.


Рисунок 15. Общая модель цилиндра и камеры.

В принципе можно запустить проект на моделирование и получить несуразные астрономические значения перемещения плунжера в тысячи километров.

Но можно включить голову и вспомнить, что на предыдущем этапе мы подавали на вход модели плунжера давления ступенькой с 200е5 Па (200 бар). Теперь нам нужно из этого блока подать такой расход, чтобы в камере сформировалось давление 200 бар.

Если использовать блок ступенька, то в момент его включения начнет подаваться расход, и он будет постоянным в течение всего времени моделирования, а для требуемого повышения давления мы должны подать в камеру расход только на некоторое время, достаточное для создания давления 200 бар, и после этого прекратить подачу.

Поскольку мы сейчас не знаем, сколько нужно закачать жидкости, для создания требуемого давления в 200 бар, мы используем блок «Кусочно-постоянная» из закладки «Источники». В качестве параметров зададим «прикидочные» значения, приведенные на рисунке 16.


Рисунок 16. Настройки источника расхода в камеру.

В данном блоке задается 3 интервала по 1 секунде. На первом интервале расход 0, на втором интервале расход 1, на следующем и до конца расчета расход 0. Таким образом мы моделируем накачку камеры расходом 1 м^3/c в течение одной секунды. Логично, что такой расход создаст невозможное давление, но мы подберем ее на следующей итерации, сейчас мы просто посмотрим, что у нас получается.

Чтобы понять, насколько мы не угадали с расходом, включим отображение значений на линиях связей (см. рис. 17), что позволит нам видеть, какое давление создано этим объемом жидкости.


Рисунок 17. Результаты расчета первое приближение.

Результаты расчета показывают, что мы «не угадали» и давление в камере установило на уровень около 3.84 е11 вместо необходимого 200е5 (200бар).

Путем подбора определяем, что для создания давления в 200 бар необходимый расход должен составлять примерно 0.98e-7 в течение 1 секунды. Результаты моделирования – на рисунке 18


Рисунок 18. Результаты моделирования равномерной подачи в камеру.

На графике видно, что если расход подавать равномерно в течение секунды, то на начальном этапе происходит рост, с колебаниями, затем устанавливается практически равномерный процесс перемещения в течение секунды, пока мы подаем расход в камеру, и затем после 2 секунд остановка с небольшими затухающими колебаниями.

Теперь нам интересно сравнить модель плунжера с пружиной, которую мы создали на первом этапе и ту же модель, но уже подключённую к камере. Поскольку первую модель мы нагружали ударной нагрузкой (ступенькой), то для формирования похожего импульса, необходимо быстро подать в камеру объем, который необходим для создания такого же давления, но за более короткое время. Можно попробовать сократить время импульса, например в 10 раз, и увеличить в 10 раз расход.

Скопируем блок плунжера с пружиной и подадим на него ступеньку 200 бар.

Подадим на вход камеры расход импульсом длительностью 0.1 секунды, подобрав его так, чтобы конечное давление было около 200 бар. Должна получится примерно такая модель как на рисунке 19.


Рисунок 19. Сравнение модели плунжера с камерой и без камеры.

Если посмотреть на графики, видно, что в течении 0,1 секунды пока идет подача расхода в камеру идет перемещение плунжера, которое потом затухает быстрее, чем без камеры (с мгновенным ростом давления), что похоже на правду.

Видно, что у нас положение плунжера примерно соответствует полученному при отдельном моделировании. Таким образом, мы с помощью SimInTech решили еще одну подзадачу.

Остался последний рывок!


Моделирование дросселя.

Ну вот мы и подходим к последнему уравнению, которое описывает расход через дроссель:

(6) где:

  • f – площадь сечения дросселя;
  • μ – коэффициент расхода;
  • pn –давление нагнетания;
  • p – давление в камере цилиндра.

В этой формуле тоже нет ничего нового для тех, кто хотя бы пол семестра изучал курс гидравлики. Единственная поправка, которую нужно внести — это учёт теоретической возможности обратного тока рабочей жидкости в случае отрицательной разницы давлений (например, когда на поршень действует сила больше, чем может противопоставить сила со стороны рабочей жидкости). Без этого мы рискуем получить отрицательное подкоренное выражение.

По цифрам: коэффициент расхода μ можно взять равным 0.62, а плотность рабочей жидкости ρ = 850 кг/м^3.

Добавляем новые константы в общий скрипт, который итого принимает вид, представленный на рисунке 20:


Рисунок 20. Список констант проекта.

Расчет проходного сечения дросселя также производим в секции инициализации.
После этого нам остается только записать последнее уравнение 6 в новом блоке «Язык программирования», см. рисунок 21.


Рисунок 21. Программа блока дроссель.

Обратите внимание, что первым в описании входов записано pk – давление в камере, соответственно вход с этим именем будет сверху, а давление нагнетания – второе, его вход на блоке будет ниже.

После этого можно соединить на схеме: выход расхода соединить с камерой, а на вход нагнетания подать ступеньку с 0 до 200 бар, как мы делали при создании плунжера с пружинкой. Общая схема получится как на рисунке 22.

Там же приведен и результат расчета переходного процесса при увеличении давления нагнетания скачком с 0 до 200 бар


Рисунок 22. Схема моделирования и результат расчета.

Если у вас получился результат как на рис. 22, то поздравляют! Вы только что разработали модель гидропривода в SimInTech. При этом у вас в качестве исходных данных были только диференциальные уравнения.

Теперь по данном образцу и подобию вы можете созать модель для чего угодно, как говорится отмоделировать все что движется и шевелится, а что не движется — подвигать и тоже отмоделировать!

В следующих частях:

  • Три варианта представления модели одной и той же модели в SimInTech.
  • Сравнение разных моделей гидравлических систем.
  • Создание модели реального гидропривода.

Let's block ads! (Why?)