Бесконечный двухмерный массив на C#

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

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

Примеры:

Создание массива

Добавление единичного значения в массив:

Добавление статического массива со сдвигом offset относительно начала координат[0,0] бесконечного массива:

Получение значения из массива:

Исходный код c#

Внимание! В массиве, как ключ используется тип Point из System.Drawing. Если вы в своем проекте используете другой тип Point (например из XNA, monoGame или OpenTK), то вам необходимо будет изменить зависимость в библиотеке.

Планы и всякое

Я давно не писал в блог “просто так”, о жизни. Этот пост будет посвящен этому. Я расскажу о том, чем я живу в последнее время, о прогрессе в разработке Ignite и о своих планах на будущее.

С 2009-го года я был в свободном плавании – будучи некрасиво уволенным по сокращению с предыдущего места работы, я не нашел ничего лучшего, чем открыть субъект предпринимательской деятельности и продолжить работать самостоятельно, на себя. Дела шли неплохо, но этот пост не про это, как и не про то, как в нашем государстве(Украина) способствуют развитию мелкого бизнеса. Скажу только, что к 2013-му году работать стало окончательно невозможно, и я начал искать работу программиста на стороне.

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

Я пошел работать на должность web developer`a и разрабатываю сейчас интересное web-приложение для своей компании. Она не занимается аутсорсом (как 99% компаний в Украине) и это первое, что меня радует. Второе – то что мне удалось совладать с собой и стресс с депресняком, которые преследовали меня при поиске работы и получении отказов, не заставили меня сменить ни род деятельности, ни даже язык программирования.. хотя конечно акцент с десктопов сместился на веб. Я все также продолжаю совершенствовать свои знания C# и .net framework.

От работы перейдем к личным проектам: работа над Ignit’ом опять застопорилась – за последние три недели я не написал ни строчки кода(ну может быть несколько). Если честно, мне просто надоело его писать. И, вероятно, это будет концом его разработки. В ближайшие дни я соберу версию, пригодную для публикации, и выдам ее на гора. Возможно, исходные коды уедут на github, но, если честно, мне стыдно за некоторые(многие) места времен hello world моего обучения языку C#. Возможно, публичный (сырой) релиз подстегнет мой интерес.. если же нет, то в задумке крутится новая (и совершенно не похожая на предыдущую) игра:

Игра будет написана с использованием MonoGame и будет поддерживать Windows/Linux из коробки и MacOS/iOS/Android в перспективе. Рабочее название Into the Void. Тематика: первое освоение далекого космоса.

C# Отложенное получение данных

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

В моей программе, я использую BackgroundWorker’ы для выполнения длительных вычислений. BackgroundWorker асинхронно выполняет поставленную ему задачу (в событии DoWork), а после ее выполнения может сделать еще какие-нибудь действия (событие RunWorkerCompleted):

К сожалению, если мы передадим переменную, которая должна измениться в результате выполнения асинхронного запроса с модификаторами out или ref следующим образом:

, то это приведет к ошибке на этапе компиляции, т.к. передача ref/out переменных в анонимные методы запрещена.

Обойдем это с использованием собственного класса:

Класс очень простой: он состоит из свойства Value типа Т (т.е. любого, заявленного заранее, типа) и события, которое срабатывает, когда Value изменяется.

Пример использования класса:

В данном случае, strings перестанет равняться null в момент завершения асинхронной операции.

FanArt – рост pagerank

Некоторое время назад я писал про собственноручно написанное приложение для автоматической генерации контента для сайта . Доделав программу, я поюзал ее несколько дней (700+ постов) и законсервировал в ожидании результатов. Результаты не заставили себя ждать: через пару недель сайт появился в выдаче Google, с поиска начались переходы (сейчас 20-30 юников в день), а сегодня, после очередного апдейта, поисковая система добавила + 2 PR.

Ignite – Менеджер для Атласа Текстур

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

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

Исторически сложилось, что хранить мелкие текстуры лучше не в отдельных файлах, а одном большом – атласе текстур. Помещенные в один такой атлас, текстуры наиболее эффективно могут быть обработаны видео-картой компьютера. Но то что хорошо для компьютера, не всегда бывает также приемлемо для человека – работать с текстурами сваленными в одну кучу (что фактически и представляет собой атлас текстур) гораздо сложнее, чем с ними же, но по отдельности. Для решения этих проблем я создал собственный Менеджер для атласа текстур.

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

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

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

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

PHP – случайные записи WordPress

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

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

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

‘numberposts’ => 5

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

‘orderby’ => ‘rand’

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

‘post_status’ => ’publish’

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

‘offset’ => 1

Смещение в одну запись от первой в списке

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

Автоматизированный сайт – автоматическое наполнение контентом

Сегодня я расскажу об одном моем сайд-проекте – сайте-галерее изображений . Изначально сайт был задуман таким образом, что наполнять его контентом должно быть быстро и просто. CMS была выбрана WordPress, а дизайн был создан практически с нуля. Перейдя на сайт вы не обнаружите ни стандартного расположения постов, ни привычной страничной разметки WordPress`a. По-мере скроллинга страницы, сайт автоматически догружает более старые посты – это реализовано с помощью jQuery.

