Дата | Видеоурок | Результат | |
---|---|---|---|
Повторение задач 100% Я это сделал, Я победитель! | + 9 | ||
Выполнил все задачи. Нашёл много новых вариантов решения задач и научился применять Linq! |
|||
Повторение задач Stop. Think. Act. Review. | + 9 | ||
Сделаю Семантику и Алгоритмику на C#. Нарисовать от руки в пейнте :) |
|||
ASP.NET и GMaps Координаты адреса | + 16 | ||
Наверное, стоит поменять местами со следующим уроком или объеденить, так как гугл уже не даёт доступа к апи карт без ключа. Кстати, гугл может выдавать данные и в JSON - наверное лучше в нём запрашивать данные, да и обращаться к отпарсенному json'у удобнее - хотя бы даже как к dynamic объекту. |
|||
ASP.NET и GMaps Подключение Entity Framework | + 15 | ||
Всегда полезно повторить работу с EF! Особенно полезно повторить исправление ошибки: EF вместо локального SQL сервера пытается привязаться к localDb и не может создать файл базы данных в папке Users из-за отстутсвия прав. Настройка прав ничего не даёт, да и к тому же, EF пропускает слеш в пути к файлу и вместо C:\Users\*файл базы данных*.mdf пытается создать C:\Users*файл базы данных*.mdf. Проблема в сети встречается, но самое простое решение просто вручную в web.config поменять путь с localDb на локальный SQL сервер. |
|||
ASP.NET и GMaps Запуск ASP.NET MVC | + 13 | ||
Повторил создание модели, контроллера и представления. |
|||
ASP.NET и GMaps Презентация | + 12 | ||
Давно думаю сделать программку для смартфона, в которой, например, указываешь время, когда надо быть дома (например курьер в час привезёт что-то) или в другом месте (забрать ребёнка из садика/школы), а до этого надо успеть сходить в магазин или ещё куда-нибудь. А программа чтобы рассчитывала не позже какого времени надо выйти из дома, когда надо поворачивать и возвращаться домой или идти в другой пункт. И чтобы программа работала в оффлайн режиме (просто замеряет время, чтобы дойти куда-то и потом использует это для расчётов) и в онлайн-реждиме с использованием карты. |
|||
Базовый ASP.ект VIP. Модерация записей | + 13 | ||
Очень познавательно! Научился сохранять сессию при авторизации, делать проверку записей авторизованным пользователем, менять записи в колонке статуса истории в базе и выводить истории в зависимости от записи в колонке статуса истории. Так как в MSSQL не поддерживается enum в качестве типа записи, то реализовал через CONSTRAINT. |
|||
On-line игра Представление выделяется | + 16 | ||
Продолжаю повторять консольные хитрости. Помимо описанного в уроке сделал ещё раскраску приветствия и перемещаемой буквы "О", а также сделал невидимым надоедливый курсор. Думаю, что в отдельный метод можно вынести цикл с обработкой нажатия клавиш. |
|||
On-line игра Марионетка | + 14 | ||
Повторил работу с консолью, что всегда полезно. |
|||
Базовый ASP.ект VIP. Авторизация на сайте | + 15 | ||
Научился делать простую проверку логина пользователя. Ошибку с добавлением новой записи после избавления от статика я как раз на прошлом уроке заметил и исправил :) |
|||
Базовый ASP.ект ФИНАЛЬНЫЙ УРОК. Презентация | + 14 | ||
* Научился делать простые страницы на ASP.NET с доступом к базе данных. * В уроке с отказом от статика не был проверен функционал добавления записей, в котором появляется ошибка если просто статический класс доступа к базе данных перевести в экземплярный. * В проект следует добавить возможность редактирования и удаления записей. * Пока думаю. |
|||
Базовый ASP.ект Отказ от статика | + 17 | ||
Не знаю, может у меня ошибка, но если делать именно по уроку и просто сделать класс работы с SQL экземплярным, то появляются ошибки с добавлением новых записей, так как требуется конструктор без параметров. Попробовал держать пустой конструктор, но тогда не создаётся экземпляр класса работы с SQL и выскакивает ошибка. Пришлось из пустого конструктора добавить вызов конструктора с параметром с передачей ему нового класса для SQL. |
|||
Базовый ASP.ект Размещение проекта в Интернете | + 15 | ||
Повторил процесс регистрации на хостинге и загрузку базы данных и сайта :) http://firewolf-001-site1.itempurl.com/ Как обычно, из-за расхождения версий пришлось заливать базу данных в виде скрипта. И ТоталКоммандер коннектился к ФТП, но останавливался на процессе отображения папки, так что пришлось через сервер архивом закидывать. |
|||
Базовый ASP.ект Оформление сайта | + 16 | ||
Наверное из-за того, что у меня на чердаке в отличие от урока есть дополнительная ссылка "About", то при ширине окна браузера болье 1200px всё равно слетает вертикальное расположение элементов формы. Так как в CSS я разбираюсь очень слабо, то найти решение проблемы пока не смог. |
|||
Базовый ASP.ект Валидация данных | + 13 | ||
Интересно про встроенную валидацию. Вотрегулярные выражения надо подучить - сильно хитрая штука и просто так не даётся. |
|||
Базовый ASP.ект Добавление истории | + 18 | ||
Научился добавлять данные из формы на странице в базу. Вообще, очень познавательно. Интересно попробовать переписать это под Entity Framework - наверное это предпочтительный способ создания сайта, но всегда полезно узнать, как оно работает, когда прописываешь всё руками. Немного пришлось поискать, как получать Id последней совершённой записи в базу в MSSQL, так как в отличие от MySQL здесь нет удобной функции получения Id псоледней записи, а надо прописывать получение сразу в строке добавления записи в базу, причём существует несколько способов, каждый со своими особенностями. Microsoft же... |
|||
Базовый ASP.ект Работа со списком историй | + 17 | ||
Да, волшебство просто. Особенно нравятся вызовы функций из htmls кода. Я, конечно, в этом ещё слабо разбираюсь, но если нам понадобился класс, содержащий список с экземплярами этого самого класса, то, возможно, это является показанием к использованию индексатора? |
|||
Базовый ASP.ект Рефакторинг модели Story | + 13 | ||
Проблемы с затенением id у меня не возникло, так как я свойства всегда пишу с большой буквы. А вместо дополнительной перегрузки вынесенного метода получения строки я просто id обозначил как необязательный аргумент со значением по умолчанию. |
|||
Базовый ASP.ект Что такое SQL-инъекция | + 10 | ||
Интересно, что у меня при таком же, как в уроке, запросе, в ответ просто приходит ошибка, а не история по номеру в начале "инъекции". Видимо, какая-то разница в реализации MySQL и MSSQL. Конечно, если н епредусмотреть защиту от SQL-инъекций, то возможности для злоумышленника поистине безграничны :) Интересно почитать на эту тему, потому что подозреваю, что одной такой предосторожности, как в уроке, явно недостаточно. |
|||
Базовый ASP.ект Запуск модели Story | + 16 | ||
Очень интересно, как получается испольщовать логику построения программы на C# в создании веб-страницы. Чувствую, что по завершении курса смогу уже попробовать сделать свою страничку :) |
|||
Базовый ASP.ект Работа над ошибками | + 15 | ||
Мне кажется, что для хранения информации об ошибках нужен отдельный класс, чтобы не хранить в классе SQL запросов ошибки из других классов (например ошибки получения данных из результата запроса). |
|||
Базовый ASP.ект Подключение к базе данных | + 14 | ||
Делал для MSSQL, так что было интересно переделывать под него показанные команды для MySQL. Вроде даже разобрался как увязываются Model, View и Controller и сделал вывод на индекс и на Last Story последней истории и случайной истории на Random. |
|||
Базовый ASP.ект Создание SQL-запросов | + 11 | ||
Пришлось повозиться, чтобы найти способ сохранять русский текст в базу. Попутно выяснилось, что тип text/ntext в MSSQL является устаревшим и вместо него рекомендуется использовать varchar/nvarchar(MAX). Ещё нашёл альтернативу sqlcmd - написанную на питоне mssql-cli которая подставляет команды и красиво форматирует вывод. Ну и нашёл сервис для конвертации команд MySQL в MSSQL :) Немного погуглить, чтобы решить проблему с русским языком в записях базы и заставить себя позаниматься командной строкой, а не только в MSSMS всё сделать :) |
|||
Базовый ASP.ект Схема базы данных | + 14 | ||
Так как делал в MSSQL, то научился создавать базу данных через sqlcmd :) но создавать таблицу с колонками через консоль я поленился. Зачем, если есть MSSMS? По-моему это тема больше для отдельного курса по SQL. База данных позволяет хранить, выводить и добавлять истории с указанием заголовка, автора и времени добавления истории. |
|||
Базовый ASP.ект Установка сервера MySQL | + 14 | ||
Устанавливать MySQL и HeidiSQL к уже установленным MSSQL и MSSMS я не стал. Буду работать с ними. |
|||
Базовый ASP.ект Формирование меню | + 10 | ||
Добавил меню "About". Разбираюсь всё лучше и лучше. Вызывает сомнение отказ в уроке от самостоятельного пункта меню "Random" и перенаправление на View "Number". У них же разное предназначение: Random по логике выводит случайную историю из базы, а Number выводит конкретную историю по номеру, разве не так? |
|||
Базовый ASP.ект Создание модели Story | + 18 | ||
Здорово! Даже почти понял, что и как работает :) Пока не дошли до взаимодействия с базой, сделал простенькое хранение историй в Dictionary<int, (string, string)>, который хранит ValueTuple из C#7, и написал метод, который при инициализации модели забивает через Add туда несколько историй (заодно и метод для добавления готов). Также сделал метод Random, который тасует истории и вызывается из View ../story/random перед выводом наполнения страницы. Пока не понял, как начальный Index только заполнить. Что-то перенапраление из PageController.Index() на экземлярный StoryController.Random() оставляет страницу с наполнением по умолчанию. Надеюсь, дальше этот вопрос осветят. |
|||
Базовый ASP.ект Создание пустых страниц | + 14 | ||
Действительно всё не так сложно и очень интересно. |
|||
Базовый ASP.ект Создание схемы проекта | + 15 | ||
.../ - главная страница, последние истории ../page/index .../story/best - лучшие истории .../story/random - случайные истории .../story/add - добавить историю .../story/number/12345 - показать историю 12345 Гм... История для сайта историй... Ну скажем было дело, давно в парке, где собирались анимешники, один знакомый менялся с другими анимешниками кассетами, а тут подъехала милиция и его забрали в отделение, так как подумали, что он нелегально фильмами торгует. В отделении поставили пару кассет, увидели, что там мультики и отпустили восвояси. Знакомый был рад, что милиционеры не стали смотреть остальные кассеты, так как там были и аниме таких жанров, что в общественных местах показывать не рекомендуется :) |
|||
Базовый ASP.ект Выбор темы для проекта | + 14 | ||
Схема сайта ithappens.me: .../ - главная страница, последние истории .../best - лучшие истории .../random - случайные истории .../story/add - добавить историю .../tags - теги историй .../tags/... - разные теги .../page/... - разные страницы Гм... История для сайта историй... Ну скажем было дело, давно в парке, где собирались анимешники, один знакомый менялся с другими анимешниками кассетами, а тут подъехала милиция и его забрали в отделение, так как подумали, что он нелегально фильмами торгует. В отделении поставили пару кассет, увидели, что там мультики и отпустили восвояси. Знакомый был рад, что милиционеры не стали смотреть остальные кассеты, так как там были и аниме таких жанров, что в общественных местах показывать не рекомендуется :) Вспомнить какую-нибудь историю. |
|||
Базовый ASP.ект Мы начинаем ASP.NET с MVC | + 16 | ||
Действительно просто. Поигрался ещё немного с CSS. Только неудобно, что нет графического дизайнера: надо тестировать изменения в браузере, потом искать классы в открытом в VS файле с CSS... Неудобно. |
|||
On-line игра 1. Консольная игра. Добро пожаловать! | + 14 | ||
Научился создавать пустые Solutions - всегда хотел, но боялся попробовать. Оказалось совсем не страшно и даже проще выполнения курса по онлайн-шахматам! Зря боялся... |
|||
Комбинаторика Рекурсия. Обратный отсчёт | + 14 | ||
Интересное решение с запоминанием введённых чисел в стаке вызова :) |
|||
Комбинаторика Рекурсия. Общий делитель | + 14 | ||
Вариант с вычитанием для поиска НОДа приводит к StackOverflow на последнем тесте, что как раз показывает недостатки рекурсии :) |
|||
Комбинаторика Рекурсия. Числа Фибоначчи | + 15 | ||
Замечательно показан рекурсивный поиск чила Фибоначчи, но за что тут платить 50 байт, если всё это можно посмотреть и в видео-решении самой задачи? Окно робота-Шарпа показать не могу, так как нажал, что задача решена, а заново её решить уже не даёт. Так что только окно со списком результатов. |
|||
Комбинаторика Рекурсия. Факториал | + 14 | ||
Круто. Но тратить 50 байтов просто за ссылку на задачу и решение, которое можно посмотреть бесплатно в самой задаче? |
|||
Комбинаторика Рекурсия. Заливка области | + 15 | ||
Очень интересно. Не знал, что алгоритмы заливки используют рекурсию. Даже, кажется, понял, как метод не просто последовательно вызывает себя, а вызывает себя сразу несколько раз. Интересно было бы попробовать распараллелить этот процесс |
|||
Комбинаторика Рекурсия. Главный секрет | + 15 | ||
Всегда хотел, но боялся разобраться в рекурсии! От руки кривую Гильберта рисовать не стал, а набросал в Илюстраторе и сохранил в 8 цветов с дизерингом, чтобы психоделичнее выглядело. |
|||
Комбинаторика Рекурсия. Вступление | + 13 | ||
Рекурсия это вызов функции самой себя до достижения какого-то условия с последующим возвратом результата по цепочке вызовов. |
|||
Итератор VIP. Оптимизация поиска простых чисел | + 14 | ||
А вот и варианты алгоритма поиска. Стоило бы сразу в лписании первого урока упомянуть, что алгоритм поиска простых чисел будет разбираться в вип-уроке :) Полезный урок, так как я особо не задумывался о поиске простых чисел. Добавлять решето Эртосфена и Аткина не стал, так как не представляю, как эти алгоритмы можно подружить с ограничением по времени выполнения: они же работают с заполненной коллекцией чисел, а не производят проверку для каждого числа. |
|||
Итератор ФИНАЛЬНЫЙ УРОК | + 16 | ||
Показана польза от использования конструкции yield но, возможно, стоило более подробно разобрать алгоритм поиска простых чисел. А то немного смешано получилось: то поиск простых чисел, то польза от замены IEnumerator на yield и в результате нет ощущения что и то и то разобрано достаточно подробно. Но это был вебинар, а не специально записанный курс, так что некоторая сжаточть изложения вполне понятна :) Следующим посмотрю комбинаторику или функциональное программирование. |
|||
Итератор Итератор. Один метод вместо классов. | + 15 | ||
Лаконичный и красивый алгоритм, а yield скрывает много работы, которую зав авс делает компилятор :) |
|||
Итератор Итератор. Список простых чисел. | + 15 | ||
У меня всегда были проблемы с пониманием математической логики и формул :( Суть yield ясна, но не смогу вот так легко создать логику для поиска простых чисел... |
|||
Итератор Итератор. Волшебное слово yield. | + 16 | ||
yield это синтаксический сахар для автоматической реализации IEnumerator в котором хранится состояние перечисления. |
|||
Итератор Итератор. Зачем нужно два класса | + 15 | ||
Хорошее объяснение того, почему надо разносить IEnumerable и IEnumerator по разным классам. Кстати, конструкцию: long primeMax = -1; public Primes() { }; public Primes(long pMax) { primeMax = pMax }; Можно заменить на: long primeMax; public Primes (long pMax = -1) => primeMax = pMax; |
|||
Итератор Итератор. Перебор простых чисел. | + 16 | ||
Полезно было вспомнить разницу между implicit и explicit реализациями интерфейса и интересные возможности для обращения к строкам как к IConvertible. |
|||
Итератор Итератор. Перебор чисел в итераторе. | + 16 | ||
Повторяем азы. |
|||
Итератор Итератор. Создание пустого итератора. | + 18 | ||
Пока всё известно, но повторить основы не помешает :) Итератор это набор методов, к которым можно обратиться для обхода коллекции. Необходимо в частности для работы foreach. |
|||
Итератор Итератор. Разложение числа на простые множители. | + 15 | ||
Вводный урок. Пока ничего нового. Вопрос: а зачем перебирать все числа вплоть до number? Достаточно до number / 2. |
|||
Web API Создание Web API проекта | + 17 | ||
Очень интересный урок по основам взаимодействия клиент-сервер через HTTP запросы. Многое из того, что читал до этого в учебниках стало понятнее. Спасибо. Есть пара замечаний по уроку: из середины и из конца можно спокойно вырезать по 20 минут оставшегося с вебинара общения в чате и рекламы покупки курсов, которая уже не актуальна, заодно и урок можно поделить на 2 части: сервер и клиент. Ещё - устанавливать Nuget Microsoft.AspNet.WebApi.Client можно и из окна установки пакетов - соседняя кнопка с вызовом консоли :) |
|||
Демо игры VIP. Бесплатная консультация | + 15 | ||
Просто закрываю последний урок курса, чтобы не маячил, как незаконченный :) |
|||
Простой WPF WPF. Простая змейка. VIP урок. Поймай хвост! | + 16 | ||
Так как я изначально стал делать Змейку под Android, то реализовать методом опроса Children в Canvas. Более того, я делал Змейку под голый Xamarin без всяких фреймворков, а прямая работа с полотном там очень неудобная и требует держать часть логики в основной Activity, а часть реализовать в отдельном View, где и создаётся Canvas. Разумеется, так как делал я делать не надо, а надо использовать какой-нибудь фреймворк для создания игр, а ещё лучше Unity. Сама Змейка была у меня уже давно сделана, но я захотел доделать курс и реализовать "самоедение". Какие были сложности: 1) Из-за прямой работы с Canvas пришлось разнести логику игры отдельно в Activity и отдельно во View. По хорошему, надо в MainActivity держать меню игры, а из него вызывать отдельную Activity для игрового поля и из него управлять состоянием View с Canvas внутри. Впрочем, у меня и так получилось, что во View происходит весь расчёт картинки, который по таймеру в MainActivity перерисовывается и запрашивается для проверки съедения хвоста, выхода за границы или выигрыша. Возможно, есть более эффективный и прямой способ, и если я решусь ещё раз на подобный эксперимент, то я буду делать немного по другому 2) Для отрисовки необходимо запрашивать UIThread, иначе на экране ничего не появится, что немного похоже на WPF, так что просто надо посмотреть, как это правильно вызывается :) (Подсказка: RunOnUiThread(() => SomeMethod());) 3) Так как у Canvas нет Children, то все части змейки надо держать в какой-то своей коллекции. Я для этого использовать Dictionary, куда записывал части змейки для отрисовки с крутящимся по кругу счётчиком в качестве ключа. Конечно, можно было использовать LinkedList или поколдовать над обычным List, чтобы он работал как Queue, но это не эффективно, потому что постоянно нужно добавлять/убавлять объекты. 4) Код сложно дебажить, так как обратной связи от Visual Studio гораздо меньше, чем если просто писать под .NET и не всегда срабатывают Breakpoint, так что без опыта написания под Android придётся страдать (как мне :)). 5) Очень мало информации по тонкостям написания под Android - такое ощущение, что программисты для мобильных устройств это какая-то тайная секта! А руководства по Xamarin по своей сухости сравнимы со списком сносок в конце научных статей, а по понятности с инструкциями по сборке вида "деталь А16, вставьте в деталь Д07 и закрепите шурупом Ф71". 6) Для реализации "самоедения" я по достижении определённой длины змейки, пропуская несколько сегментов, отправлял остальные сегменты на проверку пересечения головой (получилось использовать ранее написанный метод проверки пересечения с едой), но не сразу удалось сообразить в каком направлении крутить счётчик для опроса Dictionary с сегментами тела змейки (да, жаль что нельзя обходить Queue по индексу - жизнь была бы проще). В любом случае я рад, что решил пойти сложным путём и делать Змейку именно под Android. После этого WPF уже вообще кажется по сложности чем-то для начальных классов. Так как опыта у меня мало, это был для меня серьёзный вызов и тем более приятно, что я сним справился (вообще я обычно скромный :)). Ответить на вопрос "Зачем я это делаю?" |
|||
Демо софт VIP. Бесплатная консультация | + 15 | ||
Спасибо, но консультация (пока?) не требуется. На уроках и так всё достаточно подробно объясняется а всякие тонкости можно найти и в гугле :) Единственный вопрос в поиске работы для программиста без опыта, но этот вопрос не для данного формата :) |
|||
Нано-игры VIP урок. Игра 2048 | + 17 | ||
В этот раз удалось дойти только до 1024, но вообще 2048 я набирал. |
|||
Entity Framework Добавление - Извлечение | + 15 | ||
Спасибо! Короткий, но очень информативный курс! "Как я перестал бояться и полюбил Entity Framework". |
|||
Entity Framework Один за всех и Все за одного | + 15 | ||
Как на удивление это всё просто оказывается! Когда я когда-то в учебнике Троелсена делал создание базы мне очень мешало то, что я ещё не вполне понимал саму структуру программирования на C#. А сейчас даже вполне себе понимаю, что происходит :) Конечно, есть ещё много тонкостей и проблем, которые всплывут только на практике, но, в принципе, создать несложную и не критичную базу данных без проблем могу уже сейчас. |
|||
Entity Framework Миграция Базы | + 15 | ||
Так как MySQL нет, то всё проделал применительно к MsSQL. Понял базовый алгоритм осуществления миграций базы SQL посредством EF. Это, оказывается, не так и страшно, как мне казалось ранее :) |
|||
Entity Framework Использование MySQL | + 15 | ||
Пока не хочу забивать себе голову ещё и MySQL, так что, как было предложено в начале урока тем, кто не хочет ставить MySQL, я просто повторил и закрепил создание базы из Code First. |
|||
Entity Framework Основные приемы работы с БД через EF | + 15 | ||
Всё просто и понятно. Только студия натыкалась на запрет доступа с созданием базы в localDB с Initial Catalog. Без него всё создавалось, но создавать таблицу в master как-то некрасиво, так что я переподключил это дело к локальному Dev SQL серверу. Windows как обычно что-то напутал с разрешениями для папок... |
|||
Entity Framework Подключение БД по методу CodeFirst | + 15 | ||
Очень интересно и не так страшно, как было когда я это читал в учебнике, когда я ещё гораздо хуже разбирался в C# :) |
|||
Entity Framework Создание приложения | + 14 | ||
Пока сделаю на WinForms, чтобы не отвлекаться от изучения EntityFramework, а потом на WPF переделаю. |
|||
Entity Framework Введение в EF | + 15 | ||
Без знания Entity Framework никуда. Хотя бы для того, чтобы осознанно потом выбрать альтернативу :) Раньше по учебнику Троелсена делал базу данных через EF, но тогда я C# знал ещё совсем на начальном уровне и мало что было понятно. |
|||
Шахматы по сети VIP. Меню DimanDOSа | + 15 | ||
Научился создавать меню и привязывать методы к событию нажатия кнопки. Спасибо DimanDOS'у за полезный урок по работе с UI в Unity! В отличие от урока я не стал делать диагональную кнопку вызова меню с помощью картинки, а по примеру WPF сделал средствами самой Unity. Ну и переключение состояния элемента меню сделал одной строкой: *объект*.SetActive(!*объект*.activeSelf); В начале немного запутала интеллектуальность редактора Unity, когда было не совсем понятно, как он ассоциирует операцию над неинициализированным GameObject и элементами меню. |
|||
Шахматы по сети Рефакторинг. Последний аккорд | + 18 | ||
Отличный курс по созданию сетевых шахмат! Конечно, для полноценной игры надо добавить разделение ходов для разных пользователей, статистику и прочее, но цель этого курса дать основу для саморазвития и базовые знания для понимания работы с Unity, SQL и ASP.Core, а также программирования сложной логики и её последующего рефакторинга, с чем данный курс справляется на отлично! Было очень интересно искать способы дополнить и улучшить предложенные в уроках варианты. Например, в проверке расчёта ходов выясниллось, что реализация проверки через LINQ для глубоких расчётов быстрее простой рекурсии. В скриптах для Unity я вначале отказался от предложенного ручного парсинга JSON ответа сервера в пользу Nuget библиотеки от Newstonsoft, но затем, узнав, что в Unity есть, оказывается, встроенный парсер, стал использовать его. Также, я заменил WebClient из C# на UnityWebRequest из Unity, что потребовало некоторой реорганизации вызовов обновления состояния доски, так как веб-запросы в Unity выполняются асинхронно и из-за этого появлялась задержка с обновлением доски после хода. Еще пришлось подумать над сведением рефакторинга из уроков с разными версиями скриптов, но всё получилось. WebGL ссылка: http://hinoookami.ru/webgl/ Свести в одну версию рефакторинг по отличающемуся коду из уроков и использовать встроенный в Unity асинхронный веб-запрос. |
|||
Шахматы по сети Рефакторинг. Финальное причёсывание | + 16 | ||
Небольшая оптимизация вызова функций. Разнесение инициализации по двум методам давно смущало, но боялся трогать на случай последующих уроков :) |
|||
Шахматы по сети Рефакторинг. Двухэтажное превращение | + 18 | ||
Опять, из-за расхождения в коде в видео и в коде, имеющимся после предыдущих уроков, пришлось поискать где происходит сбой. Чувствую, что есть лишний код, но пока подожду завершения уроков по рефакторингу, прежде чем начать править всё самостоятельно :) |
|||
Шахматы по сети Рефакторинг. Класс шахматной игры | + 18 | ||
Если честно, то данный урок ломает класс Board гораздо сильнее, чем указывают примечания перед уроком, так как в уроке используется более раннее состояние Board, чем у нас уже есть к данному моменту. Пришлось подумать над костылями и как вызвать получение fen с сервера в свете рефакторинга. Практика самостоятельного придумывания костылей :) Найти, куда подставить костыли после того, как рефакторинг поломал код :) |
|||
Шахматы по сети Рефакторинг. Потерянная пешка | + 19 | ||
Очень интересно понаблюдать за процессом поиска ошибок :) |
|||
Шахматы по сети Рефакторинг. Волшебник изумрудного ящика | + 20 | ||
Отличный рефакторинг! Просто удивительно, как нагромождение сложных методов выстраивается в цепочку простых и понятных методов, распределнных по подходящим для них классам! Вдобавок к предложенному в уроке рефакторингу я применил передачу координат X и Y сразу с помощтю встроенной в Unity структуры Vector2Int. Не всегда удаётся уследить за быстрой мыслью Евгения Витольдовича :) |
|||
Шахматы по сети Рефакторинг. Хоровод из четырёх фигур | + 19 | ||
Вынос повторяющихся кусков кода в отдельные функции и подготовка к дальнейшему рефакторингу. |
|||
Шахматы по сети Рефакторинг. Шахматная независимость | + 18 | ||
Узнал ещё больше тонкостей связанных с рефакторингом и выносом методов в подходящие для них классы. |
|||
Шахматы по сети Рефакторинг. Клетка в клетке | + 17 | ||
Продолжаем разгружать класс Board посредством выноса функционала в подходящие для этого классы. |
|||
Шахматы по сети Рефакторинг. Спрайт, не дай себя заинтерфейсить | + 18 | ||
Продолжаем использовать интерфейс для упрощения и оптимизации работы скриптов! |
|||
Шахматы по сети Рефакторинг. Вынос переноса | + 18 | ||
Продолжаем выносить функциональность в абстракный класс управления объектами на доске. |
|||
Шахматы по сети Рефакторинг. Многоклеточная сущность | + 18 | ||
Продолжаем разносить функциональность по разным классам. Найти ошибочку, из-за которой всё шахматное поле замощалось чёрными пешками вдобавок к клеткам и нужным фигурам. |
|||
Шахматы по сети Рефакторинг. Ящик с фигурами | + 19 | ||
Повторил применение абстрактных классов. Пока что, без дальнейшего рефакторинга, добавление в Board.InitGameObjects() вызова figures.Init(); с оставлением имеющейся инициализации приводит к заполнению доски лишними пешками :) |
|||
Шахматы по сети Рефакторинг. Интерфейсная прослойка | + 19 | ||
Интересное использование интерфейса для получения доступа к классу из которого требуется только один метод из другого класса. |
|||
Шахматы по сети Рефакторинг. Чёрный ящик | + 20 | ||
Продолжаем рефакторинг! |
|||
Шахматы по сети Рефакторинг. Координатные трансформации | + 20 | ||
Поделал рефакторинг и внёс несколько, как надеюсь, усовершенствований по сравнению с предложенным в уроке. Мне не очень понравился вариант с раздельным получением координат X и Y, когда обычно координаты всё равно требуются вместе и для раздельного получения нужно дважды отправлять Vector2. Вначале я попытался использовать для одновременного возврата X и Y новые ValueTuples из C# 7.x, но Unity понимает только C# 6.0. Так что я подумал вначале вносить полученные из Vector2 координаты в Anonymous Types и возвращать их как dynamic, чтобы избежать приведения и обращаться к полученному dynamic типу за значениями. Но dynamic всё-таки не совсем для этого и правильней было бы использовать кастомную структуру, но это уже лишнее усложнение. Но тут я вспомнил, что в Unity всё уже придумано до нас и есть Vector2Int, который идеально отвечает требованиям. Так что я сделал возврат коордиинат через этот класс из Unity. Пример на скриншотах. |
|||
Шахматы по сети Рефакторинг. С чего начать? | + 21 | ||
Вынесли класс DragAndDrop в отдельный файл. Я бы ещё разделил класс Board на два класса: в одном обрабатывалось бы только отображение доски, а в другом взаимодействие с доской. |
|||
Шахматы по сети Клиент. ВОСЬМОЙ ФИНАЛЬНЫЙ УРОК | + 22 | ||
Научился делать сетевые шахматы на юнити под разные платформы. Были подробно рассмотрены шахматные алгоритмы и проверка правильности ходов, создание веб сервера с базой данных для сохранения игр и связи между игроками. Для полноты игры осталось добавить невозможность играть фигурами соперника, звуки, авторизацию пользователей и подобные украшательства. Ну и ещё рефакторинг... Решить некоторые возникающие в процессе создания игры ошибки, что, однако, дало бесценный опыт на будущее :) |
|||
Шахматы по сети Клиент. Фоновое обновление | + 20 | ||
Использовать встроенный в Unity таймер вызова функции для обновления состояния доски при ходе соперника. |
|||
Шахматы по сети Клиент. Следы невиданных ходов | + 18 | ||
Оптравлять ход на сервер из Unity. Как раз то, чего я всегда боялся, но хотел изучить: обмен данными с удалённым сервером :) |
|||
Шахматы по сети Клиент. Серверные пешки | + 16 | ||
Получать расстонвку фигур в Unity с сервера. Почитал, как работать с https в Unity: надо использовать встроенные в Unity классы для работы с сетью, но применять их подожду до рефакторинга. Понять, что для работы Newtonsoft надо его добавить в Assets проекта Unity :) |
|||
Шахматы по сети Клиент. Ход в мешке | + 17 | ||
Играть сам собой в шахматы в двух консолях :) Ну и отправлять ход на сервер через консоль, но это уже мелочи... |
|||
Шахматы по сети Клиент. Дедовские методы | + 18 | ||
По совету из урока переделал парсинг из Newtonsoft в ручной, но насколько я понял, есть библиотеки парсинга JSON с поддержкой Unity. |
|||
Шахматы по сети Клиент. Достучаться до облака | + 20 | ||
Научился подключаться к серверу из консольного приложения :) Для выделения FEN из полученной строки, я бы воспользовался методом, использованным мною для написания мобильного приложения для конвертирования валюты: https://www.videosharp.info/10080/checking/start=1891 То есть я использовал бы NuGet Newtonsoft и из полученной десериализированной в JSON строки по ключу FEN достал бы строку. Можно конечно и свой парсер написать, но зачем? То есть выглядит это так: class Client { public const string address = "https://hinoookami.ru/api/chess"; WebClient web; public Client() { web = new WebClient(); } public string GetFenFromServer() { string responce = web.DownloadString(address); var json = ParseJSON(responce); return json.FEN; } public static dynamic ParseJSON(string responce) { return JsonConvert.DeserializeObject(responce); } } Результат запроса к серверу с выводом оригинальной строки ответа и после вытаскивания FEN видно на скриншотах. |
|||
Шахматы по сети Хостинг. СЕДЬМОЙ ФИНАЛЬНЫЙ УРОК | + 20 | ||
Отличный раздел курса! Как раз то, что я хотел изучить: публикация сайта, сделанного на asp.net и подключение его к базе данных. Ссылка на шахматы: http://hinoookami.ru/api/chess Решить проблему с неподключением опубликованного сайта к размещённой на хостинге же базе данных. |
|||
Шахматы по сети Хостинг. VIP. Двойные стандарты | + 18 | ||
Научился модифицировать web.release.config, чтобы не приходилось переписывать строку подключения к базе данных для тестирования на локальном сервере или для релиза на удалённом. В этом уроке - ничего, а в предыдущем я столкнулся именно с такой проблемой неработоспособности сайта и героически её решил, правда переписываением web.config под работу на удалнном сервере. |
|||
Шахматы по сети Хостинг. Перенос базы данных | + 16 | ||
Научился подключать сайт к базе данных на хостинге. Найти причину неподключения сайта на хостинге к расположенной на хостинге базе данных. Оказалось, что сайт имел в приоритете строку подключения из web.config, а не из настроек ASP.Net на хостинге. Видимо причина в каком-то недосмотре при выполнении урока по генерации сайта посредством EF на основе базы данных. |
|||
Шахматы по сети Хостинг. Публикация проекта | + 17 | ||
Научился опубликовывать проект в сети напрямую из Visual Studio. Интересно, а как сделать, чтобы работало из подпапки на сайте? Просто сделать папку и опубликовать в неё? Страница упорно не хотела работать, выдавая ошибку, подробности которой скрывала из-за настроек приватности в файле global.config. Поправив настройки в файле, удалось выяснить, что не устраивает версия .Net, под которую было скомпилировано. У меня было 4.7.1, а надо было 4.7. Кстати, эту информацию можно было получить и просто сщёлкнув по надписи "Предпросмотр" под адресом сайта в панели управления хостингом. |
|||
Шахматы по сети Хостинг. Доступ по FTP | + 17 | ||
Страничка заработала через час после регистрации. Не обошлось без глюков: бесплатный SSL сертификат за первую регистрацию не привязался, так как домен уже зарегистрирован! На меня! И сертификат не привязался! |
|||
Шахматы по сети Хостинг. Лучше заплатить | + 17 | ||
Зарегистрировал хостинг и имя на reg.ru. Кстати, если не регистрировать хостинг и имя в тот же день, а подождать, то на следующий день позвонят с вопросом нет ли сложностей с решистрацией и пришлют промокоды на скидку :) |
|||
Шахматы по сети Хостинг. Регистрация аккаунта | + 19 | ||
Зарегался на reg.ru Открыть reg.ru и почту через мобильный интернет от Йоты. |
|||
Шахматы по сети Сервер. ШЕСТОЙ ФИНАЛЬНЫЙ УРОК | + 17 | ||
За исключением того, что в уроке https://www.videosharp.info/video/chess3/nr=1984 по неустанровленной причинев модели ChessModel метод "protected override void OnModelCreating(DbModelBuilder modelBuilder)" оказывался пустым и его содержимое пришлось впечатывать вручную, всё прошло гладко. На мой вгляд в программе больше всего не хватает привязки очереди ходов к игрокам, чтобы нельзя было ходить за соперника. Можно даже не создавать пополняемую таблицу игроков, а сделать, скажем, 10 свободных слотов для игры с кнопкой выхода игрока и таймаутом при неактивности. Также хорошо бы расширить набор статусов игры, чтобы было сразу понятно идёт ли она, неокончена или чем завершилась. Ещё, если не хотим раздувать базу историей игр, то можно ограничить количество слотов игр 1/2 от количества игроков и сбрасывать состояние по завершении игры. |
|||
Шахматы по сети Сервер. Китайская ничья | + 17 | ||
Продолжение развития взаимодействия с базой данных. |
|||
Шахматы по сети Сервер. Шахматная Идемпотентность | + 16 | ||
Добавил идемпотентность в код запроса базы данных. "Scientia potentia est!" |
|||
Шахматы по сети Сервер. Ваш ход! | + 18 | ||
Очень интересно и полезно изучить взаимодействие с базой данных на практике. С новым пониманием прямо захотелось перечитать главы учебника Троелсена по C#, где разбиралось нечто подобное. Чтобы конец хода увидел другой игрок, самый простой вариант, что мне пришёл в голову, это ввести новый статус "aboutdone" в случае мата или пата и, когда его видит другой игрок, тогда уже менять статус на "done". |
|||
Шахматы по сети Сервер. Официант без логики | + 17 | ||
Лучше понимать работу с SQL. Очень интересно. Давно хотел поизучать работу с SQL на парктике. |
|||
Шахматы по сети Сервер. Новая игра на JSON | + 20 | ||
Программно создавать новую игру в базе SQL. Так как я с SQL был знаком только в рамках учебника Троелсена по C#, то мне сложно с уверенностью ответить на вопрос из урока, что может не нравиться в имеющемся контроллере обращаения к базе данных. Но насколько я помню, прямая модификация базы извне является не самым безопасным и надёжным способом работы с ней и лучше использовать Stored Procedures. |
|||
Шахматы по сети Сервер. Райский Эдем - EDM | + 23 | ||
Научился подключать базу к web api. Странно: в модели ChessModel метод "protected override void OnModelCreating(DbModelBuilder modelBuilder)" оказался пустым. Не помогло и перепрохождение урока по шагам. После перепечатывания с экрана всё заработало, но причины данного явления пока непонятны. |
|||
Шахматы по сети Сервер. Последняя версия | + 19 | ||
Очень интересная и полезная тема! Есть подозрение, что без знания SQL и веб приложений работу программистом не найти... |
|||
Шахматы по сети База данных. ПЯТЫЙ ФИНАЛЬНЫЙ УРОК | + 21 | ||
Научился пользоваться SSMS, что гораздо удобнее чем из Visual Studio. Отзыв: в уроке "База данных. VIP. Таблицы на вырост" возможно стоило бы подробнее пояснить идею Foreign Keys и дать пример тестового заполнения таблиц, но так как в рамках курса для работы берётся таблица попробще, то это просто придирки :) |
|||
Шахматы по сети База данных. VIP. Красивая диаграма | + 19 | ||
Делать диаграммы таблиц SQL :) |
|||
Шахматы по сети База данных. VIP. Таблицы на вырост | + 17 | ||
Улучшил свои практически отсутсвующие навыки по работе с таблицами SQL (в учебнике Троелсена оно как-то замутнее объяснялось). |
|||
Шахматы по сети База данных. Созидание | + 16 | ||
Создавать базу SQL в SQL Management Studio. Это попроще чем напрямую из Visual Studio. А вообще наверное надо через Entity Framework учиться такое делать. Ещё нашёл где менять язык SSMS (на втором скриншоте), но там это может зависеть от языка системы и языкового пакета в Visual Studio. |
|||
Шахматы по сети База данных. Упрощение | + 17 | ||
Упрощать базы SQL на стадии планирования :) Но остаётся вопрос, как назначать цвет и следить за тем, какой игрок каким цветом играет? Ну и базу игроков для статистики можно было бы оставить... |
|||
Шахматы по сети База данных. Планирование | + 17 | ||
Наконец то базы данных! |
|||
Шахматы по сети База данных. Management в студию! | + 18 | ||
Пришлось потратить несколько дней, чтобы на мобильном интернете проапгрейдить SQL Express до SQL Developer. А может и Экспресса хватило бы? Не порубить топором и не сжечь модем Yota. |
|||
Шахматы по сети Интерфейс. ЧЕТВЁРТЫЙ ФИНАЛЬНЫЙ УРОК | + 18 | ||
Стал лучше понимать работу со скриптами в Unity. Также столкнулся с багом/фичей с возможностью повесить 2 раза один скрипт на объект из-за чего не мог понять, почему у меня доска с фигурами создавалась дважды. Перекопать код в поисках причины создания двух копий доски с фигурами, а оказалось просто дважды повесил скрипт _-_ |
|||
Шахматы по сети Интерфейс. Долгожданное превращение | + 25 | ||
Ура, теперь пешка превращается в фигуры! По предложению Игромистра в уроке я подумал над тем, что ему не нравится в if (chess.Move(move) != chess) и мне кажется, дело в лишнем пересоздании доски для проверки. Я перекостылил кусок кода так, чтобы переменная доски создавалась один раз, она используется для проверки условия, а потом она же присваивается имеющейся переменной chess (проверил - работает): Chess probing = chess.Move(move); if (figure == "P" && strTo[1] == '8' || figure == "p" && strTo[1] == '1') if (probing != chess) { onPromotionMove = move; ShowPromotionFigures(figure); return; } chess = probing; А для начала игры с начала понятно, что надо сделать кнопку, которая пересоздаст chess и всё переинициализирует, но я не нашёл, как правильно почистить уже созданные в Unity объекты, потому что при переинициализации доски создаются дубликаты фигур. |
|||
Шахматы по сети Интерфейс. Выставка фигур | + 25 | ||
Идём дальше! |
|||
Шахматы по сети Интерфейс. Щепотка рефакторинга | + 25 | ||
Вынесли повторяющиеся куски кода в отдельные функции. |
|||
Шахматы по сети Интерфейс. VIP. Клетки прибытия | + 26 | ||
Повторил работу с делегатами. Шахматы становятся всё красивее и красивее. |
|||
Шахматы по сети Интерфейс. VIP. Клетки отправления | + 26 | ||
Научился отмечать клетки, с которых можно совершить ход. |
|||
Шахматы по сети Интерфейс. Проверка хода | + 26 | ||
В уроке всё выглядит очень просто, но самому до такой простоты пришлось бы доходить очень долго :) Чтобы пешку произвести в фигуру, думаю, надо, наверное, в FigureMoving добавить проверку достижения пешкой края доски и её превращения, чтобы в NextBoard передать уже готовую фигуру. Но остаётся вопрос - производить ли пешку безусловно в ферзя или оставлять выбор (достаточно выбора ферзь или конь). Но в случае выбора, надо добавлять в игру интерфейс для этого. |
|||
Шахматы по сети Интерфейс. Ход делегата | + 25 | ||
Повторил использование делегатов :) Помню, вначале я вообще не понимал как их использовать. И даже не потому, что суть непонятна (как раз понятна), но потому что нет нормального объяснения что и как в них инициализируется. Все объяснения в учебниках похожи на то, как в институте профессор на лекции по матанализу пишет на доске: "В этой формуле берём это и это, перемножаем, сокращаем, результат подставляем в эту формулу (формула на пол доски) и отсюда ОЧЕВИДНО, что ответ будет такой, но никак не такой". Понять инициализацию делегатов мне в своё время помогли только события, в которых привязка одного к другому более понятна невооружённому взгляду :) |
|||
Шахматы по сети Интерфейс. Начальная позиция | + 26 | ||
1) Научился генерировать шахматную доску и расставалять на ней фигуры с помощью подключённой библиотеки ChessRules.dll. 2) Все фигуры и клетки вначале создавались в двойном экземпляре, но в конце концов удалось отследить проблему. Оказывается я повесил на камеру два экземпляра скрипта генерации доски и они оба исправно отрабатывали. Так что теперь, если в юнити будут загадочные дубликаты объектов я буду знать где стоит искать в первую очередь :) Найти ошибку, как обычно. |
|||
Дневник успеха 2018-05-27 План на следующую неделю | + 25 | ||
Что сделал на неделе: 1) Продолжаю проходить курс "Шахматы по сети". Курс очень нравится! 2) Поправил пару недочётов в ранее реализованном красивом отображении шахматного поля с клетками и шахматными фигурами в консоли через Unicode. 3) Протестировал быстродействие нескольких комбинаций однопоточных и многопоточных методов с LINQ и без (https://www.videosharp.info/10080/checking/chess3=1935). 4) Узнал, что последняя версия Unity может работать с .NET 4.7.1! План на следующую неделю: 1) Продолжить проходить курс "Шахматы по сети"! 2) В уроке https://www.videosharp.info/10080/checking/chess3=1935 в одной из позиций для проверки правильности шахматного алгоритма проявляется небольшая ошибка (даже в однопоточном методе), причины которой я пока не нашёл, так что в бижайших планах пересмотреть уроки по созданию алгоритма и найти в чём там может быть проблема. 3) Лучше изучить как правильно писать многопоточные алгоритмы, чтобы избавиться от ошибок при мнопоточном расчёте шахматных ходов. |
|||
Шахматы по сети Интерфейс. Генерация объектов | + 26 | ||
Улучшил свои зания по Unity, а заодно, так как пересоздал проект из-за обновления Unity и потёр имевшийся скрипт board, то повторил уроки по написанию скрипта :) |
|||
Шахматы по сети Интерфейс. План действий | + 27 | ||
В архиве с картинками пустой картинки нет, так что я сам сделал прозрачный квадратик. Идём дальше! |
|||
Шахматы по сети Алгоритмы. VIP. Как пройти в библиотеку | + 28 | ||
Вначале были проблемы с подключением dll - Unity ругалась, что не может найти объект по ссылке, но в процессе решения проблемы (видимо поменял версию .NET на 3.5, но не перекомпилировал) выяснилось, что версии Unity 2018 работают с dll версии .NET 4.X. Для этого надо сделать следующее: File -> Build Settings - > Player Settings -> в Inspector найти абзац Configuration и там поменять .NET 3.5 Equivalent на .NET 4.X Equivalent. И подключаемая dll'ка может лежать не только в корне Assets или в той же папке, что и скрип, который к ней обращается, но и, например, в отдельной папке для dll'ок (которая внутри Assets разумеется). |
|||
Шахматы по сети Алгоритмы. VIP. Можно пройти? | + 23 | ||
Реализовал проверку на правильность хода перед пересозданием доски. Как это просто оказалось, оказывается! А я пытался проверки делать в дополнительном конструкторе... Позор мне _-_ Зато моё тестирование из предыдущего урока - https://www.videosharp.info/10080/checking/chess3=1935 - показало странные результаты. (Чтобы не повторять тут стену текста, подробности посмотрите в отчёте по предыдущему уроку). А по данному уроку, после реализации проверки возможности хода перед пересозданием board для начальной шахматной позиции, без сбора подробной статистики, но после нескольких тестов, можно точно только следующее (чтобы не постить длинную таблицу поверхностного тестирования передам результаты на словах, а подробнее можно на скриншоте посмотреть): 1) Появились сильные колебания производительности на глубинах расчёта ходов 1-3 и без многократных прогонов с вычисление среднего результата сказать определённо ничего нельзя, кроме следующих пунктов: 2) На глубине расчёта 3 стабильно повторяется ускорение расчётов в связках NextMovesLINQ() + YieldValidMoves() (1775ms против 2583ms) и NextMovesLINQ() + YieldValidMovesLINQ() (1815ms против 2327ms). 3) На 2-10% ускорились все варианты расчётов для глубины ходов 4. Выводы: 1) Для собственно проверки возможности хода в данном проекте значительной разницы при избавлении от лишних пересозданий board нет - скорость расчёта сильно скачет и явно в большей мере зависит от внешних факторов (сборщик мусора, троттлинг процессора и т.п.), а для проверки возможности хода фигурой глубина расчёта больше 1 не требуется. 2) Обращает внимание значительное ускорение расчётов для глубины 3 - 30-40%. Возможно есть какой-то sweet spot в количестве создаваемых объектов и вычислений над ними конкретно для LINQ. 3) Многопоточные вычисления продолжают лидировать для глубины расчёта 4, а вот про глубину 1-3 сказать определённо уже ничего нельзя - слишком сильные колебания результатов в каждом прогоне теста. 4) В любом случае для глубины вычислений 4 избавление от лишних board сказывается благотворно. Это всё выводы для начальной шахматной позиции без сделанных ходов. Для других позиций результаты могут отличаться. К следующему финальному уроку постараюсь сделать более подробное тестирование с вычислением средних результатов :) |
|||
Шахматы по сети Алгоритмы. VIP. Шахматное супертестирование | + 24 | ||
Это будет длинный отчёт, но, надеюсь, интересный! В общем я решил заморочиться и сделать много ненужной работы! Опытным путём удалось выяснить, что очень большие потери идут на пересоздание board, но как уменьшить расходы на пересоздание, чтобы при этом не сбивалось расположение фигур я пока не придумал. Тогда я подумал, как можно ускорить расчёты и решил распараллелить метод Program.NextMoves(). Сделать по-уму через Parallels.Foreach вначале не получилось, так как получались неверные результаты, и тогда я решил схитрить и сделать через PLINQ, а заодно потестить и простой LINQ. Вначале результаты были обнадёживающие, но после нескольких тестовых запусков пошли неверные результаты в многопотоке и тогда я всё-таки разобрался, как сделать многопоточный foreach. Ещё я попытался распараллелить метод Chess.YieldValidMoves(), но из этого ничего хорошего не вышло. Точнее, все распараллеливания считали быстро, но считали ерунду :) В ходе тестирования выяснилось также, что просто перевод foreach в LINQ иногда быстрее. В общем я провёл следующее тестирование: NextMoves - простой метод из урока, NextMovesLINQ - он же, но преобразованный в LINQ, NextMovesParallel - реализованный через Parallel.Foreach Этими методами я вызывал следующие методы: YieldValidMoves - метод из Chess, стостоящий из лесенки foreach, YieldValidMovesLINQ - он же, но преобразованный в LINQ Результаты, полученные на моём ноутбуке с процессором i5 8250 для стартового FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1": NextMoves() + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 16ms NextMovesLINQ() + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 10ms NextMovesParallel + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 63ms NextMoves() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 13ms NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 6ms NextMovesParallel() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 38ms NextMoves() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 123ms NextMovesLINQ() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 82ms NextMovesParallel() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 33ms NextMoves() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 94ms NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 93ms NextMovesParallel() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 26ms NextMoves() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 3012ms NextMovesLINQ() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 2583ms NextMovesParallel() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 513ms NextMoves() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 3067ms NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 2327ms NextMovesParallel() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 471ms NextMoves() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 55673ms NextMovesLINQ() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 54321ms NextMovesParallel() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 21467ms NextMoves() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 55400ms NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 55620ms NextMovesParallel() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 21483ms Выводы: 1) Распараллеливание вредно для глубины просчёта 1, но очень полезно начиная с 2 и далее. 2) Использование LINQ в обоих методах для глубины 1 даёт наибольшую скорость расчётов. 3) Начиная с глубины просчёта 2 распараллеливание очень ускоряет расчёты. 4) Использование распараллеливания в первом методе для глубины 2 и 3 совместно с LINQ во втором методе в целом даёт наибольший эффект, за исключением NextMovesLINQ() + YieldValidMovesLINQ() для глубины 2. 5) Совместное использование NextMovesLINQ() + YieldValidMovesLINQ(), а также NextMovesParallel() + YieldValidMovesLINQ() в глубине расчётов 4 начинает немного отставать от связок NextMovesLINQ() + YieldValidMoves() и NextMovesParallel() + YieldValidMovesLINQ(). Это результат одного из прогонов теста на "прогретом" процессоре. Конечно на малой глубине просчётов были заметные колебания во времени исполнения, но я не стал собирать базу прогонов и вычислять средние значения. Но "на глаз" значения в среднем такие и получаются. Баги: 1) В одном запуске из примерно 5 на глубине 1, несмотря на использование блокировки потоков связка NextMovesParallel() + YieldValidMoves() давало результат 21. 2) В одном запуске из примерно 3 на глубине 1, просто использование связки NextMovesParallel() + YieldValidMovesLINQ() давало результат 21 или 22. 3) На глубине просчётов выше 2 ошибок не замечено. Для других стартовых позиций я подробно быстродействие не тестировал, только проверил на соответствие верным результатам. Ошибки были только во второй стартовой позиции на сайте из шести: "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R". Так как в остальных 5 позициях всё было верно (за исключением лишней 1 или 2 при многопоточности на малой глубине), то, вероятно причина в том, что в коде не учитываются особые патовые ситуации. Заставить *почти* без ошибок работать распараллеливание. |
|||
Шахматы по сети Алгоритмы. ТРЕТИЙ ФИНАЛЬНЫЙ УРОК | + 26 | ||
Замечательно просто и понятно объяснено создание алгоритмов движения шахматных фигур, хотя, из-за недостатка опыта, иногда бывает сложно помнить, что именно делает вся цепочка методов в разных классах. Некоторые алгоритмы, в частности пересоздание доски, реализованы не оптимальным методом, но это, как я понимаю, специально, чтобы не усложнять подачу материала, к тому же, никто не запрещает проявить творчество в данном вопросе :) Собственно говоря, мне доставило большое удовольствие собственное "творчество" в написании вывода шахматной доски с клетками и шахматными фигурами из Unicode ^_^ Следить за логикой шахматных алгоритмов в цепочках методов в разных классах. |
|||
Шахматы по сети Алгоритмы. Шах и Мат! | + 26 | ||
Изящный алгоритм шаха, мата и пата :) Правда, мне кажется, что для полного понимания всех алгоритмов надо будет потом переделать всё самому, а то когда следуешь за учителем, то не в полной мере понимаешь, почему сделано именно так, а не иначе, чем когда приходишь к такому решению сам. |
|||
Шахматы по сети Алгоритмы. Защита короля | + 22 | ||
Оказалось, что проверка на шах ломает введённое копирование параметров из board в nextBoard, так что пока вернул ресурсоёмкую генерацию всех параметров при пересоздании доски, но позже вернусь к этому вопросу. Ещё нашёл и исправил ошибку с упущенными скобками, которые не позволяли ладье совершить рокировку. Ничто так не позволяет понять строение проекта, как дебаггинг :) |
|||
Шахматы по сети Алгоритмы. Королевский паркур | + 27 | ||
Всё прекрасно, но меня всё-таки немного смущают лестницы из if'ов. Попробовал switch с case when, но по размеру то же самое осталось. Остановился пока на if'ах, чуть разбавленных амперсандами :) |
|||
Шахматы по сети Алгоритмы. Допрыгалась! | + 24 | ||
Очень нравится повторное использование кода и простота и наглядность алгоритмов! |
|||
Шахматы по сети Алгоритмы. Рефакторинг на доске | + 24 | ||
Оень понравилась идея со скрытием функционала создания доски в наследуемом классе. Ещё последовав идее из видео, для ускорения создания новой доски сделал копирование полей из старой доски в новую (реализация есть на скриншотах). Правда я сделал это просто копированием, но может как-нибудь переделаю через MemberwiseClone, но не хочется слишком углубляться в рефакторинг, пока программа ещё только создаётся :) |
|||
Шахматы по сети Алгоритмы. Четвёртое превращение | + 24 | ||
Очень интересно следить за постепенным надстраиванием функционала. Правда, когда так много разных классов обращаются по цепочке методов к друг другу, иногда надо отвлекаться и проходить по всей цепочке, чтобы вспомнить, как именно всё работает :) |
|||
Шахматы по сети Алгоритмы. Храбрая пешка | + 21 | ||
Всё понятно. Только я засунул методы CanPawnGo(), CanPawnJump() и CanPawnEat() прямо внутрь метода CanPawnMove(), так как они используются только как вспомогательные для него. Ничего! |
|||
Шахматы по сети Алгоритмы. Дальнобойщики | + 22 | ||
Понравился хитрый хак с Math.Sign() и удивил неожиданный подход с реализацией проверки ходов слона и ладьи через ограничение на проверку ходов ферзя, а не через проверку ферзя через проверку как ладьи и как слона. |
|||
Шахматы по сети Алгоритмы. Ночью с Конём | + 25 | ||
Всё сделал на предыдущем уроке :) |
|||
Шахматы по сети Алгоритмы. Куда идёт Король | + 25 | ||
Научился ещё лучше разносить функции по предназначенным для этого классам :) Когда основа заранее продумана и написаны базовые фнкции, действительно добавлять новые возможности не сложно. Как, например, проверку ходов коня :) (есть на скриншоте). Но меня смущает такой момент: а не было бы логичнее использовать другую парадигму и наследовать фигуры от абстрактной фигуры (или использовать интерфейс), привязать положение на доске к экземпляру фигуры и напрямую опрашивать выбранную фигуру, на какие клетки она может пойти через универсальный или абстрактный метод, который как сейчас будет вызывать подходящий метод проверки в Moves? А то сейчас фигура "проявляется" только в момент попытки совершения хода, да и вся доска пересоздаётся каждый ход. А так мы бы меняли только состояние одной-двух фигур... |
|||
Шахматы по сети Алгоритмы. Генератор ходов | + 25 | ||
Попрактиковался в использовании yield. В общих чертах представляю, что это и как это работает (что-то вроде синтаксического сахара для автогенерации Observer/Observable (?)), но всегда сложно понять, где именно это стоит применить. Ещё довёл до ума красивое отображение шахматного поля! :) Если интересно, то я его вывожу вот так (ещё я тут использую нововведение в C# 7.0 - вложенные функции): static string ChessToAscii(Chess chess) { var sb = new StringBuilder(); sb.AppendLine(" a b c d e f g h "); sb.AppendLine(" +----------------+"); for (int y = 7; y >= 0; y--) { sb.Append(" "); sb.Append(y + 1); sb.Append(" |"); for (int x = 0; x < 8; x++) sb.Append(chess.GetFigureAt(x, y)); sb.AppendLine("| " + (y + 1)); } sb.AppendLine(" +----------------+"); sb.AppendLine(" A B C D E F G H "); return sb.ToString(); } static void Print(string text) { OutputEncoding = Encoding.Unicode; ConsoleColor fcOld = ForegroundColor; ConsoleColor bcOld = BackgroundColor; int c = 0; for (int i = 0; i < text.Length; i++, c++) { if (text[i] >= 'a' && text[i] <= 'z') { ForegroundColor = ConsoleColor.Red; } else if (text[i] >= 'A' && text[i] <= 'Z') { ForegroundColor = ConsoleColor.DarkYellow; } else ForegroundColor = ConsoleColor.Cyan; PrintChar(text[i], i); } ForegroundColor = fcOld; BackgroundColor = bcOld; void PrintChar(char f, int i) { if (i > 49 && i < 209) switch (f) { case 'K' : SetBGColor(); Write('\u2654'); break; case 'Q' : SetBGColor(); Write('\u2655'); break; case 'R' : SetBGColor(); Write('\u2656'); break; case 'B' : SetBGColor(); Write('\u2657'); break; case 'N' : SetBGColor(); Write('\u2658'); break; case 'P' : SetBGColor(); Write('\u2659'); break; case 'k' : SetBGColor(); Write('\u265A'); break; case 'q' : SetBGColor(); Write('\u265B'); break; case 'r' : SetBGColor(); Write('\u265C'); break; case 'b' : SetBGColor(); Write('\u265D'); break; case 'n' : SetBGColor(); Write('\u265E'); break; case 'p' : SetBGColor(); Write('\u265F'); break; case '.' : SetBGColor(); Write(" "); break; default: Write(f); break; } else Write(f); BackgroundColor = bcOld; void SetBGColor() { BackgroundColor = (i % 2 == 0) ? ConsoleColor.Gray : ConsoleColor.DarkGray; } } } Доделать красивый вывод шахматного поля. |
|||
Шахматы по сети Алгоритмы. Сборка фена | + 26 | ||
Понравился хак с sb = sb.Replace(eight.Substring(0, i), i.ToString()); Пока не досмотрел до этого места у меня крутились мысли о проходе строки с конца, запоминании места встречи "1", подсчёта количества последовательных единиц и замены подстроки по индексу на количество насчитанных единиц. Но способ из урока конечно проще :)))) Думал над предложением реализовать вывод знаков фигур из Unicode, но они сбивают всё форматирование шахматной доски и надо всё переписывать. Попробую сделать в следующем уроке. |
|||
Шахматы по сети Алгоритмы. Волшебные шахматы | + 29 | ||
Всё знакомо и понятно. Только я использовал свой вариант парсинга через StringBuilder. Ну ещё сделал отображение доски в консоли ещё красивее чем сделал в 19-м уроке (спасибо Ивану Воронину за напоминание о BackgroundColor ;)) Ничего |
|||
Шахматы по сети Классы. ВТОРОЙ ФИНАЛЬНЫЙ УРОК | + 27 | ||
Почитал про UML - это нужно отдельно учить :( Посмотрел как диаграмму классов показывает VS (так себе), почитал о куче разных способов отрисовки и остановился на варианте с указанием какой класс используется в конструкторе другого класса, потому что если рисовать ВСЕ взаимосвязи, то вместо наглядности достигается совершенно обратный эффект. Потом нарисовал в Иллюстраторе. Прочитать про UML и нарисовать. |
|||
Шахматы по сети Классы. Консольная доска | + 31 | ||
Думаю, что сложнее всего программировать пешку из-за учёта возможности первого хода на 2 клетки, превращения в фигуру и взятия на проходе, ещё сложными должны быть короли и ладьи из-за учёта рокировки, а король ещё и из-за расчёта шаха и мата. Далее по сложности идёт конь из-за возможности перепрыгивания фигур и ферзь из-за большого числа направлений движения. А самым простым, по моему мнению, должен быть слон. А по части текущего урока я решил развить тему украшательства и сделал отображение цвета клеток :) Возможно есть более элегантный вариант расчёта цвета для точки, но для данной строки я лучше не придумал :( Чтобы не писать всё время Console.ReadLine()/WriteLine() и т.д. я вначале в списке ссылок на используемые namespace добавляю using static System.Console; Привожу метод Print() вместе с методом ChessToAscii(), так как отображение цвета точек зависит от чётности индекса знака в строке: static string ChessToAscii(Chess chess) { StringBuilder sb = new StringBuilder(); sb.AppendLine(" a b c d e f g h "); sb.AppendLine(" +-----------------+"); for (int y = 7; y >= 0; y--) { sb.Append(y + 1); sb.Append(" | "); for (int x = 0; x < 8; x++) sb.Append(chess.GetFigureAt(x, y) + " "); sb.AppendLine("| " + (y + 1)); } sb.AppendLine(" +-----------------+"); sb.AppendLine(" A B C D E F G H "); return sb.ToString(); } static void Print(string text) { ConsoleColor old = ForegroundColor; int c = 0; for (int i = 0; i< text.Length; i++, c++) { if (text[i] == ' ') c--; if (text[i] >= 'a' && text[i] <= 'z') ForegroundColor = ConsoleColor.Red; else if (text[i] >= 'A' && text[i] <= 'Z') ForegroundColor = ConsoleColor.White; else if (text[i] == '.') ForegroundColor = ((i + c) % 2 == 0) ? ConsoleColor.Red : ConsoleColor.White; else ForegroundColor = ConsoleColor.Cyan; Write(text[i]); } ForegroundColor = old; } |
|||
Шахматы по сети Классы. Шахматная бюрократия | + 26 | ||
Продолжаю учиться устанавливать взаимодействия между множеством классов. Держать в голове структуру классов, так как если повторяешь за кем-то, а не сам придумываешь реализацию, то сложнее следить за развитием классов и их взаимодействием. Но эти навыки в любом случае пригодятся при попытках разобраться в чужом коде :) |
|||
Шахматы по сети Классы. Стой, кто идёт! | + 29 | ||
Продолжаю постигать тонкости ООП :) Может я слепой, но как я ни старался, я так и не смог найти ошибку в классе Moves(), как предлагает дполнительный 8-й пункт задания :( Так и не удалось найти ошибку :( |
|||
Шахматы по сети Классы. Квадратная матрица | + 27 | ||
Очень полезный курс по части разнесения ответсвенности по классам в соответствии с принципами ООП. Надо будет внимательно пересмотреть структуру классов, чтобы лучше уяснить, какой за что отвечает, так как мне за отсутствием практики сложно воспринимать так много классов - если бы я делал самостоятельно, то у меня было бы раза в два меньше классов, но более "тяжёлых" :) |
|||
Шахматы по сети Классы. Фигурой марш! | + 27 | ||
Подсмотрел способ сокращения кода с помощью прямой передачи подстроки в конструктор и понравилось приведение к перечислению напрямую из символа в строке. |
|||
Шахматы по сети Классы. Квадратная площадь | + 25 | ||
Большое спасибо за идею с вычитанием char - я до этого отнимал 48 для цифр, 65 для строчных или 97 для прописных, но такой способ гораздо нагляднее :) В остальном всё пока знакомо. Ничего. |
|||
Шахматы по сети Классы. Цветная фигура | + 21 | ||
Про Extention Methods интересно - надо с ними больше тренироваться. Ничего. |
|||
Шахматы по сети Классы. Шахматная библиотека | + 22 | ||
Очевидно, понадобится ещё класс для взаимодействия по сети. В ChessRules добавить, собственно, проверку правил. Ещё я бы добавил историю всех ходов с автовоспроизведением и, возможно, подключить шахматный движок для одиночной игры :) Пока всё просто. Но кроме вывода доски в допзадании я решил ещё сделать вывод фигуры по координатам и попробовать "оптимизировать" перевод строки fen в двумерный массив. И по возможности использую везде StringBuilder, чтобы снизить нагрузку на GarbageCollector; Перевод строки fen в двумерный массив: char[,] board = new char[8, 8]; void FenParse(string fen) { StringBuilder figures = new StringBuilder(); foreach (var c in fen) { if (c == ' ') break; if (c >= '0' && c <= '9') { figures.Append('.', c - 48); //Добавляю точки в количестве выведенном из char } else figures.Append(c); } for (int i = 0, x = 0, y = 0; i<figures.Length; i++) { if (x == 8) x = 0; if (figures[i] == '/') { y++; continue; } board[y, x++] = figures[i]; } } Вывод строки по координатам: void PrintFigure(char figure) { if (figure == '.') { WriteLine("There is no figure at this position"); return; } StringBuilder whatfigure = new StringBuilder(); whatfigure.Append("The figure is a"); string colour = (figure > 90) ? " Black" : " White"; whatfigure.Append(colour); string name = null; figure = (char) ((figure > 90) ? figure - 32 : figure); //Привожу знак фигуры к строчной букве switch (figure) { case 'P': { name = " Pawn"; break;} case 'R': { name = " Rook"; break; } case 'N': { name = " Knight"; break; } case 'B': { name = " Bishop"; break; } case 'Q': { name = " Queen"; break; } case 'K': { name = " King"; break; } } whatfigure.Append(name); WriteLine(whatfigure); } Ничего |
|||
Шахматы по сети Доска. VIP. Запуск в Интернете | + 27 | ||
Первая генерация страницы первый раз заняла минут 5, а последующие менее 30 секунд. Сделал сайт на бесплатном хостинге https://hinoookami.000webhostapp.com/uChess/index.html (Переотправка отчёта, так как вначале не разобрался с хостингом - никогда раньше не занимался этим). Разобраться с бесплатным хостингом. |
|||
Шахматы по сети Доска. VIP. Запуск на Android | + 25 | ||
Удалось запустить на эмуляторе. Unity сразу обнаружила запущенный из под VS2017 эмулятор Андроида и запустила на нём игру. Правда, надо подумать над ресайзом в портретной ориентации, потому что игра выравнивается только по высоте. |
|||
Шахматы по сети Доска. ПЕРВЫЙ ФИНАЛЬНЫЙ УРОК | + 26 | ||
Продолжаю знакомиться с Unity, в том числе и по урокам с официального сайта. Фигурам надо бы добавить автоподстройку под нужные координаты если она не ровно перемещена игроком. |
|||
Простой WPF WPF. Финальный урок | + 27 | ||
Потренировался в записи обзоров. |
|||
Шахматы по сети Доска. Запуск на Windows | + 20 | ||
Научился запускать компиляцию под нужную платформу :) На этом знакомство с курсом пока вынужденно заканчиваю. Ничего :) |
|||
Шахматы по сети Доска. Смещение | + 20 | ||
Очень просто и понятно объяснена реализация Drag'n'Drop. Ничего :) |
|||
Шахматы по сети Доска. Подцеп фигуры | + 19 | ||
Прикреплять коллайдер к объектам и получать объект по координатам клика. Ничего :) |
|||
Шахматы по сети Доска. Состояния переноса | + 19 | ||
Подключать скрипт к объекту :) Ничего! |
|||
Шахматы по сети Доска. Фигуры | + 22 | ||
Пока что всё прямо как в простом графическом редакторе :) Ничего :) |
|||
Шахматы по сети Доска. Установка Unity 3D | + 22 | ||
Шахматные термины: 175 символов/минута - 0 ошибок. Давно хотел попробовать Юнити. Когда-то даже поставил, но тогда я только начал читать про C# и скрипты меня привели в смусщение :) Сейчас, думаю, пойдёт веселее |
|||
Простой WPF WPF. Простая змейка. VIP урок. Длина тела. | + 17 | ||
Ура! Я доделал змейку! Как оказалось, проблема с отображением только головы змейки заключалась в моём ошибочном предположении, что ShapeDrawable являет собой структуру, а не класс. Под Андроидом простое решение как для WPF не подходит, так как канва не хранит в себе объекты и надо озаботиться коллекцией объектов самому. Возможно в других View с этим легче, но я делал напрямую через канву (не делайте так! :) ) Попутно научился снимать скриншоты и записывать видео через ADB :) Все сложности были решены на предыдущих уроках :) |
|||
Простой WPF WPF. Простая змейка. Победа и поражение. | + 19 | ||
Так как делал под Андроид, то научился ещё лучше справляться с весьма альтернативным программированием под Xamarin :) Понял, что в любой непонятной ситуации, когда на экран не выводится что-то, что должно выводиться, надо использовать лямбду RunOnUiThread :) В целом делать под Xamarin довольно интересно и тренирует выдержку, чтобы удерживаться от сквернословия :) Думаю, что большинство проблем от того, что я пытаюсь работать напрямую с канвой и лучше было бы использовать какую-нибудь библиотеку для работы с графикой, но думаю, я уж лучше сейчас помучаюсь с канвой, зато потом будет отдых, когда буду с графическими библиотеками колдовать :) Попытался сразу сделать растущий хвост змеи и выводом всего дела обходом коллекции, но всё равно только голова выводится, хотя в коллекции есть отдельные сегменты с разными координатами. Буду смотреть дальше. У меня сгорел ноут. Пусть он был старый и тормозной, но интеловский процессор позволял запускать эмулятор Андроида с интеловской библиотекой HAXM. Мой стационарник же на старом АМДшном Феноме, что вызывает много боли при попытке запустить эмулятор Вижуал Студии. Genymotion в принципе работает, но написанные мной программы в этом эмуляторе не запускаются - видимо несоответствие набора команд. Победить мне пока не удалось, как я не пытался менять набор команд при компиляции... Попробую в следующий раз Bluestacks - может заработает? А то держать телефон на проводе у компа не очень удобно. |
|||
Простой WPF WPF. Простая змейка. Управление движением. | + 16 | ||
Продолжаю делать под Андроид :) Добавил перемещение "змейки" по движению пальца. По сравнению со старым, добрым, простым и понятным (всё познаётся в сравнении) WPF, в Xamarin конечно есть свои странности. В частности расположение элементов на канве надо задавать в момент вызова события OnDraw, и значит там надо делать "вилку" - для изначального расположения "змейки" в центре экрана или для послудующих управляемых положений. Наверное, есть какой-то способ заранее узнать размеры будущей канвы и просто заранее задать начальные значения для змейки без лишнего условия? В любом случае пытаться разобраться в программировании под андроид мне очень понравилось, хотя и требует много времени, в том числе и из-за медленного взаимодействия студии и эмулятора. Далее надо сделать анимацию поплавнее и, возможно, заменить полный Invalidate, на локальный. Собирать по крупицам информацию о работе разных аспектов приложения и увязывание их вместе. Конечно, если бы я не пробовал делать приложения на WPF до этого, то мне было бы гораздо сложнее разобраться с Xamarin :) |
|||
Простой WPF WPF. Простая змейка. Таймер для еды. | + 15 | ||
Делаю под Андроид :) Когда в отчёте о выполнении предыдущего урока я предположил, что будет интересно, то и не представлял насколько, хотя и чувствовал смутную тревогу перед будущим... В общем суть такова: Нельзя просто так взять и нарисовать что-то на Canvas! То-есть можно, но только один раз при создании канвы. А чтобы сделать что-то по таймеру, то надо это делать через лямбду RunOnUiThread, да ещё делать перерисовку канвы через Invalidate каждый раз... И это не говоря о том, что Layout в виде Canvas представляет собой не xml/axml файл, а cs и логика для отрисовки находится в нём! (правда и в WPF можно всю или почти всю логику тоже в XAML запихнуть). Вот теперь думаю, как съеденную еду убирать в следующих уроках, чтобы сохранять змею: сохранять координаты еды и перерисовывать только тот участок (и также поступать с хвостом змеи) или перерисовывать всё? Будет ли разница в быстродействии вообще? Или вообще делать на Xamarin Forms - там вроде почти WPF. Но это будет неспортивно! Собрать воедино разрозненные сведения о рисовании на Canvas в Xamarin, о перерисовке Canvas и о работе с UI через события, чтобы сделать такую элементарную вещь, как обновление канвы по таймеру. Нигде нет внятного руководства, только мануалы по отдельным несвязанным азам работы и читаты оттуда же. Прямо закрытая секта разработчиков под Android какая-то! |
|||
Простой WPF WPF. Простая змейка. Эллипс на канвасе | + 16 | ||
Так как после написания Калейдоскопа и Арканоида под WPF в данном уроке я нового для себя не узнал бы, то я решил закрепить навыки написания приложения под Андроид, полученные при написании конвертера валют из этого курса и игры в цифры из курса Наноигры, и написать Змейку тоже под Андроид. Оказалось, что в Андроиде есть некоторые ограничения по использованию Canvas - его нельзя поместить внутрь какого-нибудь Layout'а, так что название программы и менюшки оказываются недоступными. Наверное, сделаю вызов нового Activity при старте игры. Но главное я смог вывести красный кружок - чувствую будет очень интересно это программировать! Пока ничего, но предвижу проблемы с реализацией управления жестами, так как с ними не работал ещё, а также пока не пробовал делать перемещение графических объектов по Canvas в Андроиде. |
|||
Шахматы по сети Классы. Архитектура проекта | + 16 | ||
Для меня здесь простым кажется проверка правил на C#, а сложным Unity, так как я с ним дел особо не имел, и Entity Framework с ASP.NET. Помю, когда делал уроки по учебнику Троелсена, там могут возникнуть проблемы с миграцией версий если EF уже что-то делала с базой SQL. Помню, что мне даже удалось это решить не имея особого представления ни о работе EF ни о функционировании SQL :))) |
|||
Нано-игры ФИНАЛЬНЫЙ УРОК | + 15 | ||
На этом курсе я потренировался в использовании делегатов и научился расчитывать пересечения шарика и кирпичиков в Арканоиде написанном под WPF, испортировать функции из user32.dll для управления координатами мышки для бота-кликера и начал пробовать свои силы в написании программ под андроид в игре с цифрами. Ещё собрался с духом для записи видео :) Написанные в рамках курса программы: 1) Арканоид - Arkanoid.rar (C# + WPF) 2) Скорость реакции - Reaction.rar (C# + WPF) 3) Игра Цифры - MobiDigits.rar (Под Андроид 5.1+. C# + Xamarin) 4) Бот для Цифр - ScreenClicker.rar (C# + WPF) Архивы исходников программ доступны по ссылке: https://drive.google.com/drive/folders/17p1RWDPMPiWib4j0gDg3yNgOwtPek-ZS Собраться с духом для записи видео и решить проблему с распространённой ошибкой с отказом микрофона на ноутбуке под управлением Windows 10. |
|||
Шахматы по сети План Шахматного проекта | + 16 | ||
C# - самостоятельно изучаю. Unity - когда-то вначале запустил и сделал по официальному руководству игру с катящимся шариком на C# без понятия, как оно работает :) ASP.NET, MS-SQL, Entity Framework - делал уроки из учебника Троелсена. |
|||
Простой WPF WPF. Конвертер валюты. Ньютон против Паскаля. | + 16 | ||
Сделал под Андроид, так что я теперь умею делать простенькие мобильные приложения :) Кроме того, что эта программа под Андроид, я ещё немного отступил от предложенного в уроке: 1) По возможности сделал классы, методы и поля статичными - кроме сохраняемых значений и передачи данных в основном тут идёт просто обработка и возврат значений. Да и хотел потренироваться со статичными классами. 2) Сделал ввод ключа в отдельном окне настроек - хотел понять, как работать с несколькими окнами в Андроиде и возвращать из них данные. 3) Сделал сохранение ключа в настройках приложения, чтобы не вводить его заново, да и надо это тоже уметь :) 4) Добавил выбор из какой валюты в какую конвертировать, а всё конвертирование сделал через decimal - оно как раз для финансовых данных :) 5) Соответственно, строка запроса к сайту формируется в StringBuilder с подстановкой из какой валюты в какие - запрашиваются сразу несколько валют в какие будет конвертироваться, чтобы не делать лишних запросов. Полученный JSON парсится и сохраняется в Dictionary по ключу из какой валюты конвертируется. 6) Веб-запрос формируется, если ключ исходной валюты отсутствует в Dictionary или имеющийся там Timestamp более чем на 2 часа отстаёт от текущего, иначе берётся из Dictionary. 7) Чтобы сделать программу более гибкой и не плодить кучу шаблонов для разных вариантов отпарсенного JSON хотел сначала работать с ним как с динамическим объектом через отражения с формированием запроса поля, составленным из строки GetField(from (например "USD") + to (например "RUB")), правда оказалось, что с JObject можно работать как с Dictionary, так что потренироваться с Reflection не удалось, но возможность составлять запрос по ключу из строк пригодилась :) 8) Курс для выбранных в данное время валют сохраняется, чтобы далеко не ходить при каждом событии ввода цифры :) 9) Так как бесплатный тарифный план на apilayer.net позволяет конвертировать только из USD, то при проверке поля success в ответе сайта подставляется курс 1.00. Но, при апгрейде тарифа всё теоретически должно само заработать и для других исходных валют. Можно конечно сделать в таком случае пересчёт валют через доллар, но это сделаю если вдруг почту засыпят требованиями выложить программу в PlayMarket :))))) тогда и интерфейс дошлифую :))) Сложным было заставить эмулятор коннектиться к сети, но в результате он сам заработал как надо. Не мог получить доступ к полям через Reflection, а оказалось, что оно и не нужно :( |
|||
Простой WPF WPF. Конвертер валюты. Курс валют в JSON. | + 15 | ||
Классы парсера и конвертера сделал пока статичными. Строку запроса собираю в StringBuilder, чтобы можно было подставлять ключ и валюты (пока куски строк указаны сразу, но в конце сделаю получение ключа из настроек в другом Activity и, возможно, отдельные запросы для разных валют). Для конвертации в несколько валют думаю между запросами курса для конуретной конвертации или запрашивать сразу несколько курсов и сохранять их в Dictionary. Также в настройки надо добавить периодичность обновления курсов, чтобы не выбрать месячный лимит запросов :) А так, пока программа уже рабочая (пока из долларов в рубли). На телефоне запускается, получает курс с сервера и пересчитывает. Но вот эмулятор Андроида выходить в и-нет не хочет никак :( |
|||
Простой WPF WPF. Конвертер валюты. Класс конвертации. | + 15 | ||
Делаю под Андроид, так что с прошлого урока научился простому способу исправлять баг VS с пропаданием кнопок переключения между дизайнером/кодом Layout'а. Хочу сделать в программе конвертацию с выбором между несколькими валютами, так что в следующем уроке надо подумать, как запрашивать с сайта курсы между разными валютами и как часто их обновлять. В такой программе это не принципиально, но вместо double я решил использовать decimal - финансовые расчёты как-никак :) Ещё размеры элементов надо причесать - но это уже в конце, как всё заработает. |
|||
Простой WPF WPF. Конвертер валюты. Макет программы | + 15 | ||
Так как делать в WPF такой интерфейс для меня уже слишком просто, то я решил усложнить себе задачу и делать программу под Андроид, и в процессе узнал много хорошего про создание интерфейса под Андроид и много плохого про стабильность работы дизайнера интерфейса под Андроид в Visual Studio... Найти решение для исправления ошибки с отображением дизайнера интерфейса. |
|||
Нано-игры Бот для Цифр | + 15 | ||
Научился импортировать функции из user32.dll. Так как делал в WPF, то научился справляться с очередными сложностями создания и отображения интерфейса :) Научился синхронизировать скроллинг 2-х TextBox и создавать отсутствующий в WPF NumericUpDown из TextBox и ScrollBar :) Ещё я всё-таки сделал запись координат в List, чтобы не гонять туда-сюда преобразования из string в int. вдобавок создал структуру для целочисленной точки, чтобы хранить координаты в int, а не в double и делать преобразование один раз при получении координаты курсора. Теоретически надо добавить таймер и произвольную задержку между нажатиями и уже можно сделать бота, полезного для... не знаю для чего, но полезного :) Испытывал на игре в цифры, которую я делал по предыдущему уроку, но только под Андроид :) Отследить ошибку, связанную с назначением текста при запуске программы по событию в Контрол, который сам ещё не инициализирован :) Ещё хотел сделать запись координат в TextBlock, но там слишком изощрённое создание скроллбара, так что я сделал TextBlock и запретил редактирование :) |
|||
Невидимка Невидимка - Сматываем удочки | + 16 | ||
Научился останавливать процесс :) Спасибо за курс. Узнал полезное на тему запуска и управления процессами. |
|||
Невидимка Невидимка - Тихий старт | + 15 | ||
Научился указывать параметры запуска процесса. |
|||
Невидимка Невидимка - На шухере | + 15 | ||
Делать Windows Forms, а потом урезать мне показалось чересчур хакерским способом и я сделал через создание Blank Application, а там по умолчанию делается консольная программа и выводится окно. Нашёл два решения данной проблемы: 1) Самое простое: в настройках проекта поменять тип программы с Console Application на Windows Application (подозреваю, что это эквивалентно решению из видеоурока :) ) 2) Прописать такое (на секунду окно появится, но потом исчезнет): class Program { [DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)] static extern bool FreeConsole(); static void Main() { FreeConsole(); // closes the console // Do stuff... } } |
|||
Невидимка Невидимка - Автозапуск | + 15 | ||
Научился записывать ключи в реестр :) |
|||
Невидимка Кто такая C# Невидимка? | + 15 | ||
Уже всё давно было настроено |
|||
Нано-игры Игра Цифры | + 15 | ||
Делать на WinForms мне показалось слишком скучно и я сделал под Android. Разумеется под Android не стал делать кнопки "Выход" :) А в остальном всё-то же самое. 1) Сделать одинаковые кнопки в GridLayout - а мне раньше WPF казался неочевидным и переусложнённым! 2) Заставить отображаться меню - если компилировать под версии Android старше 7.0, то там для просто отображения меню есть официальный костыль(!). Скомпилировал под 5.1 и всё заработало :) |
|||
Java Sweeper Финальный аккорд | + 16 | ||
Спасибо за продление возможности допройти курс до конца! Видеообзор, вы уж извините, я записывать не стал, так как просто не знаю, о чём говорить достаточно долго, чтобы это было оправдано :) Я уже пару лет самостоятельно изучаю C# и поэтому из данного курса кардинально нового про программирование я не узнал, но познакомился с особенностями создания программы на Java и увидел отличный пример ООП и рекурсивных алгоритмов (с рекурсиями мне надо тренироваться - не понимаю я их работы). Думаю для самообразования теперь пропробую переписать сапёра под Андроид :) PS: Ещё раз спасибо за отличный курс! |
|||
Java Sweeper Цифровой помощник сапёра | + 15 | ||
Отличный курс, спасибо! Теперь надо будет вдумчиво почитать написанный код для полного усвоения :) |
|||
Java Sweeper Открываем карты | + 15 | ||
Просто и понятно. |
|||
Java Sweeper Первая ошибка сапёра | + 15 | ||
Всё ясно! |
|||
Java Sweeper День Победы! | + 15 | ||
Всё понятно! |
|||
Java Sweeper Телеграмма о флажках | + 15 | ||
Спасибо за отличный курс! |
|||
Java Sweeper Учёт зарытых флагов | + 15 | ||
Всё понятно! |
|||
Java Sweeper Нулевая рекурсия | + 15 | ||
Да, с рекурсией надо потренироваться. Почему-то я её совсем не умею применять. |
|||
Java Sweeper Выбор из выбора | + 15 | ||
Всё знакомо и понятно. |
|||
Java Sweeper Алгоритм открывашки | + 15 | ||
Вроде всё понятно. Интересно посмотреть на реализацию алгоритма. |
|||
Java Sweeper Актуальное информирование | + 15 | ||
Продолжаю изучать отличный пример реализации ООП! |
|||
Java Sweeper Недетские состояния | + 15 | ||
раньше я перечислениями не пользовался, но не так давно научился их ценить и стараюсь всегда использовать где они помогают вносить ясность и избегать ошибок. |
|||
Java Sweeper Добро пожаловать! | + 15 | ||
Научился добавлять компонент Label в окно программы. |
|||
Java Sweeper Смена флагов | + 15 | ||
Отличное руководство по ООП! |
|||
Java Sweeper Схема правой педали | + 15 | ||
При нажатии правой кнопки метод проверяет флаг по координатам в массиве флагов и (не) меняет флаг в зависимости от установленного в клетке флага. (Всё-таки надо что-то сделать с окном отправки задания. Вот скриншот чего здесь и в подобных уроках прикладывать? Может можно сделать возможность автору урока отключать обязательность скриншота для подобных уроков? И среди разрешённых форматов скриншота естьMP3?! Ещё неплохо бы форум к сайту прикрутить!) |
|||
Java Sweeper Мышечный адаптер | + 15 | ||
Узнал как в Java добавляется событие нажатия кнопки мыши. |
|||
Java Sweeper Клавишные инструменты | + 15 | ||
Здесь пока всё знакомо! |
|||
Java Sweeper Королевская траншея | + 15 | ||
Всё понятно! |
|||
Java Sweeper Флаг над классом | + 15 | ||
При проигрыше игры setNobombToFlagedSafeBox ставит флажок ошибочной отметки, а setOpenedToClosedBombBox открывает все неоткрытые бомбы. Оба этих метода можно, думаю, выполнять в одном цикле сверяя массив координат флажков с массивом координат бомб. |
|||
Java Sweeper Дважды в одну воронку | + 15 | ||
Продолжаю узнавать, как правильно делать ООП :) |
|||
C# Android Создание класса с алгоритмом игры | + 15 | ||
Научился писать программу под андроид. На самом деле я давно хотел попробовать и даже поставил всё необходимое, но из-за череды проблем с установкой эмулятора забросил. А начав этот курс понял, что проблемы уже были в целом решены :) Даже удалось запустить программу на телефоне напрямую из под VS (вторая картинка). |
|||
C# Android Размещение экранных форм в дизайнере | + 15 | ||
1001 ------ 1003 1007 1015 1022 1027 1037 1048 1061 1069 1085 |
|||
C# Android Установка и запуск HAXM эмулятора Android | + 15 | ||
Научился терпеливо ждать запуска эмулятора - ноут для этого всё-таки не подходит :) При установке и запуске эмулятора могут возникнуть разные сложности. Например, менеджер эмуляторов ругался на недоступность пути к AVD, а на самом деле у него в настройках эмулятора просто не был выбран CPU/ABI (см. 2-й скриншот). |
|||
C# Android Установка Xamarin для Visual Studio | + 15 | ||
Всё необходимое уже стояло :) Судя по руководству на сайте, создание мобильного UI похоже на разметку XAML в WPF, так что если в общих чертах иметь представление о WPF, то особых проблем быть не должно, я считаю. |
|||
Java Sweeper Следующая цифра | + 15 | ||
Научился пользоваться функциями автоматического рефакторинга - раньше как-то не очень обращал на них внимания... |
|||
Java Sweeper Ограда из единиц | + 15 | ||
Ну здесь в принципе всё знакомо :) |
|||
Java Sweeper Сравнение координат | + 15 | ||
Научился делать override! |
|||
Java Sweeper Случайные бомборазмещения | + 15 | ||
В этом слайде всё было знакомо :) |
|||
Java Sweeper Тестовая бомба | + 15 | ||
Учусь применять принципы ООП на практике. |
|||
Java Sweeper Бомбанутый класс | + 15 | ||
Класс Bomb нужен, чтобы все (ну или почти все) поля и методы связанные с размещением и проверкой попадания по бомбам находились в одном выделенном классе (принцип ООП). |
|||
Java Sweeper За гранью видимого | + 15 | ||
Отточил навыки создания геттеров и сеттеров :) |
|||
Java Sweeper Матрица мира | + 15 | ||
Отличный курс! Уже начинает напрягать :) Мне в таких штуках всегда сложно уследить за множеством классов, содержащих в себе экземпляры других классов, которые вызываются третьими классами... Начинаюсь путаться в этом зверинце: что, зачем, как, откуда вызывается. Был бы интересен курс, где делается вначале монструозный "божественный класс" а потом постепенно рефакторится на множество мелких по принципам ООП. |
|||
Java Sweeper Игровая координата | + 15 | ||
Учусь делать фасадный класс :) Отличный курс! Показывает, что Java не сильно сложнее C# :) |
|||
Java Sweeper Фасадный класс | + 15 | ||
Структурный шаблон проектирования "Фасад" как раз и предназначен для упрощения работы с классами внутри программы, чтобы создать несколько методов в одном классе, однажды настроить их взаимодействие с другими классами и обращаться только к этим методам, а не вспоминать каждый раз где что лежит. |
|||
Java Sweeper Радуга картинок | + 15 | ||
Отличный курс! |
|||
Java Sweeper Полный список | + 15 | ||
Видно, что много труда вложено в то, чтобы всё объяснить попроще :) |
|||
Java Sweeper Установка размеров | + 15 | ||
Пока всё ещё понятно :) |
|||
Java Sweeper Статичная граница | + 15 | ||
С нетерпением жду, что будет дальше! |
|||
Java Sweeper Наши координаты | + 15 | ||
Всё просто и понятно! |
|||
Java Sweeper Карта классных сокровищ | + 15 | ||
Идею с enum для GameState если GameState может иметь больше 2-х значений надо запомнить! Идея с отдельным массивом для флагов понятна, так как они отдельные сущности и выполняют роль фильтра для ввода пользователя. А вот зачем отдельный массив бомб? Чтобы разнести массив отображаемого на экране и проверки опасности? Наверное это может ещё помочь в уменьшении числа проверок и сделать их линейными: event Click -> (if != flag) -> (if != bomb) -> matrix. Но тогда надо сделать переход от Flag к Bomb... (Это просто мысли вслух, так как очень интересно посмотреть реализацию и сравнить со своими идеями). |
|||
Java Sweeper Запускаемый jархив | + 15 | ||
Научился делать файл jar :) |
|||
Java Sweeper Источник ресурсов | + 15 | ||
Научился указывать папки, как ресурсы :) |
|||
Java Sweeper Картинка в кубике | + 15 | ||
Какие в Java интересные перечисления, однако! Ошибка во втором пункте задания (2. Создать приватноe пoле Image) и в видео на 0:40 "Мы просто сделаем приватное поле Image" (при этом делается публичное поле). И тут приватное поле не подходит. |
|||
Java Sweeper Первый цикл | + 15 | ||
Научился одному из циклов Java :) |
|||
Java Sweeper Перечисление кубиков | + 15 | ||
Всецело одобряю перечисления! Они вначале кажутся странной штукой, которая только всё усложняет, но если распробовать, то без них уже никуда ) Мне они ещё показались удобными для свойства Tag UIElement'ов в C# WPF и, наверное это изврат, но и как ключи для Dictionary в C#! |
|||
Java Sweeper Константные размеры | + 15 | ||
Всё знакомо и понятно ) |
|||
Java Sweeper Угловая бомба | + 15 | ||
Всё знакомо по C# ) Пока ничего сложного, но в этом же и идея? ) |
|||
Java Sweeper Загрузка и отображение | + 15 | ||
Всё просто и понятно! |
|||
Java Sweeper Импорт картинок | + 15 | ||
Отточил навыки копирования файлов ))) |
|||
Java Sweeper Метод рисования | + 15 | ||
Продолжаю узнавать особенности Java :) Да пока ничего... Когджа жесть начнётся? :) |
|||
Java Sweeper Раздельная инициализация | + 15 | ||
Приятно, что IntelliJ IDEA ворочается гораздо быстрее чем Visual Studio Ничего :) |
|||
Java Sweeper Пустая панель | + 15 | ||
Интересно, что Java требует больше "ручного" кода только для запуска чем C#... Пока ничего :) |
|||
Java Sweeper Полёт над классом | + 15 | ||
Интереснее всего функция InitPanel, так как в ней должно описываться соответсвие событий нажатия кнопок и обработчиков событий, без чего графический интерфейс не сделать. ну и интересно, как это на Java делается. Придумать, что предоставить в качестве скриншота... Надо что-то придумать с интерфейсом подачи результатов урока если скриншот не важен. |
|||
Java Sweeper Закрытие на выходе | + 15 | ||
Пока всё похоже на C# Пока ничего :) |
|||
Java Sweeper Простое окно | + 15 | ||
Научился указывать путь к JDK, так как IntelliJ IDEA сам его не нашёл. Нацти путь к JDK :) |
|||
Java Sweeper Легендарная игра | + 15 | ||
Научился устанавливать IntelliJ IDEA ) Дождаться окончания скачивания ) |
|||
Нано-игры Скорость реакции. Алгоритм и рекорд | + 15 | ||
Так как делал в WPF, то пытался добавить анимацию прогресс бара и изменение градиента кнопки старта при наведении и нажатии, но для этого надо переписать шаблоны используемых контролов, что требует больше XAML кода, чем вся логическая часть программы! (И всё равно не заработало! Но, надеюсь, когда-нибудь раздберусь и в этом.) Если не считать тщетные попытки в эффекты и анимацию WPF, то всё остальное вообще проще простого :) |
|||
Нано-игры Скорость реакции. Три картинки по таймеру | + 15 | ||
Тут всё просто и понятно, хотя я и делал в WPF. Предыдущие уроки были сложнее :) Ничего :) Вот в применённых мною расчётах траектории шарика через тригонометрию и проверки столкновений в Арканоиде был хардкор, а тут даже придумать что-то этакое для добавки челленджа не выходит :( |
|||
Нано-игры Скорость реакции. Блок-схема | + 15 | ||
Научился составлять блок-схемы :) Сначала начал описывать подробно, но схема получилась трудночитаемой, так что я убрал ненужный для алгоритмической схемы мусор вроде скобок методов и их точных цепочек вызоваю Нарисовать схему, что же ещё? :) |
|||
Нано-игры Арканоид - Шарик и кирпичики | + 15 | ||
Делал в WPF, так что научился двигать шарик высчитывая координаты и назначая новые для его положения в Canvas. Также научился пользоваться Dictionary, в который внёс смещения для 8 углов шарика относительно его Canvas.Left и Canvas.Top с ключами по enum, чтобы не запутаться от каких углов в каких направлениях делать проверку столкновения и делал проверку столкновения по левому верхнему углу с примевлением смещения из Dictionary в зависимости от направления движения шарика. Ещё научился работать с углами и внёс небольшой рандомизатор отскока шарика. Так как я хотел попробовать сам и сделать сразу универсальный способ, то специально не смотрел урок до конца и прошёл через несколько вариантов, начиная от самого простого с углом в пределах 0-90, вычислением смещения через Sin и Cos, указанием направления через enum (отличный простой способ для отскока от границ, но требует много преобразований для проверки пересечения граней кирпичиков) и вычислением пересечения через вычисление гипотенузы через исходное положение шарика и перпендикуляра к грани, до более универсального с Sin и Cos от углов в пределах 0 +- 360 и вычислением пересечения через перемножение векторов. Если интересно, то архив Arkanoid.rar доступен по ссылке https://drive.google.com/open?id=0B3ZnPiwGG8zpSVpXdmNsWndmSGM Код проверки столкновений у меня там не оптимизирован, а вот реализация градиента на кирппичиках в WPF может кому-то пригодиться :) |
|||
Нано-игры Арканоид - Уровень и ракетка | + 15 | ||
Делал в WPF, так что решил, зачем мне картинка из инета, если можно сделать анимированную заставку прямо так? ))) Сделал 6 кирпичиков и поместил их в ResourceDictionary откуда или подтягиваю их свойства по таймеру со смещением для анимации заставки или заполняю по координатам для игрового поля. Ракетку двигаю по таймеру, запускаемому с нажатием клавиш лево/право и останавливаю по событии отпускания клавиш лево/право. Ещё использую фишку из C# 7.0 с дополнительными условиями фильтрации в switch - полезно для раскраски кирпичей в пределах определённых координат. Если интересно, то по ссылке https://drive.google.com/drive/folders/0B3ZnPiwGG8zpSVpXdmNsWndmSGM лежит архив Arkanoid.rar Сложным было прочитать, что словарь ресурсов надо ещё вписать в App.xaml ))) |
|||
Демо софт Квадратный калейдоскоп | + 15 | ||
Делал в WPF, так что научился применять разные Brush и разные Transform ;) Логика такая: 1) для Canvas выбирается рандомный градиентный фон, берётся рандомный прямоугольник с рандомным градиентом на заливку и на рамку, поверх накладывается рандомный эллипс с рандомной заливкой радиальным градиентом и такой же рамкой, ну и сверху лепится рандомная линия с рандомным градиентом. 2) из этого великолепия делается кисть, которой закрашиваются создаваемые Canvas перед применением трансформаций вращения и отзеркаливания. 3) по таймеру Grid очищается и заполняется новыми повёрнутыми и отзеркаленными Canvas, которые обрамляются рамкой с толщиной 0 для обхода бага Canvas с не отсечением лишних элементов при помещении в ячейку Grid. Если интересно, то архив Kaleidoscope.rar лежит по ссылке https://drive.google.com/open?id=0B3ZnPiwGG8zpSVpXdmNsWndmSGM Так как я делал в WPF рандомный вращующийся калейдоскоп, то самым сложным было подружить вращение и отражение ячеек. В принципе, подружить удалось только с внесением бага - при вращении меняется масштаб элементов, но другой стороны это только добавляет психоделичности :) |
|||
Демо софт Текстовый процессор | + 10 | ||
Ничему новому :) Ничего. Всё давно известно и просто :) Делал в WPF. Тут ничего интересного или оригинального нет, но всё равно архив TextProcessor.rar лежит по ссылке :) |
|||
Нанософт Средняя оценка | + 11 | ||
Так как делаю в WPF, то научился быстрее создавать интерфейс :) Ну и потренировался в использовании делегатов. Найти ошибки внесённые дизайнером VS при присвоении названий и тегов кнопкам. Нажатия кнопок я обрабатывал в одном событии, которое брало enum из тега кнопок и передавало его на обработку. Если интересно, то по ссылке архив проекта Scores.rar |
|||
Демо софт Менеджер паролей | + 10 | ||
"Как я перестал боятся и полюбил WPF" (c) Так как я всё делаю в WPF, то научился создавать элементы интерфейса WPF в коде, добавлять их в Grid и заменять элементы в Grid. Да, я знаю, что создание элементов WPFв коде убивает саму идею WPF, но как делать правильно и быстро через WPF я ещё не научился, а вот как делать медленно и неправильно через код я в общем представлял :) Самым сложным было сделать динамический Grid с элементами интерфейса, потому что Grid для этого не предназначен и надо было использовать какой-нибудь Stack Panel. Но мне захотелось пойти сложным путём :) В общем я сделал менеджер паролей на WPF с динамическим добавлением и удалением записей. Хотел сделать ещё сохранение и чтение из файла... но в следующий раз. Если интересно, то по ссылке лежит архив проекта Password.rar |
|||
Демо игры C# чего начать программировать | + 10 | ||
[hide] Хочу потренироваться в написании программ на C# и в разработке графического интерфейса для них. |
|||
Демо софт Английские карточки | + 16 | ||
Так как я делал в WPF, то научился пользоваться элементом MediaElement :) Ещё для получения словарной карточки я использовал анонимные Tuple из C# 7.0 Сложным было подобрать костыль для отслеживания состояния плеера в WPF :) Я дополнил концепцию плеера из урока отключающимися кнопками пролистывания если дальше нет больше карточек и отключением плеера при повторном клике. Если интересно, как это выглядит на WPF, то по ссылке архив PuzzleEnglish.rar |
|||
Демо софт Двенадцать месяцев | + 16 | ||
Делал в WPF, так что научился преодолевать очередные трудности в WPF Заставить картинку растягиваться (не сразу заметил автоматом влепленный фиксированный размер для Image) и выбирать номер месяца из календаря (оказалось просто надо конвертировать в int). Если интересна реализация в WPF, то по ссылке архив TwelveMonths.rar |
|||
Демо игры VIP. Устный счёт | + 16 | ||
Делал в WPF, так что главным образом наконец научился менять вид кнопок при наведении и нажатии. Ну и ещё действие определяется по тегу нажатой кнопки, а тег представляет собой значение из enum ;) Самое сложное было сделать интерфейс в WPF ;) Спасибо за интересный урок! Если интересно, то по ссылке архив MindCount.rar |
|||
Демо софт Вам телеграмма! | + 16 | ||
Отточил навык клика по ссылке :) Перебороть лень и сделать несколько кликов... Интересно, что дальше в заданиях. А то учусь прогать, а практики нет. |
|||
Демо игры ФИНАЛЬНЫЙ УРОК | + 16 | ||
Хороший курс. Помогает отточить азы C#. Так как я задания делал в WPF, то самым сложным было найти, как сделать то, что так просто в WinForms, сложным способом в WPF :) Степан Лопатин Хороший курс. Рекомендую для начала :) |
|||
Демо игры Камень ножницы бумага | + 16 | ||
Узнал про свойство Tag у графических элементов, использовал enum для значений рук и, так как делал в WPF, научился использовать DispatcherTimer WPF :) Да здорово всё, чего уж тут... Если интересно, как я сделал это в WPF, то по ссылке есть архив RockPaperScissors.rar |
|||
Демо игры Бот для Быстрощёлка | + 16 | ||
Так как делал в WPF, то научился некоторым отличиям в работе WPF от WF ;-) Найти как правильно настроить кликанье в WPF ;-) Всё ОК! Если интерено, то можно посмотреть AutoClicker по ссылке на GoogleDrive. |
|||
Демо игры Игра Быстрощёлк | + 16 | ||
Научился преобразовывать переменные DateTime в секунды. Всё просто : ) Надо переходить на WPF. |
|||
Демо игры Лабиринт 2D - игра | + 16 | ||
Улучшил знания WPF (так как делал на нём) и научился отключать события таймера при рестарте уровня во избежание глюков :) Много печатанья в XAML для WPF Если интересно, то Labyrinth2D на WPF по приложенной ссылке. |
|||
Демо игры Лабиринт 2D - меню | + 16 | ||
Работать со звуком ;) Так как делал в WPF, то там самое сложное найти нужный пункт в меню свойств объекта ;) А вообще самое сложное выбрать из звуков Win10 подходящие для игры. Это, как я понимаю был вебинар? Может стоит заранее перед вебинаром объявлять список ресурсов, которые понядобятся, чтобы в процессе зрители не искали картинки и звуки или не пропускали эти этапы. Идея в том, чтобы те, кто имеет на руках всё необходимое мог сразу всё попробовать и сразу задать вопрос, если что-то не получится. |
|||
Демо игры Картинка с секретом | + 16 | ||
Так как я делал не через Windows Forms, а через WPF, то научился пользоваться Grid, Image и Button ;) Продраться сквозь мутную семантику XAML. Если бы я не прочитал к этому моенту несколько учебников по C#, то послал бы затею и делал бы на Windows Forms, хотя это и не тру. Windows Forms устарело... Надо урок по WPF. Для интересующихся прикладываю ссылку на архив (SecretPicture.rar), но учтите, что делал в VS2017. |
|||
Демо софт Вступительное слово | + 16 | ||
Сделать скриншот программы. Немного затянутое вступление :) |
|||
БД - Книжка оценок Проектирование БД «Книжка оценок» | |||
|
|||
Карточки памяти Подготовка формы | |||
|
|||
Теория ООП Инкапсуляция мечты | |||
|
|||
Нанософт Твоё портфолио | |||
|
|||
Комбинаторика Рекурсия. Фракталы. Спираль | |||
|
|||
Новые технологии Модульное тестирование | |||
|
|||
Базовый ASP.ект VIP. Установка домена | |||
|
|||
Коллекция графов ArrayList | |||
|
|||
Бурные потоки Вступление | |||
|
|||
Функционал ФП - Калькулятор | |||
|
|||
НаноШахматы HTML - Шахматные фигуры | |||
|
|||
Без конкуренции Как избежать конкуренции? | |||
|
|||
ASP.NET и GMaps Золотой ключик api | |||
|
|||
МикроШахматы В начале было поле | |||
|
|||
Простой WPF WPF. Аудиотреннинг | |||
|
|||
Factory Factory - Shapes - Три фигуры | |||
|
|||
On-line игра Модель игры | |||
|
|||
Начало здесь День №1. Создание микро-Привычки. | |||
|
|||
Дневник успеха 2018-09-23 : Много спать – дело не знать. | |||
|
|||
Повторение задач 10% Процесс пошёл! | |||
|