Скриншот главной страницы сайта с автоматически-наполненным контентом

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

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

В противном случае (когда качество содержимого для вас имеет значение), пользователь волен использовать ручной режим и добавлять фотографии вручную. Для каждого конкретного сайта, из которого будут парсится фотографии, должен быть написан собственный модуль извлечения информации об изображении. Также программа способна отслеживать содержимое буфера обмена Windows, и если та появляется изображение или ссылка на него, автоматически формировать из этого изображения полноценный пост для сайта.

Страница сайта с одиночной фотографией

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

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

XNA – Используем атласы текстур

Сегодня я поделюсь с вами собственным классом, который хранит изображения в моих играх. Этот класс самостоятельно загружает текстуры при запуске игры (в обход Content Pipeline) и предоставляет возможность изменять их во время исполнения. Сегодня я также доработал его до такого состояния, что теперь можно абстрагироваться от необходимости работы текстурами внутри атласа.

Следующая структура хранит информацию о изображении:

Ничего необычного, кроме того, что данная структура может сама себя отрисовать через SpriteBatch с помощью метода Draw.

Дальше идет класс ImageManager в котором хранятся все изображения:

Изображения я храню в виде хеш-таблицы с доступом по названию текстуры.

Это конструктор, которых вылавливает все директории, которые находятся внутри Content/Images/ и вытаскивает из них все изображения. Если ваш проект настолько запутан сложен, что вы храните изображения в папках внутри папок, которые находятся внутри третьих папок, то добавляйте еще один цикл поиска директорий.

Это наш xml-файл, в котором хранится информация о каждой текстуре-атласе.

В этом блоке мы загружаем наши текстуры в заносим в string key имя текстуры в виде “folder/filename” лишая ее разрешения. По-этому имени можно будет обратиться к атласу-текстуре целиком.

В этом блоке, мы ищем информацию о более мелких текстурах, которые входят в наш атлас текстур. Если таковая находятся то каждая из мелких текстур заносится в хеш-таблицу.

В заключении, заносим в хеш-таблицу саму текстуру-атлас. Обращаю ваше внимание на то, что несмотря на то, что мы создаем структуру Image для каждой мелкой текстуры, входящей в состав атласа, сама текстура-атлас(Texture2D texture) хранится в памяти всего один раз, а доступ к ней предоставляется по ссылке.

DeviantLike – раскрутка в DeviantArt

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

Однако, идеала в этом мире не существует и у DeviantArt a есть свои недостатки. И самый большой из них, что новичку достаточно тяжело заявить о себе, сделать так, чтобы его работы просматривало большее число людей, нежели те 5-10 человек, что случайно забредают на вашу страничку, после того как вы выложите с десяток новых фотографий.

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

Но не верьте мне на слово – посмотрите на результаты работы программы для раскрутки самостоятельно:

Deviant Art посещения

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

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

DeviantArt раскрутка

Это примерно 10% уведомлений, которые я получил за последние сутки. Всмотритесь в это изображение – более 40 новых последователей, которые захотели следить за обновлениями моей галереи на DeviantArt. Все новые работы, которые вы выкладываете на DeviantArt e автоматически будут присылаться этим людям, что с течением времени (по мере увеличения количества ваших подписчиков) позволит вам постоянно увеличивать количество ежедневных посещений. Вы думаете, что 1000 посещений в день это много? С DeviantLike   Вы сможете достигнуть намного большего .

Вы ознакомились с эффектом "первого дня" работы DeviantLike , а что с долгосрочной перспективой, спросите вы меня? Для демонстрации этого я взял аккаунт, который работал с DeviantLike в течении трех месяцев, смотрите сами:

deviantart раскрутка За два месяца было получено более 110 000 просмотров профиля и более 375 000 просмотров фотографий в галерее, что вместе составляет  почти 500 000 просмотров. Как вам такое ?

deviantart раскрутка

Я специально показываю вам, что я не "фоловлю" людей тысячами в надежде, что кто-то ответит взаимностью. Более 2400 людей самостоятельно решили следить за обновлениями моей галереи.

deviantart раскрутка

Фотографии получили почти 5000 комментариев. Вы представляете себе весь этот объем сообщений, которые получат Ваши работы ? Вы будете общаться с совершенно разнообразными людьми, некоторым просто будет нравится то, что вы делаете, а кто-то будет давать вам советы, чтобы вы стали лучшим мастером, чем вы есть сейчас. Совершенствование и признание - о чем еще может мечтать творец? (я не говорю уже о 17 000 фейворитов, которые получат ваши работы).

deviantart раскрутка

Это рекорды популярности двух моих фотографий. На одной из них изображено озеро утром, а на второй мои друзья на пикнике. Друзей на пикнике увидело более 30 000 людей. Многие фотографии, которые получают daily deviation не получают такого количества просмотров. Вы их получите спустя несколько месяцев использования DeviantLike .

deviantart раскрутка

В среднем каждая моя фотография получила 35 комментариев, 120 добавлений в избранное и 2 700 просмотров - неплохая статистика для 3-х месяцев работы, правда ? Кроме этого бонусом вы получаете продвижение в поисковой системе DeviantArt, которая ранжирует ваши работы выше остальных из-за их высокой популярности. Не верьте мне на слово, проверьте сами ключевое слово donetsk - мой родной город, по-которому на первой странице выдачи исключительно мои фотографии (привет фотографам из Донецка :) ). Думаю, лишним будет говорить, что именно таким образом можно вытащить свой бренд в топ поисковой выдачи DeviantArt.

Теперь, когда вы видите результат работы программы, у вас уже должен появиться закономерный вопрос о том, каким образом вы можете начать ею пользоваться? Стоимость лицензии программы составляет 35 $ за один продвигаемый аккаунт  - скромное пожертвование, которое  поможет дальнейшему развитию данного проекта и позволит вам пользоваться всеми обновлениями, которые могут потребоваться в дальнейшем (например, при изменениях в сайте DeviantArt a).

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

Внимание! У вас есть возможность получить скидку 7$ на приобретение программы! Если у вас есть блог в интернете или какой-то другой фотосайт/арт-проект  с ежедневной посещаемостью не менее 100 уникальных пользователей, то при размещении информационного обзора программы (не менее 1500 символов) с активной dofollow-ссылкой на эту запись, вы получаете скидку на приобретение DeviantLike.

Если вы приобретаете премиум-аккаунт на Deviant Art`e, то с DeviantLike вы можете сэкономить! Я научу Вас, как с помощью моей программы и вашей высокой популярности, вы можете иметь премиум-аккаунт DeviantArt не платя за него. Премиум аккаунт стоит 4,95$ в месяц, что через год выйдет вам в 60$. При использовании DeviantLike за четверть этой суммы ( 15$ ) вы получаете это навсегда.

*ваши результаты от работы DeviantLike могут отличаться от моих в зависимости от профессионального уровня ваших работ

С# – Точка в полигоне

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

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